OSDN Git Service

2006-08-06 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151   ])
152
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         1)
156    (UNSPECV_EMMS                2)
157    (UNSPECV_LDMXCSR             3)
158    (UNSPECV_STMXCSR             4)
159    (UNSPECV_FEMMS               5)
160    (UNSPECV_CLFLUSH             6)
161    (UNSPECV_ALIGN               7)
162    (UNSPECV_MONITOR             8)
163    (UNSPECV_MWAIT               9)
164    (UNSPECV_CMPXCHG_1           10)
165    (UNSPECV_CMPXCHG_2           11)
166    (UNSPECV_XCHG                12)
167    (UNSPECV_LOCK                13)
168   ])
169
170 ;; Registers by name.
171 (define_constants
172   [(BP_REG                       6)
173    (SP_REG                       7)
174    (FLAGS_REG                   17)
175    (FPSR_REG                    18)
176    (DIRFLAG_REG                 19)
177   ])
178
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
181
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first.  This allows for better optimization.  For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
186
187 \f
188 ;; Processor type.  This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191   (const (symbol_ref "ix86_tune")))
192
193 ;; A basic instruction type.  Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196   "other,multi,
197    alu,alu1,negnot,imov,imovx,lea,
198    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199    icmp,test,ibr,setcc,icmov,
200    push,pop,call,callv,leave,
201    str,cld,
202    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203    sselog,sselog1,sseiadd,sseishft,sseimul,
204    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206   (const_string "other"))
207
208 ;; Main data type used by the insn
209 (define_attr "mode"
210   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211   (const_string "unknown"))
212
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216            (const_string "i387")
217          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219            (const_string "sse")
220          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221            (const_string "mmx")
222          (eq_attr "type" "other")
223            (const_string "unknown")]
224          (const_string "integer")))
225
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229            (const_int 0)
230          (eq_attr "unit" "i387,sse,mmx")
231            (const_int 0)
232          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233                           imul,icmp,push,pop")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235          (eq_attr "type" "imov,test")
236            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237          (eq_attr "type" "call")
238            (if_then_else (match_operand 0 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          (eq_attr "type" "callv")
242            (if_then_else (match_operand 1 "constant_call_address_operand" "")
243              (const_int 4)
244              (const_int 0))
245          ;; We don't know the size before shorten_branches.  Expect
246          ;; the instruction to fit for better scheduling.
247          (eq_attr "type" "ibr")
248            (const_int 1)
249          ]
250          (symbol_ref "/* Update immediate_length and other attributes! */
251                       gcc_unreachable (),1")))
252
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256            (const_int 0)
257          (and (eq_attr "type" "call")
258               (match_operand 0 "constant_call_address_operand" ""))
259              (const_int 0)
260          (and (eq_attr "type" "callv")
261               (match_operand 1 "constant_call_address_operand" ""))
262              (const_int 0)
263          ]
264          (symbol_ref "ix86_attr_length_address_default (insn)")))
265
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268   (if_then_else (ior (eq_attr "mode" "HI")
269                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270     (const_int 1)
271     (const_int 0)))
272
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" "" 
275   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276     (const_int 1)
277     (const_int 0)))
278
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281   (if_then_else 
282     (ior (eq_attr "type" "imovx,setcc,icmov")
283          (eq_attr "unit" "sse,mmx"))
284     (const_int 1)
285     (const_int 0)))
286
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289   (cond [(and (eq_attr "mode" "DI")
290               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291            (const_int 1)
292          (and (eq_attr "mode" "QI")
293               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294                   (const_int 0)))
295            (const_int 1)
296          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297              (const_int 0))
298            (const_int 1)
299         ]
300         (const_int 0)))
301
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304   (cond [(eq_attr "type" "str,cld,leave")
305            (const_int 0)
306          (eq_attr "unit" "i387")
307            (const_int 0)
308          (and (eq_attr "type" "incdec")
309               (ior (match_operand:SI 1 "register_operand" "")
310                    (match_operand:HI 1 "register_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "push")
313               (not (match_operand 1 "memory_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "pop")
316               (not (match_operand 0 "memory_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "imov")
319               (ior (and (match_operand 0 "register_operand" "")
320                         (match_operand 1 "immediate_operand" ""))
321                    (ior (and (match_operand 0 "ax_reg_operand" "")
322                              (match_operand 1 "memory_displacement_only_operand" ""))
323                         (and (match_operand 0 "memory_displacement_only_operand" "")
324                              (match_operand 1 "ax_reg_operand" "")))))
325            (const_int 0)
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328              (const_int 0)
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331              (const_int 0)
332          ]
333          (const_int 1)))
334
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340   (cond [(eq_attr "type" "other,multi,fistp,frndint")
341            (const_int 16)
342          (eq_attr "type" "fcmp")
343            (const_int 4)
344          (eq_attr "unit" "i387")
345            (plus (const_int 2)
346                  (plus (attr "prefix_data16")
347                        (attr "length_address")))]
348          (plus (plus (attr "modrm")
349                      (plus (attr "prefix_0f")
350                            (plus (attr "prefix_rex")
351                                  (const_int 1))))
352                (plus (attr "prefix_rep")
353                      (plus (attr "prefix_data16")
354                            (plus (attr "length_immediate")
355                                  (attr "length_address")))))))
356
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
360
361 (define_attr "memory" "none,load,store,both,unknown"
362   (cond [(eq_attr "type" "other,multi,str")
363            (const_string "unknown")
364          (eq_attr "type" "lea,fcmov,fpspc,cld")
365            (const_string "none")
366          (eq_attr "type" "fistp,leave")
367            (const_string "both")
368          (eq_attr "type" "frndint")
369            (const_string "load")
370          (eq_attr "type" "push")
371            (if_then_else (match_operand 1 "memory_operand" "")
372              (const_string "both")
373              (const_string "store"))
374          (eq_attr "type" "pop")
375            (if_then_else (match_operand 0 "memory_operand" "")
376              (const_string "both")
377              (const_string "load"))
378          (eq_attr "type" "setcc")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "store")
381              (const_string "none"))
382          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383            (if_then_else (ior (match_operand 0 "memory_operand" "")
384                               (match_operand 1 "memory_operand" ""))
385              (const_string "load")
386              (const_string "none"))
387          (eq_attr "type" "ibr")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "load")
390              (const_string "none"))
391          (eq_attr "type" "call")
392            (if_then_else (match_operand 0 "constant_call_address_operand" "")
393              (const_string "none")
394              (const_string "load"))
395          (eq_attr "type" "callv")
396            (if_then_else (match_operand 1 "constant_call_address_operand" "")
397              (const_string "none")
398              (const_string "load"))
399          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400               (match_operand 1 "memory_operand" ""))
401            (const_string "both")
402          (and (match_operand 0 "memory_operand" "")
403               (match_operand 1 "memory_operand" ""))
404            (const_string "both")
405          (match_operand 0 "memory_operand" "")
406            (const_string "store")
407          (match_operand 1 "memory_operand" "")
408            (const_string "load")
409          (and (eq_attr "type"
410                  "!alu1,negnot,ishift1,
411                    imov,imovx,icmp,test,
412                    fmov,fcmp,fsgn,
413                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414                    mmx,mmxmov,mmxcmp,mmxcvt")
415               (match_operand 2 "memory_operand" ""))
416            (const_string "load")
417          (and (eq_attr "type" "icmov")
418               (match_operand 3 "memory_operand" ""))
419            (const_string "load")
420         ]
421         (const_string "none")))
422
423 ;; Indicates if an instruction has both an immediate and a displacement.
424
425 (define_attr "imm_disp" "false,true,unknown"
426   (cond [(eq_attr "type" "other,multi")
427            (const_string "unknown")
428          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429               (and (match_operand 0 "memory_displacement_operand" "")
430                    (match_operand 1 "immediate_operand" "")))
431            (const_string "true")
432          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433               (and (match_operand 0 "memory_displacement_operand" "")
434                    (match_operand 2 "immediate_operand" "")))
435            (const_string "true")
436         ]
437         (const_string "false")))
438
439 ;; Indicates if an FP operation has an integer source.
440
441 (define_attr "fp_int_src" "false,true"
442   (const_string "false"))
443
444 ;; Defines rounding mode of an FP operation.
445
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447   (const_string "any"))
448
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451   [(set_attr "length" "128")
452    (set_attr "type" "multi")])
453
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
456  
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
459
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
462
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
465  
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
468
469 \f
470 ;; Scheduling descriptions
471
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
476
477 \f
478 ;; Operand and operator predicates and constraints
479
480 (include "predicates.md")
481 (include "constraints.md")
482
483 \f
484 ;; Compare instructions.
485
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
489
490 (define_expand "cmpti"
491   [(set (reg:CC FLAGS_REG)
492         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493                     (match_operand:TI 1 "x86_64_general_operand" "")))]
494   "TARGET_64BIT"
495 {
496   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497     operands[0] = force_reg (TImode, operands[0]);
498   ix86_compare_op0 = operands[0];
499   ix86_compare_op1 = operands[1];
500   DONE;
501 })
502
503 (define_expand "cmpdi"
504   [(set (reg:CC FLAGS_REG)
505         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506                     (match_operand:DI 1 "x86_64_general_operand" "")))]
507   ""
508 {
509   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510     operands[0] = force_reg (DImode, operands[0]);
511   ix86_compare_op0 = operands[0];
512   ix86_compare_op1 = operands[1];
513   DONE;
514 })
515
516 (define_expand "cmpsi"
517   [(set (reg:CC FLAGS_REG)
518         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519                     (match_operand:SI 1 "general_operand" "")))]
520   ""
521 {
522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523     operands[0] = force_reg (SImode, operands[0]);
524   ix86_compare_op0 = operands[0];
525   ix86_compare_op1 = operands[1];
526   DONE;
527 })
528
529 (define_expand "cmphi"
530   [(set (reg:CC FLAGS_REG)
531         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532                     (match_operand:HI 1 "general_operand" "")))]
533   ""
534 {
535   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536     operands[0] = force_reg (HImode, operands[0]);
537   ix86_compare_op0 = operands[0];
538   ix86_compare_op1 = operands[1];
539   DONE;
540 })
541
542 (define_expand "cmpqi"
543   [(set (reg:CC FLAGS_REG)
544         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545                     (match_operand:QI 1 "general_operand" "")))]
546   "TARGET_QIMODE_MATH"
547 {
548   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549     operands[0] = force_reg (QImode, operands[0]);
550   ix86_compare_op0 = operands[0];
551   ix86_compare_op1 = operands[1];
552   DONE;
553 })
554
555 (define_insn "cmpdi_ccno_1_rex64"
556   [(set (reg FLAGS_REG)
557         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558                  (match_operand:DI 1 "const0_operand" "n,n")))]
559   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560   "@
561    test{q}\t{%0, %0|%0, %0}
562    cmp{q}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "test,icmp")
564    (set_attr "length_immediate" "0,1")
565    (set_attr "mode" "DI")])
566
567 (define_insn "*cmpdi_minus_1_rex64"
568   [(set (reg FLAGS_REG)
569         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571                  (const_int 0)))]
572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573   "cmp{q}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "DI")])
576
577 (define_expand "cmpdi_1_rex64"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580                     (match_operand:DI 1 "general_operand" "")))]
581   "TARGET_64BIT"
582   "")
583
584 (define_insn "cmpdi_1_insn_rex64"
585   [(set (reg FLAGS_REG)
586         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589   "cmp{q}\t{%1, %0|%0, %1}"
590   [(set_attr "type" "icmp")
591    (set_attr "mode" "DI")])
592
593
594 (define_insn "*cmpsi_ccno_1"
595   [(set (reg FLAGS_REG)
596         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597                  (match_operand:SI 1 "const0_operand" "n,n")))]
598   "ix86_match_ccmode (insn, CCNOmode)"
599   "@
600    test{l}\t{%0, %0|%0, %0}
601    cmp{l}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "test,icmp")
603    (set_attr "length_immediate" "0,1")
604    (set_attr "mode" "SI")])
605
606 (define_insn "*cmpsi_minus_1"
607   [(set (reg FLAGS_REG)
608         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609                            (match_operand:SI 1 "general_operand" "ri,mr"))
610                  (const_int 0)))]
611   "ix86_match_ccmode (insn, CCGOCmode)"
612   "cmp{l}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "SI")])
615
616 (define_expand "cmpsi_1"
617   [(set (reg:CC FLAGS_REG)
618         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619                     (match_operand:SI 1 "general_operand" "ri,mr")))]
620   ""
621   "")
622
623 (define_insn "*cmpsi_1_insn"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626                  (match_operand:SI 1 "general_operand" "ri,mr")))]
627   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628     && ix86_match_ccmode (insn, CCmode)"
629   "cmp{l}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "SI")])
632
633 (define_insn "*cmphi_ccno_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636                  (match_operand:HI 1 "const0_operand" "n,n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "@
639    test{w}\t{%0, %0|%0, %0}
640    cmp{w}\t{%1, %0|%0, %1}"
641   [(set_attr "type" "test,icmp")
642    (set_attr "length_immediate" "0,1")
643    (set_attr "mode" "HI")])
644
645 (define_insn "*cmphi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648                            (match_operand:HI 1 "general_operand" "ri,mr"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{w}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "HI")])
654
655 (define_insn "*cmphi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658                  (match_operand:HI 1 "general_operand" "ri,mr")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660    && ix86_match_ccmode (insn, CCmode)"
661   "cmp{w}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "HI")])
664
665 (define_insn "*cmpqi_ccno_1"
666   [(set (reg FLAGS_REG)
667         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668                  (match_operand:QI 1 "const0_operand" "n,n")))]
669   "ix86_match_ccmode (insn, CCNOmode)"
670   "@
671    test{b}\t{%0, %0|%0, %0}
672    cmp{b}\t{$0, %0|%0, 0}"
673   [(set_attr "type" "test,icmp")
674    (set_attr "length_immediate" "0,1")
675    (set_attr "mode" "QI")])
676
677 (define_insn "*cmpqi_1"
678   [(set (reg FLAGS_REG)
679         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680                  (match_operand:QI 1 "general_operand" "qi,mq")))]
681   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682     && ix86_match_ccmode (insn, CCmode)"
683   "cmp{b}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "icmp")
685    (set_attr "mode" "QI")])
686
687 (define_insn "*cmpqi_minus_1"
688   [(set (reg FLAGS_REG)
689         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690                            (match_operand:QI 1 "general_operand" "qi,mq"))
691                  (const_int 0)))]
692   "ix86_match_ccmode (insn, CCGOCmode)"
693   "cmp{b}\t{%1, %0|%0, %1}"
694   [(set_attr "type" "icmp")
695    (set_attr "mode" "QI")])
696
697 (define_insn "*cmpqi_ext_1"
698   [(set (reg FLAGS_REG)
699         (compare
700           (match_operand:QI 0 "general_operand" "Qm")
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 1 "ext_register_operand" "Q")
704               (const_int 8)
705               (const_int 8)) 0)))]
706   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707   "cmp{b}\t{%h1, %0|%0, %h1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1_rex64"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "register_operand" "Q")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_2"
726   [(set (reg FLAGS_REG)
727         (compare
728           (subreg:QI
729             (zero_extract:SI
730               (match_operand 0 "ext_register_operand" "Q")
731               (const_int 8)
732               (const_int 8)) 0)
733           (match_operand:QI 1 "const0_operand" "n")))]
734   "ix86_match_ccmode (insn, CCNOmode)"
735   "test{b}\t%h0, %h0"
736   [(set_attr "type" "test")
737    (set_attr "length_immediate" "0")
738    (set_attr "mode" "QI")])
739
740 (define_expand "cmpqi_ext_3"
741   [(set (reg:CC FLAGS_REG)
742         (compare:CC
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "general_operand" "")))]
749   ""
750   "")
751
752 (define_insn "cmpqi_ext_3_insn"
753   [(set (reg FLAGS_REG)
754         (compare
755           (subreg:QI
756             (zero_extract:SI
757               (match_operand 0 "ext_register_operand" "Q")
758               (const_int 8)
759               (const_int 8)) 0)
760           (match_operand:QI 1 "general_operand" "Qmn")))]
761   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762   "cmp{b}\t{%1, %h0|%h0, %1}"
763   [(set_attr "type" "icmp")
764    (set_attr "mode" "QI")])
765
766 (define_insn "cmpqi_ext_3_insn_rex64"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
779
780 (define_insn "*cmpqi_ext_4"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (subreg:QI
789             (zero_extract:SI
790               (match_operand 1 "ext_register_operand" "Q")
791               (const_int 8)
792               (const_int 8)) 0)))]
793   "ix86_match_ccmode (insn, CCmode)"
794   "cmp{b}\t{%h1, %h0|%h0, %h1}"
795   [(set_attr "type" "icmp")
796    (set_attr "mode" "QI")])
797
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares.  Which is what
801 ;; the old patterns did, but with many more of them.
802
803 (define_expand "cmpxf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806                     (match_operand:XF 1 "nonmemory_operand" "")))]
807   "TARGET_80387"
808 {
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
812 })
813
814 (define_expand "cmpdf"
815   [(set (reg:CC FLAGS_REG)
816         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819 {
820   ix86_compare_op0 = operands[0];
821   ix86_compare_op1 = operands[1];
822   DONE;
823 })
824
825 (define_expand "cmpsf"
826   [(set (reg:CC FLAGS_REG)
827         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829   "TARGET_80387 || TARGET_SSE_MATH"
830 {
831   ix86_compare_op0 = operands[0];
832   ix86_compare_op1 = operands[1];
833   DONE;
834 })
835
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
838 ;;
839 ;; CCFPmode     compare with exceptions
840 ;; CCFPUmode    compare with no exceptions
841
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
844
845 (define_insn "*cmpfp_0"
846   [(set (match_operand:HI 0 "register_operand" "=a")
847         (unspec:HI
848           [(compare:CCFP
849              (match_operand 1 "register_operand" "f")
850              (match_operand 2 "const0_operand" "X"))]
851         UNSPEC_FNSTSW))]
852   "TARGET_80387
853    && FLOAT_MODE_P (GET_MODE (operands[1]))
854    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855   "* return output_fp_compare (insn, operands, 0, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "unit" "i387")
858    (set (attr "mode")
859      (cond [(match_operand:SF 1 "" "")
860               (const_string "SF")
861             (match_operand:DF 1 "" "")
862               (const_string "DF")
863            ]
864            (const_string "XF")))])
865
866 (define_insn "*cmpfp_sf"
867   [(set (match_operand:HI 0 "register_operand" "=a")
868         (unspec:HI
869           [(compare:CCFP
870              (match_operand:SF 1 "register_operand" "f")
871              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
872           UNSPEC_FNSTSW))]
873   "TARGET_80387"
874   "* return output_fp_compare (insn, operands, 0, 0);"
875   [(set_attr "type" "multi")
876    (set_attr "unit" "i387")
877    (set_attr "mode" "SF")])
878
879 (define_insn "*cmpfp_df"
880   [(set (match_operand:HI 0 "register_operand" "=a")
881         (unspec:HI
882           [(compare:CCFP
883              (match_operand:DF 1 "register_operand" "f")
884              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
885           UNSPEC_FNSTSW))]
886   "TARGET_80387"
887   "* return output_fp_compare (insn, operands, 0, 0);"
888   [(set_attr "type" "multi")
889    (set_attr "unit" "i387")
890    (set_attr "mode" "DF")])
891
892 (define_insn "*cmpfp_xf"
893   [(set (match_operand:HI 0 "register_operand" "=a")
894         (unspec:HI
895           [(compare:CCFP
896              (match_operand:XF 1 "register_operand" "f")
897              (match_operand:XF 2 "register_operand" "f"))]
898           UNSPEC_FNSTSW))]
899   "TARGET_80387"
900   "* return output_fp_compare (insn, operands, 0, 0);"
901   [(set_attr "type" "multi")
902    (set_attr "unit" "i387")
903    (set_attr "mode" "XF")])
904
905 (define_insn "*cmpfp_u"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFPU
909              (match_operand 1 "register_operand" "f")
910              (match_operand 2 "register_operand" "f"))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387
913    && FLOAT_MODE_P (GET_MODE (operands[1]))
914    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915   "* return output_fp_compare (insn, operands, 0, 1);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set (attr "mode")
919      (cond [(match_operand:SF 1 "" "")
920               (const_string "SF")
921             (match_operand:DF 1 "" "")
922               (const_string "DF")
923            ]
924            (const_string "XF")))])
925
926 (define_insn "*cmpfp_<mode>"
927   [(set (match_operand:HI 0 "register_operand" "=a")
928         (unspec:HI
929           [(compare:CCFP
930              (match_operand 1 "register_operand" "f")
931              (match_operator 3 "float_operator"
932                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933           UNSPEC_FNSTSW))]
934   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935    && FLOAT_MODE_P (GET_MODE (operands[1]))
936    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937   "* return output_fp_compare (insn, operands, 0, 0);"
938   [(set_attr "type" "multi")
939    (set_attr "unit" "i387")
940    (set_attr "fp_int_src" "true")
941    (set_attr "mode" "<MODE>")])
942
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
945
946 (define_insn "x86_fnstsw_1"
947   [(set (match_operand:HI 0 "register_operand" "=a")
948         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
949   "TARGET_80387"
950   "fnstsw\t%0"
951   [(set_attr "length" "2")
952    (set_attr "mode" "SI")
953    (set_attr "unit" "i387")])
954
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
957
958 (define_insn "x86_sahf_1"
959   [(set (reg:CC FLAGS_REG)
960         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
961   "!TARGET_64BIT"
962   "sahf"
963   [(set_attr "length" "1")
964    (set_attr "athlon_decode" "vector")
965    (set_attr "mode" "SI")])
966
967 ;; Pentium Pro can do steps 1 through 3 in one go.
968
969 (define_insn "*cmpfp_i_mixed"
970   [(set (reg:CCFP FLAGS_REG)
971         (compare:CCFP (match_operand 0 "register_operand" "f,x")
972                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
973   "TARGET_MIX_SSE_I387
974    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 0);"
977   [(set_attr "type" "fcmp,ssecomi")
978    (set (attr "mode")
979      (if_then_else (match_operand:SF 1 "" "")
980         (const_string "SF")
981         (const_string "DF")))
982    (set_attr "athlon_decode" "vector")])
983
984 (define_insn "*cmpfp_i_sse"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "x")
987                       (match_operand 1 "nonimmediate_operand" "xm")))]
988   "TARGET_SSE_MATH
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
998
999 (define_insn "*cmpfp_i_i387"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "f")
1002                       (match_operand 1 "register_operand" "f")))]
1003   "TARGET_80387 && TARGET_CMOVE
1004    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005    && FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "fcmp")
1009    (set (attr "mode")
1010      (cond [(match_operand:SF 1 "" "")
1011               (const_string "SF")
1012             (match_operand:DF 1 "" "")
1013               (const_string "DF")
1014            ]
1015            (const_string "XF")))
1016    (set_attr "athlon_decode" "vector")])
1017
1018 (define_insn "*cmpfp_iu_mixed"
1019   [(set (reg:CCFPU FLAGS_REG)
1020         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022   "TARGET_MIX_SSE_I387
1023    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "fcmp,ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_sse"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "x")
1036                        (match_operand 1 "nonimmediate_operand" "xm")))]
1037   "TARGET_SSE_MATH
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_387"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "f")
1051                        (match_operand 1 "register_operand" "f")))]
1052   "TARGET_80387 && TARGET_CMOVE
1053    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054    && FLOAT_MODE_P (GET_MODE (operands[0]))
1055    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056   "* return output_fp_compare (insn, operands, 1, 1);"
1057   [(set_attr "type" "fcmp")
1058    (set (attr "mode")
1059      (cond [(match_operand:SF 1 "" "")
1060               (const_string "SF")
1061             (match_operand:DF 1 "" "")
1062               (const_string "DF")
1063            ]
1064            (const_string "XF")))
1065    (set_attr "athlon_decode" "vector")])
1066 \f
1067 ;; Move instructions.
1068
1069 ;; General case of fullword move.
1070
1071 (define_expand "movsi"
1072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073         (match_operand:SI 1 "general_operand" ""))]
1074   ""
1075   "ix86_expand_move (SImode, operands); DONE;")
1076
1077 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1078 ;; general_operand.
1079 ;;
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1085
1086 (define_insn "*pushsi2"
1087   [(set (match_operand:SI 0 "push_operand" "=<")
1088         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1089   "!TARGET_64BIT"
1090   "push{l}\t%1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1093
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096   [(set (match_operand:SI 0 "push_operand" "=X")
1097         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1098   "TARGET_64BIT"
1099   "push{q}\t%q1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1102
1103 (define_insn "*pushsi2_prologue"
1104   [(set (match_operand:SI 0 "push_operand" "=<")
1105         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106    (clobber (mem:BLK (scratch)))]
1107   "!TARGET_64BIT"
1108   "push{l}\t%1"
1109   [(set_attr "type" "push")
1110    (set_attr "mode" "SI")])
1111
1112 (define_insn "*popsi1_epilogue"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114         (mem:SI (reg:SI SP_REG)))
1115    (set (reg:SI SP_REG)
1116         (plus:SI (reg:SI SP_REG) (const_int 4)))
1117    (clobber (mem:BLK (scratch)))]
1118   "!TARGET_64BIT"
1119   "pop{l}\t%0"
1120   [(set_attr "type" "pop")
1121    (set_attr "mode" "SI")])
1122
1123 (define_insn "popsi1"
1124   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125         (mem:SI (reg:SI SP_REG)))
1126    (set (reg:SI SP_REG)
1127         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1128   "!TARGET_64BIT"
1129   "pop{l}\t%0"
1130   [(set_attr "type" "pop")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*movsi_xor"
1134   [(set (match_operand:SI 0 "register_operand" "=r")
1135         (match_operand:SI 1 "const0_operand" "i"))
1136    (clobber (reg:CC FLAGS_REG))]
1137   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138   "xor{l}\t{%0, %0|%0, %0}"
1139   [(set_attr "type" "alu1")
1140    (set_attr "mode" "SI")
1141    (set_attr "length_immediate" "0")])
1142  
1143 (define_insn "*movsi_or"
1144   [(set (match_operand:SI 0 "register_operand" "=r")
1145         (match_operand:SI 1 "immediate_operand" "i"))
1146    (clobber (reg:CC FLAGS_REG))]
1147   "reload_completed
1148    && operands[1] == constm1_rtx
1149    && (TARGET_PENTIUM || optimize_size)"
1150 {
1151   operands[1] = constm1_rtx;
1152   return "or{l}\t{%1, %0|%0, %1}";
1153 }
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "1")])
1157
1158 (define_insn "*movsi_1"
1159   [(set (match_operand:SI 0 "nonimmediate_operand"
1160                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161         (match_operand:SI 1 "general_operand"
1162                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1163   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164 {
1165   switch (get_attr_type (insn))
1166     {
1167     case TYPE_SSELOG1:
1168       if (get_attr_mode (insn) == MODE_TI)
1169         return "pxor\t%0, %0";
1170       return "xorps\t%0, %0";
1171
1172     case TYPE_SSEMOV:
1173       switch (get_attr_mode (insn))
1174         {
1175         case MODE_TI:
1176           return "movdqa\t{%1, %0|%0, %1}";
1177         case MODE_V4SF:
1178           return "movaps\t{%1, %0|%0, %1}";
1179         case MODE_SI:
1180           return "movd\t{%1, %0|%0, %1}";
1181         case MODE_SF:
1182           return "movss\t{%1, %0|%0, %1}";
1183         default:
1184           gcc_unreachable ();
1185         }
1186
1187     case TYPE_MMXADD:
1188       return "pxor\t%0, %0";
1189
1190     case TYPE_MMXMOV:
1191       if (get_attr_mode (insn) == MODE_DI)
1192         return "movq\t{%1, %0|%0, %1}";
1193       return "movd\t{%1, %0|%0, %1}";
1194
1195     case TYPE_LEA:
1196       return "lea{l}\t{%1, %0|%0, %1}";
1197
1198     default:
1199       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200       return "mov{l}\t{%1, %0|%0, %1}";
1201     }
1202 }
1203   [(set (attr "type")
1204      (cond [(eq_attr "alternative" "2")
1205               (const_string "mmxadd")
1206             (eq_attr "alternative" "3,4,5")
1207               (const_string "mmxmov")
1208             (eq_attr "alternative" "6")
1209               (const_string "sselog1")
1210             (eq_attr "alternative" "7,8,9,10,11")
1211               (const_string "ssemov")
1212             (match_operand:DI 1 "pic_32bit_operand" "")
1213               (const_string "lea")
1214            ]
1215            (const_string "imov")))
1216    (set (attr "mode")
1217      (cond [(eq_attr "alternative" "2,3")
1218               (const_string "DI")
1219             (eq_attr "alternative" "6,7")
1220               (if_then_else
1221                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222                 (const_string "V4SF")
1223                 (const_string "TI"))
1224             (and (eq_attr "alternative" "8,9,10,11")
1225                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1226               (const_string "SF")
1227            ]
1228            (const_string "SI")))])
1229
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237   "@
1238    movabs{l}\t{%1, %P0|%P0, %1}
1239    mov{l}\t{%1, %a0|%a0, %1}"
1240   [(set_attr "type" "imov")
1241    (set_attr "modrm" "0,*")
1242    (set_attr "length_address" "8,0")
1243    (set_attr "length_immediate" "0,*")
1244    (set_attr "memory" "store")
1245    (set_attr "mode" "SI")])
1246
1247 (define_insn "*movabssi_2_rex64"
1248   [(set (match_operand:SI 0 "register_operand" "=a,r")
1249         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251   "@
1252    movabs{l}\t{%P1, %0|%0, %P1}
1253    mov{l}\t{%a1, %0|%0, %a1}"
1254   [(set_attr "type" "imov")
1255    (set_attr "modrm" "0,*")
1256    (set_attr "length_address" "8,0")
1257    (set_attr "length_immediate" "0")
1258    (set_attr "memory" "load")
1259    (set_attr "mode" "SI")])
1260
1261 (define_insn "*swapsi"
1262   [(set (match_operand:SI 0 "register_operand" "+r")
1263         (match_operand:SI 1 "register_operand" "+r"))
1264    (set (match_dup 1)
1265         (match_dup 0))]
1266   ""
1267   "xchg{l}\t%1, %0"
1268   [(set_attr "type" "imov")
1269    (set_attr "mode" "SI")
1270    (set_attr "pent_pair" "np")
1271    (set_attr "athlon_decode" "vector")])
1272
1273 (define_expand "movhi"
1274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275         (match_operand:HI 1 "general_operand" ""))]
1276   ""
1277   "ix86_expand_move (HImode, operands); DONE;")
1278
1279 (define_insn "*pushhi2"
1280   [(set (match_operand:HI 0 "push_operand" "=X")
1281         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1282   "!TARGET_64BIT"
1283   "push{l}\t%k1"
1284   [(set_attr "type" "push")
1285    (set_attr "mode" "SI")])
1286
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289   [(set (match_operand:HI 0 "push_operand" "=X")
1290         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1291   "TARGET_64BIT"
1292   "push{q}\t%q1"
1293   [(set_attr "type" "push")
1294    (set_attr "mode" "DI")])
1295
1296 (define_insn "*movhi_1"
1297   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 {
1301   switch (get_attr_type (insn))
1302     {
1303     case TYPE_IMOVX:
1304       /* movzwl is faster than movw on p2 due to partial word stalls,
1305          though not as fast as an aligned movl.  */
1306       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307     default:
1308       if (get_attr_mode (insn) == MODE_SI)
1309         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310       else
1311         return "mov{w}\t{%1, %0|%0, %1}";
1312     }
1313 }
1314   [(set (attr "type")
1315      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316               (const_string "imov")
1317             (and (eq_attr "alternative" "0")
1318                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319                           (const_int 0))
1320                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1321                           (const_int 0))))
1322               (const_string "imov")
1323             (and (eq_attr "alternative" "1,2")
1324                  (match_operand:HI 1 "aligned_operand" ""))
1325               (const_string "imov")
1326             (and (ne (symbol_ref "TARGET_MOVX")
1327                      (const_int 0))
1328                  (eq_attr "alternative" "0,2"))
1329               (const_string "imovx")
1330            ]
1331            (const_string "imov")))
1332     (set (attr "mode")
1333       (cond [(eq_attr "type" "imovx")
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "1,2")
1336                   (match_operand:HI 1 "aligned_operand" ""))
1337                (const_string "SI")
1338              (and (eq_attr "alternative" "0")
1339                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340                            (const_int 0))
1341                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1342                            (const_int 0))))
1343                (const_string "SI")
1344             ]
1345             (const_string "HI")))])
1346
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354   "@
1355    movabs{w}\t{%1, %P0|%P0, %1}
1356    mov{w}\t{%1, %a0|%a0, %1}"
1357   [(set_attr "type" "imov")
1358    (set_attr "modrm" "0,*")
1359    (set_attr "length_address" "8,0")
1360    (set_attr "length_immediate" "0,*")
1361    (set_attr "memory" "store")
1362    (set_attr "mode" "HI")])
1363
1364 (define_insn "*movabshi_2_rex64"
1365   [(set (match_operand:HI 0 "register_operand" "=a,r")
1366         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368   "@
1369    movabs{w}\t{%P1, %0|%0, %P1}
1370    mov{w}\t{%a1, %0|%0, %a1}"
1371   [(set_attr "type" "imov")
1372    (set_attr "modrm" "0,*")
1373    (set_attr "length_address" "8,0")
1374    (set_attr "length_immediate" "0")
1375    (set_attr "memory" "load")
1376    (set_attr "mode" "HI")])
1377
1378 (define_insn "*swaphi_1"
1379   [(set (match_operand:HI 0 "register_operand" "+r")
1380         (match_operand:HI 1 "register_operand" "+r"))
1381    (set (match_dup 1)
1382         (match_dup 0))]
1383   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384   "xchg{l}\t%k1, %k0"
1385   [(set_attr "type" "imov")
1386    (set_attr "mode" "SI")
1387    (set_attr "pent_pair" "np")
1388    (set_attr "athlon_decode" "vector")])
1389
1390 (define_insn "*swaphi_2"
1391   [(set (match_operand:HI 0 "register_operand" "+r")
1392         (match_operand:HI 1 "register_operand" "+r"))
1393    (set (match_dup 1)
1394         (match_dup 0))]
1395   "TARGET_PARTIAL_REG_STALL"
1396   "xchg{w}\t%1, %0"
1397   [(set_attr "type" "imov")
1398    (set_attr "mode" "HI")
1399    (set_attr "pent_pair" "np")
1400    (set_attr "athlon_decode" "vector")])
1401
1402 (define_expand "movstricthi"
1403   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404         (match_operand:HI 1 "general_operand" ""))]
1405   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 {
1407   /* Don't generate memory->memory moves, go through a register */
1408   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409     operands[1] = force_reg (HImode, operands[1]);
1410 })
1411
1412 (define_insn "*movstricthi_1"
1413   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414         (match_operand:HI 1 "general_operand" "rn,m"))]
1415   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417   "mov{w}\t{%1, %0|%0, %1}"
1418   [(set_attr "type" "imov")
1419    (set_attr "mode" "HI")])
1420
1421 (define_insn "*movstricthi_xor"
1422   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423         (match_operand:HI 1 "const0_operand" "i"))
1424    (clobber (reg:CC FLAGS_REG))]
1425   "reload_completed
1426    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427   "xor{w}\t{%0, %0|%0, %0}"
1428   [(set_attr "type" "alu1")
1429    (set_attr "mode" "HI")
1430    (set_attr "length_immediate" "0")])
1431
1432 (define_expand "movqi"
1433   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434         (match_operand:QI 1 "general_operand" ""))]
1435   ""
1436   "ix86_expand_move (QImode, operands); DONE;")
1437
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte".  But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1441
1442 (define_insn "*pushqi2"
1443   [(set (match_operand:QI 0 "push_operand" "=X")
1444         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1445   "!TARGET_64BIT"
1446   "push{l}\t%k1"
1447   [(set_attr "type" "push")
1448    (set_attr "mode" "SI")])
1449
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452   [(set (match_operand:QI 0 "push_operand" "=X")
1453         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454   "TARGET_64BIT"
1455   "push{q}\t%q1"
1456   [(set_attr "type" "push")
1457    (set_attr "mode" "DI")])
1458
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1464 ;; instruction).
1465 ;;
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there.  Then we use movzx.
1469 (define_insn "*movqi_1"
1470   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1472   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473 {
1474   switch (get_attr_type (insn))
1475     {
1476     case TYPE_IMOVX:
1477       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479     default:
1480       if (get_attr_mode (insn) == MODE_SI)
1481         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482       else
1483         return "mov{b}\t{%1, %0|%0, %1}";
1484     }
1485 }
1486   [(set (attr "type")
1487      (cond [(and (eq_attr "alternative" "5")
1488                  (not (match_operand:QI 1 "aligned_operand" "")))
1489               (const_string "imovx")
1490             (ne (symbol_ref "optimize_size") (const_int 0))
1491               (const_string "imov")
1492             (and (eq_attr "alternative" "3")
1493                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494                           (const_int 0))
1495                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1496                           (const_int 0))))
1497               (const_string "imov")
1498             (eq_attr "alternative" "3,5")
1499               (const_string "imovx")
1500             (and (ne (symbol_ref "TARGET_MOVX")
1501                      (const_int 0))
1502                  (eq_attr "alternative" "2"))
1503               (const_string "imovx")
1504            ]
1505            (const_string "imov")))
1506    (set (attr "mode")
1507       (cond [(eq_attr "alternative" "3,4,5")
1508                (const_string "SI")
1509              (eq_attr "alternative" "6")
1510                (const_string "QI")
1511              (eq_attr "type" "imovx")
1512                (const_string "SI")
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516                                 (const_int 0))
1517                             (and (eq (symbol_ref "optimize_size")
1518                                      (const_int 0))
1519                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520                                      (const_int 0))))))
1521                (const_string "SI")
1522              ;; Avoid partial register stalls when not using QImode arithmetic
1523              (and (eq_attr "type" "imov")
1524                   (and (eq_attr "alternative" "0,1")
1525                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526                                 (const_int 0))
1527                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1528                                 (const_int 0)))))
1529                (const_string "SI")
1530            ]
1531            (const_string "QI")))])
1532
1533 (define_expand "reload_outqi"
1534   [(parallel [(match_operand:QI 0 "" "=m")
1535               (match_operand:QI 1 "register_operand" "r")
1536               (match_operand:QI 2 "register_operand" "=&q")])]
1537   ""
1538 {
1539   rtx op0, op1, op2;
1540   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541
1542   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543   if (! q_regs_operand (op1, QImode))
1544     {
1545       emit_insn (gen_movqi (op2, op1));
1546       op1 = op2;
1547     }
1548   emit_insn (gen_movqi (op0, op1));
1549   DONE;
1550 })
1551
1552 (define_insn "*swapqi_1"
1553   [(set (match_operand:QI 0 "register_operand" "+r")
1554         (match_operand:QI 1 "register_operand" "+r"))
1555    (set (match_dup 1)
1556         (match_dup 0))]
1557   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558   "xchg{l}\t%k1, %k0"
1559   [(set_attr "type" "imov")
1560    (set_attr "mode" "SI")
1561    (set_attr "pent_pair" "np")
1562    (set_attr "athlon_decode" "vector")])
1563
1564 (define_insn "*swapqi_2"
1565   [(set (match_operand:QI 0 "register_operand" "+q")
1566         (match_operand:QI 1 "register_operand" "+q"))
1567    (set (match_dup 1)
1568         (match_dup 0))]
1569   "TARGET_PARTIAL_REG_STALL"
1570   "xchg{b}\t%1, %0"
1571   [(set_attr "type" "imov")
1572    (set_attr "mode" "QI")
1573    (set_attr "pent_pair" "np")
1574    (set_attr "athlon_decode" "vector")])
1575
1576 (define_expand "movstrictqi"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578         (match_operand:QI 1 "general_operand" ""))]
1579   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580 {
1581   /* Don't generate memory->memory moves, go through a register.  */
1582   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583     operands[1] = force_reg (QImode, operands[1]);
1584 })
1585
1586 (define_insn "*movstrictqi_1"
1587   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588         (match_operand:QI 1 "general_operand" "*qn,m"))]
1589   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591   "mov{b}\t{%1, %0|%0, %1}"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "QI")])
1594
1595 (define_insn "*movstrictqi_xor"
1596   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597         (match_operand:QI 1 "const0_operand" "i"))
1598    (clobber (reg:CC FLAGS_REG))]
1599   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600   "xor{b}\t{%0, %0|%0, %0}"
1601   [(set_attr "type" "alu1")
1602    (set_attr "mode" "QI")
1603    (set_attr "length_immediate" "0")])
1604
1605 (define_insn "*movsi_extv_1"
1606   [(set (match_operand:SI 0 "register_operand" "=R")
1607         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1614
1615 (define_insn "*movhi_extv_1"
1616   [(set (match_operand:HI 0 "register_operand" "=R")
1617         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   ""
1621   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622   [(set_attr "type" "imovx")
1623    (set_attr "mode" "SI")])
1624
1625 (define_insn "*movqi_extv_1"
1626   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628                          (const_int 8)
1629                          (const_int 8)))]
1630   "!TARGET_64BIT"
1631 {
1632   switch (get_attr_type (insn))
1633     {
1634     case TYPE_IMOVX:
1635       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636     default:
1637       return "mov{b}\t{%h1, %0|%0, %h1}";
1638     }
1639 }
1640   [(set (attr "type")
1641      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643                              (ne (symbol_ref "TARGET_MOVX")
1644                                  (const_int 0))))
1645         (const_string "imovx")
1646         (const_string "imov")))
1647    (set (attr "mode")
1648      (if_then_else (eq_attr "type" "imovx")
1649         (const_string "SI")
1650         (const_string "QI")))])
1651
1652 (define_insn "*movqi_extv_1_rex64"
1653   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                          (const_int 8)
1656                          (const_int 8)))]
1657   "TARGET_64BIT"
1658 {
1659   switch (get_attr_type (insn))
1660     {
1661     case TYPE_IMOVX:
1662       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663     default:
1664       return "mov{b}\t{%h1, %0|%0, %h1}";
1665     }
1666 }
1667   [(set (attr "type")
1668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                              (ne (symbol_ref "TARGET_MOVX")
1671                                  (const_int 0))))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1678
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686   "@
1687    movabs{b}\t{%1, %P0|%P0, %1}
1688    mov{b}\t{%1, %a0|%a0, %1}"
1689   [(set_attr "type" "imov")
1690    (set_attr "modrm" "0,*")
1691    (set_attr "length_address" "8,0")
1692    (set_attr "length_immediate" "0,*")
1693    (set_attr "memory" "store")
1694    (set_attr "mode" "QI")])
1695
1696 (define_insn "*movabsqi_2_rex64"
1697   [(set (match_operand:QI 0 "register_operand" "=a,r")
1698         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700   "@
1701    movabs{b}\t{%P1, %0|%0, %P1}
1702    mov{b}\t{%a1, %0|%0, %a1}"
1703   [(set_attr "type" "imov")
1704    (set_attr "modrm" "0,*")
1705    (set_attr "length_address" "8,0")
1706    (set_attr "length_immediate" "0")
1707    (set_attr "memory" "load")
1708    (set_attr "mode" "QI")])
1709
1710 (define_insn "*movdi_extzv_1"
1711   [(set (match_operand:DI 0 "register_operand" "=R")
1712         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   "TARGET_64BIT"
1716   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "DI")])
1719
1720 (define_insn "*movsi_extzv_1"
1721   [(set (match_operand:SI 0 "register_operand" "=R")
1722         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723                          (const_int 8)
1724                          (const_int 8)))]
1725   ""
1726   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727   [(set_attr "type" "imovx")
1728    (set_attr "mode" "SI")])
1729
1730 (define_insn "*movqi_extzv_2"
1731   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "!TARGET_64BIT"
1736 {
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1744 }
1745   [(set (attr "type")
1746      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748                              (ne (symbol_ref "TARGET_MOVX")
1749                                  (const_int 0))))
1750         (const_string "imovx")
1751         (const_string "imov")))
1752    (set (attr "mode")
1753      (if_then_else (eq_attr "type" "imovx")
1754         (const_string "SI")
1755         (const_string "QI")))])
1756
1757 (define_insn "*movqi_extzv_2_rex64"
1758   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760                                     (const_int 8)
1761                                     (const_int 8)) 0))]
1762   "TARGET_64BIT"
1763 {
1764   switch (get_attr_type (insn))
1765     {
1766     case TYPE_IMOVX:
1767       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768     default:
1769       return "mov{b}\t{%h1, %0|%0, %h1}";
1770     }
1771 }
1772   [(set (attr "type")
1773      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                         (ne (symbol_ref "TARGET_MOVX")
1775                             (const_int 0)))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1782
1783 (define_insn "movsi_insv_1"
1784   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:SI 1 "general_operand" "Qmn"))]
1788   "!TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1792
1793 (define_insn "movdi_insv_1_rex64"
1794   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798   "TARGET_64BIT"
1799   "mov{b}\t{%b1, %h0|%h0, %b1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1802
1803 (define_insn "*movqi_insv_2"
1804   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805                          (const_int 8)
1806                          (const_int 8))
1807         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808                      (const_int 8)))]
1809   ""
1810   "mov{b}\t{%h1, %h0|%h0, %h1}"
1811   [(set_attr "type" "imov")
1812    (set_attr "mode" "QI")])
1813
1814 (define_expand "movdi"
1815   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816         (match_operand:DI 1 "general_operand" ""))]
1817   ""
1818   "ix86_expand_move (DImode, operands); DONE;")
1819
1820 (define_insn "*pushdi"
1821   [(set (match_operand:DI 0 "push_operand" "=<")
1822         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823   "!TARGET_64BIT"
1824   "#")
1825
1826 (define_insn "*pushdi2_rex64"
1827   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829   "TARGET_64BIT"
1830   "@
1831    push{q}\t%1
1832    #"
1833   [(set_attr "type" "push,multi")
1834    (set_attr "mode" "DI")])
1835
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it.  In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1840 (define_peephole2
1841   [(match_scratch:DI 2 "r")
1842    (set (match_operand:DI 0 "push_operand" "")
1843         (match_operand:DI 1 "immediate_operand" ""))]
1844   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845    && !x86_64_immediate_operand (operands[1], DImode)"
1846   [(set (match_dup 2) (match_dup 1))
1847    (set (match_dup 0) (match_dup 2))]
1848   "")
1849
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 (define_peephole2
1854   [(set (match_operand:DI 0 "push_operand" "")
1855         (match_operand:DI 1 "immediate_operand" ""))]
1856   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858   [(set (match_dup 0) (match_dup 1))
1859    (set (match_dup 2) (match_dup 3))]
1860   "split_di (operands + 1, 1, operands + 2, operands + 3);
1861    operands[1] = gen_lowpart (DImode, operands[2]);
1862    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863                                                     GEN_INT (4)));
1864   ")
1865
1866 (define_split
1867   [(set (match_operand:DI 0 "push_operand" "")
1868         (match_operand:DI 1 "immediate_operand" ""))]
1869   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870                     ? flow2_completed : reload_completed)
1871    && !symbolic_operand (operands[1], DImode)
1872    && !x86_64_immediate_operand (operands[1], DImode)"
1873   [(set (match_dup 0) (match_dup 1))
1874    (set (match_dup 2) (match_dup 3))]
1875   "split_di (operands + 1, 1, operands + 2, operands + 3);
1876    operands[1] = gen_lowpart (DImode, operands[2]);
1877    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878                                                     GEN_INT (4)));
1879   ")
1880
1881 (define_insn "*pushdi2_prologue_rex64"
1882   [(set (match_operand:DI 0 "push_operand" "=<")
1883         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "push{q}\t%1"
1887   [(set_attr "type" "push")
1888    (set_attr "mode" "DI")])
1889
1890 (define_insn "*popdi1_epilogue_rex64"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))
1895    (clobber (mem:BLK (scratch)))]
1896   "TARGET_64BIT"
1897   "pop{q}\t%0"
1898   [(set_attr "type" "pop")
1899    (set_attr "mode" "DI")])
1900
1901 (define_insn "popdi1"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903         (mem:DI (reg:DI SP_REG)))
1904    (set (reg:DI SP_REG)
1905         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1906   "TARGET_64BIT"
1907   "pop{q}\t%0"
1908   [(set_attr "type" "pop")
1909    (set_attr "mode" "DI")])
1910
1911 (define_insn "*movdi_xor_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const0_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916    && reload_completed"
1917   "xor{l}\t{%k0, %k0|%k0, %k0}"
1918   [(set_attr "type" "alu1")
1919    (set_attr "mode" "SI")
1920    (set_attr "length_immediate" "0")])
1921
1922 (define_insn "*movdi_or_rex64"
1923   [(set (match_operand:DI 0 "register_operand" "=r")
1924         (match_operand:DI 1 "const_int_operand" "i"))
1925    (clobber (reg:CC FLAGS_REG))]
1926   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927    && reload_completed
1928    && operands[1] == constm1_rtx"
1929 {
1930   operands[1] = constm1_rtx;
1931   return "or{q}\t{%1, %0|%0, %1}";
1932 }
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "DI")
1935    (set_attr "length_immediate" "1")])
1936
1937 (define_insn "*movdi_2"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940         (match_operand:DI 1 "general_operand"
1941                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943   "@
1944    #
1945    #
1946    pxor\t%0, %0
1947    movq\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    pxor\t%0, %0
1950    movq\t{%1, %0|%0, %1}
1951    movdqa\t{%1, %0|%0, %1}
1952    movq\t{%1, %0|%0, %1}
1953    xorps\t%0, %0
1954    movlps\t{%1, %0|%0, %1}
1955    movaps\t{%1, %0|%0, %1}
1956    movlps\t{%1, %0|%0, %1}"
1957   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1959
1960 (define_split
1961   [(set (match_operand:DI 0 "push_operand" "")
1962         (match_operand:DI 1 "general_operand" ""))]
1963   "!TARGET_64BIT && reload_completed
1964    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965   [(const_int 0)]
1966   "ix86_split_long_move (operands); DONE;")
1967
1968 ;; %%% This multiword shite has got to go.
1969 (define_split
1970   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971         (match_operand:DI 1 "general_operand" ""))]
1972   "!TARGET_64BIT && reload_completed
1973    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975   [(const_int 0)]
1976   "ix86_split_long_move (operands); DONE;")
1977
1978 (define_insn "*movdi_1_rex64"
1979   [(set (match_operand:DI 0 "nonimmediate_operand"
1980                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981         (match_operand:DI 1 "general_operand"
1982                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 {
1985   switch (get_attr_type (insn))
1986     {
1987     case TYPE_SSECVT:
1988       if (which_alternative == 13)
1989         return "movq2dq\t{%1, %0|%0, %1}";
1990       else
1991         return "movdq2q\t{%1, %0|%0, %1}";
1992     case TYPE_SSEMOV:
1993       if (get_attr_mode (insn) == MODE_TI)
1994           return "movdqa\t{%1, %0|%0, %1}";
1995       /* FALLTHRU */
1996     case TYPE_MMXMOV:
1997       /* Moves from and into integer register is done using movd opcode with
1998          REX prefix.  */
1999       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000           return "movd\t{%1, %0|%0, %1}";
2001       return "movq\t{%1, %0|%0, %1}";
2002     case TYPE_SSELOG1:
2003     case TYPE_MMXADD:
2004       return "pxor\t%0, %0";
2005     case TYPE_MULTI:
2006       return "#";
2007     case TYPE_LEA:
2008       return "lea{q}\t{%a1, %0|%0, %a1}";
2009     default:
2010       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011       if (get_attr_mode (insn) == MODE_SI)
2012         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013       else if (which_alternative == 2)
2014         return "movabs{q}\t{%1, %0|%0, %1}";
2015       else
2016         return "mov{q}\t{%1, %0|%0, %1}";
2017     }
2018 }
2019   [(set (attr "type")
2020      (cond [(eq_attr "alternative" "5")
2021               (const_string "mmxadd")
2022             (eq_attr "alternative" "6,7,8")
2023               (const_string "mmxmov")
2024             (eq_attr "alternative" "9")
2025               (const_string "sselog1")
2026             (eq_attr "alternative" "10,11,12")
2027               (const_string "ssemov")
2028             (eq_attr "alternative" "13,14")
2029               (const_string "ssecvt")
2030             (eq_attr "alternative" "4")
2031               (const_string "multi")
2032             (match_operand:DI 1 "pic_32bit_operand" "")
2033               (const_string "lea")
2034            ]
2035            (const_string "imov")))
2036    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047   "@
2048    movabs{q}\t{%1, %P0|%P0, %1}
2049    mov{q}\t{%1, %a0|%a0, %1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "modrm" "0,*")
2052    (set_attr "length_address" "8,0")
2053    (set_attr "length_immediate" "0,*")
2054    (set_attr "memory" "store")
2055    (set_attr "mode" "DI")])
2056
2057 (define_insn "*movabsdi_2_rex64"
2058   [(set (match_operand:DI 0 "register_operand" "=a,r")
2059         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061   "@
2062    movabs{q}\t{%P1, %0|%0, %P1}
2063    mov{q}\t{%a1, %0|%0, %a1}"
2064   [(set_attr "type" "imov")
2065    (set_attr "modrm" "0,*")
2066    (set_attr "length_address" "8,0")
2067    (set_attr "length_immediate" "0")
2068    (set_attr "memory" "load")
2069    (set_attr "mode" "DI")])
2070
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it.  In case this
2073 ;; fails, move by 32bit parts.
2074 (define_peephole2
2075   [(match_scratch:DI 2 "r")
2076    (set (match_operand:DI 0 "memory_operand" "")
2077         (match_operand:DI 1 "immediate_operand" ""))]
2078   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079    && !x86_64_immediate_operand (operands[1], DImode)"
2080   [(set (match_dup 2) (match_dup 1))
2081    (set (match_dup 0) (match_dup 2))]
2082   "")
2083
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 (define_peephole2
2088   [(set (match_operand:DI 0 "memory_operand" "")
2089         (match_operand:DI 1 "immediate_operand" ""))]
2090   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092   [(set (match_dup 2) (match_dup 3))
2093    (set (match_dup 4) (match_dup 5))]
2094   "split_di (operands, 2, operands + 2, operands + 4);")
2095
2096 (define_split
2097   [(set (match_operand:DI 0 "memory_operand" "")
2098         (match_operand:DI 1 "immediate_operand" ""))]
2099   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100                     ? flow2_completed : reload_completed)
2101    && !symbolic_operand (operands[1], DImode)
2102    && !x86_64_immediate_operand (operands[1], DImode)"
2103   [(set (match_dup 2) (match_dup 3))
2104    (set (match_dup 4) (match_dup 5))]
2105   "split_di (operands, 2, operands + 2, operands + 4);")
2106
2107 (define_insn "*swapdi_rex64"
2108   [(set (match_operand:DI 0 "register_operand" "+r")
2109         (match_operand:DI 1 "register_operand" "+r"))
2110    (set (match_dup 1)
2111         (match_dup 0))]
2112   "TARGET_64BIT"
2113   "xchg{q}\t%1, %0"
2114   [(set_attr "type" "imov")
2115    (set_attr "mode" "DI")
2116    (set_attr "pent_pair" "np")
2117    (set_attr "athlon_decode" "vector")])
2118
2119 (define_expand "movti"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121         (match_operand:TI 1 "nonimmediate_operand" ""))]
2122   "TARGET_SSE || TARGET_64BIT"
2123 {
2124   if (TARGET_64BIT)
2125     ix86_expand_move (TImode, operands);
2126   else
2127     ix86_expand_vector_move (TImode, operands);
2128   DONE;
2129 })
2130
2131 (define_insn "*movti_internal"
2132   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134   "TARGET_SSE && !TARGET_64BIT
2135    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136 {
2137   switch (which_alternative)
2138     {
2139     case 0:
2140       if (get_attr_mode (insn) == MODE_V4SF)
2141         return "xorps\t%0, %0";
2142       else
2143         return "pxor\t%0, %0";
2144     case 1:
2145     case 2:
2146       if (get_attr_mode (insn) == MODE_V4SF)
2147         return "movaps\t{%1, %0|%0, %1}";
2148       else
2149         return "movdqa\t{%1, %0|%0, %1}";
2150     default:
2151       gcc_unreachable ();
2152     }
2153 }
2154   [(set_attr "type" "sselog1,ssemov,ssemov")
2155    (set (attr "mode")
2156         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157                     (ne (symbol_ref "optimize_size") (const_int 0)))
2158                  (const_string "V4SF")
2159                (and (eq_attr "alternative" "2")
2160                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161                         (const_int 0)))
2162                  (const_string "V4SF")]
2163               (const_string "TI")))])
2164
2165 (define_insn "*movti_rex64"
2166   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168   "TARGET_64BIT
2169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170 {
2171   switch (which_alternative)
2172     {
2173     case 0:
2174     case 1:
2175       return "#";
2176     case 2:
2177       if (get_attr_mode (insn) == MODE_V4SF)
2178         return "xorps\t%0, %0";
2179       else
2180         return "pxor\t%0, %0";
2181     case 3:
2182     case 4:
2183       if (get_attr_mode (insn) == MODE_V4SF)
2184         return "movaps\t{%1, %0|%0, %1}";
2185       else
2186         return "movdqa\t{%1, %0|%0, %1}";
2187     default:
2188       gcc_unreachable ();
2189     }
2190 }
2191   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192    (set (attr "mode")
2193         (cond [(eq_attr "alternative" "2,3")
2194                  (if_then_else
2195                    (ne (symbol_ref "optimize_size")
2196                        (const_int 0))
2197                    (const_string "V4SF")
2198                    (const_string "TI"))
2199                (eq_attr "alternative" "4")
2200                  (if_then_else
2201                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202                             (const_int 0))
2203                         (ne (symbol_ref "optimize_size")
2204                             (const_int 0)))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))]
2207                (const_string "DI")))])
2208
2209 (define_split
2210   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211         (match_operand:TI 1 "general_operand" ""))]
2212   "reload_completed && !SSE_REG_P (operands[0])
2213    && !SSE_REG_P (operands[1])"
2214   [(const_int 0)]
2215   "ix86_split_long_move (operands); DONE;")
2216
2217 (define_expand "movsf"
2218   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219         (match_operand:SF 1 "general_operand" ""))]
2220   ""
2221   "ix86_expand_move (SFmode, operands); DONE;")
2222
2223 (define_insn "*pushsf"
2224   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2226   "!TARGET_64BIT"
2227 {
2228   /* Anything else should be already split before reg-stack.  */
2229   gcc_assert (which_alternative == 1);
2230   return "push{l}\t%1";
2231 }
2232   [(set_attr "type" "multi,push,multi")
2233    (set_attr "unit" "i387,*,*")
2234    (set_attr "mode" "SF,SI,SF")])
2235
2236 (define_insn "*pushsf_rex64"
2237   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2239   "TARGET_64BIT"
2240 {
2241   /* Anything else should be already split before reg-stack.  */
2242   gcc_assert (which_alternative == 1);
2243   return "push{q}\t%q1";
2244 }
2245   [(set_attr "type" "multi,push,multi")
2246    (set_attr "unit" "i387,*,*")
2247    (set_attr "mode" "SF,DI,SF")])
2248
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "memory_operand" ""))]
2252   "reload_completed
2253    && GET_CODE (operands[1]) == MEM
2254    && constant_pool_reference_p (operands[1])"
2255   [(set (match_dup 0)
2256         (match_dup 1))]
2257   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2258
2259
2260 ;; %%% Kill this when call knows how to work this out.
2261 (define_split
2262   [(set (match_operand:SF 0 "push_operand" "")
2263         (match_operand:SF 1 "any_fp_register_operand" ""))]
2264   "!TARGET_64BIT"
2265   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2267
2268 (define_split
2269   [(set (match_operand:SF 0 "push_operand" "")
2270         (match_operand:SF 1 "any_fp_register_operand" ""))]
2271   "TARGET_64BIT"
2272   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274
2275 (define_insn "*movsf_1"
2276   [(set (match_operand:SF 0 "nonimmediate_operand"
2277           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2278         (match_operand:SF 1 "general_operand"
2279           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2280   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281    && (reload_in_progress || reload_completed
2282        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283        || GET_CODE (operands[1]) != CONST_DOUBLE
2284        || memory_operand (operands[0], SFmode))" 
2285 {
2286   switch (which_alternative)
2287     {
2288     case 0:
2289       return output_387_reg_move (insn, operands);
2290
2291     case 1:
2292       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293         return "fstp%z0\t%y0";
2294       else
2295         return "fst%z0\t%y0";
2296
2297     case 2:
2298       return standard_80387_constant_opcode (operands[1]);
2299
2300     case 3:
2301     case 4:
2302       return "mov{l}\t{%1, %0|%0, %1}";
2303     case 5:
2304       if (get_attr_mode (insn) == MODE_TI)
2305         return "pxor\t%0, %0";
2306       else
2307         return "xorps\t%0, %0";
2308     case 6:
2309       if (get_attr_mode (insn) == MODE_V4SF)
2310         return "movaps\t{%1, %0|%0, %1}";
2311       else
2312         return "movss\t{%1, %0|%0, %1}";
2313     case 7:
2314     case 8:
2315       return "movss\t{%1, %0|%0, %1}";
2316
2317     case 9:
2318     case 10:
2319       return "movd\t{%1, %0|%0, %1}";
2320
2321     case 11:
2322       return "movq\t{%1, %0|%0, %1}";
2323
2324     default:
2325       gcc_unreachable ();
2326     }
2327 }
2328   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329    (set (attr "mode")
2330         (cond [(eq_attr "alternative" "3,4,9,10")
2331                  (const_string "SI")
2332                (eq_attr "alternative" "5")
2333                  (if_then_else
2334                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335                                  (const_int 0))
2336                              (ne (symbol_ref "TARGET_SSE2")
2337                                  (const_int 0)))
2338                         (eq (symbol_ref "optimize_size")
2339                             (const_int 0)))
2340                    (const_string "TI")
2341                    (const_string "V4SF"))
2342                /* For architectures resolving dependencies on
2343                   whole SSE registers use APS move to break dependency
2344                   chains, otherwise use short move to avoid extra work. 
2345
2346                   Do the same for architectures resolving dependencies on
2347                   the parts.  While in DF mode it is better to always handle
2348                   just register parts, the SF mode is different due to lack
2349                   of instructions to load just part of the register.  It is
2350                   better to maintain the whole registers in single format
2351                   to avoid problems on using packed logical operations.  */
2352                (eq_attr "alternative" "6")
2353                  (if_then_else
2354                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355                             (const_int 0))
2356                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357                             (const_int 0)))
2358                    (const_string "V4SF")
2359                    (const_string "SF"))
2360                (eq_attr "alternative" "11")
2361                  (const_string "DI")]
2362                (const_string "SF")))])
2363
2364 (define_insn "*swapsf"
2365   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366         (match_operand:SF 1 "fp_register_operand" "+f"))
2367    (set (match_dup 1)
2368         (match_dup 0))]
2369   "reload_completed || TARGET_80387"
2370 {
2371   if (STACK_TOP_P (operands[0]))
2372     return "fxch\t%1";
2373   else
2374     return "fxch\t%0";
2375 }
2376   [(set_attr "type" "fxch")
2377    (set_attr "mode" "SF")])
2378
2379 (define_expand "movdf"
2380   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381         (match_operand:DF 1 "general_operand" ""))]
2382   ""
2383   "ix86_expand_move (DFmode, operands); DONE;")
2384
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter.  Allow this
2388 ;; pattern for optimize_size too.
2389
2390 (define_insn "*pushdf_nointeger"
2391   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 {
2395   /* This insn should be already split before reg-stack.  */
2396   gcc_unreachable ();
2397 }
2398   [(set_attr "type" "multi")
2399    (set_attr "unit" "i387,*,*,*")
2400    (set_attr "mode" "DF,SI,SI,DF")])
2401
2402 (define_insn "*pushdf_integer"
2403   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 {
2407   /* This insn should be already split before reg-stack.  */
2408   gcc_unreachable ();
2409 }
2410   [(set_attr "type" "multi")
2411    (set_attr "unit" "i387,*,*")
2412    (set_attr "mode" "DF,SI,DF")])
2413
2414 ;; %%% Kill this when call knows how to work this out.
2415 (define_split
2416   [(set (match_operand:DF 0 "push_operand" "")
2417         (match_operand:DF 1 "any_fp_register_operand" ""))]
2418   "!TARGET_64BIT && reload_completed"
2419   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421   "")
2422
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "TARGET_64BIT && reload_completed"
2427   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429   "")
2430
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "general_operand" ""))]
2434   "reload_completed"
2435   [(const_int 0)]
2436   "ix86_split_long_move (operands); DONE;")
2437
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2441
2442 (define_insn "*movdf_nointeger"
2443   [(set (match_operand:DF 0 "nonimmediate_operand"
2444                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2445         (match_operand:DF 1 "general_operand"
2446                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2447   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449    && (reload_in_progress || reload_completed
2450        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451        || GET_CODE (operands[1]) != CONST_DOUBLE
2452        || memory_operand (operands[0], DFmode))" 
2453 {
2454   switch (which_alternative)
2455     {
2456     case 0:
2457       return output_387_reg_move (insn, operands);
2458
2459     case 1:
2460       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461         return "fstp%z0\t%y0";
2462       else
2463         return "fst%z0\t%y0";
2464
2465     case 2:
2466       return standard_80387_constant_opcode (operands[1]);
2467
2468     case 3:
2469     case 4:
2470       return "#";
2471     case 5:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "xorps\t%0, %0";
2476         case MODE_V2DF:
2477           return "xorpd\t%0, %0";
2478         case MODE_TI:
2479           return "pxor\t%0, %0";
2480         default:
2481           gcc_unreachable ();
2482         }
2483     case 6:
2484     case 7:
2485     case 8:
2486       switch (get_attr_mode (insn))
2487         {
2488         case MODE_V4SF:
2489           return "movaps\t{%1, %0|%0, %1}";
2490         case MODE_V2DF:
2491           return "movapd\t{%1, %0|%0, %1}";
2492         case MODE_TI:
2493           return "movdqa\t{%1, %0|%0, %1}";
2494         case MODE_DI:
2495           return "movq\t{%1, %0|%0, %1}";
2496         case MODE_DF:
2497           return "movsd\t{%1, %0|%0, %1}";
2498         case MODE_V1DF:
2499           return "movlpd\t{%1, %0|%0, %1}";
2500         case MODE_V2SF:
2501           return "movlps\t{%1, %0|%0, %1}";
2502         default:
2503           gcc_unreachable ();
2504         }
2505
2506     default:
2507       gcc_unreachable ();
2508     }
2509 }
2510   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511    (set (attr "mode")
2512         (cond [(eq_attr "alternative" "0,1,2")
2513                  (const_string "DF")
2514                (eq_attr "alternative" "3,4")
2515                  (const_string "SI")
2516
2517                /* For SSE1, we have many fewer alternatives.  */
2518                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519                  (cond [(eq_attr "alternative" "5,6")
2520                           (const_string "V4SF")
2521                        ]
2522                    (const_string "V2SF"))
2523
2524                /* xorps is one byte shorter.  */
2525                (eq_attr "alternative" "5")
2526                  (cond [(ne (symbol_ref "optimize_size")
2527                             (const_int 0))
2528                           (const_string "V4SF")
2529                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530                             (const_int 0))
2531                           (const_string "TI")
2532                        ]
2533                        (const_string "V2DF"))
2534
2535                /* For architectures resolving dependencies on
2536                   whole SSE registers use APD move to break dependency
2537                   chains, otherwise use short move to avoid extra work.
2538
2539                   movaps encodes one byte shorter.  */
2540                (eq_attr "alternative" "6")
2541                  (cond
2542                    [(ne (symbol_ref "optimize_size")
2543                         (const_int 0))
2544                       (const_string "V4SF")
2545                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546                         (const_int 0))
2547                       (const_string "V2DF")
2548                    ]
2549                    (const_string "DF"))
2550                /* For architectures resolving dependencies on register
2551                   parts we may avoid extra work to zero out upper part
2552                   of register.  */
2553                (eq_attr "alternative" "7")
2554                  (if_then_else
2555                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556                        (const_int 0))
2557                    (const_string "V1DF")
2558                    (const_string "DF"))
2559               ]
2560               (const_string "DF")))])
2561
2562 (define_insn "*movdf_integer"
2563   [(set (match_operand:DF 0 "nonimmediate_operand"
2564                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2565         (match_operand:DF 1 "general_operand"
2566                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2567   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569    && (reload_in_progress || reload_completed
2570        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571        || GET_CODE (operands[1]) != CONST_DOUBLE
2572        || memory_operand (operands[0], DFmode))" 
2573 {
2574   switch (which_alternative)
2575     {
2576     case 0:
2577       return output_387_reg_move (insn, operands);
2578
2579     case 1:
2580       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581         return "fstp%z0\t%y0";
2582       else
2583         return "fst%z0\t%y0";
2584
2585     case 2:
2586       return standard_80387_constant_opcode (operands[1]);
2587
2588     case 3:
2589     case 4:
2590       return "#";
2591
2592     case 5:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "xorps\t%0, %0";
2597         case MODE_V2DF:
2598           return "xorpd\t%0, %0";
2599         case MODE_TI:
2600           return "pxor\t%0, %0";
2601         default:
2602           gcc_unreachable ();
2603         }
2604     case 6:
2605     case 7:
2606     case 8:
2607       switch (get_attr_mode (insn))
2608         {
2609         case MODE_V4SF:
2610           return "movaps\t{%1, %0|%0, %1}";
2611         case MODE_V2DF:
2612           return "movapd\t{%1, %0|%0, %1}";
2613         case MODE_TI:
2614           return "movdqa\t{%1, %0|%0, %1}";
2615         case MODE_DI:
2616           return "movq\t{%1, %0|%0, %1}";
2617         case MODE_DF:
2618           return "movsd\t{%1, %0|%0, %1}";
2619         case MODE_V1DF:
2620           return "movlpd\t{%1, %0|%0, %1}";
2621         case MODE_V2SF:
2622           return "movlps\t{%1, %0|%0, %1}";
2623         default:
2624           gcc_unreachable ();
2625         }
2626
2627     default:
2628       gcc_unreachable();
2629     }
2630 }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "0,1,2")
2634                  (const_string "DF")
2635                (eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2637
2638                /* For SSE1, we have many fewer alternatives.  */
2639                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640                  (cond [(eq_attr "alternative" "5,6")
2641                           (const_string "V4SF")
2642                        ]
2643                    (const_string "V2SF"))
2644
2645                /* xorps is one byte shorter.  */
2646                (eq_attr "alternative" "5")
2647                  (cond [(ne (symbol_ref "optimize_size")
2648                             (const_int 0))
2649                           (const_string "V4SF")
2650                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                             (const_int 0))
2652                           (const_string "TI")
2653                        ]
2654                        (const_string "V2DF"))
2655
2656                /* For architectures resolving dependencies on
2657                   whole SSE registers use APD move to break dependency
2658                   chains, otherwise use short move to avoid extra work.
2659
2660                   movaps encodes one byte shorter.  */
2661                (eq_attr "alternative" "6")
2662                  (cond
2663                    [(ne (symbol_ref "optimize_size")
2664                         (const_int 0))
2665                       (const_string "V4SF")
2666                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667                         (const_int 0))
2668                       (const_string "V2DF")
2669                    ]
2670                    (const_string "DF"))
2671                /* For architectures resolving dependencies on register
2672                   parts we may avoid extra work to zero out upper part
2673                   of register.  */
2674                (eq_attr "alternative" "7")
2675                  (if_then_else
2676                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677                        (const_int 0))
2678                    (const_string "V1DF")
2679                    (const_string "DF"))
2680               ]
2681               (const_string "DF")))])
2682
2683 (define_split
2684   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685         (match_operand:DF 1 "general_operand" ""))]
2686   "reload_completed
2687    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688    && ! (ANY_FP_REG_P (operands[0]) || 
2689          (GET_CODE (operands[0]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691    && ! (ANY_FP_REG_P (operands[1]) || 
2692          (GET_CODE (operands[1]) == SUBREG
2693           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694   [(const_int 0)]
2695   "ix86_split_long_move (operands); DONE;")
2696
2697 (define_insn "*swapdf"
2698   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699         (match_operand:DF 1 "fp_register_operand" "+f"))
2700    (set (match_dup 1)
2701         (match_dup 0))]
2702   "reload_completed || TARGET_80387"
2703 {
2704   if (STACK_TOP_P (operands[0]))
2705     return "fxch\t%1";
2706   else
2707     return "fxch\t%0";
2708 }
2709   [(set_attr "type" "fxch")
2710    (set_attr "mode" "DF")])
2711
2712 (define_expand "movxf"
2713   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714         (match_operand:XF 1 "general_operand" ""))]
2715   ""
2716   "ix86_expand_move (XFmode, operands); DONE;")
2717
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;;  handled elsewhere).
2724
2725 (define_insn "*pushxf_nointeger"
2726   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728   "optimize_size"
2729 {
2730   /* This insn should be already split before reg-stack.  */
2731   gcc_unreachable ();
2732 }
2733   [(set_attr "type" "multi")
2734    (set_attr "unit" "i387,*,*")
2735    (set_attr "mode" "XF,SI,SI")])
2736
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740   "!optimize_size"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   gcc_unreachable ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "unit" "i387,*")
2747    (set_attr "mode" "XF,SI")])
2748
2749 (define_split
2750   [(set (match_operand 0 "push_operand" "")
2751         (match_operand 1 "general_operand" ""))]
2752   "reload_completed
2753    && (GET_MODE (operands[0]) == XFmode
2754        || GET_MODE (operands[0]) == DFmode)
2755    && !ANY_FP_REG_P (operands[1])"
2756   [(const_int 0)]
2757   "ix86_split_long_move (operands); DONE;")
2758
2759 (define_split
2760   [(set (match_operand:XF 0 "push_operand" "")
2761         (match_operand:XF 1 "any_fp_register_operand" ""))]
2762   "!TARGET_64BIT"
2763   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "TARGET_64BIT"
2771   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779   "optimize_size
2780    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781    && (reload_in_progress || reload_completed
2782        || GET_CODE (operands[1]) != CONST_DOUBLE
2783        || memory_operand (operands[0], XFmode))" 
2784 {
2785   switch (which_alternative)
2786     {
2787     case 0:
2788       return output_387_reg_move (insn, operands);
2789
2790     case 1:
2791       /* There is no non-popping store to memory for XFmode.  So if
2792          we need one, follow the store with a load.  */
2793       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794         return "fstp%z0\t%y0\;fld%z0\t%y0";
2795       else
2796         return "fstp%z0\t%y0";
2797
2798     case 2:
2799       return standard_80387_constant_opcode (operands[1]);
2800
2801     case 3: case 4:
2802       return "#";
2803     default:
2804       gcc_unreachable ();
2805     }
2806 }
2807   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808    (set_attr "mode" "XF,XF,XF,SI,SI")])
2809
2810 (define_insn "*movxf_integer"
2811   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813   "!optimize_size
2814    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815    && (reload_in_progress || reload_completed
2816        || GET_CODE (operands[1]) != CONST_DOUBLE
2817        || memory_operand (operands[0], XFmode))" 
2818 {
2819   switch (which_alternative)
2820     {
2821     case 0:
2822       return output_387_reg_move (insn, operands);
2823
2824     case 1:
2825       /* There is no non-popping store to memory for XFmode.  So if
2826          we need one, follow the store with a load.  */
2827       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828         return "fstp%z0\t%y0\;fld%z0\t%y0";
2829       else
2830         return "fstp%z0\t%y0";
2831
2832     case 2:
2833       return standard_80387_constant_opcode (operands[1]);
2834
2835     case 3: case 4:
2836       return "#";
2837
2838     default:
2839       gcc_unreachable ();
2840     }
2841 }
2842   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843    (set_attr "mode" "XF,XF,XF,SI,SI")])
2844
2845 (define_split
2846   [(set (match_operand 0 "nonimmediate_operand" "")
2847         (match_operand 1 "general_operand" ""))]
2848   "reload_completed
2849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850    && GET_MODE (operands[0]) == XFmode
2851    && ! (ANY_FP_REG_P (operands[0]) || 
2852          (GET_CODE (operands[0]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854    && ! (ANY_FP_REG_P (operands[1]) || 
2855          (GET_CODE (operands[1]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857   [(const_int 0)]
2858   "ix86_split_long_move (operands); DONE;")
2859
2860 (define_split
2861   [(set (match_operand 0 "register_operand" "")
2862         (match_operand 1 "memory_operand" ""))]
2863   "reload_completed
2864    && GET_CODE (operands[1]) == MEM
2865    && (GET_MODE (operands[0]) == XFmode
2866        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867    && constant_pool_reference_p (operands[1])"
2868   [(set (match_dup 0) (match_dup 1))]
2869 {
2870   rtx c = avoid_constant_pool_reference (operands[1]);
2871   rtx r = operands[0];
2872
2873   if (GET_CODE (r) == SUBREG)
2874     r = SUBREG_REG (r);
2875
2876   if (SSE_REG_P (r))
2877     {
2878       if (!standard_sse_constant_p (c))
2879         FAIL;
2880     }
2881   else if (FP_REG_P (r))
2882     {
2883       if (!standard_80387_constant_p (c))
2884         FAIL;
2885     }
2886   else if (MMX_REG_P (r))
2887     FAIL;
2888
2889   operands[1] = c;
2890 })
2891
2892 (define_insn "swapxf"
2893   [(set (match_operand:XF 0 "register_operand" "+f")
2894         (match_operand:XF 1 "register_operand" "+f"))
2895    (set (match_dup 1)
2896         (match_dup 0))]
2897   "TARGET_80387"
2898 {
2899   if (STACK_TOP_P (operands[0]))
2900     return "fxch\t%1";
2901   else
2902     return "fxch\t%0";
2903 }
2904   [(set_attr "type" "fxch")
2905    (set_attr "mode" "XF")])
2906
2907 (define_expand "movtf"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909         (match_operand:TF 1 "nonimmediate_operand" ""))]
2910   "TARGET_64BIT"
2911 {
2912   ix86_expand_move (TFmode, operands);
2913   DONE;
2914 })
2915
2916 (define_insn "*movtf_internal"
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919   "TARGET_64BIT
2920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 {
2922   switch (which_alternative)
2923     {
2924     case 0:
2925     case 1:
2926       return "#";
2927     case 2:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "xorps\t%0, %0";
2930       else
2931         return "pxor\t%0, %0";
2932     case 3:
2933     case 4:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "movaps\t{%1, %0|%0, %1}";
2936       else
2937         return "movdqa\t{%1, %0|%0, %1}";
2938     default:
2939       gcc_unreachable ();
2940     }
2941 }
2942   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943    (set (attr "mode")
2944         (cond [(eq_attr "alternative" "2,3")
2945                  (if_then_else
2946                    (ne (symbol_ref "optimize_size")
2947                        (const_int 0))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))
2950                (eq_attr "alternative" "4")
2951                  (if_then_else
2952                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953                             (const_int 0))
2954                         (ne (symbol_ref "optimize_size")
2955                             (const_int 0)))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))]
2958                (const_string "DI")))])
2959
2960 (define_split
2961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962         (match_operand:TF 1 "general_operand" ""))]
2963   "reload_completed && !SSE_REG_P (operands[0])
2964    && !SSE_REG_P (operands[1])"
2965   [(const_int 0)]
2966   "ix86_split_long_move (operands); DONE;")
2967 \f
2968 ;; Zero extension instructions
2969
2970 (define_expand "zero_extendhisi2"
2971   [(set (match_operand:SI 0 "register_operand" "")
2972      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973   ""
2974 {
2975   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976     {
2977       operands[1] = force_reg (HImode, operands[1]);
2978       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979       DONE;
2980     }
2981 })
2982
2983 (define_insn "zero_extendhisi2_and"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   "#"
2989   [(set_attr "type" "alu1")
2990    (set_attr "mode" "SI")])
2991
2992 (define_split
2993   [(set (match_operand:SI 0 "register_operand" "")
2994         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998               (clobber (reg:CC FLAGS_REG))])]
2999   "")
3000
3001 (define_insn "*zero_extendhisi2_movzwl"
3002   [(set (match_operand:SI 0 "register_operand" "=r")
3003      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005   "movz{wl|x}\t{%1, %0|%0, %1}"
3006   [(set_attr "type" "imovx")
3007    (set_attr "mode" "SI")])
3008
3009 (define_expand "zero_extendqihi2"
3010   [(parallel
3011     [(set (match_operand:HI 0 "register_operand" "")
3012        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3016
3017 (define_insn "*zero_extendqihi2_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "HI")])
3025
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027   [(set (match_operand:HI 0 "register_operand" "=r,r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "HI")])
3034
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037   [(set (match_operand:HI 0 "register_operand" "=r")
3038      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041   [(set_attr "type" "imovx")
3042    (set_attr "mode" "SI")])
3043
3044 ;; For the movzbw case strip only the clobber
3045 (define_split
3046   [(set (match_operand:HI 0 "register_operand" "")
3047         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048    (clobber (reg:CC FLAGS_REG))]
3049   "reload_completed 
3050    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3057 (define_split
3058   [(set (match_operand:HI 0 "register_operand" "")
3059         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060    (clobber (reg:CC FLAGS_REG))]
3061   "reload_completed
3062    && ANY_QI_REG_P (operands[0])
3063    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065   [(set (match_dup 0) (const_int 0))
3066    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067   "operands[2] = gen_lowpart (QImode, operands[0]);")
3068
3069 ;; Rest is handled by single and.
3070 (define_split
3071   [(set (match_operand:HI 0 "register_operand" "")
3072         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && true_regnum (operands[0]) == true_regnum (operands[1])"
3076   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077               (clobber (reg:CC FLAGS_REG))])]
3078   "")
3079
3080 (define_expand "zero_extendqisi2"
3081   [(parallel
3082     [(set (match_operand:SI 0 "register_operand" "")
3083        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084      (clobber (reg:CC FLAGS_REG))])]
3085   ""
3086   "")
3087
3088 (define_insn "*zero_extendqisi2_and"
3089   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091    (clobber (reg:CC FLAGS_REG))]
3092   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093   "#"
3094   [(set_attr "type" "alu1")
3095    (set_attr "mode" "SI")])
3096
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098   [(set (match_operand:SI 0 "register_operand" "=r,r")
3099      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102   "#"
3103   [(set_attr "type" "imovx,alu1")
3104    (set_attr "mode" "SI")])
3105
3106 (define_insn "*zero_extendqisi2_movzbw"
3107   [(set (match_operand:SI 0 "register_operand" "=r")
3108      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110   "movz{bl|x}\t{%1, %0|%0, %1}"
3111   [(set_attr "type" "imovx")
3112    (set_attr "mode" "SI")])
3113
3114 ;; For the movzbl case strip only the clobber
3115 (define_split
3116   [(set (match_operand:SI 0 "register_operand" "")
3117         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "reload_completed 
3120    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122   [(set (match_dup 0)
3123         (zero_extend:SI (match_dup 1)))])
3124
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3127 (define_split
3128   [(set (match_operand:SI 0 "register_operand" "")
3129         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130    (clobber (reg:CC FLAGS_REG))]
3131   "reload_completed
3132    && ANY_QI_REG_P (operands[0])
3133    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136   [(set (match_dup 0) (const_int 0))
3137    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138   "operands[2] = gen_lowpart (QImode, operands[0]);")
3139
3140 ;; Rest is handled by single and.
3141 (define_split
3142   [(set (match_operand:SI 0 "register_operand" "")
3143         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144    (clobber (reg:CC FLAGS_REG))]
3145   "reload_completed
3146    && true_regnum (operands[0]) == true_regnum (operands[1])"
3147   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148               (clobber (reg:CC FLAGS_REG))])]
3149   "")
3150
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153   [(set (match_operand:DI 0 "register_operand" "=r")
3154      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155   ""
3156   "if (!TARGET_64BIT)
3157      {
3158        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3159        DONE;
3160      }
3161   ")
3162
3163 (define_insn "zero_extendsidi2_32"
3164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166    (clobber (reg:CC FLAGS_REG))]
3167   "!TARGET_64BIT"
3168   "@
3169    #
3170    #
3171    #
3172    movd\t{%1, %0|%0, %1}
3173    movd\t{%1, %0|%0, %1}"
3174   [(set_attr "mode" "SI,SI,SI,DI,TI")
3175    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176
3177 (define_insn "zero_extendsidi2_rex64"
3178   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3180   "TARGET_64BIT"
3181   "@
3182    mov\t{%k1, %k0|%k0, %k1}
3183    #
3184    movd\t{%1, %0|%0, %1}
3185    movd\t{%1, %0|%0, %1}"
3186   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187    (set_attr "mode" "SI,DI,SI,SI")])
3188
3189 (define_split
3190   [(set (match_operand:DI 0 "memory_operand" "")
3191      (zero_extend:DI (match_dup 0)))]
3192   "TARGET_64BIT"
3193   [(set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195
3196 (define_split 
3197   [(set (match_operand:DI 0 "register_operand" "")
3198         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "!TARGET_64BIT && reload_completed
3201    && true_regnum (operands[0]) == true_regnum (operands[1])"
3202   [(set (match_dup 4) (const_int 0))]
3203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204
3205 (define_split 
3206   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208    (clobber (reg:CC FLAGS_REG))]
3209   "!TARGET_64BIT && reload_completed
3210    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211   [(set (match_dup 3) (match_dup 1))
3212    (set (match_dup 4) (const_int 0))]
3213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214
3215 (define_insn "zero_extendhidi2"
3216   [(set (match_operand:DI 0 "register_operand" "=r")
3217      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218   "TARGET_64BIT"
3219   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220   [(set_attr "type" "imovx")
3221    (set_attr "mode" "DI")])
3222
3223 (define_insn "zero_extendqidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226   "TARGET_64BIT"
3227   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228   [(set_attr "type" "imovx")
3229    (set_attr "mode" "DI")])
3230 \f
3231 ;; Sign extension instructions
3232
3233 (define_expand "extendsidi2"
3234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236               (clobber (reg:CC FLAGS_REG))
3237               (clobber (match_scratch:SI 2 ""))])]
3238   ""
3239 {
3240   if (TARGET_64BIT)
3241     {
3242       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3243       DONE;
3244     }
3245 })
3246
3247 (define_insn "*extendsidi2_1"
3248   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250    (clobber (reg:CC FLAGS_REG))
3251    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252   "!TARGET_64BIT"
3253   "#")
3254
3255 (define_insn "extendsidi2_rex64"
3256   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258   "TARGET_64BIT"
3259   "@
3260    {cltq|cdqe}
3261    movs{lq|x}\t{%1,%0|%0, %1}"
3262   [(set_attr "type" "imovx")
3263    (set_attr "mode" "DI")
3264    (set_attr "prefix_0f" "0")
3265    (set_attr "modrm" "0,1")])
3266
3267 (define_insn "extendhidi2"
3268   [(set (match_operand:DI 0 "register_operand" "=r")
3269         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270   "TARGET_64BIT"
3271   "movs{wq|x}\t{%1,%0|%0, %1}"
3272   [(set_attr "type" "imovx")
3273    (set_attr "mode" "DI")])
3274
3275 (define_insn "extendqidi2"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "TARGET_64BIT"
3279   "movs{bq|x}\t{%1,%0|%0, %1}"
3280    [(set_attr "type" "imovx")
3281     (set_attr "mode" "DI")])
3282
3283 ;; Extend to memory case when source register does die.
3284 (define_split 
3285   [(set (match_operand:DI 0 "memory_operand" "")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_operand:SI 2 "register_operand" ""))]
3289   "(reload_completed
3290     && dead_or_set_p (insn, operands[1])
3291     && !reg_mentioned_p (operands[1], operands[0]))"
3292   [(set (match_dup 3) (match_dup 1))
3293    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294               (clobber (reg:CC FLAGS_REG))])
3295    (set (match_dup 4) (match_dup 1))]
3296   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297
3298 ;; Extend to memory case when source register does not die.
3299 (define_split 
3300   [(set (match_operand:DI 0 "memory_operand" "")
3301         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302    (clobber (reg:CC FLAGS_REG))
3303    (clobber (match_operand:SI 2 "register_operand" ""))]
3304   "reload_completed"
3305   [(const_int 0)]
3306 {
3307   split_di (&operands[0], 1, &operands[3], &operands[4]);
3308
3309   emit_move_insn (operands[3], operands[1]);
3310
3311   /* Generate a cltd if possible and doing so it profitable.  */
3312   if (true_regnum (operands[1]) == 0
3313       && true_regnum (operands[2]) == 1
3314       && (optimize_size || TARGET_USE_CLTD))
3315     {
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317     }
3318   else
3319     {
3320       emit_move_insn (operands[2], operands[1]);
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322     }
3323   emit_move_insn (operands[4], operands[2]);
3324   DONE;
3325 })
3326
3327 ;; Extend to register case.  Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3329 (define_split 
3330   [(set (match_operand:DI 0 "register_operand" "")
3331         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332    (clobber (reg:CC FLAGS_REG))
3333    (clobber (match_scratch:SI 2 ""))]
3334   "reload_completed"
3335   [(const_int 0)]
3336 {
3337   split_di (&operands[0], 1, &operands[3], &operands[4]);
3338
3339   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340     emit_move_insn (operands[3], operands[1]);
3341
3342   /* Generate a cltd if possible and doing so it profitable.  */
3343   if (true_regnum (operands[3]) == 0
3344       && (optimize_size || TARGET_USE_CLTD))
3345     {
3346       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347       DONE;
3348     }
3349
3350   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351     emit_move_insn (operands[4], operands[1]);
3352
3353   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354   DONE;
3355 })
3356
3357 (define_insn "extendhisi2"
3358   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3360   ""
3361 {
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%0|%0, %1}";
3368     }
3369 }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3382
3383 (define_insn "*extendhisi2_zext"
3384   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385         (zero_extend:DI
3386           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3387   "TARGET_64BIT"
3388 {
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cwtl|cwde}";
3393     default:
3394       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3395     }
3396 }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "SI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3409
3410 (define_insn "extendqihi2"
3411   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3413   ""
3414 {
3415   switch (get_attr_prefix_0f (insn))
3416     {
3417     case 0:
3418       return "{cbtw|cbw}";
3419     default:
3420       return "movs{bw|x}\t{%1,%0|%0, %1}";
3421     }
3422 }
3423   [(set_attr "type" "imovx")
3424    (set_attr "mode" "HI")
3425    (set (attr "prefix_0f")
3426      ;; movsx is short decodable while cwtl is vector decoded.
3427      (if_then_else (and (eq_attr "cpu" "!k6")
3428                         (eq_attr "alternative" "0"))
3429         (const_string "0")
3430         (const_string "1")))
3431    (set (attr "modrm")
3432      (if_then_else (eq_attr "prefix_0f" "0")
3433         (const_string "0")
3434         (const_string "1")))])
3435
3436 (define_insn "extendqisi2"
3437   [(set (match_operand:SI 0 "register_operand" "=r")
3438         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439   ""
3440   "movs{bl|x}\t{%1,%0|%0, %1}"
3441    [(set_attr "type" "imovx")
3442     (set_attr "mode" "SI")])
3443
3444 (define_insn "*extendqisi2_zext"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI
3447           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448   "TARGET_64BIT"
3449   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450    [(set_attr "type" "imovx")
3451     (set_attr "mode" "SI")])
3452 \f
3453 ;; Conversions between float and double.
3454
3455 ;; These are all no-ops in the model used for the 80387.  So just
3456 ;; emit moves.
3457
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3459 (define_insn "*dummy_extendsfdf2"
3460   [(set (match_operand:DF 0 "push_operand" "=<")
3461         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3462   "0"
3463   "#")
3464
3465 (define_split
3466   [(set (match_operand:DF 0 "push_operand" "")
3467         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "!TARGET_64BIT"
3469   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3471
3472 (define_split
3473   [(set (match_operand:DF 0 "push_operand" "")
3474         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475   "TARGET_64BIT"
3476   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478
3479 (define_insn "*dummy_extendsfxf2"
3480   [(set (match_operand:XF 0 "push_operand" "=<")
3481         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3482   "0"
3483   "#")
3484
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488   ""
3489   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496   "TARGET_64BIT"
3497   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_split
3502   [(set (match_operand:XF 0 "push_operand" "")
3503         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504   ""
3505   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508
3509 (define_split
3510   [(set (match_operand:XF 0 "push_operand" "")
3511         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512   "TARGET_64BIT"
3513   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516
3517 (define_expand "extendsfdf2"
3518   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521 {
3522   /* ??? Needed for compress_float_constant since all fp constants
3523      are LEGITIMATE_CONSTANT_P.  */
3524   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3525     {
3526       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527           && standard_80387_constant_p (operands[1]) > 0)
3528         {
3529           operands[1] = simplify_const_unary_operation
3530             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531           emit_move_insn_1 (operands[0], operands[1]);
3532           DONE;
3533         }
3534       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3535     }
3536   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537     operands[1] = force_reg (SFmode, operands[1]);
3538 })
3539
3540 (define_insn "*extendsfdf2_mixed"
3541   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3545 {
3546   switch (which_alternative)
3547     {
3548     case 0:
3549       return output_387_reg_move (insn, operands);
3550
3551     case 1:
3552       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553         return "fstp%z0\t%y0";
3554       else
3555         return "fst%z0\t%y0";
3556
3557     case 2:
3558       return "cvtss2sd\t{%1, %0|%0, %1}";
3559
3560     default:
3561       gcc_unreachable ();
3562     }
3563 }
3564   [(set_attr "type" "fmov,fmov,ssecvt")
3565    (set_attr "mode" "SF,XF,DF")])
3566
3567 (define_insn "*extendsfdf2_sse"
3568   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570   "TARGET_SSE2 && TARGET_SSE_MATH
3571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572   "cvtss2sd\t{%1, %0|%0, %1}"
3573   [(set_attr "type" "ssecvt")
3574    (set_attr "mode" "DF")])
3575
3576 (define_insn "*extendsfdf2_i387"
3577   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579   "TARGET_80387
3580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3581 {
3582   switch (which_alternative)
3583     {
3584     case 0:
3585       return output_387_reg_move (insn, operands);
3586
3587     case 1:
3588       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589         return "fstp%z0\t%y0";
3590       else
3591         return "fst%z0\t%y0";
3592
3593     default:
3594       gcc_unreachable ();
3595     }
3596 }
3597   [(set_attr "type" "fmov")
3598    (set_attr "mode" "SF,XF")])
3599
3600 (define_expand "extendsfxf2"
3601   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3603   "TARGET_80387"
3604 {
3605   /* ??? Needed for compress_float_constant since all fp constants
3606      are LEGITIMATE_CONSTANT_P.  */
3607   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608     {
3609       if (standard_80387_constant_p (operands[1]) > 0)
3610         {
3611           operands[1] = simplify_const_unary_operation
3612             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613           emit_move_insn_1 (operands[0], operands[1]);
3614           DONE;
3615         }
3616       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3617     }
3618   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619     operands[1] = force_reg (SFmode, operands[1]);
3620 })
3621
3622 (define_insn "*extendsfxf2_i387"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3625   "TARGET_80387
3626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3627 {
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3632
3633     case 1:
3634       /* There is no non-popping store to memory for XFmode.  So if
3635          we need one, follow the store with a load.  */
3636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637         return "fstp%z0\t%y0";
3638       else
3639         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640
3641     default:
3642       gcc_unreachable ();
3643     }
3644 }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "SF,XF")])
3647
3648 (define_expand "extenddfxf2"
3649   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651   "TARGET_80387"
3652 {
3653   /* ??? Needed for compress_float_constant since all fp constants
3654      are LEGITIMATE_CONSTANT_P.  */
3655   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656     {
3657       if (standard_80387_constant_p (operands[1]) > 0)
3658         {
3659           operands[1] = simplify_const_unary_operation
3660             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661           emit_move_insn_1 (operands[0], operands[1]);
3662           DONE;
3663         }
3664       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665     }
3666   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667     operands[1] = force_reg (DFmode, operands[1]);
3668 })
3669
3670 (define_insn "*extenddfxf2_i387"
3671   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3673   "TARGET_80387
3674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3675 {
3676   switch (which_alternative)
3677     {
3678     case 0:
3679       return output_387_reg_move (insn, operands);
3680
3681     case 1:
3682       /* There is no non-popping store to memory for XFmode.  So if
3683          we need one, follow the store with a load.  */
3684       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3686       else
3687         return "fstp%z0\t%y0";
3688
3689     default:
3690       gcc_unreachable ();
3691     }
3692 }
3693   [(set_attr "type" "fmov")
3694    (set_attr "mode" "DF,XF")])
3695
3696 ;; %%% This seems bad bad news.
3697 ;; This cannot output into an f-reg because there is no way to be sure
3698 ;; of truncating in that case.  Otherwise this is just like a simple move
3699 ;; insn.  So we pretend we can output to a reg in order to get better
3700 ;; register preferencing, but we really use a stack slot.
3701
3702 ;; Conversion from DFmode to SFmode.
3703
3704 (define_expand "truncdfsf2"
3705   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3706         (float_truncate:SF
3707           (match_operand:DF 1 "nonimmediate_operand" "")))]
3708   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3709 {
3710   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711     operands[1] = force_reg (DFmode, operands[1]);
3712
3713   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3714     ;
3715   else if (flag_unsafe_math_optimizations)
3716     ;
3717   else
3718     {
3719       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3720       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3721       DONE;
3722     }
3723 })
3724
3725 (define_expand "truncdfsf2_with_temp"
3726   [(parallel [(set (match_operand:SF 0 "" "")
3727                    (float_truncate:SF (match_operand:DF 1 "" "")))
3728               (clobber (match_operand:SF 2 "" ""))])]
3729   "")
3730
3731 (define_insn "*truncdfsf_fast_mixed"
3732   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3736 {
3737   switch (which_alternative)
3738     {
3739     case 0:
3740       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741         return "fstp%z0\t%y0";
3742       else
3743         return "fst%z0\t%y0";
3744     case 1:
3745       return output_387_reg_move (insn, operands);
3746     case 2:
3747       return "cvtsd2ss\t{%1, %0|%0, %1}";
3748     default:
3749       gcc_unreachable ();
3750     }
3751 }
3752   [(set_attr "type" "fmov,fmov,ssecvt")
3753    (set_attr "mode" "SF")])
3754
3755 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756 ;; because nothing we do here is unsafe.
3757 (define_insn "*truncdfsf_fast_sse"
3758   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3759         (float_truncate:SF
3760           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761   "TARGET_SSE2 && TARGET_SSE_MATH"
3762   "cvtsd2ss\t{%1, %0|%0, %1}"
3763   [(set_attr "type" "ssecvt")
3764    (set_attr "mode" "SF")])
3765
3766 (define_insn "*truncdfsf_fast_i387"
3767   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3768         (float_truncate:SF
3769           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770   "TARGET_80387 && flag_unsafe_math_optimizations"
3771   "* return output_387_reg_move (insn, operands);"
3772   [(set_attr "type" "fmov")
3773    (set_attr "mode" "SF")])
3774
3775 (define_insn "*truncdfsf_mixed"
3776   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3777         (float_truncate:SF
3778           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3779    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3780   "TARGET_MIX_SSE_I387"
3781 {
3782   switch (which_alternative)
3783     {
3784     case 0:
3785       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786         return "fstp%z0\t%y0";
3787       else
3788         return "fst%z0\t%y0";
3789     case 1:
3790       return "#";
3791     case 2:
3792       return "cvtsd2ss\t{%1, %0|%0, %1}";
3793     default:
3794       gcc_unreachable ();
3795     }
3796 }
3797   [(set_attr "type" "fmov,multi,ssecvt")
3798    (set_attr "unit" "*,i387,*")
3799    (set_attr "mode" "SF")])
3800
3801 (define_insn "*truncdfsf_i387"
3802   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3803         (float_truncate:SF
3804           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3806   "TARGET_80387"
3807 {
3808   switch (which_alternative)
3809     {
3810     case 0:
3811       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812         return "fstp%z0\t%y0";
3813       else
3814         return "fst%z0\t%y0";
3815     case 1:
3816       return "#";
3817     default:
3818       gcc_unreachable ();
3819     }
3820 }
3821   [(set_attr "type" "fmov,multi")
3822    (set_attr "unit" "*,i387")
3823    (set_attr "mode" "SF")])
3824
3825 (define_insn "*truncdfsf2_i387_1"
3826   [(set (match_operand:SF 0 "memory_operand" "=m")
3827         (float_truncate:SF
3828           (match_operand:DF 1 "register_operand" "f")))]
3829   "TARGET_80387
3830    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831    && !TARGET_MIX_SSE_I387"
3832 {
3833   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834     return "fstp%z0\t%y0";
3835   else
3836     return "fst%z0\t%y0";
3837 }
3838   [(set_attr "type" "fmov")
3839    (set_attr "mode" "SF")])
3840
3841 (define_split
3842   [(set (match_operand:SF 0 "register_operand" "")
3843         (float_truncate:SF
3844          (match_operand:DF 1 "fp_register_operand" "")))
3845    (clobber (match_operand 2 "" ""))]
3846   "reload_completed"
3847   [(set (match_dup 2) (match_dup 1))
3848    (set (match_dup 0) (match_dup 2))]
3849 {
3850   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3851 })
3852
3853 ;; Conversion from XFmode to SFmode.
3854
3855 (define_expand "truncxfsf2"
3856   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3857                    (float_truncate:SF
3858                     (match_operand:XF 1 "register_operand" "")))
3859               (clobber (match_dup 2))])]
3860   "TARGET_80387"
3861 {
3862   if (flag_unsafe_math_optimizations)
3863     {
3864       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866       if (reg != operands[0])
3867         emit_move_insn (operands[0], reg);
3868       DONE;
3869     }
3870   else
3871     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3872 })
3873
3874 (define_insn "*truncxfsf2_mixed"
3875   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879   "TARGET_MIX_SSE_I387"
3880 {
3881   gcc_assert (!which_alternative);
3882   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883     return "fstp%z0\t%y0";
3884   else
3885     return "fst%z0\t%y0";
3886 }
3887   [(set_attr "type" "fmov,multi,multi,multi")
3888    (set_attr "unit" "*,i387,i387,i387")
3889    (set_attr "mode" "SF")])
3890
3891 (define_insn "truncxfsf2_i387_noop"
3892   [(set (match_operand:SF 0 "register_operand" "=f")
3893         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894   "TARGET_80387 && flag_unsafe_math_optimizations"
3895 {
3896   return output_387_reg_move (insn, operands);
3897 }
3898   [(set_attr "type" "fmov")
3899    (set_attr "mode" "SF")])
3900
3901 (define_insn "*truncxfsf2_i387"
3902   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3903         (float_truncate:SF
3904          (match_operand:XF 1 "register_operand" "f,f,f")))
3905    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3906   "TARGET_80387"
3907 {
3908   gcc_assert (!which_alternative);
3909   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910     return "fstp%z0\t%y0";
3911    else
3912      return "fst%z0\t%y0";
3913 }
3914   [(set_attr "type" "fmov,multi,multi")
3915    (set_attr "unit" "*,i387,i387")
3916    (set_attr "mode" "SF")])
3917
3918 (define_insn "*truncxfsf2_i387_1"
3919   [(set (match_operand:SF 0 "memory_operand" "=m")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "f")))]
3922   "TARGET_80387"
3923 {
3924   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925     return "fstp%z0\t%y0";
3926   else
3927     return "fst%z0\t%y0";
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "SF")])
3931
3932 (define_split
3933   [(set (match_operand:SF 0 "register_operand" "")
3934         (float_truncate:SF
3935          (match_operand:XF 1 "register_operand" "")))
3936    (clobber (match_operand:SF 2 "memory_operand" ""))]
3937   "TARGET_80387 && reload_completed"
3938   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939    (set (match_dup 0) (match_dup 2))]
3940   "")
3941
3942 (define_split
3943   [(set (match_operand:SF 0 "memory_operand" "")
3944         (float_truncate:SF
3945          (match_operand:XF 1 "register_operand" "")))
3946    (clobber (match_operand:SF 2 "memory_operand" ""))]
3947   "TARGET_80387"
3948   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3949   "")
3950
3951 ;; Conversion from XFmode to DFmode.
3952
3953 (define_expand "truncxfdf2"
3954   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3955                    (float_truncate:DF
3956                     (match_operand:XF 1 "register_operand" "")))
3957               (clobber (match_dup 2))])]
3958   "TARGET_80387"
3959 {
3960   if (flag_unsafe_math_optimizations)
3961     {
3962       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964       if (reg != operands[0])
3965         emit_move_insn (operands[0], reg);
3966       DONE;
3967     }
3968   else
3969     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3970 })
3971
3972 (define_insn "*truncxfdf2_mixed"
3973   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3974         (float_truncate:DF
3975          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3978 {
3979   gcc_assert (!which_alternative);
3980   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981     return "fstp%z0\t%y0";
3982   else
3983     return "fst%z0\t%y0";
3984 }
3985   [(set_attr "type" "fmov,multi,multi,multi")
3986    (set_attr "unit" "*,i387,i387,i387")
3987    (set_attr "mode" "DF")])
3988
3989 (define_insn "truncxfdf2_i387_noop"
3990   [(set (match_operand:DF 0 "register_operand" "=f")
3991         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387 && flag_unsafe_math_optimizations"
3993 {
3994   return output_387_reg_move (insn, operands);
3995 }
3996   [(set_attr "type" "fmov")
3997    (set_attr "mode" "DF")])
3998
3999 (define_insn "*truncxfdf2_i387"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4001         (float_truncate:DF
4002          (match_operand:XF 1 "register_operand" "f,f,f")))
4003    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4004   "TARGET_80387"
4005 {
4006   gcc_assert (!which_alternative);
4007   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008     return "fstp%z0\t%y0";
4009   else
4010     return "fst%z0\t%y0";
4011 }
4012   [(set_attr "type" "fmov,multi,multi")
4013    (set_attr "unit" "*,i387,i387")
4014    (set_attr "mode" "DF")])
4015
4016 (define_insn "*truncxfdf2_i387_1"
4017   [(set (match_operand:DF 0 "memory_operand" "=m")
4018         (float_truncate:DF
4019           (match_operand:XF 1 "register_operand" "f")))]
4020   "TARGET_80387"
4021 {
4022   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023     return "fstp%z0\t%y0";
4024   else
4025     return "fst%z0\t%y0";
4026 }
4027   [(set_attr "type" "fmov")
4028    (set_attr "mode" "DF")])
4029
4030 (define_split
4031   [(set (match_operand:DF 0 "register_operand" "")
4032         (float_truncate:DF
4033          (match_operand:XF 1 "register_operand" "")))
4034    (clobber (match_operand:DF 2 "memory_operand" ""))]
4035   "TARGET_80387 && reload_completed"
4036   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037    (set (match_dup 0) (match_dup 2))]
4038   "")
4039
4040 (define_split
4041   [(set (match_operand:DF 0 "memory_operand" "")
4042         (float_truncate:DF
4043          (match_operand:XF 1 "register_operand" "")))
4044    (clobber (match_operand:DF 2 "memory_operand" ""))]
4045   "TARGET_80387"
4046   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4047   "")
4048 \f
4049 ;; Signed conversion to DImode.
4050
4051 (define_expand "fix_truncxfdi2"
4052   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4054               (clobber (reg:CC FLAGS_REG))])]
4055   "TARGET_80387"
4056 {
4057   if (TARGET_FISTTP)
4058    {
4059      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060      DONE;
4061    }
4062 })
4063
4064 (define_expand "fix_trunc<mode>di2"
4065   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067               (clobber (reg:CC FLAGS_REG))])]
4068   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4069 {
4070   if (TARGET_FISTTP
4071       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4072    {
4073      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4074      DONE;
4075    }
4076   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4077    {
4078      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080      if (out != operands[0])
4081         emit_move_insn (operands[0], out);
4082      DONE;
4083    }
4084 })
4085
4086 ;; Signed conversion to SImode.
4087
4088 (define_expand "fix_truncxfsi2"
4089   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4091               (clobber (reg:CC FLAGS_REG))])]
4092   "TARGET_80387"
4093 {
4094   if (TARGET_FISTTP)
4095    {
4096      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097      DONE;
4098    }
4099 })
4100
4101 (define_expand "fix_trunc<mode>si2"
4102   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104               (clobber (reg:CC FLAGS_REG))])]
4105   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4106 {
4107   if (TARGET_FISTTP
4108       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4109    {
4110      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4111      DONE;
4112    }
4113   if (SSE_FLOAT_MODE_P (<MODE>mode))
4114    {
4115      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117      if (out != operands[0])
4118         emit_move_insn (operands[0], out);
4119      DONE;
4120    }
4121 })
4122
4123 ;; Signed conversion to HImode.
4124
4125 (define_expand "fix_trunc<mode>hi2"
4126   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128               (clobber (reg:CC FLAGS_REG))])]
4129   "TARGET_80387
4130    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4131 {
4132   if (TARGET_FISTTP)
4133    {
4134      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4135      DONE;
4136    }
4137 })
4138
4139 ;; When SSE is available, it is always faster to use it!
4140 (define_insn "fix_truncsfdi_sse"
4141   [(set (match_operand:DI 0 "register_operand" "=r,r")
4142         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144   "cvttss2si{q}\t{%1, %0|%0, %1}"
4145   [(set_attr "type" "sseicvt")
4146    (set_attr "mode" "SF")
4147    (set_attr "athlon_decode" "double,vector")])
4148
4149 (define_insn "fix_truncdfdi_sse"
4150   [(set (match_operand:DI 0 "register_operand" "=r,r")
4151         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154   [(set_attr "type" "sseicvt")
4155    (set_attr "mode" "DF")
4156    (set_attr "athlon_decode" "double,vector")])
4157
4158 (define_insn "fix_truncsfsi_sse"
4159   [(set (match_operand:SI 0 "register_operand" "=r,r")
4160         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162   "cvttss2si\t{%1, %0|%0, %1}"
4163   [(set_attr "type" "sseicvt")
4164    (set_attr "mode" "DF")
4165    (set_attr "athlon_decode" "double,vector")])
4166
4167 (define_insn "fix_truncdfsi_sse"
4168   [(set (match_operand:SI 0 "register_operand" "=r,r")
4169         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171   "cvttsd2si\t{%1, %0|%0, %1}"
4172   [(set_attr "type" "sseicvt")
4173    (set_attr "mode" "DF")
4174    (set_attr "athlon_decode" "double,vector")])
4175
4176 ;; Avoid vector decoded forms of the instruction.
4177 (define_peephole2
4178   [(match_scratch:DF 2 "Y")
4179    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182   [(set (match_dup 2) (match_dup 1))
4183    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4184   "")
4185
4186 (define_peephole2
4187   [(match_scratch:SF 2 "x")
4188    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191   [(set (match_dup 2) (match_dup 1))
4192    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4193   "")
4194
4195 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4198   "TARGET_FISTTP
4199    && FLOAT_MODE_P (GET_MODE (operands[1]))
4200    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201          && (TARGET_64BIT || <MODE>mode != DImode))
4202         && TARGET_SSE_MATH)
4203    && !(reload_completed || reload_in_progress)"
4204   "#"
4205   "&& 1"
4206   [(const_int 0)]
4207 {
4208   if (memory_operand (operands[0], VOIDmode))
4209     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4210   else
4211     {
4212       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4214                                                             operands[1],
4215                                                             operands[2]));
4216     }
4217   DONE;
4218 }
4219   [(set_attr "type" "fisttp")
4220    (set_attr "mode" "<MODE>")])
4221
4222 (define_insn "fix_trunc<mode>_i387_fisttp"
4223   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225    (clobber (match_scratch:XF 2 "=&1f"))]
4226   "TARGET_FISTTP
4227    && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229          && (TARGET_64BIT || <MODE>mode != DImode))
4230         && TARGET_SSE_MATH)"
4231   "* return output_fix_trunc (insn, operands, 1);"
4232   [(set_attr "type" "fisttp")
4233    (set_attr "mode" "<MODE>")])
4234
4235 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4240   "TARGET_FISTTP
4241    && FLOAT_MODE_P (GET_MODE (operands[1]))
4242    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243         && (TARGET_64BIT || <MODE>mode != DImode))
4244         && TARGET_SSE_MATH)"
4245   "#"
4246   [(set_attr "type" "fisttp")
4247    (set_attr "mode" "<MODE>")])
4248
4249 (define_split
4250   [(set (match_operand:X87MODEI 0 "register_operand" "")
4251         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4252    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253    (clobber (match_scratch 3 ""))]
4254   "reload_completed"
4255   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256               (clobber (match_dup 3))])
4257    (set (match_dup 0) (match_dup 2))]
4258   "")
4259
4260 (define_split
4261   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4263    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264    (clobber (match_scratch 3 ""))]
4265   "reload_completed"
4266   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267               (clobber (match_dup 3))])]
4268   "")
4269
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274 ;; function in i386.c.
4275 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4276   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278    (clobber (reg:CC FLAGS_REG))]
4279   "TARGET_80387 && !TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282          && (TARGET_64BIT || <MODE>mode != DImode))
4283    && !(reload_completed || reload_in_progress)"
4284   "#"
4285   "&& 1"
4286   [(const_int 0)]
4287 {
4288   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4289
4290   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292   if (memory_operand (operands[0], VOIDmode))
4293     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294                                          operands[2], operands[3]));
4295   else
4296     {
4297       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299                                                      operands[2], operands[3],
4300                                                      operands[4]));
4301     }
4302   DONE;
4303 }
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "<MODE>")])
4307
4308 (define_insn "fix_truncdi_i387"
4309   [(set (match_operand:DI 0 "memory_operand" "=m")
4310         (fix:DI (match_operand 1 "register_operand" "f")))
4311    (use (match_operand:HI 2 "memory_operand" "m"))
4312    (use (match_operand:HI 3 "memory_operand" "m"))
4313    (clobber (match_scratch:XF 4 "=&1f"))]
4314   "TARGET_80387 && !TARGET_FISTTP
4315    && FLOAT_MODE_P (GET_MODE (operands[1]))
4316    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317   "* return output_fix_trunc (insn, operands, 0);"
4318   [(set_attr "type" "fistp")
4319    (set_attr "i387_cw" "trunc")
4320    (set_attr "mode" "DI")])
4321
4322 (define_insn "fix_truncdi_i387_with_temp"
4323   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324         (fix:DI (match_operand 1 "register_operand" "f,f")))
4325    (use (match_operand:HI 2 "memory_operand" "m,m"))
4326    (use (match_operand:HI 3 "memory_operand" "m,m"))
4327    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329   "TARGET_80387 && !TARGET_FISTTP
4330    && FLOAT_MODE_P (GET_MODE (operands[1]))
4331    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332   "#"
4333   [(set_attr "type" "fistp")
4334    (set_attr "i387_cw" "trunc")
4335    (set_attr "mode" "DI")])
4336
4337 (define_split 
4338   [(set (match_operand:DI 0 "register_operand" "")
4339         (fix:DI (match_operand 1 "register_operand" "")))
4340    (use (match_operand:HI 2 "memory_operand" ""))
4341    (use (match_operand:HI 3 "memory_operand" ""))
4342    (clobber (match_operand:DI 4 "memory_operand" ""))
4343    (clobber (match_scratch 5 ""))]
4344   "reload_completed"
4345   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4346               (use (match_dup 2))
4347               (use (match_dup 3))
4348               (clobber (match_dup 5))])
4349    (set (match_dup 0) (match_dup 4))]
4350   "")
4351
4352 (define_split 
4353   [(set (match_operand:DI 0 "memory_operand" "")
4354         (fix:DI (match_operand 1 "register_operand" "")))
4355    (use (match_operand:HI 2 "memory_operand" ""))
4356    (use (match_operand:HI 3 "memory_operand" ""))
4357    (clobber (match_operand:DI 4 "memory_operand" ""))
4358    (clobber (match_scratch 5 ""))]
4359   "reload_completed"
4360   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4361               (use (match_dup 2))
4362               (use (match_dup 3))
4363               (clobber (match_dup 5))])]
4364   "")
4365
4366 (define_insn "fix_trunc<mode>_i387"
4367   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369    (use (match_operand:HI 2 "memory_operand" "m"))
4370    (use (match_operand:HI 3 "memory_operand" "m"))]
4371   "TARGET_80387 && !TARGET_FISTTP
4372    && FLOAT_MODE_P (GET_MODE (operands[1]))
4373    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374   "* return output_fix_trunc (insn, operands, 0);"
4375   [(set_attr "type" "fistp")
4376    (set_attr "i387_cw" "trunc")
4377    (set_attr "mode" "<MODE>")])
4378
4379 (define_insn "fix_trunc<mode>_i387_with_temp"
4380   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4382    (use (match_operand:HI 2 "memory_operand" "m,m"))
4383    (use (match_operand:HI 3 "memory_operand" "m,m"))
4384    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4385   "TARGET_80387 && !TARGET_FISTTP
4386    && FLOAT_MODE_P (GET_MODE (operands[1]))
4387    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388   "#"
4389   [(set_attr "type" "fistp")
4390    (set_attr "i387_cw" "trunc")
4391    (set_attr "mode" "<MODE>")])
4392
4393 (define_split 
4394   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396    (use (match_operand:HI 2 "memory_operand" ""))
4397    (use (match_operand:HI 3 "memory_operand" ""))
4398    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))])
4403    (set (match_dup 0) (match_dup 4))]
4404   "")
4405
4406 (define_split 
4407   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409    (use (match_operand:HI 2 "memory_operand" ""))
4410    (use (match_operand:HI 3 "memory_operand" ""))
4411    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4412   "reload_completed"
4413   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4414               (use (match_dup 2))
4415               (use (match_dup 3))])]
4416   "")
4417
4418 (define_insn "x86_fnstcw_1"
4419   [(set (match_operand:HI 0 "memory_operand" "=m")
4420         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4421   "TARGET_80387"
4422   "fnstcw\t%0"
4423   [(set_attr "length" "2")
4424    (set_attr "mode" "HI")
4425    (set_attr "unit" "i387")])
4426
4427 (define_insn "x86_fldcw_1"
4428   [(set (reg:HI FPSR_REG)
4429         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4430   "TARGET_80387"
4431   "fldcw\t%0"
4432   [(set_attr "length" "2")
4433    (set_attr "mode" "HI")
4434    (set_attr "unit" "i387")
4435    (set_attr "athlon_decode" "vector")])
4436 \f
4437 ;; Conversion between fixed point and floating point.
4438
4439 ;; Even though we only accept memory inputs, the backend _really_
4440 ;; wants to be able to do this between registers.
4441
4442 (define_expand "floathisf2"
4443   [(set (match_operand:SF 0 "register_operand" "")
4444         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445   "TARGET_80387 || TARGET_SSE_MATH"
4446 {
4447   if (TARGET_SSE_MATH)
4448     {
4449       emit_insn (gen_floatsisf2 (operands[0],
4450                                  convert_to_mode (SImode, operands[1], 0)));
4451       DONE;
4452     }
4453 })
4454
4455 (define_insn "*floathisf2_i387"
4456   [(set (match_operand:SF 0 "register_operand" "=f,f")
4457         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4459   "@
4460    fild%z1\t%1
4461    #"
4462   [(set_attr "type" "fmov,multi")
4463    (set_attr "mode" "SF")
4464    (set_attr "unit" "*,i387")
4465    (set_attr "fp_int_src" "true")])
4466
4467 (define_expand "floatsisf2"
4468   [(set (match_operand:SF 0 "register_operand" "")
4469         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470   "TARGET_80387 || TARGET_SSE_MATH"
4471   "")
4472
4473 (define_insn "*floatsisf2_mixed"
4474   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476   "TARGET_MIX_SSE_I387"
4477   "@
4478    fild%z1\t%1
4479    #
4480    cvtsi2ss\t{%1, %0|%0, %1}
4481    cvtsi2ss\t{%1, %0|%0, %1}"
4482   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483    (set_attr "mode" "SF")
4484    (set_attr "unit" "*,i387,*,*")
4485    (set_attr "athlon_decode" "*,*,vector,double")
4486    (set_attr "fp_int_src" "true")])
4487
4488 (define_insn "*floatsisf2_sse"
4489   [(set (match_operand:SF 0 "register_operand" "=x,x")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4491   "TARGET_SSE_MATH"
4492   "cvtsi2ss\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "athlon_decode" "vector,double")
4496    (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatsisf2_i387"
4499   [(set (match_operand:SF 0 "register_operand" "=f,f")
4500         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4501   "TARGET_80387"
4502   "@
4503    fild%z1\t%1
4504    #"
4505   [(set_attr "type" "fmov,multi")
4506    (set_attr "mode" "SF")
4507    (set_attr "unit" "*,i387")
4508    (set_attr "fp_int_src" "true")])
4509
4510 (define_expand "floatdisf2"
4511   [(set (match_operand:SF 0 "register_operand" "")
4512         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4514   "")
4515
4516 (define_insn "*floatdisf2_mixed"
4517   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4520   "@
4521    fild%z1\t%1
4522    #
4523    cvtsi2ss{q}\t{%1, %0|%0, %1}
4524    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526    (set_attr "mode" "SF")
4527    (set_attr "unit" "*,i387,*,*")
4528    (set_attr "athlon_decode" "*,*,vector,double")
4529    (set_attr "fp_int_src" "true")])
4530
4531 (define_insn "*floatdisf2_sse"
4532   [(set (match_operand:SF 0 "register_operand" "=x,x")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534   "TARGET_64BIT && TARGET_SSE_MATH"
4535   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "vector,double")
4539    (set_attr "fp_int_src" "true")])
4540
4541 (define_insn "*floatdisf2_i387"
4542   [(set (match_operand:SF 0 "register_operand" "=f,f")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4544   "TARGET_80387"
4545   "@
4546    fild%z1\t%1
4547    #"
4548   [(set_attr "type" "fmov,multi")
4549    (set_attr "mode" "SF")
4550    (set_attr "unit" "*,i387")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_expand "floathidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557 {
4558   if (TARGET_SSE2 && TARGET_SSE_MATH)
4559     {
4560       emit_insn (gen_floatsidf2 (operands[0],
4561                                  convert_to_mode (SImode, operands[1], 0)));
4562       DONE;
4563     }
4564 })
4565
4566 (define_insn "*floathidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "unit" "*,i387")
4576    (set_attr "fp_int_src" "true")])
4577
4578 (define_expand "floatsidf2"
4579   [(set (match_operand:DF 0 "register_operand" "")
4580         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4582   "")
4583
4584 (define_insn "*floatsidf2_mixed"
4585   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4588   "@
4589    fild%z1\t%1
4590    #
4591    cvtsi2sd\t{%1, %0|%0, %1}
4592    cvtsi2sd\t{%1, %0|%0, %1}"
4593   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594    (set_attr "mode" "DF")
4595    (set_attr "unit" "*,i387,*,*")
4596    (set_attr "athlon_decode" "*,*,double,direct")
4597    (set_attr "fp_int_src" "true")])
4598
4599 (define_insn "*floatsidf2_sse"
4600   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602   "TARGET_SSE2 && TARGET_SSE_MATH"
4603   "cvtsi2sd\t{%1, %0|%0, %1}"
4604   [(set_attr "type" "sseicvt")
4605    (set_attr "mode" "DF")
4606    (set_attr "athlon_decode" "double,direct")
4607    (set_attr "fp_int_src" "true")])
4608
4609 (define_insn "*floatsidf2_i387"
4610   [(set (match_operand:DF 0 "register_operand" "=f,f")
4611         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4612   "TARGET_80387"
4613   "@
4614    fild%z1\t%1
4615    #"
4616   [(set_attr "type" "fmov,multi")
4617    (set_attr "mode" "DF")
4618    (set_attr "unit" "*,i387")
4619    (set_attr "fp_int_src" "true")])
4620
4621 (define_expand "floatdidf2"
4622   [(set (match_operand:DF 0 "register_operand" "")
4623         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4625   "")
4626
4627 (define_insn "*floatdidf2_mixed"
4628   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4631   "@
4632    fild%z1\t%1
4633    #
4634    cvtsi2sd{q}\t{%1, %0|%0, %1}
4635    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637    (set_attr "mode" "DF")
4638    (set_attr "unit" "*,i387,*,*")
4639    (set_attr "athlon_decode" "*,*,double,direct")
4640    (set_attr "fp_int_src" "true")])
4641
4642 (define_insn "*floatdidf2_sse"
4643   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "athlon_decode" "double,direct")
4650    (set_attr "fp_int_src" "true")])
4651
4652 (define_insn "*floatdidf2_i387"
4653   [(set (match_operand:DF 0 "register_operand" "=f,f")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4655   "TARGET_80387"
4656   "@
4657    fild%z1\t%1
4658    #"
4659   [(set_attr "type" "fmov,multi")
4660    (set_attr "mode" "DF")
4661    (set_attr "unit" "*,i387")
4662    (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "floathixf2"
4665   [(set (match_operand:XF 0 "register_operand" "=f,f")
4666         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "XF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "floatsixf2"
4677   [(set (match_operand:XF 0 "register_operand" "=f,f")
4678         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4679   "TARGET_80387"
4680   "@
4681    fild%z1\t%1
4682    #"
4683   [(set_attr "type" "fmov,multi")
4684    (set_attr "mode" "XF")
4685    (set_attr "unit" "*,i387")
4686    (set_attr "fp_int_src" "true")])
4687
4688 (define_insn "floatdixf2"
4689   [(set (match_operand:XF 0 "register_operand" "=f,f")
4690         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691   "TARGET_80387"
4692   "@
4693    fild%z1\t%1
4694    #"
4695   [(set_attr "type" "fmov,multi")
4696    (set_attr "mode" "XF")
4697    (set_attr "unit" "*,i387")
4698    (set_attr "fp_int_src" "true")])
4699
4700 ;; %%% Kill these when reload knows how to do it.
4701 (define_split
4702   [(set (match_operand 0 "fp_register_operand" "")
4703         (float (match_operand 1 "register_operand" "")))]
4704   "reload_completed
4705    && TARGET_80387
4706    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4707   [(const_int 0)]
4708 {
4709   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712   ix86_free_from_memory (GET_MODE (operands[1]));
4713   DONE;
4714 })
4715
4716 (define_expand "floatunssisf2"
4717   [(use (match_operand:SF 0 "register_operand" ""))
4718    (use (match_operand:SI 1 "register_operand" ""))]
4719   "!TARGET_64BIT && TARGET_SSE_MATH"
4720   "x86_emit_floatuns (operands); DONE;")
4721
4722 (define_expand "floatunsdisf2"
4723   [(use (match_operand:SF 0 "register_operand" ""))
4724    (use (match_operand:DI 1 "register_operand" ""))]
4725   "TARGET_64BIT && TARGET_SSE_MATH"
4726   "x86_emit_floatuns (operands); DONE;")
4727
4728 (define_expand "floatunsdidf2"
4729   [(use (match_operand:DF 0 "register_operand" ""))
4730    (use (match_operand:DI 1 "register_operand" ""))]
4731   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732   "x86_emit_floatuns (operands); DONE;")
4733 \f
4734 ;; SSE extract/set expanders
4735
4736 \f
4737 ;; Add instructions
4738
4739 ;; %%% splits for addditi3
4740
4741 (define_expand "addti3"
4742   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744                  (match_operand:TI 2 "x86_64_general_operand" "")))
4745    (clobber (reg:CC FLAGS_REG))]
4746   "TARGET_64BIT"
4747   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4748
4749 (define_insn "*addti3_1"
4750   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4753    (clobber (reg:CC FLAGS_REG))]
4754   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4755   "#")
4756
4757 (define_split
4758   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760                  (match_operand:TI 2 "general_operand" "")))
4761    (clobber (reg:CC FLAGS_REG))]
4762   "TARGET_64BIT && reload_completed"
4763   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4764                                           UNSPEC_ADD_CARRY))
4765               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766    (parallel [(set (match_dup 3)
4767                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4768                                      (match_dup 4))
4769                             (match_dup 5)))
4770               (clobber (reg:CC FLAGS_REG))])]
4771   "split_ti (operands+0, 1, operands+0, operands+3);
4772    split_ti (operands+1, 1, operands+1, operands+4);
4773    split_ti (operands+2, 1, operands+2, operands+5);")
4774
4775 ;; %%% splits for addsidi3
4776 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4778 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4779
4780 (define_expand "adddi3"
4781   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783                  (match_operand:DI 2 "x86_64_general_operand" "")))
4784    (clobber (reg:CC FLAGS_REG))]
4785   ""
4786   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4787
4788 (define_insn "*adddi3_1"
4789   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4792    (clobber (reg:CC FLAGS_REG))]
4793   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794   "#")
4795
4796 (define_split
4797   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799                  (match_operand:DI 2 "general_operand" "")))
4800    (clobber (reg:CC FLAGS_REG))]
4801   "!TARGET_64BIT && reload_completed"
4802   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4803                                           UNSPEC_ADD_CARRY))
4804               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805    (parallel [(set (match_dup 3)
4806                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4807                                      (match_dup 4))
4808                             (match_dup 5)))
4809               (clobber (reg:CC FLAGS_REG))])]
4810   "split_di (operands+0, 1, operands+0, operands+3);
4811    split_di (operands+1, 1, operands+1, operands+4);
4812    split_di (operands+2, 1, operands+2, operands+5);")
4813
4814 (define_insn "adddi3_carry_rex64"
4815   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819    (clobber (reg:CC FLAGS_REG))]
4820   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821   "adc{q}\t{%2, %0|%0, %2}"
4822   [(set_attr "type" "alu")
4823    (set_attr "pent_pair" "pu")
4824    (set_attr "mode" "DI")])
4825
4826 (define_insn "*adddi3_cc_rex64"
4827   [(set (reg:CC FLAGS_REG)
4828         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4830                    UNSPEC_ADD_CARRY))
4831    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832         (plus:DI (match_dup 1) (match_dup 2)))]
4833   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834   "add{q}\t{%2, %0|%0, %2}"
4835   [(set_attr "type" "alu")
4836    (set_attr "mode" "DI")])
4837
4838 (define_insn "addqi3_carry"
4839   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842                    (match_operand:QI 2 "general_operand" "qi,qm")))
4843    (clobber (reg:CC FLAGS_REG))]
4844   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845   "adc{b}\t{%2, %0|%0, %2}"
4846   [(set_attr "type" "alu")
4847    (set_attr "pent_pair" "pu")
4848    (set_attr "mode" "QI")])
4849
4850 (define_insn "addhi3_carry"
4851   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854                    (match_operand:HI 2 "general_operand" "ri,rm")))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857   "adc{w}\t{%2, %0|%0, %2}"
4858   [(set_attr "type" "alu")
4859    (set_attr "pent_pair" "pu")
4860    (set_attr "mode" "HI")])
4861
4862 (define_insn "addsi3_carry"
4863   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866                    (match_operand:SI 2 "general_operand" "ri,rm")))
4867    (clobber (reg:CC FLAGS_REG))]
4868   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869   "adc{l}\t{%2, %0|%0, %2}"
4870   [(set_attr "type" "alu")
4871    (set_attr "pent_pair" "pu")
4872    (set_attr "mode" "SI")])
4873
4874 (define_insn "*addsi3_carry_zext"
4875   [(set (match_operand:DI 0 "register_operand" "=r")
4876           (zero_extend:DI 
4877             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879                      (match_operand:SI 2 "general_operand" "rim"))))
4880    (clobber (reg:CC FLAGS_REG))]
4881   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882   "adc{l}\t{%2, %k0|%k0, %2}"
4883   [(set_attr "type" "alu")
4884    (set_attr "pent_pair" "pu")
4885    (set_attr "mode" "SI")])
4886
4887 (define_insn "*addsi3_cc"
4888   [(set (reg:CC FLAGS_REG)
4889         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890                     (match_operand:SI 2 "general_operand" "ri,rm")]
4891                    UNSPEC_ADD_CARRY))
4892    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893         (plus:SI (match_dup 1) (match_dup 2)))]
4894   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895   "add{l}\t{%2, %0|%0, %2}"
4896   [(set_attr "type" "alu")
4897    (set_attr "mode" "SI")])
4898
4899 (define_insn "addqi3_cc"
4900   [(set (reg:CC FLAGS_REG)
4901         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902                     (match_operand:QI 2 "general_operand" "qi,qm")]
4903                    UNSPEC_ADD_CARRY))
4904    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905         (plus:QI (match_dup 1) (match_dup 2)))]
4906   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907   "add{b}\t{%2, %0|%0, %2}"
4908   [(set_attr "type" "alu")
4909    (set_attr "mode" "QI")])
4910
4911 (define_expand "addsi3"
4912   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914                             (match_operand:SI 2 "general_operand" "")))
4915               (clobber (reg:CC FLAGS_REG))])]
4916   ""
4917   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4918
4919 (define_insn "*lea_1"
4920   [(set (match_operand:SI 0 "register_operand" "=r")
4921         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4922   "!TARGET_64BIT"
4923   "lea{l}\t{%a1, %0|%0, %a1}"
4924   [(set_attr "type" "lea")
4925    (set_attr "mode" "SI")])
4926
4927 (define_insn "*lea_1_rex64"
4928   [(set (match_operand:SI 0 "register_operand" "=r")
4929         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4930   "TARGET_64BIT"
4931   "lea{l}\t{%a1, %0|%0, %a1}"
4932   [(set_attr "type" "lea")
4933    (set_attr "mode" "SI")])
4934
4935 (define_insn "*lea_1_zext"
4936   [(set (match_operand:DI 0 "register_operand" "=r")
4937         (zero_extend:DI
4938          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4939   "TARGET_64BIT"
4940   "lea{l}\t{%a1, %k0|%k0, %a1}"
4941   [(set_attr "type" "lea")
4942    (set_attr "mode" "SI")])
4943
4944 (define_insn "*lea_2_rex64"
4945   [(set (match_operand:DI 0 "register_operand" "=r")
4946         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4947   "TARGET_64BIT"
4948   "lea{q}\t{%a1, %0|%0, %a1}"
4949   [(set_attr "type" "lea")
4950    (set_attr "mode" "DI")])
4951
4952 ;; The lea patterns for non-Pmodes needs to be matched by several
4953 ;; insns converted to real lea by splitters.
4954
4955 (define_insn_and_split "*lea_general_1"
4956   [(set (match_operand 0 "register_operand" "=r")
4957         (plus (plus (match_operand 1 "index_register_operand" "l")
4958                     (match_operand 2 "register_operand" "r"))
4959               (match_operand 3 "immediate_operand" "i")))]
4960   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966        || GET_MODE (operands[3]) == VOIDmode)"
4967   "#"
4968   "&& reload_completed"
4969   [(const_int 0)]
4970 {
4971   rtx pat;
4972   operands[0] = gen_lowpart (SImode, operands[0]);
4973   operands[1] = gen_lowpart (Pmode, operands[1]);
4974   operands[2] = gen_lowpart (Pmode, operands[2]);
4975   operands[3] = gen_lowpart (Pmode, operands[3]);
4976   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4977                       operands[3]);
4978   if (Pmode != SImode)
4979     pat = gen_rtx_SUBREG (SImode, pat, 0);
4980   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4981   DONE;
4982 }
4983   [(set_attr "type" "lea")
4984    (set_attr "mode" "SI")])
4985
4986 (define_insn_and_split "*lea_general_1_zext"
4987   [(set (match_operand:DI 0 "register_operand" "=r")
4988         (zero_extend:DI
4989           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990                             (match_operand:SI 2 "register_operand" "r"))
4991                    (match_operand:SI 3 "immediate_operand" "i"))))]
4992   "TARGET_64BIT"
4993   "#"
4994   "&& reload_completed"
4995   [(set (match_dup 0)
4996         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4997                                                      (match_dup 2))
4998                                             (match_dup 3)) 0)))]
4999 {
5000   operands[1] = gen_lowpart (Pmode, operands[1]);
5001   operands[2] = gen_lowpart (Pmode, operands[2]);
5002   operands[3] = gen_lowpart (Pmode, operands[3]);
5003 }
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5006
5007 (define_insn_and_split "*lea_general_2"
5008   [(set (match_operand 0 "register_operand" "=r")
5009         (plus (mult (match_operand 1 "index_register_operand" "l")
5010                     (match_operand 2 "const248_operand" "i"))
5011               (match_operand 3 "nonmemory_operand" "ri")))]
5012   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017        || GET_MODE (operands[3]) == VOIDmode)"
5018   "#"
5019   "&& reload_completed"
5020   [(const_int 0)]
5021 {
5022   rtx pat;
5023   operands[0] = gen_lowpart (SImode, operands[0]);
5024   operands[1] = gen_lowpart (Pmode, operands[1]);
5025   operands[3] = gen_lowpart (Pmode, operands[3]);
5026   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5027                       operands[3]);
5028   if (Pmode != SImode)
5029     pat = gen_rtx_SUBREG (SImode, pat, 0);
5030   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5031   DONE;
5032 }
5033   [(set_attr "type" "lea")
5034    (set_attr "mode" "SI")])
5035
5036 (define_insn_and_split "*lea_general_2_zext"
5037   [(set (match_operand:DI 0 "register_operand" "=r")
5038         (zero_extend:DI
5039           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040                             (match_operand:SI 2 "const248_operand" "n"))
5041                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5042   "TARGET_64BIT"
5043   "#"
5044   "&& reload_completed"
5045   [(set (match_dup 0)
5046         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5047                                                      (match_dup 2))
5048                                             (match_dup 3)) 0)))]
5049 {
5050   operands[1] = gen_lowpart (Pmode, operands[1]);
5051   operands[3] = gen_lowpart (Pmode, operands[3]);
5052 }
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3"
5057   [(set (match_operand 0 "register_operand" "=r")
5058         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059                           (match_operand 2 "const248_operand" "i"))
5060                     (match_operand 3 "register_operand" "r"))
5061               (match_operand 4 "immediate_operand" "i")))]
5062   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5067   "#"
5068   "&& reload_completed"
5069   [(const_int 0)]
5070 {
5071   rtx pat;
5072   operands[0] = gen_lowpart (SImode, operands[0]);
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076   pat = gen_rtx_PLUS (Pmode,
5077                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5078                                                          operands[2]),
5079                                     operands[3]),
5080                       operands[4]);
5081   if (Pmode != SImode)
5082     pat = gen_rtx_SUBREG (SImode, pat, 0);
5083   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5084   DONE;
5085 }
5086   [(set_attr "type" "lea")
5087    (set_attr "mode" "SI")])
5088
5089 (define_insn_and_split "*lea_general_3_zext"
5090   [(set (match_operand:DI 0 "register_operand" "=r")
5091         (zero_extend:DI
5092           (plus:SI (plus:SI (mult:SI
5093                               (match_operand:SI 1 "index_register_operand" "l")
5094                               (match_operand:SI 2 "const248_operand" "n"))
5095                             (match_operand:SI 3 "register_operand" "r"))
5096                    (match_operand:SI 4 "immediate_operand" "i"))))]
5097   "TARGET_64BIT"
5098   "#"
5099   "&& reload_completed"
5100   [(set (match_dup 0)
5101         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5102                                                               (match_dup 2))
5103                                                      (match_dup 3))
5104                                             (match_dup 4)) 0)))]
5105 {
5106   operands[1] = gen_lowpart (Pmode, operands[1]);
5107   operands[3] = gen_lowpart (Pmode, operands[3]);
5108   operands[4] = gen_lowpart (Pmode, operands[4]);
5109 }
5110   [(set_attr "type" "lea")
5111    (set_attr "mode" "SI")])
5112
5113 (define_insn "*adddi_1_rex64"
5114   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117    (clobber (reg:CC FLAGS_REG))]
5118   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5119 {
5120   switch (get_attr_type (insn))
5121     {
5122     case TYPE_LEA:
5123       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124       return "lea{q}\t{%a2, %0|%0, %a2}";
5125
5126     case TYPE_INCDEC:
5127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128       if (operands[2] == const1_rtx)
5129         return "inc{q}\t%0";
5130       else
5131         {
5132           gcc_assert (operands[2] == constm1_rtx);
5133           return "dec{q}\t%0";
5134         }
5135
5136     default:
5137       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5138
5139       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5141       if (GET_CODE (operands[2]) == CONST_INT
5142           /* Avoid overflows.  */
5143           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144           && (INTVAL (operands[2]) == 128
5145               || (INTVAL (operands[2]) < 0
5146                   && INTVAL (operands[2]) != -128)))
5147         {
5148           operands[2] = GEN_INT (-INTVAL (operands[2]));
5149           return "sub{q}\t{%2, %0|%0, %2}";
5150         }
5151       return "add{q}\t{%2, %0|%0, %2}";
5152     }
5153 }
5154   [(set (attr "type")
5155      (cond [(eq_attr "alternative" "2")
5156               (const_string "lea")
5157             ; Current assemblers are broken and do not allow @GOTOFF in
5158             ; ought but a memory context.
5159             (match_operand:DI 2 "pic_symbolic_operand" "")
5160               (const_string "lea")
5161             (match_operand:DI 2 "incdec_operand" "")
5162               (const_string "incdec")
5163            ]
5164            (const_string "alu")))
5165    (set_attr "mode" "DI")])
5166
5167 ;; Convert lea to the lea pattern to avoid flags dependency.
5168 (define_split
5169   [(set (match_operand:DI 0 "register_operand" "")
5170         (plus:DI (match_operand:DI 1 "register_operand" "")
5171                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172    (clobber (reg:CC FLAGS_REG))]
5173   "TARGET_64BIT && reload_completed
5174    && true_regnum (operands[0]) != true_regnum (operands[1])"
5175   [(set (match_dup 0)
5176         (plus:DI (match_dup 1)
5177                  (match_dup 2)))]
5178   "")
5179
5180 (define_insn "*adddi_2_rex64"
5181   [(set (reg FLAGS_REG)
5182         (compare
5183           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5185           (const_int 0)))                       
5186    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187         (plus:DI (match_dup 1) (match_dup 2)))]
5188   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189    && ix86_binary_operator_ok (PLUS, DImode, operands)
5190    /* Current assemblers are broken and do not allow @GOTOFF in
5191       ought but a memory context.  */
5192    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5193 {
5194   switch (get_attr_type (insn))
5195     {
5196     case TYPE_INCDEC:
5197       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198       if (operands[2] == const1_rtx)
5199         return "inc{q}\t%0";
5200       else
5201         {
5202           gcc_assert (operands[2] == constm1_rtx);
5203           return "dec{q}\t%0";
5204         }
5205
5206     default:
5207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208       /* ???? We ought to handle there the 32bit case too
5209          - do we need new constraint?  */
5210       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5212       if (GET_CODE (operands[2]) == CONST_INT
5213           /* Avoid overflows.  */
5214           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215           && (INTVAL (operands[2]) == 128
5216               || (INTVAL (operands[2]) < 0
5217                   && INTVAL (operands[2]) != -128)))
5218         {
5219           operands[2] = GEN_INT (-INTVAL (operands[2]));
5220           return "sub{q}\t{%2, %0|%0, %2}";
5221         }
5222       return "add{q}\t{%2, %0|%0, %2}";
5223     }
5224 }
5225   [(set (attr "type")
5226      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227         (const_string "incdec")
5228         (const_string "alu")))
5229    (set_attr "mode" "DI")])
5230
5231 (define_insn "*adddi_3_rex64"
5232   [(set (reg FLAGS_REG)
5233         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235    (clobber (match_scratch:DI 0 "=r"))]
5236   "TARGET_64BIT
5237    && ix86_match_ccmode (insn, CCZmode)
5238    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239    /* Current assemblers are broken and do not allow @GOTOFF in
5240       ought but a memory context.  */
5241    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5242 {
5243   switch (get_attr_type (insn))
5244     {
5245     case TYPE_INCDEC:
5246       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247       if (operands[2] == const1_rtx)
5248         return "inc{q}\t%0";
5249       else
5250         {
5251           gcc_assert (operands[2] == constm1_rtx);
5252           return "dec{q}\t%0";
5253         }
5254
5255     default:
5256       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257       /* ???? We ought to handle there the 32bit case too
5258          - do we need new constraint?  */
5259       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5261       if (GET_CODE (operands[2]) == CONST_INT
5262           /* Avoid overflows.  */
5263           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264           && (INTVAL (operands[2]) == 128
5265               || (INTVAL (operands[2]) < 0
5266                   && INTVAL (operands[2]) != -128)))
5267         {
5268           operands[2] = GEN_INT (-INTVAL (operands[2]));
5269           return "sub{q}\t{%2, %0|%0, %2}";
5270         }
5271       return "add{q}\t{%2, %0|%0, %2}";
5272     }
5273 }
5274   [(set (attr "type")
5275      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276         (const_string "incdec")
5277         (const_string "alu")))
5278    (set_attr "mode" "DI")])
5279
5280 ; For comparisons against 1, -1 and 128, we may generate better code
5281 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5282 ; is matched then.  We can't accept general immediate, because for
5283 ; case of overflows,  the result is messed up.
5284 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5285 ; when negated.
5286 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5287 ; only for comparisons not depending on it.
5288 (define_insn "*adddi_4_rex64"
5289   [(set (reg FLAGS_REG)
5290         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292    (clobber (match_scratch:DI 0 "=rm"))]
5293   "TARGET_64BIT
5294    &&  ix86_match_ccmode (insn, CCGCmode)"
5295 {
5296   switch (get_attr_type (insn))
5297     {
5298     case TYPE_INCDEC:
5299       if (operands[2] == constm1_rtx)
5300         return "inc{q}\t%0";
5301       else
5302         {
5303           gcc_assert (operands[2] == const1_rtx);
5304           return "dec{q}\t%0";
5305         }
5306
5307     default:
5308       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5311       if ((INTVAL (operands[2]) == -128
5312            || (INTVAL (operands[2]) > 0
5313                && INTVAL (operands[2]) != 128))
5314           /* Avoid overflows.  */
5315           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316         return "sub{q}\t{%2, %0|%0, %2}";
5317       operands[2] = GEN_INT (-INTVAL (operands[2]));
5318       return "add{q}\t{%2, %0|%0, %2}";
5319     }
5320 }
5321   [(set (attr "type")
5322      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323         (const_string "incdec")
5324         (const_string "alu")))
5325    (set_attr "mode" "DI")])
5326
5327 (define_insn "*adddi_5_rex64"
5328   [(set (reg FLAGS_REG)
5329         (compare
5330           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5332           (const_int 0)))                       
5333    (clobber (match_scratch:DI 0 "=r"))]
5334   "TARGET_64BIT
5335    && ix86_match_ccmode (insn, CCGOCmode)
5336    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337    /* Current assemblers are broken and do not allow @GOTOFF in
5338       ought but a memory context.  */
5339    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5340 {
5341   switch (get_attr_type (insn))
5342     {
5343     case TYPE_INCDEC:
5344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345       if (operands[2] == const1_rtx)
5346         return "inc{q}\t%0";
5347       else
5348         {
5349           gcc_assert (operands[2] == constm1_rtx);
5350           return "dec{q}\t%0";
5351         }
5352
5353     default:
5354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5357       if (GET_CODE (operands[2]) == CONST_INT
5358           /* Avoid overflows.  */
5359           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360           && (INTVAL (operands[2]) == 128
5361               || (INTVAL (operands[2]) < 0
5362                   && INTVAL (operands[2]) != -128)))
5363         {
5364           operands[2] = GEN_INT (-INTVAL (operands[2]));
5365           return "sub{q}\t{%2, %0|%0, %2}";
5366         }
5367       return "add{q}\t{%2, %0|%0, %2}";
5368     }
5369 }
5370   [(set (attr "type")
5371      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372         (const_string "incdec")
5373         (const_string "alu")))
5374    (set_attr "mode" "DI")])
5375
5376
5377 (define_insn "*addsi_1"
5378   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381    (clobber (reg:CC FLAGS_REG))]
5382   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5383 {
5384   switch (get_attr_type (insn))
5385     {
5386     case TYPE_LEA:
5387       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388       return "lea{l}\t{%a2, %0|%0, %a2}";
5389
5390     case TYPE_INCDEC:
5391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392       if (operands[2] == const1_rtx)
5393         return "inc{l}\t%0";
5394       else
5395         {
5396           gcc_assert (operands[2] == constm1_rtx);
5397           return "dec{l}\t%0";
5398         }
5399
5400     default:
5401       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402
5403       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5405       if (GET_CODE (operands[2]) == CONST_INT
5406           && (INTVAL (operands[2]) == 128
5407               || (INTVAL (operands[2]) < 0
5408                   && INTVAL (operands[2]) != -128)))
5409         {
5410           operands[2] = GEN_INT (-INTVAL (operands[2]));
5411           return "sub{l}\t{%2, %0|%0, %2}";
5412         }
5413       return "add{l}\t{%2, %0|%0, %2}";
5414     }
5415 }
5416   [(set (attr "type")
5417      (cond [(eq_attr "alternative" "2")
5418               (const_string "lea")
5419             ; Current assemblers are broken and do not allow @GOTOFF in
5420             ; ought but a memory context.
5421             (match_operand:SI 2 "pic_symbolic_operand" "")
5422               (const_string "lea")
5423             (match_operand:SI 2 "incdec_operand" "")
5424               (const_string "incdec")
5425            ]
5426            (const_string "alu")))
5427    (set_attr "mode" "SI")])
5428
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5430 (define_split
5431   [(set (match_operand 0 "register_operand" "")
5432         (plus (match_operand 1 "register_operand" "")
5433               (match_operand 2 "nonmemory_operand" "")))
5434    (clobber (reg:CC FLAGS_REG))]
5435   "reload_completed
5436    && true_regnum (operands[0]) != true_regnum (operands[1])"
5437   [(const_int 0)]
5438 {
5439   rtx pat;
5440   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441      may confuse gen_lowpart.  */
5442   if (GET_MODE (operands[0]) != Pmode)
5443     {
5444       operands[1] = gen_lowpart (Pmode, operands[1]);
5445       operands[2] = gen_lowpart (Pmode, operands[2]);
5446     }
5447   operands[0] = gen_lowpart (SImode, operands[0]);
5448   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449   if (Pmode != SImode)
5450     pat = gen_rtx_SUBREG (SImode, pat, 0);
5451   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5452   DONE;
5453 })
5454
5455 ;; It may seem that nonimmediate operand is proper one for operand 1.
5456 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5457 ;; we take care in ix86_binary_operator_ok to not allow two memory
5458 ;; operands so proper swapping will be done in reload.  This allow
5459 ;; patterns constructed from addsi_1 to match.
5460 (define_insn "addsi_1_zext"
5461   [(set (match_operand:DI 0 "register_operand" "=r,r")
5462         (zero_extend:DI
5463           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465    (clobber (reg:CC FLAGS_REG))]
5466   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5467 {
5468   switch (get_attr_type (insn))
5469     {
5470     case TYPE_LEA:
5471       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5473
5474     case TYPE_INCDEC:
5475       if (operands[2] == const1_rtx)
5476         return "inc{l}\t%k0";
5477       else
5478         {
5479           gcc_assert (operands[2] == constm1_rtx);
5480           return "dec{l}\t%k0";
5481         }
5482
5483     default:
5484       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5486       if (GET_CODE (operands[2]) == CONST_INT
5487           && (INTVAL (operands[2]) == 128
5488               || (INTVAL (operands[2]) < 0
5489                   && INTVAL (operands[2]) != -128)))
5490         {
5491           operands[2] = GEN_INT (-INTVAL (operands[2]));
5492           return "sub{l}\t{%2, %k0|%k0, %2}";
5493         }
5494       return "add{l}\t{%2, %k0|%k0, %2}";
5495     }
5496 }
5497   [(set (attr "type")
5498      (cond [(eq_attr "alternative" "1")
5499               (const_string "lea")
5500             ; Current assemblers are broken and do not allow @GOTOFF in
5501             ; ought but a memory context.
5502             (match_operand:SI 2 "pic_symbolic_operand" "")
5503               (const_string "lea")
5504             (match_operand:SI 2 "incdec_operand" "")
5505               (const_string "incdec")
5506            ]
5507            (const_string "alu")))
5508    (set_attr "mode" "SI")])
5509
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5511 (define_split
5512   [(set (match_operand:DI 0 "register_operand" "")
5513         (zero_extend:DI
5514           (plus:SI (match_operand:SI 1 "register_operand" "")
5515                    (match_operand:SI 2 "nonmemory_operand" ""))))
5516    (clobber (reg:CC FLAGS_REG))]
5517   "TARGET_64BIT && reload_completed
5518    && true_regnum (operands[0]) != true_regnum (operands[1])"
5519   [(set (match_dup 0)
5520         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5521 {
5522   operands[1] = gen_lowpart (Pmode, operands[1]);
5523   operands[2] = gen_lowpart (Pmode, operands[2]);
5524 })
5525
5526 (define_insn "*addsi_2"
5527   [(set (reg FLAGS_REG)
5528         (compare
5529           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5531           (const_int 0)))                       
5532    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533         (plus:SI (match_dup 1) (match_dup 2)))]
5534   "ix86_match_ccmode (insn, CCGOCmode)
5535    && ix86_binary_operator_ok (PLUS, SImode, operands)
5536    /* Current assemblers are broken and do not allow @GOTOFF in
5537       ought but a memory context.  */
5538    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5539 {
5540   switch (get_attr_type (insn))
5541     {
5542     case TYPE_INCDEC:
5543       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544       if (operands[2] == const1_rtx)
5545         return "inc{l}\t%0";
5546       else
5547         {
5548           gcc_assert (operands[2] == constm1_rtx);
5549           return "dec{l}\t%0";
5550         }
5551
5552     default:
5553       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5556       if (GET_CODE (operands[2]) == CONST_INT
5557           && (INTVAL (operands[2]) == 128
5558               || (INTVAL (operands[2]) < 0
5559                   && INTVAL (operands[2]) != -128)))
5560         {
5561           operands[2] = GEN_INT (-INTVAL (operands[2]));
5562           return "sub{l}\t{%2, %0|%0, %2}";
5563         }
5564       return "add{l}\t{%2, %0|%0, %2}";
5565     }
5566 }
5567   [(set (attr "type")
5568      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569         (const_string "incdec")
5570         (const_string "alu")))
5571    (set_attr "mode" "SI")])
5572
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_2_zext"
5575   [(set (reg FLAGS_REG)
5576         (compare
5577           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578                    (match_operand:SI 2 "general_operand" "rmni"))
5579           (const_int 0)))                       
5580    (set (match_operand:DI 0 "register_operand" "=r")
5581         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583    && ix86_binary_operator_ok (PLUS, SImode, operands)
5584    /* Current assemblers are broken and do not allow @GOTOFF in
5585       ought but a memory context.  */
5586    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5587 {
5588   switch (get_attr_type (insn))
5589     {
5590     case TYPE_INCDEC:
5591       if (operands[2] == const1_rtx)
5592         return "inc{l}\t%k0";
5593       else
5594         {
5595           gcc_assert (operands[2] == constm1_rtx);
5596           return "dec{l}\t%k0";
5597         }
5598
5599     default:
5600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5602       if (GET_CODE (operands[2]) == CONST_INT
5603           && (INTVAL (operands[2]) == 128
5604               || (INTVAL (operands[2]) < 0
5605                   && INTVAL (operands[2]) != -128)))
5606         {
5607           operands[2] = GEN_INT (-INTVAL (operands[2]));
5608           return "sub{l}\t{%2, %k0|%k0, %2}";
5609         }
5610       return "add{l}\t{%2, %k0|%k0, %2}";
5611     }
5612 }
5613   [(set (attr "type")
5614      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615         (const_string "incdec")
5616         (const_string "alu")))
5617    (set_attr "mode" "SI")])
5618
5619 (define_insn "*addsi_3"
5620   [(set (reg FLAGS_REG)
5621         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623    (clobber (match_scratch:SI 0 "=r"))]
5624   "ix86_match_ccmode (insn, CCZmode)
5625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626    /* Current assemblers are broken and do not allow @GOTOFF in
5627       ought but a memory context.  */
5628    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629 {
5630   switch (get_attr_type (insn))
5631     {
5632     case TYPE_INCDEC:
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (operands[2] == const1_rtx)
5635         return "inc{l}\t%0";
5636       else
5637         {
5638           gcc_assert (operands[2] == constm1_rtx);
5639           return "dec{l}\t%0";
5640         }
5641
5642     default:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5646       if (GET_CODE (operands[2]) == CONST_INT
5647           && (INTVAL (operands[2]) == 128
5648               || (INTVAL (operands[2]) < 0
5649                   && INTVAL (operands[2]) != -128)))
5650         {
5651           operands[2] = GEN_INT (-INTVAL (operands[2]));
5652           return "sub{l}\t{%2, %0|%0, %2}";
5653         }
5654       return "add{l}\t{%2, %0|%0, %2}";
5655     }
5656 }
5657   [(set (attr "type")
5658      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659         (const_string "incdec")
5660         (const_string "alu")))
5661    (set_attr "mode" "SI")])
5662
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_3_zext"
5665   [(set (reg FLAGS_REG)
5666         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668    (set (match_operand:DI 0 "register_operand" "=r")
5669         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671    && ix86_binary_operator_ok (PLUS, SImode, operands)
5672    /* Current assemblers are broken and do not allow @GOTOFF in
5673       ought but a memory context.  */
5674    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675 {
5676   switch (get_attr_type (insn))
5677     {
5678     case TYPE_INCDEC:
5679       if (operands[2] == const1_rtx)
5680         return "inc{l}\t%k0";
5681       else
5682         {
5683           gcc_assert (operands[2] == constm1_rtx);
5684           return "dec{l}\t%k0";
5685         }
5686
5687     default:
5688       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5690       if (GET_CODE (operands[2]) == CONST_INT
5691           && (INTVAL (operands[2]) == 128
5692               || (INTVAL (operands[2]) < 0
5693                   && INTVAL (operands[2]) != -128)))
5694         {
5695           operands[2] = GEN_INT (-INTVAL (operands[2]));
5696           return "sub{l}\t{%2, %k0|%k0, %2}";
5697         }
5698       return "add{l}\t{%2, %k0|%k0, %2}";
5699     }
5700 }
5701   [(set (attr "type")
5702      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703         (const_string "incdec")
5704         (const_string "alu")))
5705    (set_attr "mode" "SI")])
5706
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5709 ; is matched then.  We can't accept general immediate, because for
5710 ; case of overflows,  the result is messed up.
5711 ; This pattern also don't hold of 0x80000000, since the value overflows
5712 ; when negated.
5713 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5714 ; only for comparisons not depending on it.
5715 (define_insn "*addsi_4"
5716   [(set (reg FLAGS_REG)
5717         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718                  (match_operand:SI 2 "const_int_operand" "n")))
5719    (clobber (match_scratch:SI 0 "=rm"))]
5720   "ix86_match_ccmode (insn, CCGCmode)
5721    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5722 {
5723   switch (get_attr_type (insn))
5724     {
5725     case TYPE_INCDEC:
5726       if (operands[2] == constm1_rtx)
5727         return "inc{l}\t%0";
5728       else
5729         {
5730           gcc_assert (operands[2] == const1_rtx);
5731           return "dec{l}\t%0";
5732         }
5733
5734     default:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5738       if ((INTVAL (operands[2]) == -128
5739            || (INTVAL (operands[2]) > 0
5740                && INTVAL (operands[2]) != 128)))
5741         return "sub{l}\t{%2, %0|%0, %2}";
5742       operands[2] = GEN_INT (-INTVAL (operands[2]));
5743       return "add{l}\t{%2, %0|%0, %2}";
5744     }
5745 }
5746   [(set (attr "type")
5747      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748         (const_string "incdec")
5749         (const_string "alu")))
5750    (set_attr "mode" "SI")])
5751
5752 (define_insn "*addsi_5"
5753   [(set (reg FLAGS_REG)
5754         (compare
5755           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756                    (match_operand:SI 2 "general_operand" "rmni"))
5757           (const_int 0)))                       
5758    (clobber (match_scratch:SI 0 "=r"))]
5759   "ix86_match_ccmode (insn, CCGOCmode)
5760    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761    /* Current assemblers are broken and do not allow @GOTOFF in
5762       ought but a memory context.  */
5763    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764 {
5765   switch (get_attr_type (insn))
5766     {
5767     case TYPE_INCDEC:
5768       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769       if (operands[2] == const1_rtx)
5770         return "inc{l}\t%0";
5771       else
5772         {
5773           gcc_assert (operands[2] == constm1_rtx);
5774           return "dec{l}\t%0";
5775         }
5776
5777     default:
5778       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5781       if (GET_CODE (operands[2]) == CONST_INT
5782           && (INTVAL (operands[2]) == 128
5783               || (INTVAL (operands[2]) < 0
5784                   && INTVAL (operands[2]) != -128)))
5785         {
5786           operands[2] = GEN_INT (-INTVAL (operands[2]));
5787           return "sub{l}\t{%2, %0|%0, %2}";
5788         }
5789       return "add{l}\t{%2, %0|%0, %2}";
5790     }
5791 }
5792   [(set (attr "type")
5793      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794         (const_string "incdec")
5795         (const_string "alu")))
5796    (set_attr "mode" "SI")])
5797
5798 (define_expand "addhi3"
5799   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801                             (match_operand:HI 2 "general_operand" "")))
5802               (clobber (reg:CC FLAGS_REG))])]
5803   "TARGET_HIMODE_MATH"
5804   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5805
5806 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807 ;; type optimizations enabled by define-splits.  This is not important
5808 ;; for PII, and in fact harmful because of partial register stalls.
5809
5810 (define_insn "*addhi_1_lea"
5811   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814    (clobber (reg:CC FLAGS_REG))]
5815   "!TARGET_PARTIAL_REG_STALL
5816    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817 {
5818   switch (get_attr_type (insn))
5819     {
5820     case TYPE_LEA:
5821       return "#";
5822     case TYPE_INCDEC:
5823       if (operands[2] == const1_rtx)
5824         return "inc{w}\t%0";
5825       else
5826         {
5827           gcc_assert (operands[2] == constm1_rtx);
5828           return "dec{w}\t%0";
5829         }
5830
5831     default:
5832       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5834       if (GET_CODE (operands[2]) == CONST_INT
5835           && (INTVAL (operands[2]) == 128
5836               || (INTVAL (operands[2]) < 0
5837                   && INTVAL (operands[2]) != -128)))
5838         {
5839           operands[2] = GEN_INT (-INTVAL (operands[2]));
5840           return "sub{w}\t{%2, %0|%0, %2}";
5841         }
5842       return "add{w}\t{%2, %0|%0, %2}";
5843     }
5844 }
5845   [(set (attr "type")
5846      (if_then_else (eq_attr "alternative" "2")
5847         (const_string "lea")
5848         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5849            (const_string "incdec")
5850            (const_string "alu"))))
5851    (set_attr "mode" "HI,HI,SI")])
5852
5853 (define_insn "*addhi_1"
5854   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856                  (match_operand:HI 2 "general_operand" "ri,rm")))
5857    (clobber (reg:CC FLAGS_REG))]
5858   "TARGET_PARTIAL_REG_STALL
5859    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5860 {
5861   switch (get_attr_type (insn))
5862     {
5863     case TYPE_INCDEC:
5864       if (operands[2] == const1_rtx)
5865         return "inc{w}\t%0";
5866       else
5867         {
5868           gcc_assert (operands[2] == constm1_rtx);
5869           return "dec{w}\t%0";
5870         }
5871
5872     default:
5873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875       if (GET_CODE (operands[2]) == CONST_INT
5876           && (INTVAL (operands[2]) == 128
5877               || (INTVAL (operands[2]) < 0
5878                   && INTVAL (operands[2]) != -128)))
5879         {
5880           operands[2] = GEN_INT (-INTVAL (operands[2]));
5881           return "sub{w}\t{%2, %0|%0, %2}";
5882         }
5883       return "add{w}\t{%2, %0|%0, %2}";
5884     }
5885 }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set_attr "mode" "HI")])
5891
5892 (define_insn "*addhi_2"
5893   [(set (reg FLAGS_REG)
5894         (compare
5895           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5897           (const_int 0)))                       
5898    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899         (plus:HI (match_dup 1) (match_dup 2)))]
5900   "ix86_match_ccmode (insn, CCGOCmode)
5901    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5902 {
5903   switch (get_attr_type (insn))
5904     {
5905     case TYPE_INCDEC:
5906       if (operands[2] == const1_rtx)
5907         return "inc{w}\t%0";
5908       else
5909         {
5910           gcc_assert (operands[2] == constm1_rtx);
5911           return "dec{w}\t%0";
5912         }
5913
5914     default:
5915       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917       if (GET_CODE (operands[2]) == CONST_INT
5918           && (INTVAL (operands[2]) == 128
5919               || (INTVAL (operands[2]) < 0
5920                   && INTVAL (operands[2]) != -128)))
5921         {
5922           operands[2] = GEN_INT (-INTVAL (operands[2]));
5923           return "sub{w}\t{%2, %0|%0, %2}";
5924         }
5925       return "add{w}\t{%2, %0|%0, %2}";
5926     }
5927 }
5928   [(set (attr "type")
5929      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930         (const_string "incdec")
5931         (const_string "alu")))
5932    (set_attr "mode" "HI")])
5933
5934 (define_insn "*addhi_3"
5935   [(set (reg FLAGS_REG)
5936         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938    (clobber (match_scratch:HI 0 "=r"))]
5939   "ix86_match_ccmode (insn, CCZmode)
5940    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941 {
5942   switch (get_attr_type (insn))
5943     {
5944     case TYPE_INCDEC:
5945       if (operands[2] == const1_rtx)
5946         return "inc{w}\t%0";
5947       else
5948         {
5949           gcc_assert (operands[2] == constm1_rtx);
5950           return "dec{w}\t%0";
5951         }
5952
5953     default:
5954       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5956       if (GET_CODE (operands[2]) == CONST_INT
5957           && (INTVAL (operands[2]) == 128
5958               || (INTVAL (operands[2]) < 0
5959                   && INTVAL (operands[2]) != -128)))
5960         {
5961           operands[2] = GEN_INT (-INTVAL (operands[2]));
5962           return "sub{w}\t{%2, %0|%0, %2}";
5963         }
5964       return "add{w}\t{%2, %0|%0, %2}";
5965     }
5966 }
5967   [(set (attr "type")
5968      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969         (const_string "incdec")
5970         (const_string "alu")))
5971    (set_attr "mode" "HI")])
5972
5973 ; See comments above addsi_4 for details.
5974 (define_insn "*addhi_4"
5975   [(set (reg FLAGS_REG)
5976         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977                  (match_operand:HI 2 "const_int_operand" "n")))
5978    (clobber (match_scratch:HI 0 "=rm"))]
5979   "ix86_match_ccmode (insn, CCGCmode)
5980    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5981 {
5982   switch (get_attr_type (insn))
5983     {
5984     case TYPE_INCDEC:
5985       if (operands[2] == constm1_rtx)
5986         return "inc{w}\t%0";
5987       else
5988         {
5989           gcc_assert (operands[2] == const1_rtx);
5990           return "dec{w}\t%0";
5991         }
5992
5993     default:
5994       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997       if ((INTVAL (operands[2]) == -128
5998            || (INTVAL (operands[2]) > 0
5999                && INTVAL (operands[2]) != 128)))
6000         return "sub{w}\t{%2, %0|%0, %2}";
6001       operands[2] = GEN_INT (-INTVAL (operands[2]));
6002       return "add{w}\t{%2, %0|%0, %2}";
6003     }
6004 }
6005   [(set (attr "type")
6006      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007         (const_string "incdec")
6008         (const_string "alu")))
6009    (set_attr "mode" "SI")])
6010
6011
6012 (define_insn "*addhi_5"
6013   [(set (reg FLAGS_REG)
6014         (compare
6015           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016                    (match_operand:HI 2 "general_operand" "rmni"))
6017           (const_int 0)))                       
6018    (clobber (match_scratch:HI 0 "=r"))]
6019   "ix86_match_ccmode (insn, CCGOCmode)
6020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == const1_rtx)
6026         return "inc{w}\t%0";
6027       else
6028         {
6029           gcc_assert (operands[2] == constm1_rtx);
6030           return "dec{w}\t%0";
6031         }
6032
6033     default:
6034       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6036       if (GET_CODE (operands[2]) == CONST_INT
6037           && (INTVAL (operands[2]) == 128
6038               || (INTVAL (operands[2]) < 0
6039                   && INTVAL (operands[2]) != -128)))
6040         {
6041           operands[2] = GEN_INT (-INTVAL (operands[2]));
6042           return "sub{w}\t{%2, %0|%0, %2}";
6043         }
6044       return "add{w}\t{%2, %0|%0, %2}";
6045     }
6046 }
6047   [(set (attr "type")
6048      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049         (const_string "incdec")
6050         (const_string "alu")))
6051    (set_attr "mode" "HI")])
6052
6053 (define_expand "addqi3"
6054   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056                             (match_operand:QI 2 "general_operand" "")))
6057               (clobber (reg:CC FLAGS_REG))])]
6058   "TARGET_QIMODE_MATH"
6059   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6060
6061 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6062 (define_insn "*addqi_1_lea"
6063   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066    (clobber (reg:CC FLAGS_REG))]
6067   "!TARGET_PARTIAL_REG_STALL
6068    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6069 {
6070   int widen = (which_alternative == 2);
6071   switch (get_attr_type (insn))
6072     {
6073     case TYPE_LEA:
6074       return "#";
6075     case TYPE_INCDEC:
6076       if (operands[2] == const1_rtx)
6077         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6078       else
6079         {
6080           gcc_assert (operands[2] == constm1_rtx);
6081           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6082         }
6083
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if (GET_CODE (operands[2]) == CONST_INT
6088           && (INTVAL (operands[2]) == 128
6089               || (INTVAL (operands[2]) < 0
6090                   && INTVAL (operands[2]) != -128)))
6091         {
6092           operands[2] = GEN_INT (-INTVAL (operands[2]));
6093           if (widen)
6094             return "sub{l}\t{%2, %k0|%k0, %2}";
6095           else
6096             return "sub{b}\t{%2, %0|%0, %2}";
6097         }
6098       if (widen)
6099         return "add{l}\t{%k2, %k0|%k0, %k2}";
6100       else
6101         return "add{b}\t{%2, %0|%0, %2}";
6102     }
6103 }
6104   [(set (attr "type")
6105      (if_then_else (eq_attr "alternative" "3")
6106         (const_string "lea")
6107         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108            (const_string "incdec")
6109            (const_string "alu"))))
6110    (set_attr "mode" "QI,QI,SI,SI")])
6111
6112 (define_insn "*addqi_1"
6113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116    (clobber (reg:CC FLAGS_REG))]
6117   "TARGET_PARTIAL_REG_STALL
6118    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119 {
6120   int widen = (which_alternative == 2);
6121   switch (get_attr_type (insn))
6122     {
6123     case TYPE_INCDEC:
6124       if (operands[2] == const1_rtx)
6125         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6126       else
6127         {
6128           gcc_assert (operands[2] == constm1_rtx);
6129           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6130         }
6131
6132     default:
6133       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135       if (GET_CODE (operands[2]) == CONST_INT
6136           && (INTVAL (operands[2]) == 128
6137               || (INTVAL (operands[2]) < 0
6138                   && INTVAL (operands[2]) != -128)))
6139         {
6140           operands[2] = GEN_INT (-INTVAL (operands[2]));
6141           if (widen)
6142             return "sub{l}\t{%2, %k0|%k0, %2}";
6143           else
6144             return "sub{b}\t{%2, %0|%0, %2}";
6145         }
6146       if (widen)
6147         return "add{l}\t{%k2, %k0|%k0, %k2}";
6148       else
6149         return "add{b}\t{%2, %0|%0, %2}";
6150     }
6151 }
6152   [(set (attr "type")
6153      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154         (const_string "incdec")
6155         (const_string "alu")))
6156    (set_attr "mode" "QI,QI,SI")])
6157
6158 (define_insn "*addqi_1_slp"
6159   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160         (plus:QI (match_dup 0)
6161                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6162    (clobber (reg:CC FLAGS_REG))]
6163   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[1] == const1_rtx)
6170         return "inc{b}\t%0";
6171       else
6172         {
6173           gcc_assert (operands[1] == constm1_rtx);
6174           return "dec{b}\t%0";
6175         }
6176
6177     default:
6178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6179       if (GET_CODE (operands[1]) == CONST_INT
6180           && INTVAL (operands[1]) < 0)
6181         {
6182           operands[1] = GEN_INT (-INTVAL (operands[1]));
6183           return "sub{b}\t{%1, %0|%0, %1}";
6184         }
6185       return "add{b}\t{%1, %0|%0, %1}";
6186     }
6187 }
6188   [(set (attr "type")
6189      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190         (const_string "incdec")
6191         (const_string "alu1")))
6192    (set (attr "memory")
6193      (if_then_else (match_operand 1 "memory_operand" "")
6194         (const_string "load")
6195         (const_string "none")))
6196    (set_attr "mode" "QI")])
6197
6198 (define_insn "*addqi_2"
6199   [(set (reg FLAGS_REG)
6200         (compare
6201           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6203           (const_int 0)))
6204    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205         (plus:QI (match_dup 1) (match_dup 2)))]
6206   "ix86_match_ccmode (insn, CCGOCmode)
6207    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6208 {
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == const1_rtx)
6213         return "inc{b}\t%0";
6214       else
6215         {
6216           gcc_assert (operands[2] == constm1_rtx
6217                       || (GET_CODE (operands[2]) == CONST_INT
6218                           && INTVAL (operands[2]) == 255));
6219           return "dec{b}\t%0";
6220         }
6221
6222     default:
6223       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6224       if (GET_CODE (operands[2]) == CONST_INT
6225           && INTVAL (operands[2]) < 0)
6226         {
6227           operands[2] = GEN_INT (-INTVAL (operands[2]));
6228           return "sub{b}\t{%2, %0|%0, %2}";
6229         }
6230       return "add{b}\t{%2, %0|%0, %2}";
6231     }
6232 }
6233   [(set (attr "type")
6234      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235         (const_string "incdec")
6236         (const_string "alu")))
6237    (set_attr "mode" "QI")])
6238
6239 (define_insn "*addqi_3"
6240   [(set (reg FLAGS_REG)
6241         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243    (clobber (match_scratch:QI 0 "=q"))]
6244   "ix86_match_ccmode (insn, CCZmode)
6245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6246 {
6247   switch (get_attr_type (insn))
6248     {
6249     case TYPE_INCDEC:
6250       if (operands[2] == const1_rtx)
6251         return "inc{b}\t%0";
6252       else
6253         {
6254           gcc_assert (operands[2] == constm1_rtx
6255                       || (GET_CODE (operands[2]) == CONST_INT
6256                           && INTVAL (operands[2]) == 255));
6257           return "dec{b}\t%0";
6258         }
6259
6260     default:
6261       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6262       if (GET_CODE (operands[2]) == CONST_INT
6263           && INTVAL (operands[2]) < 0)
6264         {
6265           operands[2] = GEN_INT (-INTVAL (operands[2]));
6266           return "sub{b}\t{%2, %0|%0, %2}";
6267         }
6268       return "add{b}\t{%2, %0|%0, %2}";
6269     }
6270 }
6271   [(set (attr "type")
6272      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273         (const_string "incdec")
6274         (const_string "alu")))
6275    (set_attr "mode" "QI")])
6276
6277 ; See comments above addsi_4 for details.
6278 (define_insn "*addqi_4"
6279   [(set (reg FLAGS_REG)
6280         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281                  (match_operand:QI 2 "const_int_operand" "n")))
6282    (clobber (match_scratch:QI 0 "=qm"))]
6283   "ix86_match_ccmode (insn, CCGCmode)
6284    && (INTVAL (operands[2]) & 0xff) != 0x80"
6285 {
6286   switch (get_attr_type (insn))
6287     {
6288     case TYPE_INCDEC:
6289       if (operands[2] == constm1_rtx
6290           || (GET_CODE (operands[2]) == CONST_INT
6291               && INTVAL (operands[2]) == 255))
6292         return "inc{b}\t%0";
6293       else
6294         {
6295           gcc_assert (operands[2] == const1_rtx);
6296           return "dec{b}\t%0";
6297         }
6298
6299     default:
6300       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301       if (INTVAL (operands[2]) < 0)
6302         {
6303           operands[2] = GEN_INT (-INTVAL (operands[2]));
6304           return "add{b}\t{%2, %0|%0, %2}";
6305         }
6306       return "sub{b}\t{%2, %0|%0, %2}";
6307     }
6308 }
6309   [(set (attr "type")
6310      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311         (const_string "incdec")
6312         (const_string "alu")))
6313    (set_attr "mode" "QI")])
6314
6315
6316 (define_insn "*addqi_5"
6317   [(set (reg FLAGS_REG)
6318         (compare
6319           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320                    (match_operand:QI 2 "general_operand" "qmni"))
6321           (const_int 0)))
6322    (clobber (match_scratch:QI 0 "=q"))]
6323   "ix86_match_ccmode (insn, CCGOCmode)
6324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6325 {
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == const1_rtx)
6330         return "inc{b}\t%0";
6331       else
6332         {
6333           gcc_assert (operands[2] == constm1_rtx
6334                       || (GET_CODE (operands[2]) == CONST_INT
6335                           && INTVAL (operands[2]) == 255));
6336           return "dec{b}\t%0";
6337         }
6338
6339     default:
6340       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6341       if (GET_CODE (operands[2]) == CONST_INT
6342           && INTVAL (operands[2]) < 0)
6343         {
6344           operands[2] = GEN_INT (-INTVAL (operands[2]));
6345           return "sub{b}\t{%2, %0|%0, %2}";
6346         }
6347       return "add{b}\t{%2, %0|%0, %2}";
6348     }
6349 }
6350   [(set (attr "type")
6351      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352         (const_string "incdec")
6353         (const_string "alu")))
6354    (set_attr "mode" "QI")])
6355
6356
6357 (define_insn "addqi_ext_1"
6358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359                          (const_int 8)
6360                          (const_int 8))
6361         (plus:SI
6362           (zero_extract:SI
6363             (match_operand 1 "ext_register_operand" "0")
6364             (const_int 8)
6365             (const_int 8))
6366           (match_operand:QI 2 "general_operand" "Qmn")))
6367    (clobber (reg:CC FLAGS_REG))]
6368   "!TARGET_64BIT"
6369 {
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_INCDEC:
6373       if (operands[2] == const1_rtx)
6374         return "inc{b}\t%h0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx
6378                       || (GET_CODE (operands[2]) == CONST_INT
6379                           && INTVAL (operands[2]) == 255));
6380           return "dec{b}\t%h0";
6381         }
6382
6383     default:
6384       return "add{b}\t{%2, %h0|%h0, %2}";
6385     }
6386 }
6387   [(set (attr "type")
6388      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389         (const_string "incdec")
6390         (const_string "alu")))
6391    (set_attr "mode" "QI")])
6392
6393 (define_insn "*addqi_ext_1_rex64"
6394   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395                          (const_int 8)
6396                          (const_int 8))
6397         (plus:SI
6398           (zero_extract:SI
6399             (match_operand 1 "ext_register_operand" "0")
6400             (const_int 8)
6401             (const_int 8))
6402           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "TARGET_64BIT"
6405 {
6406   switch (get_attr_type (insn))
6407     {
6408     case TYPE_INCDEC:
6409       if (operands[2] == const1_rtx)
6410         return "inc{b}\t%h0";
6411       else
6412         {
6413           gcc_assert (operands[2] == constm1_rtx
6414                       || (GET_CODE (operands[2]) == CONST_INT
6415                           && INTVAL (operands[2]) == 255));
6416           return "dec{b}\t%h0";
6417         }
6418
6419     default:
6420       return "add{b}\t{%2, %h0|%h0, %2}";
6421     }
6422 }
6423   [(set (attr "type")
6424      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425         (const_string "incdec")
6426         (const_string "alu")))
6427    (set_attr "mode" "QI")])
6428
6429 (define_insn "*addqi_ext_2"
6430   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431                          (const_int 8)
6432                          (const_int 8))
6433         (plus:SI
6434           (zero_extract:SI
6435             (match_operand 1 "ext_register_operand" "%0")
6436             (const_int 8)
6437             (const_int 8))
6438           (zero_extract:SI
6439             (match_operand 2 "ext_register_operand" "Q")
6440             (const_int 8)
6441             (const_int 8))))
6442    (clobber (reg:CC FLAGS_REG))]
6443   ""
6444   "add{b}\t{%h2, %h0|%h0, %h2}"
6445   [(set_attr "type" "alu")
6446    (set_attr "mode" "QI")])
6447
6448 ;; The patterns that match these are at the end of this file.
6449
6450 (define_expand "addxf3"
6451   [(set (match_operand:XF 0 "register_operand" "")
6452         (plus:XF (match_operand:XF 1 "register_operand" "")
6453                  (match_operand:XF 2 "register_operand" "")))]
6454   "TARGET_80387"
6455   "")
6456
6457 (define_expand "adddf3"
6458   [(set (match_operand:DF 0 "register_operand" "")
6459         (plus:DF (match_operand:DF 1 "register_operand" "")
6460                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6461   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6462   "")
6463
6464 (define_expand "addsf3"
6465   [(set (match_operand:SF 0 "register_operand" "")
6466         (plus:SF (match_operand:SF 1 "register_operand" "")
6467                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6468   "TARGET_80387 || TARGET_SSE_MATH"
6469   "")
6470 \f
6471 ;; Subtract instructions
6472
6473 ;; %%% splits for subditi3
6474
6475 (define_expand "subti3"
6476   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478                              (match_operand:TI 2 "x86_64_general_operand" "")))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   "TARGET_64BIT"
6481   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6482
6483 (define_insn "*subti3_1"
6484   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6489   "#")
6490
6491 (define_split
6492   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494                   (match_operand:TI 2 "general_operand" "")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "TARGET_64BIT && reload_completed"
6497   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499    (parallel [(set (match_dup 3)
6500                    (minus:DI (match_dup 4)
6501                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6502                                       (match_dup 5))))
6503               (clobber (reg:CC FLAGS_REG))])]
6504   "split_ti (operands+0, 1, operands+0, operands+3);
6505    split_ti (operands+1, 1, operands+1, operands+4);
6506    split_ti (operands+2, 1, operands+2, operands+5);")
6507
6508 ;; %%% splits for subsidi3
6509
6510 (define_expand "subdi3"
6511   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513                              (match_operand:DI 2 "x86_64_general_operand" "")))
6514               (clobber (reg:CC FLAGS_REG))])]
6515   ""
6516   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6517
6518 (define_insn "*subdi3_1"
6519   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6522    (clobber (reg:CC FLAGS_REG))]
6523   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6524   "#")
6525
6526 (define_split
6527   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529                   (match_operand:DI 2 "general_operand" "")))
6530    (clobber (reg:CC FLAGS_REG))]
6531   "!TARGET_64BIT && reload_completed"
6532   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534    (parallel [(set (match_dup 3)
6535                    (minus:SI (match_dup 4)
6536                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6537                                       (match_dup 5))))
6538               (clobber (reg:CC FLAGS_REG))])]
6539   "split_di (operands+0, 1, operands+0, operands+3);
6540    split_di (operands+1, 1, operands+1, operands+4);
6541    split_di (operands+2, 1, operands+2, operands+5);")
6542
6543 (define_insn "subdi3_carry_rex64"
6544   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550   "sbb{q}\t{%2, %0|%0, %2}"
6551   [(set_attr "type" "alu")
6552    (set_attr "pent_pair" "pu")
6553    (set_attr "mode" "DI")])
6554
6555 (define_insn "*subdi_1_rex64"
6556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561   "sub{q}\t{%2, %0|%0, %2}"
6562   [(set_attr "type" "alu")
6563    (set_attr "mode" "DI")])
6564
6565 (define_insn "*subdi_2_rex64"
6566   [(set (reg FLAGS_REG)
6567         (compare
6568           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6570           (const_int 0)))
6571    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572         (minus:DI (match_dup 1) (match_dup 2)))]
6573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575   "sub{q}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "mode" "DI")])
6578
6579 (define_insn "*subdi_3_rex63"
6580   [(set (reg FLAGS_REG)
6581         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584         (minus:DI (match_dup 1) (match_dup 2)))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sub{q}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "mode" "DI")])
6590
6591 (define_insn "subqi3_carry"
6592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595                (match_operand:QI 2 "general_operand" "qi,qm"))))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598   "sbb{b}\t{%2, %0|%0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "pent_pair" "pu")
6601    (set_attr "mode" "QI")])
6602
6603 (define_insn "subhi3_carry"
6604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607                (match_operand:HI 2 "general_operand" "ri,rm"))))
6608    (clobber (reg:CC FLAGS_REG))]
6609   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610   "sbb{w}\t{%2, %0|%0, %2}"
6611   [(set_attr "type" "alu")
6612    (set_attr "pent_pair" "pu")
6613    (set_attr "mode" "HI")])
6614
6615 (define_insn "subsi3_carry"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619                (match_operand:SI 2 "general_operand" "ri,rm"))))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622   "sbb{l}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "pent_pair" "pu")
6625    (set_attr "mode" "SI")])
6626
6627 (define_insn "subsi3_carry_zext"
6628   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6629           (zero_extend:DI
6630             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635   "sbb{l}\t{%2, %k0|%k0, %2}"
6636   [(set_attr "type" "alu")
6637    (set_attr "pent_pair" "pu")
6638    (set_attr "mode" "SI")])
6639
6640 (define_expand "subsi3"
6641   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643                              (match_operand:SI 2 "general_operand" "")))
6644               (clobber (reg:CC FLAGS_REG))])]
6645   ""
6646   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6647
6648 (define_insn "*subsi_1"
6649   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651                   (match_operand:SI 2 "general_operand" "ri,rm")))
6652    (clobber (reg:CC FLAGS_REG))]
6653   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654   "sub{l}\t{%2, %0|%0, %2}"
6655   [(set_attr "type" "alu")
6656    (set_attr "mode" "SI")])
6657
6658 (define_insn "*subsi_1_zext"
6659   [(set (match_operand:DI 0 "register_operand" "=r")
6660         (zero_extend:DI
6661           (minus:SI (match_operand:SI 1 "register_operand" "0")
6662                     (match_operand:SI 2 "general_operand" "rim"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665   "sub{l}\t{%2, %k0|%k0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "SI")])
6668
6669 (define_insn "*subsi_2"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673                     (match_operand:SI 2 "general_operand" "ri,rm"))
6674           (const_int 0)))
6675    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676         (minus:SI (match_dup 1) (match_dup 2)))]
6677   "ix86_match_ccmode (insn, CCGOCmode)
6678    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679   "sub{l}\t{%2, %0|%0, %2}"
6680   [(set_attr "type" "alu")
6681    (set_attr "mode" "SI")])
6682
6683 (define_insn "*subsi_2_zext"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (minus:SI (match_operand:SI 1 "register_operand" "0")
6687                     (match_operand:SI 2 "general_operand" "rim"))
6688           (const_int 0)))
6689    (set (match_operand:DI 0 "register_operand" "=r")
6690         (zero_extend:DI
6691           (minus:SI (match_dup 1)
6692                     (match_dup 2))))]
6693   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695   "sub{l}\t{%2, %k0|%k0, %2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "mode" "SI")])
6698
6699 (define_insn "*subsi_3"
6700   [(set (reg FLAGS_REG)
6701         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702                  (match_operand:SI 2 "general_operand" "ri,rm")))
6703    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704         (minus:SI (match_dup 1) (match_dup 2)))]
6705   "ix86_match_ccmode (insn, CCmode)
6706    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707   "sub{l}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "SI")])
6710
6711 (define_insn "*subsi_3_zext"
6712   [(set (reg FLAGS_REG)
6713         (compare (match_operand:SI 1 "register_operand" "0")
6714                  (match_operand:SI 2 "general_operand" "rim")))
6715    (set (match_operand:DI 0 "register_operand" "=r")
6716         (zero_extend:DI
6717           (minus:SI (match_dup 1)
6718                     (match_dup 2))))]
6719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721   "sub{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 "general_operand" "0")))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "TARGET_64BIT
9332    && ix86_unary_operator_ok (NEG, TImode, operands)"
9333   "#")
9334
9335 (define_split
9336   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337         (neg:TI (match_operand:TI 1 "general_operand" "")))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "TARGET_64BIT && reload_completed"
9340   [(parallel
9341     [(set (reg:CCZ FLAGS_REG)
9342           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343      (set (match_dup 0) (neg:DI (match_dup 2)))])
9344    (parallel
9345     [(set (match_dup 1)
9346           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9347                             (match_dup 3))
9348                    (const_int 0)))
9349      (clobber (reg:CC FLAGS_REG))])
9350    (parallel
9351     [(set (match_dup 1)
9352           (neg:DI (match_dup 1)))
9353      (clobber (reg:CC FLAGS_REG))])]
9354   "split_ti (operands+1, 1, operands+2, operands+3);
9355    split_ti (operands+0, 1, operands+0, operands+1);")
9356
9357 (define_expand "negdi2"
9358   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360               (clobber (reg:CC FLAGS_REG))])]
9361   ""
9362   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9363
9364 (define_insn "*negdi2_1"
9365   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "!TARGET_64BIT
9369    && ix86_unary_operator_ok (NEG, DImode, operands)"
9370   "#")
9371
9372 (define_split
9373   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374         (neg:DI (match_operand:DI 1 "general_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "!TARGET_64BIT && reload_completed"
9377   [(parallel
9378     [(set (reg:CCZ FLAGS_REG)
9379           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380      (set (match_dup 0) (neg:SI (match_dup 2)))])
9381    (parallel
9382     [(set (match_dup 1)
9383           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9384                             (match_dup 3))
9385                    (const_int 0)))
9386      (clobber (reg:CC FLAGS_REG))])
9387    (parallel
9388     [(set (match_dup 1)
9389           (neg:SI (match_dup 1)))
9390      (clobber (reg:CC FLAGS_REG))])]
9391   "split_di (operands+1, 1, operands+2, operands+3);
9392    split_di (operands+0, 1, operands+0, operands+1);")
9393
9394 (define_insn "*negdi2_1_rex64"
9395   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9399   "neg{q}\t%0"
9400   [(set_attr "type" "negnot")
9401    (set_attr "mode" "DI")])
9402
9403 ;; The problem with neg is that it does not perform (compare x 0),
9404 ;; it really performs (compare 0 x), which leaves us with the zero
9405 ;; flag being the only useful item.
9406
9407 (define_insn "*negdi2_cmpz_rex64"
9408   [(set (reg:CCZ FLAGS_REG)
9409         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9410                      (const_int 0)))
9411    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412         (neg:DI (match_dup 1)))]
9413   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414   "neg{q}\t%0"
9415   [(set_attr "type" "negnot")
9416    (set_attr "mode" "DI")])
9417
9418
9419 (define_expand "negsi2"
9420   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422               (clobber (reg:CC FLAGS_REG))])]
9423   ""
9424   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9425
9426 (define_insn "*negsi2_1"
9427   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "ix86_unary_operator_ok (NEG, SImode, operands)"
9431   "neg{l}\t%0"
9432   [(set_attr "type" "negnot")
9433    (set_attr "mode" "SI")])
9434
9435 ;; Combine is quite creative about this pattern.
9436 (define_insn "*negsi2_1_zext"
9437   [(set (match_operand:DI 0 "register_operand" "=r")
9438         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9439                                         (const_int 32)))
9440                      (const_int 32)))
9441    (clobber (reg:CC FLAGS_REG))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443   "neg{l}\t%k0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "SI")])
9446
9447 ;; The problem with neg is that it does not perform (compare x 0),
9448 ;; it really performs (compare 0 x), which leaves us with the zero
9449 ;; flag being the only useful item.
9450
9451 (define_insn "*negsi2_cmpz"
9452   [(set (reg:CCZ FLAGS_REG)
9453         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9454                      (const_int 0)))
9455    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456         (neg:SI (match_dup 1)))]
9457   "ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9461
9462 (define_insn "*negsi2_cmpz_zext"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (lshiftrt:DI
9465                        (neg:DI (ashift:DI
9466                                  (match_operand:DI 1 "register_operand" "0")
9467                                  (const_int 32)))
9468                        (const_int 32))
9469                      (const_int 0)))
9470    (set (match_operand:DI 0 "register_operand" "=r")
9471         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9472                                         (const_int 32)))
9473                      (const_int 32)))]
9474   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9475   "neg{l}\t%k0"
9476   [(set_attr "type" "negnot")
9477    (set_attr "mode" "SI")])
9478
9479 (define_expand "neghi2"
9480   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482               (clobber (reg:CC FLAGS_REG))])]
9483   "TARGET_HIMODE_MATH"
9484   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9485
9486 (define_insn "*neghi2_1"
9487   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "ix86_unary_operator_ok (NEG, HImode, operands)"
9491   "neg{w}\t%0"
9492   [(set_attr "type" "negnot")
9493    (set_attr "mode" "HI")])
9494
9495 (define_insn "*neghi2_cmpz"
9496   [(set (reg:CCZ FLAGS_REG)
9497         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9498                      (const_int 0)))
9499    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500         (neg:HI (match_dup 1)))]
9501   "ix86_unary_operator_ok (NEG, HImode, operands)"
9502   "neg{w}\t%0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "HI")])
9505
9506 (define_expand "negqi2"
9507   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   "TARGET_QIMODE_MATH"
9511   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9512
9513 (define_insn "*negqi2_1"
9514   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "ix86_unary_operator_ok (NEG, QImode, operands)"
9518   "neg{b}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "QI")])
9521
9522 (define_insn "*negqi2_cmpz"
9523   [(set (reg:CCZ FLAGS_REG)
9524         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9525                      (const_int 0)))
9526    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527         (neg:QI (match_dup 1)))]
9528   "ix86_unary_operator_ok (NEG, QImode, operands)"
9529   "neg{b}\t%0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "QI")])
9532
9533 ;; Changing of sign for FP values is doable using integer unit too.
9534
9535 (define_expand "negsf2"
9536   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538   "TARGET_80387 || TARGET_SSE_MATH"
9539   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9540
9541 (define_expand "abssf2"
9542   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544   "TARGET_80387 || TARGET_SSE_MATH"
9545   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9546
9547 (define_insn "*absnegsf2_mixed"
9548   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9549         (match_operator:SF 3 "absneg_operator"
9550           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9551    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9555   "#")
9556
9557 (define_insn "*absnegsf2_sse"
9558   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9559         (match_operator:SF 3 "absneg_operator"
9560           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "TARGET_SSE_MATH
9564    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9565   "#")
9566
9567 (define_insn "*absnegsf2_i387"
9568   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569         (match_operator:SF 3 "absneg_operator"
9570           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571    (use (match_operand 2 "" ""))
9572    (clobber (reg:CC FLAGS_REG))]
9573   "TARGET_80387 && !TARGET_SSE_MATH
9574    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9575   "#")
9576
9577 (define_expand "copysignsf3"
9578   [(match_operand:SF 0 "register_operand" "")
9579    (match_operand:SF 1 "nonmemory_operand" "")
9580    (match_operand:SF 2 "register_operand" "")]
9581   "TARGET_SSE_MATH"
9582 {
9583   ix86_expand_copysign (operands);
9584   DONE;
9585 })
9586
9587 (define_insn_and_split "copysignsf3_const"
9588   [(set (match_operand:SF 0 "register_operand"          "=x")
9589         (unspec:SF
9590           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9591            (match_operand:SF 2 "register_operand"       "0")
9592            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9593           UNSPEC_COPYSIGN))]
9594   "TARGET_SSE_MATH"
9595   "#"
9596   "&& reload_completed"
9597   [(const_int 0)]
9598 {
9599   ix86_split_copysign_const (operands);
9600   DONE;
9601 })
9602
9603 (define_insn "copysignsf3_var"
9604   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9605         (unspec:SF
9606           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9607            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9608            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9610           UNSPEC_COPYSIGN))
9611    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9612   "TARGET_SSE_MATH"
9613   "#")
9614
9615 (define_split
9616   [(set (match_operand:SF 0 "register_operand" "")
9617         (unspec:SF
9618           [(match_operand:SF 2 "register_operand" "")
9619            (match_operand:SF 3 "register_operand" "")
9620            (match_operand:V4SF 4 "" "")
9621            (match_operand:V4SF 5 "" "")]
9622           UNSPEC_COPYSIGN))
9623    (clobber (match_scratch:V4SF 1 ""))]
9624   "TARGET_SSE_MATH && reload_completed"
9625   [(const_int 0)]
9626 {
9627   ix86_split_copysign_var (operands);
9628   DONE;
9629 })
9630
9631 (define_expand "negdf2"
9632   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9636
9637 (define_expand "absdf2"
9638   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9642
9643 (define_insn "*absnegdf2_mixed"
9644   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9645         (match_operator:DF 3 "absneg_operator"
9646           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9647    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9651   "#")
9652
9653 (define_insn "*absnegdf2_sse"
9654   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9655         (match_operator:DF 3 "absneg_operator"
9656           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9657    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9658    (clobber (reg:CC FLAGS_REG))]
9659   "TARGET_SSE2 && TARGET_SSE_MATH
9660    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9661   "#")
9662
9663 (define_insn "*absnegdf2_i387"
9664   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665         (match_operator:DF 3 "absneg_operator"
9666           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667    (use (match_operand 2 "" ""))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9671   "#")
9672
9673 (define_expand "copysigndf3"
9674   [(match_operand:DF 0 "register_operand" "")
9675    (match_operand:DF 1 "nonmemory_operand" "")
9676    (match_operand:DF 2 "register_operand" "")]
9677   "TARGET_SSE2 && TARGET_SSE_MATH"
9678 {
9679   ix86_expand_copysign (operands);
9680   DONE;
9681 })
9682
9683 (define_insn_and_split "copysigndf3_const"
9684   [(set (match_operand:DF 0 "register_operand"          "=x")
9685         (unspec:DF
9686           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9687            (match_operand:DF 2 "register_operand"       "0")
9688            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9689           UNSPEC_COPYSIGN))]
9690   "TARGET_SSE2 && TARGET_SSE_MATH"
9691   "#"
9692   "&& reload_completed"
9693   [(const_int 0)]
9694 {
9695   ix86_split_copysign_const (operands);
9696   DONE;
9697 })
9698
9699 (define_insn "copysigndf3_var"
9700   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9701         (unspec:DF
9702           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9703            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9704            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9706           UNSPEC_COPYSIGN))
9707    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9708   "TARGET_SSE2 && TARGET_SSE_MATH"
9709   "#")
9710
9711 (define_split
9712   [(set (match_operand:DF 0 "register_operand" "")
9713         (unspec:DF
9714           [(match_operand:DF 2 "register_operand" "")
9715            (match_operand:DF 3 "register_operand" "")
9716            (match_operand:V2DF 4 "" "")
9717            (match_operand:V2DF 5 "" "")]
9718           UNSPEC_COPYSIGN))
9719    (clobber (match_scratch:V2DF 1 ""))]
9720   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9721   [(const_int 0)]
9722 {
9723   ix86_split_copysign_var (operands);
9724   DONE;
9725 })
9726
9727 (define_expand "negxf2"
9728   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9730   "TARGET_80387"
9731   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9732
9733 (define_expand "absxf2"
9734   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736   "TARGET_80387"
9737   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9738
9739 (define_insn "*absnegxf2_i387"
9740   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741         (match_operator:XF 3 "absneg_operator"
9742           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743    (use (match_operand 2 "" ""))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "TARGET_80387
9746    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9747   "#")
9748
9749 ;; Splitters for fp abs and neg.
9750
9751 (define_split
9752   [(set (match_operand 0 "fp_register_operand" "")
9753         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9754    (use (match_operand 2 "" ""))
9755    (clobber (reg:CC FLAGS_REG))]
9756   "reload_completed"
9757   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9758
9759 (define_split
9760   [(set (match_operand 0 "register_operand" "")
9761         (match_operator 3 "absneg_operator"
9762           [(match_operand 1 "register_operand" "")]))
9763    (use (match_operand 2 "nonimmediate_operand" ""))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "reload_completed && SSE_REG_P (operands[0])"
9766   [(set (match_dup 0) (match_dup 3))]
9767 {
9768   enum machine_mode mode = GET_MODE (operands[0]);
9769   enum machine_mode vmode = GET_MODE (operands[2]);
9770   rtx tmp;
9771   
9772   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774   if (operands_match_p (operands[0], operands[2]))
9775     {
9776       tmp = operands[1];
9777       operands[1] = operands[2];
9778       operands[2] = tmp;
9779     }
9780   if (GET_CODE (operands[3]) == ABS)
9781     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9782   else
9783     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9784   operands[3] = tmp;
9785 })
9786
9787 (define_split
9788   [(set (match_operand:SF 0 "register_operand" "")
9789         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790    (use (match_operand:V4SF 2 "" ""))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "reload_completed"
9793   [(parallel [(set (match_dup 0) (match_dup 1))
9794               (clobber (reg:CC FLAGS_REG))])]
9795
9796   rtx tmp;
9797   operands[0] = gen_lowpart (SImode, operands[0]);
9798   if (GET_CODE (operands[1]) == ABS)
9799     {
9800       tmp = gen_int_mode (0x7fffffff, SImode);
9801       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9802     }
9803   else
9804     {
9805       tmp = gen_int_mode (0x80000000, SImode);
9806       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9807     }
9808   operands[1] = tmp;
9809 })
9810
9811 (define_split
9812   [(set (match_operand:DF 0 "register_operand" "")
9813         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814    (use (match_operand 2 "" ""))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "reload_completed"
9817   [(parallel [(set (match_dup 0) (match_dup 1))
9818               (clobber (reg:CC FLAGS_REG))])]
9819 {
9820   rtx tmp;
9821   if (TARGET_64BIT)
9822     {
9823       tmp = gen_lowpart (DImode, operands[0]);
9824       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9825       operands[0] = tmp;
9826
9827       if (GET_CODE (operands[1]) == ABS)
9828         tmp = const0_rtx;
9829       else
9830         tmp = gen_rtx_NOT (DImode, tmp);
9831     }
9832   else
9833     {
9834       operands[0] = gen_highpart (SImode, operands[0]);
9835       if (GET_CODE (operands[1]) == ABS)
9836         {
9837           tmp = gen_int_mode (0x7fffffff, SImode);
9838           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839         }
9840       else
9841         {
9842           tmp = gen_int_mode (0x80000000, SImode);
9843           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844         }
9845     }
9846   operands[1] = tmp;
9847 })
9848
9849 (define_split
9850   [(set (match_operand:XF 0 "register_operand" "")
9851         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852    (use (match_operand 2 "" ""))
9853    (clobber (reg:CC FLAGS_REG))]
9854   "reload_completed"
9855   [(parallel [(set (match_dup 0) (match_dup 1))
9856               (clobber (reg:CC FLAGS_REG))])]
9857 {
9858   rtx tmp;
9859   operands[0] = gen_rtx_REG (SImode,
9860                              true_regnum (operands[0])
9861                              + (TARGET_64BIT ? 1 : 2));
9862   if (GET_CODE (operands[1]) == ABS)
9863     {
9864       tmp = GEN_INT (0x7fff);
9865       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9866     }
9867   else
9868     {
9869       tmp = GEN_INT (0x8000);
9870       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9871     }
9872   operands[1] = tmp;
9873 })
9874
9875 (define_split
9876   [(set (match_operand 0 "memory_operand" "")
9877         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9878    (use (match_operand 2 "" ""))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "reload_completed"
9881   [(parallel [(set (match_dup 0) (match_dup 1))
9882               (clobber (reg:CC FLAGS_REG))])]
9883 {
9884   enum machine_mode mode = GET_MODE (operands[0]);
9885   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9886   rtx tmp;
9887
9888   operands[0] = adjust_address (operands[0], QImode, size - 1);
9889   if (GET_CODE (operands[1]) == ABS)
9890     {
9891       tmp = gen_int_mode (0x7f, QImode);
9892       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9893     }
9894   else
9895     {
9896       tmp = gen_int_mode (0x80, QImode);
9897       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9898     }
9899   operands[1] = tmp;
9900 })
9901
9902 ;; Conditionalize these after reload. If they match before reload, we 
9903 ;; lose the clobber and ability to use integer instructions.
9904
9905 (define_insn "*negsf2_1"
9906   [(set (match_operand:SF 0 "register_operand" "=f")
9907         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908   "TARGET_80387 && (reload_completed || !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 {
10401   switch (get_attr_type (insn))
10402     {
10403     case TYPE_ALU:
10404       gcc_assert (operands[2] == const1_rtx);
10405       return "add{q}\t{%0, %0|%0, %0}";
10406
10407     default:
10408       if (REG_P (operands[2]))
10409         return "sal{q}\t{%b2, %0|%0, %b2}";
10410       else if (operands[2] == const1_rtx
10411                && (TARGET_SHIFT1 || optimize_size))
10412         return "sal{q}\t%0";
10413       else
10414         return "sal{q}\t{%2, %0|%0, %2}";
10415     }
10416 }
10417   [(set (attr "type")
10418      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10419                           (const_int 0))
10420                       (match_operand 0 "register_operand" ""))
10421                  (match_operand 2 "const1_operand" ""))
10422               (const_string "alu")
10423            ]
10424            (const_string "ishift")))
10425    (set_attr "mode" "DI")])
10426
10427 (define_insn "*ashldi3_1"
10428   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10429         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10430                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10431    (clobber (reg:CC FLAGS_REG))]
10432   "!TARGET_64BIT"
10433   "#"
10434   [(set_attr "type" "multi")])
10435
10436 ;; By default we don't ask for a scratch register, because when DImode
10437 ;; values are manipulated, registers are already at a premium.  But if
10438 ;; we have one handy, we won't turn it away.
10439 (define_peephole2
10440   [(match_scratch:SI 3 "r")
10441    (parallel [(set (match_operand:DI 0 "register_operand" "")
10442                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10443                               (match_operand:QI 2 "nonmemory_operand" "")))
10444               (clobber (reg:CC FLAGS_REG))])
10445    (match_dup 3)]
10446   "!TARGET_64BIT && TARGET_CMOVE"
10447   [(const_int 0)]
10448   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10449
10450 (define_split
10451   [(set (match_operand:DI 0 "register_operand" "")
10452         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10453                    (match_operand:QI 2 "nonmemory_operand" "")))
10454    (clobber (reg:CC FLAGS_REG))]
10455   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10456                      ? flow2_completed : reload_completed)"
10457   [(const_int 0)]
10458   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10459
10460 (define_insn "x86_shld_1"
10461   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10462         (ior:SI (ashift:SI (match_dup 0)
10463                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10464                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10465                   (minus:QI (const_int 32) (match_dup 2)))))
10466    (clobber (reg:CC FLAGS_REG))]
10467   ""
10468   "@
10469    shld{l}\t{%2, %1, %0|%0, %1, %2}
10470    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10471   [(set_attr "type" "ishift")
10472    (set_attr "prefix_0f" "1")
10473    (set_attr "mode" "SI")
10474    (set_attr "pent_pair" "np")
10475    (set_attr "athlon_decode" "vector")])
10476
10477 (define_expand "x86_shift_adj_1"
10478   [(set (reg:CCZ FLAGS_REG)
10479         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10480                              (const_int 32))
10481                      (const_int 0)))
10482    (set (match_operand:SI 0 "register_operand" "")
10483         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10484                          (match_operand:SI 1 "register_operand" "")
10485                          (match_dup 0)))
10486    (set (match_dup 1)
10487         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488                          (match_operand:SI 3 "register_operand" "r")
10489                          (match_dup 1)))]
10490   "TARGET_CMOVE"
10491   "")
10492
10493 (define_expand "x86_shift_adj_2"
10494   [(use (match_operand:SI 0 "register_operand" ""))
10495    (use (match_operand:SI 1 "register_operand" ""))
10496    (use (match_operand:QI 2 "register_operand" ""))]
10497   ""
10498 {
10499   rtx label = gen_label_rtx ();
10500   rtx tmp;
10501
10502   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10503
10504   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10505   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10506   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10507                               gen_rtx_LABEL_REF (VOIDmode, label),
10508                               pc_rtx);
10509   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10510   JUMP_LABEL (tmp) = label;
10511
10512   emit_move_insn (operands[0], operands[1]);
10513   ix86_expand_clear (operands[1]);
10514
10515   emit_label (label);
10516   LABEL_NUSES (label) = 1;
10517
10518   DONE;
10519 })
10520
10521 (define_expand "ashlsi3"
10522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10523         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10524                    (match_operand:QI 2 "nonmemory_operand" "")))
10525    (clobber (reg:CC FLAGS_REG))]
10526   ""
10527   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10528
10529 (define_insn "*ashlsi3_1"
10530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10531         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10532                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10533    (clobber (reg:CC FLAGS_REG))]
10534   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10535 {
10536   switch (get_attr_type (insn))
10537     {
10538     case TYPE_ALU:
10539       gcc_assert (operands[2] == const1_rtx);
10540       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10541       return "add{l}\t{%0, %0|%0, %0}";
10542
10543     case TYPE_LEA:
10544       return "#";
10545
10546     default:
10547       if (REG_P (operands[2]))
10548         return "sal{l}\t{%b2, %0|%0, %b2}";
10549       else if (operands[2] == const1_rtx
10550                && (TARGET_SHIFT1 || optimize_size))
10551         return "sal{l}\t%0";
10552       else
10553         return "sal{l}\t{%2, %0|%0, %2}";
10554     }
10555 }
10556   [(set (attr "type")
10557      (cond [(eq_attr "alternative" "1")
10558               (const_string "lea")
10559             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10560                           (const_int 0))
10561                       (match_operand 0 "register_operand" ""))
10562                  (match_operand 2 "const1_operand" ""))
10563               (const_string "alu")
10564            ]
10565            (const_string "ishift")))
10566    (set_attr "mode" "SI")])
10567
10568 ;; Convert lea to the lea pattern to avoid flags dependency.
10569 (define_split
10570   [(set (match_operand 0 "register_operand" "")
10571         (ashift (match_operand 1 "index_register_operand" "")
10572                 (match_operand:QI 2 "const_int_operand" "")))
10573    (clobber (reg:CC FLAGS_REG))]
10574   "reload_completed
10575    && true_regnum (operands[0]) != true_regnum (operands[1])
10576    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10577   [(const_int 0)]
10578 {
10579   rtx pat;
10580   enum machine_mode mode = GET_MODE (operands[0]);
10581
10582   if (GET_MODE_SIZE (mode) < 4)
10583     operands[0] = gen_lowpart (SImode, operands[0]);
10584   if (mode != Pmode)
10585     operands[1] = gen_lowpart (Pmode, operands[1]);
10586   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10587
10588   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10589   if (Pmode != SImode)
10590     pat = gen_rtx_SUBREG (SImode, pat, 0);
10591   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10592   DONE;
10593 })
10594
10595 ;; Rare case of shifting RSP is handled by generating move and shift
10596 (define_split
10597   [(set (match_operand 0 "register_operand" "")
10598         (ashift (match_operand 1 "register_operand" "")
10599                 (match_operand:QI 2 "const_int_operand" "")))
10600    (clobber (reg:CC FLAGS_REG))]
10601   "reload_completed
10602    && true_regnum (operands[0]) != true_regnum (operands[1])"
10603   [(const_int 0)]
10604 {
10605   rtx pat, clob;
10606   emit_move_insn (operands[0], operands[1]);
10607   pat = gen_rtx_SET (VOIDmode, operands[0],
10608                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10609                                      operands[0], operands[2]));
10610   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10611   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10612   DONE;
10613 })
10614
10615 (define_insn "*ashlsi3_1_zext"
10616   [(set (match_operand:DI 0 "register_operand" "=r,r")
10617         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10618                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10621 {
10622   switch (get_attr_type (insn))
10623     {
10624     case TYPE_ALU:
10625       gcc_assert (operands[2] == const1_rtx);
10626       return "add{l}\t{%k0, %k0|%k0, %k0}";
10627
10628     case TYPE_LEA:
10629       return "#";
10630
10631     default:
10632       if (REG_P (operands[2]))
10633         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10634       else if (operands[2] == const1_rtx
10635                && (TARGET_SHIFT1 || optimize_size))
10636         return "sal{l}\t%k0";
10637       else
10638         return "sal{l}\t{%2, %k0|%k0, %2}";
10639     }
10640 }
10641   [(set (attr "type")
10642      (cond [(eq_attr "alternative" "1")
10643               (const_string "lea")
10644             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10645                      (const_int 0))
10646                  (match_operand 2 "const1_operand" ""))
10647               (const_string "alu")
10648            ]
10649            (const_string "ishift")))
10650    (set_attr "mode" "SI")])
10651
10652 ;; Convert lea to the lea pattern to avoid flags dependency.
10653 (define_split
10654   [(set (match_operand:DI 0 "register_operand" "")
10655         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10656                                 (match_operand:QI 2 "const_int_operand" ""))))
10657    (clobber (reg:CC FLAGS_REG))]
10658   "TARGET_64BIT && reload_completed
10659    && true_regnum (operands[0]) != true_regnum (operands[1])"
10660   [(set (match_dup 0) (zero_extend:DI
10661                         (subreg:SI (mult:SI (match_dup 1)
10662                                             (match_dup 2)) 0)))]
10663 {
10664   operands[1] = gen_lowpart (Pmode, operands[1]);
10665   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10666 })
10667
10668 ;; This pattern can't accept a variable shift count, since shifts by
10669 ;; zero don't affect the flags.  We assume that shifts by constant
10670 ;; zero are optimized away.
10671 (define_insn "*ashlsi3_cmp"
10672   [(set (reg FLAGS_REG)
10673         (compare
10674           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10675                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10676           (const_int 0)))
10677    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10678         (ashift:SI (match_dup 1) (match_dup 2)))]
10679   "ix86_match_ccmode (insn, CCGOCmode)
10680    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10681 {
10682   switch (get_attr_type (insn))
10683     {
10684     case TYPE_ALU:
10685       gcc_assert (operands[2] == const1_rtx);
10686       return "add{l}\t{%0, %0|%0, %0}";
10687
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{l}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{l}\t%0";
10694       else
10695         return "sal{l}\t{%2, %0|%0, %2}";
10696     }
10697 }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "SI")])
10707
10708 (define_insn "*ashlsi3_cmp_zext"
10709   [(set (reg FLAGS_REG)
10710         (compare
10711           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10712                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10713           (const_int 0)))
10714    (set (match_operand:DI 0 "register_operand" "=r")
10715         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10717    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10718 {
10719   switch (get_attr_type (insn))
10720     {
10721     case TYPE_ALU:
10722       gcc_assert (operands[2] == const1_rtx);
10723       return "add{l}\t{%k0, %k0|%k0, %k0}";
10724
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{l}\t%k0";
10731       else
10732         return "sal{l}\t{%2, %k0|%k0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737                      (const_int 0))
10738                  (match_operand 2 "const1_operand" ""))
10739               (const_string "alu")
10740            ]
10741            (const_string "ishift")))
10742    (set_attr "mode" "SI")])
10743
10744 (define_expand "ashlhi3"
10745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10746         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10747                    (match_operand:QI 2 "nonmemory_operand" "")))
10748    (clobber (reg:CC FLAGS_REG))]
10749   "TARGET_HIMODE_MATH"
10750   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10751
10752 (define_insn "*ashlhi3_1_lea"
10753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10754         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10755                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10756    (clobber (reg:CC FLAGS_REG))]
10757   "!TARGET_PARTIAL_REG_STALL
10758    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10759 {
10760   switch (get_attr_type (insn))
10761     {
10762     case TYPE_LEA:
10763       return "#";
10764     case TYPE_ALU:
10765       gcc_assert (operands[2] == const1_rtx);
10766       return "add{w}\t{%0, %0|%0, %0}";
10767
10768     default:
10769       if (REG_P (operands[2]))
10770         return "sal{w}\t{%b2, %0|%0, %b2}";
10771       else if (operands[2] == const1_rtx
10772                && (TARGET_SHIFT1 || optimize_size))
10773         return "sal{w}\t%0";
10774       else
10775         return "sal{w}\t{%2, %0|%0, %2}";
10776     }
10777 }
10778   [(set (attr "type")
10779      (cond [(eq_attr "alternative" "1")
10780               (const_string "lea")
10781             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782                           (const_int 0))
10783                       (match_operand 0 "register_operand" ""))
10784                  (match_operand 2 "const1_operand" ""))
10785               (const_string "alu")
10786            ]
10787            (const_string "ishift")))
10788    (set_attr "mode" "HI,SI")])
10789
10790 (define_insn "*ashlhi3_1"
10791   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10793                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10794    (clobber (reg:CC FLAGS_REG))]
10795   "TARGET_PARTIAL_REG_STALL
10796    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797 {
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       gcc_assert (operands[2] == const1_rtx);
10802       return "add{w}\t{%0, %0|%0, %0}";
10803
10804     default:
10805       if (REG_P (operands[2]))
10806         return "sal{w}\t{%b2, %0|%0, %b2}";
10807       else if (operands[2] == const1_rtx
10808                && (TARGET_SHIFT1 || optimize_size))
10809         return "sal{w}\t%0";
10810       else
10811         return "sal{w}\t{%2, %0|%0, %2}";
10812     }
10813 }
10814   [(set (attr "type")
10815      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "HI")])
10823
10824 ;; This pattern can't accept a variable shift count, since shifts by
10825 ;; zero don't affect the flags.  We assume that shifts by constant
10826 ;; zero are optimized away.
10827 (define_insn "*ashlhi3_cmp"
10828   [(set (reg FLAGS_REG)
10829         (compare
10830           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10831                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10832           (const_int 0)))
10833    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10834         (ashift:HI (match_dup 1) (match_dup 2)))]
10835   "ix86_match_ccmode (insn, CCGOCmode)
10836    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10837 {
10838   switch (get_attr_type (insn))
10839     {
10840     case TYPE_ALU:
10841       gcc_assert (operands[2] == const1_rtx);
10842       return "add{w}\t{%0, %0|%0, %0}";
10843
10844     default:
10845       if (REG_P (operands[2]))
10846         return "sal{w}\t{%b2, %0|%0, %b2}";
10847       else if (operands[2] == const1_rtx
10848                && (TARGET_SHIFT1 || optimize_size))
10849         return "sal{w}\t%0";
10850       else
10851         return "sal{w}\t{%2, %0|%0, %2}";
10852     }
10853 }
10854   [(set (attr "type")
10855      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10856                           (const_int 0))
10857                       (match_operand 0 "register_operand" ""))
10858                  (match_operand 2 "const1_operand" ""))
10859               (const_string "alu")
10860            ]
10861            (const_string "ishift")))
10862    (set_attr "mode" "HI")])
10863
10864 (define_expand "ashlqi3"
10865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10866         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10867                    (match_operand:QI 2 "nonmemory_operand" "")))
10868    (clobber (reg:CC FLAGS_REG))]
10869   "TARGET_QIMODE_MATH"
10870   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10871
10872 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10873
10874 (define_insn "*ashlqi3_1_lea"
10875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10876         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10877                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10878    (clobber (reg:CC FLAGS_REG))]
10879   "!TARGET_PARTIAL_REG_STALL
10880    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10881 {
10882   switch (get_attr_type (insn))
10883     {
10884     case TYPE_LEA:
10885       return "#";
10886     case TYPE_ALU:
10887       gcc_assert (operands[2] == const1_rtx);
10888       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10889         return "add{l}\t{%k0, %k0|%k0, %k0}";
10890       else
10891         return "add{b}\t{%0, %0|%0, %0}";
10892
10893     default:
10894       if (REG_P (operands[2]))
10895         {
10896           if (get_attr_mode (insn) == MODE_SI)
10897             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10898           else
10899             return "sal{b}\t{%b2, %0|%0, %b2}";
10900         }
10901       else if (operands[2] == const1_rtx
10902                && (TARGET_SHIFT1 || optimize_size))
10903         {
10904           if (get_attr_mode (insn) == MODE_SI)
10905             return "sal{l}\t%0";
10906           else
10907             return "sal{b}\t%0";
10908         }
10909       else
10910         {
10911           if (get_attr_mode (insn) == MODE_SI)
10912             return "sal{l}\t{%2, %k0|%k0, %2}";
10913           else
10914             return "sal{b}\t{%2, %0|%0, %2}";
10915         }
10916     }
10917 }
10918   [(set (attr "type")
10919      (cond [(eq_attr "alternative" "2")
10920               (const_string "lea")
10921             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10922                           (const_int 0))
10923                       (match_operand 0 "register_operand" ""))
10924                  (match_operand 2 "const1_operand" ""))
10925               (const_string "alu")
10926            ]
10927            (const_string "ishift")))
10928    (set_attr "mode" "QI,SI,SI")])
10929
10930 (define_insn "*ashlqi3_1"
10931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10932         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10933                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_PARTIAL_REG_STALL
10936    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10937 {
10938   switch (get_attr_type (insn))
10939     {
10940     case TYPE_ALU:
10941       gcc_assert (operands[2] == const1_rtx);
10942       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10943         return "add{l}\t{%k0, %k0|%k0, %k0}";
10944       else
10945         return "add{b}\t{%0, %0|%0, %0}";
10946
10947     default:
10948       if (REG_P (operands[2]))
10949         {
10950           if (get_attr_mode (insn) == MODE_SI)
10951             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10952           else
10953             return "sal{b}\t{%b2, %0|%0, %b2}";
10954         }
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         {
10958           if (get_attr_mode (insn) == MODE_SI)
10959             return "sal{l}\t%0";
10960           else
10961             return "sal{b}\t%0";
10962         }
10963       else
10964         {
10965           if (get_attr_mode (insn) == MODE_SI)
10966             return "sal{l}\t{%2, %k0|%k0, %2}";
10967           else
10968             return "sal{b}\t{%2, %0|%0, %2}";
10969         }
10970     }
10971 }
10972   [(set (attr "type")
10973      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974                           (const_int 0))
10975                       (match_operand 0 "register_operand" ""))
10976                  (match_operand 2 "const1_operand" ""))
10977               (const_string "alu")
10978            ]
10979            (const_string "ishift")))
10980    (set_attr "mode" "QI,SI")])
10981
10982 ;; This pattern can't accept a variable shift count, since shifts by
10983 ;; zero don't affect the flags.  We assume that shifts by constant
10984 ;; zero are optimized away.
10985 (define_insn "*ashlqi3_cmp"
10986   [(set (reg FLAGS_REG)
10987         (compare
10988           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10989                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10990           (const_int 0)))
10991    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10992         (ashift:QI (match_dup 1) (match_dup 2)))]
10993   "ix86_match_ccmode (insn, CCGOCmode)
10994    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10995 {
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{b}\t{%0, %0|%0, %0}";
11001
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{b}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{b}\t%0";
11008       else
11009         return "sal{b}\t{%2, %0|%0, %2}";
11010     }
11011 }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "QI")])
11021
11022 ;; See comment above `ashldi3' about how this works.
11023
11024 (define_expand "ashrti3"
11025   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11026                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027                                 (match_operand:QI 2 "nonmemory_operand" "")))
11028               (clobber (reg:CC FLAGS_REG))])]
11029   "TARGET_64BIT"
11030 {
11031   if (! immediate_operand (operands[2], QImode))
11032     {
11033       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11034       DONE;
11035     }
11036   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11037   DONE;
11038 })
11039
11040 (define_insn "ashrti3_1"
11041   [(set (match_operand:TI 0 "register_operand" "=r")
11042         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11043                      (match_operand:QI 2 "register_operand" "c")))
11044    (clobber (match_scratch:DI 3 "=&r"))
11045    (clobber (reg:CC FLAGS_REG))]
11046   "TARGET_64BIT"
11047   "#"
11048   [(set_attr "type" "multi")])
11049
11050 (define_insn "*ashrti3_2"
11051   [(set (match_operand:TI 0 "register_operand" "=r")
11052         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11053                      (match_operand:QI 2 "immediate_operand" "O")))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "TARGET_64BIT"
11056   "#"
11057   [(set_attr "type" "multi")])
11058
11059 (define_split
11060   [(set (match_operand:TI 0 "register_operand" "")
11061         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11062                      (match_operand:QI 2 "register_operand" "")))
11063    (clobber (match_scratch:DI 3 ""))
11064    (clobber (reg:CC FLAGS_REG))]
11065   "TARGET_64BIT && reload_completed"
11066   [(const_int 0)]
11067   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11068
11069 (define_split
11070   [(set (match_operand:TI 0 "register_operand" "")
11071         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11072                      (match_operand:QI 2 "immediate_operand" "")))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "TARGET_64BIT && reload_completed"
11075   [(const_int 0)]
11076   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11077
11078 (define_insn "x86_64_shrd"
11079   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11080         (ior:DI (ashiftrt:DI (match_dup 0)
11081                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11082                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11083                   (minus:QI (const_int 64) (match_dup 2)))))
11084    (clobber (reg:CC FLAGS_REG))]
11085   "TARGET_64BIT"
11086   "@
11087    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11088    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11089   [(set_attr "type" "ishift")
11090    (set_attr "prefix_0f" "1")
11091    (set_attr "mode" "DI")
11092    (set_attr "athlon_decode" "vector")])
11093
11094 (define_expand "ashrdi3"
11095   [(set (match_operand:DI 0 "shiftdi_operand" "")
11096         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11097                      (match_operand:QI 2 "nonmemory_operand" "")))]
11098   ""
11099   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11100
11101 (define_insn "*ashrdi3_63_rex64"
11102   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11103         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11104                      (match_operand:DI 2 "const_int_operand" "i,i")))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "TARGET_64BIT && INTVAL (operands[2]) == 63
11107    && (TARGET_USE_CLTD || optimize_size)
11108    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11109   "@
11110    {cqto|cqo}
11111    sar{q}\t{%2, %0|%0, %2}"
11112   [(set_attr "type" "imovx,ishift")
11113    (set_attr "prefix_0f" "0,*")
11114    (set_attr "length_immediate" "0,*")
11115    (set_attr "modrm" "0,1")
11116    (set_attr "mode" "DI")])
11117
11118 (define_insn "*ashrdi3_1_one_bit_rex64"
11119   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11120         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11121                      (match_operand:QI 2 "const1_operand" "")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11124    && (TARGET_SHIFT1 || optimize_size)"
11125   "sar{q}\t%0"
11126   [(set_attr "type" "ishift")
11127    (set (attr "length") 
11128      (if_then_else (match_operand:DI 0 "register_operand" "") 
11129         (const_string "2")
11130         (const_string "*")))])
11131
11132 (define_insn "*ashrdi3_1_rex64"
11133   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11134         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11135                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138   "@
11139    sar{q}\t{%2, %0|%0, %2}
11140    sar{q}\t{%b2, %0|%0, %b2}"
11141   [(set_attr "type" "ishift")
11142    (set_attr "mode" "DI")])
11143
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags.  We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11148   [(set (reg FLAGS_REG)
11149         (compare
11150           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11151                        (match_operand:QI 2 "const1_operand" ""))
11152           (const_int 0)))
11153    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11154         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156    && (TARGET_SHIFT1 || optimize_size)
11157    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11158   "sar{q}\t%0"
11159   [(set_attr "type" "ishift")
11160    (set (attr "length") 
11161      (if_then_else (match_operand:DI 0 "register_operand" "") 
11162         (const_string "2")
11163         (const_string "*")))])
11164
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags.  We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashrdi3_cmp_rex64"
11169   [(set (reg FLAGS_REG)
11170         (compare
11171           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11172                        (match_operand:QI 2 "const_int_operand" "n"))
11173           (const_int 0)))
11174    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11175         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11176   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11177    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11178   "sar{q}\t{%2, %0|%0, %2}"
11179   [(set_attr "type" "ishift")
11180    (set_attr "mode" "DI")])
11181
11182 (define_insn "*ashrdi3_1"
11183   [(set (match_operand:DI 0 "register_operand" "=r")
11184         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11185                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11186    (clobber (reg:CC FLAGS_REG))]
11187   "!TARGET_64BIT"
11188   "#"
11189   [(set_attr "type" "multi")])
11190
11191 ;; By default we don't ask for a scratch register, because when DImode
11192 ;; values are manipulated, registers are already at a premium.  But if
11193 ;; we have one handy, we won't turn it away.
11194 (define_peephole2
11195   [(match_scratch:SI 3 "r")
11196    (parallel [(set (match_operand:DI 0 "register_operand" "")
11197                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11198                                 (match_operand:QI 2 "nonmemory_operand" "")))
11199               (clobber (reg:CC FLAGS_REG))])
11200    (match_dup 3)]
11201   "!TARGET_64BIT && TARGET_CMOVE"
11202   [(const_int 0)]
11203   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11204
11205 (define_split
11206   [(set (match_operand:DI 0 "register_operand" "")
11207         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11208                      (match_operand:QI 2 "nonmemory_operand" "")))
11209    (clobber (reg:CC FLAGS_REG))]
11210   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11211                      ? flow2_completed : reload_completed)"
11212   [(const_int 0)]
11213   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11214
11215 (define_insn "x86_shrd_1"
11216   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11217         (ior:SI (ashiftrt:SI (match_dup 0)
11218                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11219                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11220                   (minus:QI (const_int 32) (match_dup 2)))))
11221    (clobber (reg:CC FLAGS_REG))]
11222   ""
11223   "@
11224    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11225    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11226   [(set_attr "type" "ishift")
11227    (set_attr "prefix_0f" "1")
11228    (set_attr "pent_pair" "np")
11229    (set_attr "mode" "SI")])
11230
11231 (define_expand "x86_shift_adj_3"
11232   [(use (match_operand:SI 0 "register_operand" ""))
11233    (use (match_operand:SI 1 "register_operand" ""))
11234    (use (match_operand:QI 2 "register_operand" ""))]
11235   ""
11236 {
11237   rtx label = gen_label_rtx ();
11238   rtx tmp;
11239
11240   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11241
11242   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11243   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11244   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11245                               gen_rtx_LABEL_REF (VOIDmode, label),
11246                               pc_rtx);
11247   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11248   JUMP_LABEL (tmp) = label;
11249
11250   emit_move_insn (operands[0], operands[1]);
11251   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11252
11253   emit_label (label);
11254   LABEL_NUSES (label) = 1;
11255
11256   DONE;
11257 })
11258
11259 (define_insn "ashrsi3_31"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11262                      (match_operand:SI 2 "const_int_operand" "i,i")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11265    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11266   "@
11267    {cltd|cdq}
11268    sar{l}\t{%2, %0|%0, %2}"
11269   [(set_attr "type" "imovx,ishift")
11270    (set_attr "prefix_0f" "0,*")
11271    (set_attr "length_immediate" "0,*")
11272    (set_attr "modrm" "0,1")
11273    (set_attr "mode" "SI")])
11274
11275 (define_insn "*ashrsi3_31_zext"
11276   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11277         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11278                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11281    && INTVAL (operands[2]) == 31
11282    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11283   "@
11284    {cltd|cdq}
11285    sar{l}\t{%2, %k0|%k0, %2}"
11286   [(set_attr "type" "imovx,ishift")
11287    (set_attr "prefix_0f" "0,*")
11288    (set_attr "length_immediate" "0,*")
11289    (set_attr "modrm" "0,1")
11290    (set_attr "mode" "SI")])
11291
11292 (define_expand "ashrsi3"
11293   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11294         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11295                      (match_operand:QI 2 "nonmemory_operand" "")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   ""
11298   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11299
11300 (define_insn "*ashrsi3_1_one_bit"
11301   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11302         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11303                      (match_operand:QI 2 "const1_operand" "")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11306    && (TARGET_SHIFT1 || optimize_size)"
11307   "sar{l}\t%0"
11308   [(set_attr "type" "ishift")
11309    (set (attr "length") 
11310      (if_then_else (match_operand:SI 0 "register_operand" "") 
11311         (const_string "2")
11312         (const_string "*")))])
11313
11314 (define_insn "*ashrsi3_1_one_bit_zext"
11315   [(set (match_operand:DI 0 "register_operand" "=r")
11316         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11317                                      (match_operand:QI 2 "const1_operand" ""))))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11320    && (TARGET_SHIFT1 || optimize_size)"
11321   "sar{l}\t%k0"
11322   [(set_attr "type" "ishift")
11323    (set_attr "length" "2")])
11324
11325 (define_insn "*ashrsi3_1"
11326   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11327         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11328                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11329    (clobber (reg:CC FLAGS_REG))]
11330   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11331   "@
11332    sar{l}\t{%2, %0|%0, %2}
11333    sar{l}\t{%b2, %0|%0, %b2}"
11334   [(set_attr "type" "ishift")
11335    (set_attr "mode" "SI")])
11336
11337 (define_insn "*ashrsi3_1_zext"
11338   [(set (match_operand:DI 0 "register_operand" "=r,r")
11339         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11340                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11341    (clobber (reg:CC FLAGS_REG))]
11342   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11343   "@
11344    sar{l}\t{%2, %k0|%k0, %2}
11345    sar{l}\t{%b2, %k0|%k0, %b2}"
11346   [(set_attr "type" "ishift")
11347    (set_attr "mode" "SI")])
11348
11349 ;; This pattern can't accept a variable shift count, since shifts by
11350 ;; zero don't affect the flags.  We assume that shifts by constant
11351 ;; zero are optimized away.
11352 (define_insn "*ashrsi3_one_bit_cmp"
11353   [(set (reg FLAGS_REG)
11354         (compare
11355           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11356                        (match_operand:QI 2 "const1_operand" ""))
11357           (const_int 0)))
11358    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11359         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11360   "ix86_match_ccmode (insn, CCGOCmode)
11361    && (TARGET_SHIFT1 || optimize_size)
11362    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363   "sar{l}\t%0"
11364   [(set_attr "type" "ishift")
11365    (set (attr "length") 
11366      (if_then_else (match_operand:SI 0 "register_operand" "") 
11367         (const_string "2")
11368         (const_string "*")))])
11369
11370 (define_insn "*ashrsi3_one_bit_cmp_zext"
11371   [(set (reg FLAGS_REG)
11372         (compare
11373           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11374                        (match_operand:QI 2 "const1_operand" ""))
11375           (const_int 0)))
11376    (set (match_operand:DI 0 "register_operand" "=r")
11377         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11378   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11379    && (TARGET_SHIFT1 || optimize_size)
11380    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11381   "sar{l}\t%k0"
11382   [(set_attr "type" "ishift")
11383    (set_attr "length" "2")])
11384
11385 ;; This pattern can't accept a variable shift count, since shifts by
11386 ;; zero don't affect the flags.  We assume that shifts by constant
11387 ;; zero are optimized away.
11388 (define_insn "*ashrsi3_cmp"
11389   [(set (reg FLAGS_REG)
11390         (compare
11391           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11393           (const_int 0)))
11394    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11395         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11396   "ix86_match_ccmode (insn, CCGOCmode)
11397    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11398   "sar{l}\t{%2, %0|%0, %2}"
11399   [(set_attr "type" "ishift")
11400    (set_attr "mode" "SI")])
11401
11402 (define_insn "*ashrsi3_cmp_zext"
11403   [(set (reg FLAGS_REG)
11404         (compare
11405           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11406                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11407           (const_int 0)))
11408    (set (match_operand:DI 0 "register_operand" "=r")
11409         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11410   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11411    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412   "sar{l}\t{%2, %k0|%k0, %2}"
11413   [(set_attr "type" "ishift")
11414    (set_attr "mode" "SI")])
11415
11416 (define_expand "ashrhi3"
11417   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419                      (match_operand:QI 2 "nonmemory_operand" "")))
11420    (clobber (reg:CC FLAGS_REG))]
11421   "TARGET_HIMODE_MATH"
11422   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11423
11424 (define_insn "*ashrhi3_1_one_bit"
11425   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11426         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11427                      (match_operand:QI 2 "const1_operand" "")))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11430    && (TARGET_SHIFT1 || optimize_size)"
11431   "sar{w}\t%0"
11432   [(set_attr "type" "ishift")
11433    (set (attr "length") 
11434      (if_then_else (match_operand 0 "register_operand" "") 
11435         (const_string "2")
11436         (const_string "*")))])
11437
11438 (define_insn "*ashrhi3_1"
11439   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11440         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11441                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11442    (clobber (reg:CC FLAGS_REG))]
11443   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11444   "@
11445    sar{w}\t{%2, %0|%0, %2}
11446    sar{w}\t{%b2, %0|%0, %b2}"
11447   [(set_attr "type" "ishift")
11448    (set_attr "mode" "HI")])
11449
11450 ;; This pattern can't accept a variable shift count, since shifts by
11451 ;; zero don't affect the flags.  We assume that shifts by constant
11452 ;; zero are optimized away.
11453 (define_insn "*ashrhi3_one_bit_cmp"
11454   [(set (reg FLAGS_REG)
11455         (compare
11456           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11457                        (match_operand:QI 2 "const1_operand" ""))
11458           (const_int 0)))
11459    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11460         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11461   "ix86_match_ccmode (insn, CCGOCmode)
11462    && (TARGET_SHIFT1 || optimize_size)
11463    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11464   "sar{w}\t%0"
11465   [(set_attr "type" "ishift")
11466    (set (attr "length") 
11467      (if_then_else (match_operand 0 "register_operand" "") 
11468         (const_string "2")
11469         (const_string "*")))])
11470
11471 ;; This pattern can't accept a variable shift count, since shifts by
11472 ;; zero don't affect the flags.  We assume that shifts by constant
11473 ;; zero are optimized away.
11474 (define_insn "*ashrhi3_cmp"
11475   [(set (reg FLAGS_REG)
11476         (compare
11477           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11478                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11479           (const_int 0)))
11480    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11481         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11482   "ix86_match_ccmode (insn, CCGOCmode)
11483    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11484   "sar{w}\t{%2, %0|%0, %2}"
11485   [(set_attr "type" "ishift")
11486    (set_attr "mode" "HI")])
11487
11488 (define_expand "ashrqi3"
11489   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11490         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11491                      (match_operand:QI 2 "nonmemory_operand" "")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "TARGET_QIMODE_MATH"
11494   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11495
11496 (define_insn "*ashrqi3_1_one_bit"
11497   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11498         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11499                      (match_operand:QI 2 "const1_operand" "")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11502    && (TARGET_SHIFT1 || optimize_size)"
11503   "sar{b}\t%0"
11504   [(set_attr "type" "ishift")
11505    (set (attr "length") 
11506      (if_then_else (match_operand 0 "register_operand" "") 
11507         (const_string "2")
11508         (const_string "*")))])
11509
11510 (define_insn "*ashrqi3_1_one_bit_slp"
11511   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11512         (ashiftrt:QI (match_dup 0)
11513                      (match_operand:QI 1 "const1_operand" "")))
11514    (clobber (reg:CC FLAGS_REG))]
11515   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11516    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11517    && (TARGET_SHIFT1 || optimize_size)"
11518   "sar{b}\t%0"
11519   [(set_attr "type" "ishift1")
11520    (set (attr "length") 
11521      (if_then_else (match_operand 0 "register_operand" "") 
11522         (const_string "2")
11523         (const_string "*")))])
11524
11525 (define_insn "*ashrqi3_1"
11526   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11527         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11528                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11531   "@
11532    sar{b}\t{%2, %0|%0, %2}
11533    sar{b}\t{%b2, %0|%0, %b2}"
11534   [(set_attr "type" "ishift")
11535    (set_attr "mode" "QI")])
11536
11537 (define_insn "*ashrqi3_1_slp"
11538   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11539         (ashiftrt:QI (match_dup 0)
11540                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11541    (clobber (reg:CC FLAGS_REG))]
11542   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11543    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11544   "@
11545    sar{b}\t{%1, %0|%0, %1}
11546    sar{b}\t{%b1, %0|%0, %b1}"
11547   [(set_attr "type" "ishift1")
11548    (set_attr "mode" "QI")])
11549
11550 ;; This pattern can't accept a variable shift count, since shifts by
11551 ;; zero don't affect the flags.  We assume that shifts by constant
11552 ;; zero are optimized away.
11553 (define_insn "*ashrqi3_one_bit_cmp"
11554   [(set (reg FLAGS_REG)
11555         (compare
11556           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11557                        (match_operand:QI 2 "const1_operand" "I"))
11558           (const_int 0)))
11559    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11560         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11561   "ix86_match_ccmode (insn, CCGOCmode)
11562    && (TARGET_SHIFT1 || optimize_size)
11563    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11564   "sar{b}\t%0"
11565   [(set_attr "type" "ishift")
11566    (set (attr "length") 
11567      (if_then_else (match_operand 0 "register_operand" "") 
11568         (const_string "2")
11569         (const_string "*")))])
11570
11571 ;; This pattern can't accept a variable shift count, since shifts by
11572 ;; zero don't affect the flags.  We assume that shifts by constant
11573 ;; zero are optimized away.
11574 (define_insn "*ashrqi3_cmp"
11575   [(set (reg FLAGS_REG)
11576         (compare
11577           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11578                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11579           (const_int 0)))
11580    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11581         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11582   "ix86_match_ccmode (insn, CCGOCmode)
11583    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11584   "sar{b}\t{%2, %0|%0, %2}"
11585   [(set_attr "type" "ishift")
11586    (set_attr "mode" "QI")])
11587 \f
11588 ;; Logical shift instructions
11589
11590 ;; See comment above `ashldi3' about how this works.
11591
11592 (define_expand "lshrti3"
11593   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11594                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595                                 (match_operand:QI 2 "nonmemory_operand" "")))
11596               (clobber (reg:CC FLAGS_REG))])]
11597   "TARGET_64BIT"
11598 {
11599   if (! immediate_operand (operands[2], QImode))
11600     {
11601       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11602       DONE;
11603     }
11604   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11605   DONE;
11606 })
11607
11608 (define_insn "lshrti3_1"
11609   [(set (match_operand:TI 0 "register_operand" "=r")
11610         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11611                      (match_operand:QI 2 "register_operand" "c")))
11612    (clobber (match_scratch:DI 3 "=&r"))
11613    (clobber (reg:CC FLAGS_REG))]
11614   "TARGET_64BIT"
11615   "#"
11616   [(set_attr "type" "multi")])
11617
11618 (define_insn "*lshrti3_2"
11619   [(set (match_operand:TI 0 "register_operand" "=r")
11620         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11621                      (match_operand:QI 2 "immediate_operand" "O")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "TARGET_64BIT"
11624   "#"
11625   [(set_attr "type" "multi")])
11626
11627 (define_split 
11628   [(set (match_operand:TI 0 "register_operand" "")
11629         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11630                      (match_operand:QI 2 "register_operand" "")))
11631    (clobber (match_scratch:DI 3 ""))
11632    (clobber (reg:CC FLAGS_REG))]
11633   "TARGET_64BIT && reload_completed"
11634   [(const_int 0)]
11635   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11636
11637 (define_split 
11638   [(set (match_operand:TI 0 "register_operand" "")
11639         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11640                      (match_operand:QI 2 "immediate_operand" "")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "TARGET_64BIT && reload_completed"
11643   [(const_int 0)]
11644   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11645
11646 (define_expand "lshrdi3"
11647   [(set (match_operand:DI 0 "shiftdi_operand" "")
11648         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11649                      (match_operand:QI 2 "nonmemory_operand" "")))]
11650   ""
11651   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11652
11653 (define_insn "*lshrdi3_1_one_bit_rex64"
11654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11655         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11656                      (match_operand:QI 2 "const1_operand" "")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11659    && (TARGET_SHIFT1 || optimize_size)"
11660   "shr{q}\t%0"
11661   [(set_attr "type" "ishift")
11662    (set (attr "length") 
11663      (if_then_else (match_operand:DI 0 "register_operand" "") 
11664         (const_string "2")
11665         (const_string "*")))])
11666
11667 (define_insn "*lshrdi3_1_rex64"
11668   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11669         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11670                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11671    (clobber (reg:CC FLAGS_REG))]
11672   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11673   "@
11674    shr{q}\t{%2, %0|%0, %2}
11675    shr{q}\t{%b2, %0|%0, %b2}"
11676   [(set_attr "type" "ishift")
11677    (set_attr "mode" "DI")])
11678
11679 ;; This pattern can't accept a variable shift count, since shifts by
11680 ;; zero don't affect the flags.  We assume that shifts by constant
11681 ;; zero are optimized away.
11682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11683   [(set (reg FLAGS_REG)
11684         (compare
11685           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11686                        (match_operand:QI 2 "const1_operand" ""))
11687           (const_int 0)))
11688    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11690   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11691    && (TARGET_SHIFT1 || optimize_size)
11692    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11693   "shr{q}\t%0"
11694   [(set_attr "type" "ishift")
11695    (set (attr "length") 
11696      (if_then_else (match_operand:DI 0 "register_operand" "") 
11697         (const_string "2")
11698         (const_string "*")))])
11699
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags.  We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*lshrdi3_cmp_rex64"
11704   [(set (reg FLAGS_REG)
11705         (compare
11706           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707                        (match_operand:QI 2 "const_int_operand" "e"))
11708           (const_int 0)))
11709    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11710         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11711   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11712    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11713   "shr{q}\t{%2, %0|%0, %2}"
11714   [(set_attr "type" "ishift")
11715    (set_attr "mode" "DI")])
11716
11717 (define_insn "*lshrdi3_1"
11718   [(set (match_operand:DI 0 "register_operand" "=r")
11719         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11720                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "!TARGET_64BIT"
11723   "#"
11724   [(set_attr "type" "multi")])
11725
11726 ;; By default we don't ask for a scratch register, because when DImode
11727 ;; values are manipulated, registers are already at a premium.  But if
11728 ;; we have one handy, we won't turn it away.
11729 (define_peephole2
11730   [(match_scratch:SI 3 "r")
11731    (parallel [(set (match_operand:DI 0 "register_operand" "")
11732                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11733                                 (match_operand:QI 2 "nonmemory_operand" "")))
11734               (clobber (reg:CC FLAGS_REG))])
11735    (match_dup 3)]
11736   "!TARGET_64BIT && TARGET_CMOVE"
11737   [(const_int 0)]
11738   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11739
11740 (define_split 
11741   [(set (match_operand:DI 0 "register_operand" "")
11742         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11743                      (match_operand:QI 2 "nonmemory_operand" "")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11746                      ? flow2_completed : reload_completed)"
11747   [(const_int 0)]
11748   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11749
11750 (define_expand "lshrsi3"
11751   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753                      (match_operand:QI 2 "nonmemory_operand" "")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   ""
11756   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11757
11758 (define_insn "*lshrsi3_1_one_bit"
11759   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761                      (match_operand:QI 2 "const1_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764    && (TARGET_SHIFT1 || optimize_size)"
11765   "shr{l}\t%0"
11766   [(set_attr "type" "ishift")
11767    (set (attr "length") 
11768      (if_then_else (match_operand:SI 0 "register_operand" "") 
11769         (const_string "2")
11770         (const_string "*")))])
11771
11772 (define_insn "*lshrsi3_1_one_bit_zext"
11773   [(set (match_operand:DI 0 "register_operand" "=r")
11774         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775                      (match_operand:QI 2 "const1_operand" "")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778    && (TARGET_SHIFT1 || optimize_size)"
11779   "shr{l}\t%k0"
11780   [(set_attr "type" "ishift")
11781    (set_attr "length" "2")])
11782
11783 (define_insn "*lshrsi3_1"
11784   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787    (clobber (reg:CC FLAGS_REG))]
11788   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11789   "@
11790    shr{l}\t{%2, %0|%0, %2}
11791    shr{l}\t{%b2, %0|%0, %b2}"
11792   [(set_attr "type" "ishift")
11793    (set_attr "mode" "SI")])
11794
11795 (define_insn "*lshrsi3_1_zext"
11796   [(set (match_operand:DI 0 "register_operand" "=r,r")
11797         (zero_extend:DI
11798           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800    (clobber (reg:CC FLAGS_REG))]
11801   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802   "@
11803    shr{l}\t{%2, %k0|%k0, %2}
11804    shr{l}\t{%b2, %k0|%k0, %b2}"
11805   [(set_attr "type" "ishift")
11806    (set_attr "mode" "SI")])
11807
11808 ;; This pattern can't accept a variable shift count, since shifts by
11809 ;; zero don't affect the flags.  We assume that shifts by constant
11810 ;; zero are optimized away.
11811 (define_insn "*lshrsi3_one_bit_cmp"
11812   [(set (reg FLAGS_REG)
11813         (compare
11814           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815                        (match_operand:QI 2 "const1_operand" ""))
11816           (const_int 0)))
11817    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11819   "ix86_match_ccmode (insn, CCGOCmode)
11820    && (TARGET_SHIFT1 || optimize_size)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t%0"
11823   [(set_attr "type" "ishift")
11824    (set (attr "length") 
11825      (if_then_else (match_operand:SI 0 "register_operand" "") 
11826         (const_string "2")
11827         (const_string "*")))])
11828
11829 (define_insn "*lshrsi3_cmp_one_bit_zext"
11830   [(set (reg FLAGS_REG)
11831         (compare
11832           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833                        (match_operand:QI 2 "const1_operand" ""))
11834           (const_int 0)))
11835    (set (match_operand:DI 0 "register_operand" "=r")
11836         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838    && (TARGET_SHIFT1 || optimize_size)
11839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840   "shr{l}\t%k0"
11841   [(set_attr "type" "ishift")
11842    (set_attr "length" "2")])
11843
11844 ;; This pattern can't accept a variable shift count, since shifts by
11845 ;; zero don't affect the flags.  We assume that shifts by constant
11846 ;; zero are optimized away.
11847 (define_insn "*lshrsi3_cmp"
11848   [(set (reg FLAGS_REG)
11849         (compare
11850           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11852           (const_int 0)))
11853    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11854         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11855   "ix86_match_ccmode (insn, CCGOCmode)
11856    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857   "shr{l}\t{%2, %0|%0, %2}"
11858   [(set_attr "type" "ishift")
11859    (set_attr "mode" "SI")])
11860
11861 (define_insn "*lshrsi3_cmp_zext"
11862   [(set (reg FLAGS_REG)
11863         (compare
11864           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866           (const_int 0)))
11867    (set (match_operand:DI 0 "register_operand" "=r")
11868         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "shr{l}\t{%2, %k0|%k0, %2}"
11872   [(set_attr "type" "ishift")
11873    (set_attr "mode" "SI")])
11874
11875 (define_expand "lshrhi3"
11876   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878                      (match_operand:QI 2 "nonmemory_operand" "")))
11879    (clobber (reg:CC FLAGS_REG))]
11880   "TARGET_HIMODE_MATH"
11881   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11882
11883 (define_insn "*lshrhi3_1_one_bit"
11884   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886                      (match_operand:QI 2 "const1_operand" "")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889    && (TARGET_SHIFT1 || optimize_size)"
11890   "shr{w}\t%0"
11891   [(set_attr "type" "ishift")
11892    (set (attr "length") 
11893      (if_then_else (match_operand 0 "register_operand" "") 
11894         (const_string "2")
11895         (const_string "*")))])
11896
11897 (define_insn "*lshrhi3_1"
11898   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11903   "@
11904    shr{w}\t{%2, %0|%0, %2}
11905    shr{w}\t{%b2, %0|%0, %b2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11908
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags.  We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*lshrhi3_one_bit_cmp"
11913   [(set (reg FLAGS_REG)
11914         (compare
11915           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916                        (match_operand:QI 2 "const1_operand" ""))
11917           (const_int 0)))
11918    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11920   "ix86_match_ccmode (insn, CCGOCmode)
11921    && (TARGET_SHIFT1 || optimize_size)
11922    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11923   "shr{w}\t%0"
11924   [(set_attr "type" "ishift")
11925    (set (attr "length") 
11926      (if_then_else (match_operand:SI 0 "register_operand" "") 
11927         (const_string "2")
11928         (const_string "*")))])
11929
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags.  We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*lshrhi3_cmp"
11934   [(set (reg FLAGS_REG)
11935         (compare
11936           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11938           (const_int 0)))
11939    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11940         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11941   "ix86_match_ccmode (insn, CCGOCmode)
11942    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11943   "shr{w}\t{%2, %0|%0, %2}"
11944   [(set_attr "type" "ishift")
11945    (set_attr "mode" "HI")])
11946
11947 (define_expand "lshrqi3"
11948   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950                      (match_operand:QI 2 "nonmemory_operand" "")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "TARGET_QIMODE_MATH"
11953   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11954
11955 (define_insn "*lshrqi3_1_one_bit"
11956   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958                      (match_operand:QI 2 "const1_operand" "")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961    && (TARGET_SHIFT1 || optimize_size)"
11962   "shr{b}\t%0"
11963   [(set_attr "type" "ishift")
11964    (set (attr "length") 
11965      (if_then_else (match_operand 0 "register_operand" "") 
11966         (const_string "2")
11967         (const_string "*")))])
11968
11969 (define_insn "*lshrqi3_1_one_bit_slp"
11970   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11971         (lshiftrt:QI (match_dup 0)
11972                      (match_operand:QI 1 "const1_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11975    && (TARGET_SHIFT1 || optimize_size)"
11976   "shr{b}\t%0"
11977   [(set_attr "type" "ishift1")
11978    (set (attr "length") 
11979      (if_then_else (match_operand 0 "register_operand" "") 
11980         (const_string "2")
11981         (const_string "*")))])
11982
11983 (define_insn "*lshrqi3_1"
11984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11985         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11989   "@
11990    shr{b}\t{%2, %0|%0, %2}
11991    shr{b}\t{%b2, %0|%0, %b2}"
11992   [(set_attr "type" "ishift")
11993    (set_attr "mode" "QI")])
11994
11995 (define_insn "*lshrqi3_1_slp"
11996   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11997         (lshiftrt:QI (match_dup 0)
11998                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11999    (clobber (reg:CC FLAGS_REG))]
12000   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12002   "@
12003    shr{b}\t{%1, %0|%0, %1}
12004    shr{b}\t{%b1, %0|%0, %b1}"
12005   [(set_attr "type" "ishift1")
12006    (set_attr "mode" "QI")])
12007
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags.  We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*lshrqi2_one_bit_cmp"
12012   [(set (reg FLAGS_REG)
12013         (compare
12014           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015                        (match_operand:QI 2 "const1_operand" ""))
12016           (const_int 0)))
12017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12019   "ix86_match_ccmode (insn, CCGOCmode)
12020    && (TARGET_SHIFT1 || optimize_size)
12021    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12022   "shr{b}\t%0"
12023   [(set_attr "type" "ishift")
12024    (set (attr "length") 
12025      (if_then_else (match_operand:SI 0 "register_operand" "") 
12026         (const_string "2")
12027         (const_string "*")))])
12028
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags.  We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*lshrqi2_cmp"
12033   [(set (reg FLAGS_REG)
12034         (compare
12035           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12036                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037           (const_int 0)))
12038    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12039         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12040   "ix86_match_ccmode (insn, CCGOCmode)
12041    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12042   "shr{b}\t{%2, %0|%0, %2}"
12043   [(set_attr "type" "ishift")
12044    (set_attr "mode" "QI")])
12045 \f
12046 ;; Rotate instructions
12047
12048 (define_expand "rotldi3"
12049   [(set (match_operand:DI 0 "shiftdi_operand" "")
12050         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12051                    (match_operand:QI 2 "nonmemory_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053  ""
12054 {
12055   if (TARGET_64BIT)
12056     {
12057       ix86_expand_binary_operator (ROTATE, DImode, operands);
12058       DONE;
12059     }
12060   if (!const_1_to_31_operand (operands[2], VOIDmode))
12061     FAIL;
12062   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12063   DONE;
12064 })
12065
12066 ;; Implement rotation using two double-precision shift instructions
12067 ;; and a scratch register.   
12068 (define_insn_and_split "ix86_rotldi3"
12069  [(set (match_operand:DI 0 "register_operand" "=r")
12070        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12071                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12072   (clobber (reg:CC FLAGS_REG))
12073   (clobber (match_scratch:SI 3 "=&r"))]
12074  "!TARGET_64BIT"
12075  "" 
12076  "&& reload_completed"
12077  [(set (match_dup 3) (match_dup 4))
12078   (parallel
12079    [(set (match_dup 4)
12080          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12081                  (lshiftrt:SI (match_dup 5)
12082                               (minus:QI (const_int 32) (match_dup 2)))))
12083     (clobber (reg:CC FLAGS_REG))])
12084   (parallel
12085    [(set (match_dup 5)
12086          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12087                  (lshiftrt:SI (match_dup 3)
12088                               (minus:QI (const_int 32) (match_dup 2)))))
12089     (clobber (reg:CC FLAGS_REG))])]
12090  "split_di (operands, 1, operands + 4, operands + 5);")
12091  
12092 (define_insn "*rotlsi3_1_one_bit_rex64"
12093   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12095                    (match_operand:QI 2 "const1_operand" "")))
12096    (clobber (reg:CC FLAGS_REG))]
12097   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12098    && (TARGET_SHIFT1 || optimize_size)"
12099   "rol{q}\t%0"
12100   [(set_attr "type" "rotate")
12101    (set (attr "length") 
12102      (if_then_else (match_operand:DI 0 "register_operand" "") 
12103         (const_string "2")
12104         (const_string "*")))])
12105
12106 (define_insn "*rotldi3_1_rex64"
12107   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12108         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12109                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12112   "@
12113    rol{q}\t{%2, %0|%0, %2}
12114    rol{q}\t{%b2, %0|%0, %b2}"
12115   [(set_attr "type" "rotate")
12116    (set_attr "mode" "DI")])
12117
12118 (define_expand "rotlsi3"
12119   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12120         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12121                    (match_operand:QI 2 "nonmemory_operand" "")))
12122    (clobber (reg:CC FLAGS_REG))]
12123   ""
12124   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12125
12126 (define_insn "*rotlsi3_1_one_bit"
12127   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12128         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12129                    (match_operand:QI 2 "const1_operand" "")))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12132    && (TARGET_SHIFT1 || optimize_size)"
12133   "rol{l}\t%0"
12134   [(set_attr "type" "rotate")
12135    (set (attr "length") 
12136      (if_then_else (match_operand:SI 0 "register_operand" "") 
12137         (const_string "2")
12138         (const_string "*")))])
12139
12140 (define_insn "*rotlsi3_1_one_bit_zext"
12141   [(set (match_operand:DI 0 "register_operand" "=r")
12142         (zero_extend:DI
12143           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12144                      (match_operand:QI 2 "const1_operand" ""))))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12147    && (TARGET_SHIFT1 || optimize_size)"
12148   "rol{l}\t%k0"
12149   [(set_attr "type" "rotate")
12150    (set_attr "length" "2")])
12151
12152 (define_insn "*rotlsi3_1"
12153   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12154         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12155                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12158   "@
12159    rol{l}\t{%2, %0|%0, %2}
12160    rol{l}\t{%b2, %0|%0, %b2}"
12161   [(set_attr "type" "rotate")
12162    (set_attr "mode" "SI")])
12163
12164 (define_insn "*rotlsi3_1_zext"
12165   [(set (match_operand:DI 0 "register_operand" "=r,r")
12166         (zero_extend:DI
12167           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12168                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12171   "@
12172    rol{l}\t{%2, %k0|%k0, %2}
12173    rol{l}\t{%b2, %k0|%k0, %b2}"
12174   [(set_attr "type" "rotate")
12175    (set_attr "mode" "SI")])
12176
12177 (define_expand "rotlhi3"
12178   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12179         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12180                    (match_operand:QI 2 "nonmemory_operand" "")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "TARGET_HIMODE_MATH"
12183   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12184
12185 (define_insn "*rotlhi3_1_one_bit"
12186   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12187         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12188                    (match_operand:QI 2 "const1_operand" "")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12191    && (TARGET_SHIFT1 || optimize_size)"
12192   "rol{w}\t%0"
12193   [(set_attr "type" "rotate")
12194    (set (attr "length") 
12195      (if_then_else (match_operand 0 "register_operand" "") 
12196         (const_string "2")
12197         (const_string "*")))])
12198
12199 (define_insn "*rotlhi3_1"
12200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12201         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12202                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12205   "@
12206    rol{w}\t{%2, %0|%0, %2}
12207    rol{w}\t{%b2, %0|%0, %b2}"
12208   [(set_attr "type" "rotate")
12209    (set_attr "mode" "HI")])
12210
12211 (define_expand "rotlqi3"
12212   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12213         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12214                    (match_operand:QI 2 "nonmemory_operand" "")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_QIMODE_MATH"
12217   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12218
12219 (define_insn "*rotlqi3_1_one_bit_slp"
12220   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221         (rotate:QI (match_dup 0)
12222                    (match_operand:QI 1 "const1_operand" "")))
12223    (clobber (reg:CC FLAGS_REG))]
12224   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225    && (TARGET_SHIFT1 || optimize_size)"
12226   "rol{b}\t%0"
12227   [(set_attr "type" "rotate1")
12228    (set (attr "length") 
12229      (if_then_else (match_operand 0 "register_operand" "") 
12230         (const_string "2")
12231         (const_string "*")))])
12232
12233 (define_insn "*rotlqi3_1_one_bit"
12234   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236                    (match_operand:QI 2 "const1_operand" "")))
12237    (clobber (reg:CC FLAGS_REG))]
12238   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12239    && (TARGET_SHIFT1 || optimize_size)"
12240   "rol{b}\t%0"
12241   [(set_attr "type" "rotate")
12242    (set (attr "length") 
12243      (if_then_else (match_operand 0 "register_operand" "") 
12244         (const_string "2")
12245         (const_string "*")))])
12246
12247 (define_insn "*rotlqi3_1_slp"
12248   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12249         (rotate:QI (match_dup 0)
12250                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12251    (clobber (reg:CC FLAGS_REG))]
12252   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12253    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12254   "@
12255    rol{b}\t{%1, %0|%0, %1}
12256    rol{b}\t{%b1, %0|%0, %b1}"
12257   [(set_attr "type" "rotate1")
12258    (set_attr "mode" "QI")])
12259
12260 (define_insn "*rotlqi3_1"
12261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12262         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12263                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264    (clobber (reg:CC FLAGS_REG))]
12265   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12266   "@
12267    rol{b}\t{%2, %0|%0, %2}
12268    rol{b}\t{%b2, %0|%0, %b2}"
12269   [(set_attr "type" "rotate")
12270    (set_attr "mode" "QI")])
12271
12272 (define_expand "rotrdi3"
12273   [(set (match_operand:DI 0 "shiftdi_operand" "")
12274         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12275                    (match_operand:QI 2 "nonmemory_operand" "")))
12276    (clobber (reg:CC FLAGS_REG))]
12277  ""
12278 {
12279   if (TARGET_64BIT)
12280     {
12281       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12282       DONE;
12283     }
12284   if (!const_1_to_31_operand (operands[2], VOIDmode))
12285     FAIL;
12286   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12287   DONE;
12288 })
12289   
12290 ;; Implement rotation using two double-precision shift instructions
12291 ;; and a scratch register.   
12292 (define_insn_and_split "ix86_rotrdi3"
12293  [(set (match_operand:DI 0 "register_operand" "=r")
12294        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12295                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12296   (clobber (reg:CC FLAGS_REG))
12297   (clobber (match_scratch:SI 3 "=&r"))]
12298  "!TARGET_64BIT"
12299  ""
12300  "&& reload_completed"
12301  [(set (match_dup 3) (match_dup 4))
12302   (parallel
12303    [(set (match_dup 4)
12304          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12305                  (ashift:SI (match_dup 5)
12306                             (minus:QI (const_int 32) (match_dup 2)))))
12307     (clobber (reg:CC FLAGS_REG))])
12308   (parallel
12309    [(set (match_dup 5)
12310          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12311                  (ashift:SI (match_dup 3)
12312                             (minus:QI (const_int 32) (match_dup 2)))))
12313     (clobber (reg:CC FLAGS_REG))])]
12314  "split_di (operands, 1, operands + 4, operands + 5);")
12315
12316 (define_insn "*rotrdi3_1_one_bit_rex64"
12317   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12318         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12319                      (match_operand:QI 2 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "ror{q}\t%0"
12324   [(set_attr "type" "rotate")
12325    (set (attr "length") 
12326      (if_then_else (match_operand:DI 0 "register_operand" "") 
12327         (const_string "2")
12328         (const_string "*")))])
12329
12330 (define_insn "*rotrdi3_1_rex64"
12331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12332         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12333                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12336   "@
12337    ror{q}\t{%2, %0|%0, %2}
12338    ror{q}\t{%b2, %0|%0, %b2}"
12339   [(set_attr "type" "rotate")
12340    (set_attr "mode" "DI")])
12341
12342 (define_expand "rotrsi3"
12343   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12344         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12345                      (match_operand:QI 2 "nonmemory_operand" "")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   ""
12348   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12349
12350 (define_insn "*rotrsi3_1_one_bit"
12351   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12352         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353                      (match_operand:QI 2 "const1_operand" "")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12356    && (TARGET_SHIFT1 || optimize_size)"
12357   "ror{l}\t%0"
12358   [(set_attr "type" "rotate")
12359    (set (attr "length") 
12360      (if_then_else (match_operand:SI 0 "register_operand" "") 
12361         (const_string "2")
12362         (const_string "*")))])
12363
12364 (define_insn "*rotrsi3_1_one_bit_zext"
12365   [(set (match_operand:DI 0 "register_operand" "=r")
12366         (zero_extend:DI
12367           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "ror{l}\t%k0"
12373   [(set_attr "type" "rotate")
12374    (set (attr "length") 
12375      (if_then_else (match_operand:SI 0 "register_operand" "") 
12376         (const_string "2")
12377         (const_string "*")))])
12378
12379 (define_insn "*rotrsi3_1"
12380   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12381         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12382                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12385   "@
12386    ror{l}\t{%2, %0|%0, %2}
12387    ror{l}\t{%b2, %0|%0, %b2}"
12388   [(set_attr "type" "rotate")
12389    (set_attr "mode" "SI")])
12390
12391 (define_insn "*rotrsi3_1_zext"
12392   [(set (match_operand:DI 0 "register_operand" "=r,r")
12393         (zero_extend:DI
12394           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12395                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12398   "@
12399    ror{l}\t{%2, %k0|%k0, %2}
12400    ror{l}\t{%b2, %k0|%k0, %b2}"
12401   [(set_attr "type" "rotate")
12402    (set_attr "mode" "SI")])
12403
12404 (define_expand "rotrhi3"
12405   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12406         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12407                      (match_operand:QI 2 "nonmemory_operand" "")))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "TARGET_HIMODE_MATH"
12410   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12411
12412 (define_insn "*rotrhi3_one_bit"
12413   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12414         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415                      (match_operand:QI 2 "const1_operand" "")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12418    && (TARGET_SHIFT1 || optimize_size)"
12419   "ror{w}\t%0"
12420   [(set_attr "type" "rotate")
12421    (set (attr "length") 
12422      (if_then_else (match_operand 0 "register_operand" "") 
12423         (const_string "2")
12424         (const_string "*")))])
12425
12426 (define_insn "*rotrhi3"
12427   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12428         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12429                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12432   "@
12433    ror{w}\t{%2, %0|%0, %2}
12434    ror{w}\t{%b2, %0|%0, %b2}"
12435   [(set_attr "type" "rotate")
12436    (set_attr "mode" "HI")])
12437
12438 (define_expand "rotrqi3"
12439   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441                      (match_operand:QI 2 "nonmemory_operand" "")))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "TARGET_QIMODE_MATH"
12444   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12445
12446 (define_insn "*rotrqi3_1_one_bit"
12447   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449                      (match_operand:QI 2 "const1_operand" "")))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12452    && (TARGET_SHIFT1 || optimize_size)"
12453   "ror{b}\t%0"
12454   [(set_attr "type" "rotate")
12455    (set (attr "length") 
12456      (if_then_else (match_operand 0 "register_operand" "") 
12457         (const_string "2")
12458         (const_string "*")))])
12459
12460 (define_insn "*rotrqi3_1_one_bit_slp"
12461   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462         (rotatert:QI (match_dup 0)
12463                      (match_operand:QI 1 "const1_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466    && (TARGET_SHIFT1 || optimize_size)"
12467   "ror{b}\t%0"
12468   [(set_attr "type" "rotate1")
12469    (set (attr "length") 
12470      (if_then_else (match_operand 0 "register_operand" "") 
12471         (const_string "2")
12472         (const_string "*")))])
12473
12474 (define_insn "*rotrqi3_1"
12475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478    (clobber (reg:CC FLAGS_REG))]
12479   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12480   "@
12481    ror{b}\t{%2, %0|%0, %2}
12482    ror{b}\t{%b2, %0|%0, %b2}"
12483   [(set_attr "type" "rotate")
12484    (set_attr "mode" "QI")])
12485
12486 (define_insn "*rotrqi3_1_slp"
12487   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12488         (rotatert:QI (match_dup 0)
12489                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12492    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12493   "@
12494    ror{b}\t{%1, %0|%0, %1}
12495    ror{b}\t{%b1, %0|%0, %b1}"
12496   [(set_attr "type" "rotate1")
12497    (set_attr "mode" "QI")])
12498 \f
12499 ;; Bit set / bit test instructions
12500
12501 (define_expand "extv"
12502   [(set (match_operand:SI 0 "register_operand" "")
12503         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12504                          (match_operand:SI 2 "const8_operand" "")
12505                          (match_operand:SI 3 "const8_operand" "")))]
12506   ""
12507 {
12508   /* Handle extractions from %ah et al.  */
12509   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12510     FAIL;
12511
12512   /* From mips.md: extract_bit_field doesn't verify that our source
12513      matches the predicate, so check it again here.  */
12514   if (! ext_register_operand (operands[1], VOIDmode))
12515     FAIL;
12516 })
12517
12518 (define_expand "extzv"
12519   [(set (match_operand:SI 0 "register_operand" "")
12520         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12521                          (match_operand:SI 2 "const8_operand" "")
12522                          (match_operand:SI 3 "const8_operand" "")))]
12523   ""
12524 {
12525   /* Handle extractions from %ah et al.  */
12526   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12527     FAIL;
12528
12529   /* From mips.md: extract_bit_field doesn't verify that our source
12530      matches the predicate, so check it again here.  */
12531   if (! ext_register_operand (operands[1], VOIDmode))
12532     FAIL;
12533 })
12534
12535 (define_expand "insv"
12536   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12537                       (match_operand 1 "const8_operand" "")
12538                       (match_operand 2 "const8_operand" ""))
12539         (match_operand 3 "register_operand" ""))]
12540   ""
12541 {
12542   /* Handle insertions to %ah et al.  */
12543   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12544     FAIL;
12545
12546   /* From mips.md: insert_bit_field doesn't verify that our source
12547      matches the predicate, so check it again here.  */
12548   if (! ext_register_operand (operands[0], VOIDmode))
12549     FAIL;
12550
12551   if (TARGET_64BIT)
12552     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12553   else
12554     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12555
12556   DONE;
12557 })
12558
12559 ;; %%% bts, btr, btc, bt.
12560 ;; In general these instructions are *slow* when applied to memory,
12561 ;; since they enforce atomic operation.  When applied to registers,
12562 ;; it depends on the cpu implementation.  They're never faster than
12563 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12564 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12565 ;; within the instruction itself, so operating on bits in the high
12566 ;; 32-bits of a register becomes easier.
12567 ;;
12568 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12569 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12570 ;; negdf respectively, so they can never be disabled entirely.
12571
12572 (define_insn "*btsq"
12573   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12574                          (const_int 1)
12575                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12576         (const_int 1))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12579   "bts{q} %1,%0"
12580   [(set_attr "type" "alu1")])
12581
12582 (define_insn "*btrq"
12583   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12584                          (const_int 1)
12585                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12586         (const_int 0))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12589   "btr{q} %1,%0"
12590   [(set_attr "type" "alu1")])
12591
12592 (define_insn "*btcq"
12593   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12594                          (const_int 1)
12595                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12596         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12599   "btc{q} %1,%0"
12600   [(set_attr "type" "alu1")])
12601
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12603
12604 (define_peephole2
12605   [(match_scratch:DI 2 "r")
12606    (parallel [(set (zero_extract:DI
12607                      (match_operand:DI 0 "register_operand" "")
12608                      (const_int 1)
12609                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12610                    (const_int 1))
12611               (clobber (reg:CC FLAGS_REG))])]
12612   "TARGET_64BIT && !TARGET_USE_BT"
12613   [(const_int 0)]
12614 {
12615   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616   rtx op1;
12617
12618   if (HOST_BITS_PER_WIDE_INT >= 64)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else if (i < HOST_BITS_PER_WIDE_INT)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else
12623     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624
12625   op1 = immed_double_const (lo, hi, DImode);
12626   if (i >= 31)
12627     {
12628       emit_move_insn (operands[2], op1);
12629       op1 = operands[2];
12630     }
12631
12632   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12633   DONE;
12634 })
12635
12636 (define_peephole2
12637   [(match_scratch:DI 2 "r")
12638    (parallel [(set (zero_extract:DI
12639                      (match_operand:DI 0 "register_operand" "")
12640                      (const_int 1)
12641                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12642                    (const_int 0))
12643               (clobber (reg:CC FLAGS_REG))])]
12644   "TARGET_64BIT && !TARGET_USE_BT"
12645   [(const_int 0)]
12646 {
12647   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648   rtx op1;
12649
12650   if (HOST_BITS_PER_WIDE_INT >= 64)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else if (i < HOST_BITS_PER_WIDE_INT)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else
12655     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656
12657   op1 = immed_double_const (~lo, ~hi, DImode);
12658   if (i >= 32)
12659     {
12660       emit_move_insn (operands[2], op1);
12661       op1 = operands[2];
12662     }
12663
12664   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12665   DONE;
12666 })
12667
12668 (define_peephole2
12669   [(match_scratch:DI 2 "r")
12670    (parallel [(set (zero_extract:DI
12671                      (match_operand:DI 0 "register_operand" "")
12672                      (const_int 1)
12673                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12674               (not:DI (zero_extract:DI
12675                         (match_dup 0) (const_int 1) (match_dup 1))))
12676               (clobber (reg:CC FLAGS_REG))])]
12677   "TARGET_64BIT && !TARGET_USE_BT"
12678   [(const_int 0)]
12679 {
12680   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12681   rtx op1;
12682
12683   if (HOST_BITS_PER_WIDE_INT >= 64)
12684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685   else if (i < HOST_BITS_PER_WIDE_INT)
12686     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687   else
12688     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12689
12690   op1 = immed_double_const (lo, hi, DImode);
12691   if (i >= 31)
12692     {
12693       emit_move_insn (operands[2], op1);
12694       op1 = operands[2];
12695     }
12696
12697   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12698   DONE;
12699 })
12700 \f
12701 ;; Store-flag instructions.
12702
12703 ;; For all sCOND expanders, also expand the compare or test insn that
12704 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12705
12706 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12707 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12708 ;; way, which can later delete the movzx if only QImode is needed.
12709
12710 (define_expand "seq"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sne"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sgt"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   ""
12726   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sgtu"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   ""
12732   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "slt"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   ""
12738   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sltu"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   ""
12744   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sge"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   ""
12750   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "sgeu"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   ""
12756   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sle"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   ""
12762   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sleu"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   ""
12768   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sunordered"
12771   [(set (match_operand:QI 0 "register_operand" "")
12772         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773   "TARGET_80387 || TARGET_SSE"
12774   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12775
12776 (define_expand "sordered"
12777   [(set (match_operand:QI 0 "register_operand" "")
12778         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12779   "TARGET_80387"
12780   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12781
12782 (define_expand "suneq"
12783   [(set (match_operand:QI 0 "register_operand" "")
12784         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785   "TARGET_80387 || TARGET_SSE"
12786   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12787
12788 (define_expand "sunge"
12789   [(set (match_operand:QI 0 "register_operand" "")
12790         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12791   "TARGET_80387 || TARGET_SSE"
12792   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12793
12794 (define_expand "sungt"
12795   [(set (match_operand:QI 0 "register_operand" "")
12796         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12797   "TARGET_80387 || TARGET_SSE"
12798   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12799
12800 (define_expand "sunle"
12801   [(set (match_operand:QI 0 "register_operand" "")
12802         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12803   "TARGET_80387 || TARGET_SSE"
12804   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12805
12806 (define_expand "sunlt"
12807   [(set (match_operand:QI 0 "register_operand" "")
12808         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12809   "TARGET_80387 || TARGET_SSE"
12810   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12811
12812 (define_expand "sltgt"
12813   [(set (match_operand:QI 0 "register_operand" "")
12814         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12815   "TARGET_80387 || TARGET_SSE"
12816   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12817
12818 (define_insn "*setcc_1"
12819   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820         (match_operator:QI 1 "ix86_comparison_operator"
12821           [(reg FLAGS_REG) (const_int 0)]))]
12822   ""
12823   "set%C1\t%0"
12824   [(set_attr "type" "setcc")
12825    (set_attr "mode" "QI")])
12826
12827 (define_insn "*setcc_2"
12828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12829         (match_operator:QI 1 "ix86_comparison_operator"
12830           [(reg FLAGS_REG) (const_int 0)]))]
12831   ""
12832   "set%C1\t%0"
12833   [(set_attr "type" "setcc")
12834    (set_attr "mode" "QI")])
12835
12836 ;; In general it is not safe to assume too much about CCmode registers,
12837 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12838 ;; conditions this is safe on x86, so help combine not create
12839 ;;
12840 ;;      seta    %al
12841 ;;      testb   %al, %al
12842 ;;      sete    %al
12843
12844 (define_split 
12845   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12846         (ne:QI (match_operator 1 "ix86_comparison_operator"
12847                  [(reg FLAGS_REG) (const_int 0)])
12848             (const_int 0)))]
12849   ""
12850   [(set (match_dup 0) (match_dup 1))]
12851 {
12852   PUT_MODE (operands[1], QImode);
12853 })
12854
12855 (define_split 
12856   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857         (ne:QI (match_operator 1 "ix86_comparison_operator"
12858                  [(reg FLAGS_REG) (const_int 0)])
12859             (const_int 0)))]
12860   ""
12861   [(set (match_dup 0) (match_dup 1))]
12862 {
12863   PUT_MODE (operands[1], QImode);
12864 })
12865
12866 (define_split 
12867   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868         (eq:QI (match_operator 1 "ix86_comparison_operator"
12869                  [(reg FLAGS_REG) (const_int 0)])
12870             (const_int 0)))]
12871   ""
12872   [(set (match_dup 0) (match_dup 1))]
12873 {
12874   rtx new_op1 = copy_rtx (operands[1]);
12875   operands[1] = new_op1;
12876   PUT_MODE (new_op1, QImode);
12877   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12878                                              GET_MODE (XEXP (new_op1, 0))));
12879
12880   /* Make sure that (a) the CCmode we have for the flags is strong
12881      enough for the reversed compare or (b) we have a valid FP compare.  */
12882   if (! ix86_comparison_operator (new_op1, VOIDmode))
12883     FAIL;
12884 })
12885
12886 (define_split 
12887   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12888         (eq:QI (match_operator 1 "ix86_comparison_operator"
12889                  [(reg FLAGS_REG) (const_int 0)])
12890             (const_int 0)))]
12891   ""
12892   [(set (match_dup 0) (match_dup 1))]
12893 {
12894   rtx new_op1 = copy_rtx (operands[1]);
12895   operands[1] = new_op1;
12896   PUT_MODE (new_op1, QImode);
12897   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12898                                              GET_MODE (XEXP (new_op1, 0))));
12899
12900   /* Make sure that (a) the CCmode we have for the flags is strong
12901      enough for the reversed compare or (b) we have a valid FP compare.  */
12902   if (! ix86_comparison_operator (new_op1, VOIDmode))
12903     FAIL;
12904 })
12905
12906 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12907 ;; subsequent logical operations are used to imitate conditional moves.
12908 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12909 ;; it directly.
12910
12911 (define_insn "*sse_setccsf"
12912   [(set (match_operand:SF 0 "register_operand" "=x")
12913         (match_operator:SF 1 "sse_comparison_operator"
12914           [(match_operand:SF 2 "register_operand" "0")
12915            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12916   "TARGET_SSE"
12917   "cmp%D1ss\t{%3, %0|%0, %3}"
12918   [(set_attr "type" "ssecmp")
12919    (set_attr "mode" "SF")])
12920
12921 (define_insn "*sse_setccdf"
12922   [(set (match_operand:DF 0 "register_operand" "=Y")
12923         (match_operator:DF 1 "sse_comparison_operator"
12924           [(match_operand:DF 2 "register_operand" "0")
12925            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12926   "TARGET_SSE2"
12927   "cmp%D1sd\t{%3, %0|%0, %3}"
12928   [(set_attr "type" "ssecmp")
12929    (set_attr "mode" "DF")])
12930 \f
12931 ;; Basic conditional jump instructions.
12932 ;; We ignore the overflow flag for signed branch instructions.
12933
12934 ;; For all bCOND expanders, also expand the compare or test insn that
12935 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12936
12937 (define_expand "beq"
12938   [(set (pc)
12939         (if_then_else (match_dup 1)
12940                       (label_ref (match_operand 0 "" ""))
12941                       (pc)))]
12942   ""
12943   "ix86_expand_branch (EQ, operands[0]); DONE;")
12944
12945 (define_expand "bne"
12946   [(set (pc)
12947         (if_then_else (match_dup 1)
12948                       (label_ref (match_operand 0 "" ""))
12949                       (pc)))]
12950   ""
12951   "ix86_expand_branch (NE, operands[0]); DONE;")
12952
12953 (define_expand "bgt"
12954   [(set (pc)
12955         (if_then_else (match_dup 1)
12956                       (label_ref (match_operand 0 "" ""))
12957                       (pc)))]
12958   ""
12959   "ix86_expand_branch (GT, operands[0]); DONE;")
12960
12961 (define_expand "bgtu"
12962   [(set (pc)
12963         (if_then_else (match_dup 1)
12964                       (label_ref (match_operand 0 "" ""))
12965                       (pc)))]
12966   ""
12967   "ix86_expand_branch (GTU, operands[0]); DONE;")
12968
12969 (define_expand "blt"
12970   [(set (pc)
12971         (if_then_else (match_dup 1)
12972                       (label_ref (match_operand 0 "" ""))
12973                       (pc)))]
12974   ""
12975   "ix86_expand_branch (LT, operands[0]); DONE;")
12976
12977 (define_expand "bltu"
12978   [(set (pc)
12979         (if_then_else (match_dup 1)
12980                       (label_ref (match_operand 0 "" ""))
12981                       (pc)))]
12982   ""
12983   "ix86_expand_branch (LTU, operands[0]); DONE;")
12984
12985 (define_expand "bge"
12986   [(set (pc)
12987         (if_then_else (match_dup 1)
12988                       (label_ref (match_operand 0 "" ""))
12989                       (pc)))]
12990   ""
12991   "ix86_expand_branch (GE, operands[0]); DONE;")
12992
12993 (define_expand "bgeu"
12994   [(set (pc)
12995         (if_then_else (match_dup 1)
12996                       (label_ref (match_operand 0 "" ""))
12997                       (pc)))]
12998   ""
12999   "ix86_expand_branch (GEU, operands[0]); DONE;")
13000
13001 (define_expand "ble"
13002   [(set (pc)
13003         (if_then_else (match_dup 1)
13004                       (label_ref (match_operand 0 "" ""))
13005                       (pc)))]
13006   ""
13007   "ix86_expand_branch (LE, operands[0]); DONE;")
13008
13009 (define_expand "bleu"
13010   [(set (pc)
13011         (if_then_else (match_dup 1)
13012                       (label_ref (match_operand 0 "" ""))
13013                       (pc)))]
13014   ""
13015   "ix86_expand_branch (LEU, operands[0]); DONE;")
13016
13017 (define_expand "bunordered"
13018   [(set (pc)
13019         (if_then_else (match_dup 1)
13020                       (label_ref (match_operand 0 "" ""))
13021                       (pc)))]
13022   "TARGET_80387 || TARGET_SSE_MATH"
13023   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13024
13025 (define_expand "bordered"
13026   [(set (pc)
13027         (if_then_else (match_dup 1)
13028                       (label_ref (match_operand 0 "" ""))
13029                       (pc)))]
13030   "TARGET_80387 || TARGET_SSE_MATH"
13031   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13032
13033 (define_expand "buneq"
13034   [(set (pc)
13035         (if_then_else (match_dup 1)
13036                       (label_ref (match_operand 0 "" ""))
13037                       (pc)))]
13038   "TARGET_80387 || TARGET_SSE_MATH"
13039   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13040
13041 (define_expand "bunge"
13042   [(set (pc)
13043         (if_then_else (match_dup 1)
13044                       (label_ref (match_operand 0 "" ""))
13045                       (pc)))]
13046   "TARGET_80387 || TARGET_SSE_MATH"
13047   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13048
13049 (define_expand "bungt"
13050   [(set (pc)
13051         (if_then_else (match_dup 1)
13052                       (label_ref (match_operand 0 "" ""))
13053                       (pc)))]
13054   "TARGET_80387 || TARGET_SSE_MATH"
13055   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13056
13057 (define_expand "bunle"
13058   [(set (pc)
13059         (if_then_else (match_dup 1)
13060                       (label_ref (match_operand 0 "" ""))
13061                       (pc)))]
13062   "TARGET_80387 || TARGET_SSE_MATH"
13063   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13064
13065 (define_expand "bunlt"
13066   [(set (pc)
13067         (if_then_else (match_dup 1)
13068                       (label_ref (match_operand 0 "" ""))
13069                       (pc)))]
13070   "TARGET_80387 || TARGET_SSE_MATH"
13071   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13072
13073 (define_expand "bltgt"
13074   [(set (pc)
13075         (if_then_else (match_dup 1)
13076                       (label_ref (match_operand 0 "" ""))
13077                       (pc)))]
13078   "TARGET_80387 || TARGET_SSE_MATH"
13079   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13080
13081 (define_insn "*jcc_1"
13082   [(set (pc)
13083         (if_then_else (match_operator 1 "ix86_comparison_operator"
13084                                       [(reg FLAGS_REG) (const_int 0)])
13085                       (label_ref (match_operand 0 "" ""))
13086                       (pc)))]
13087   ""
13088   "%+j%C1\t%l0"
13089   [(set_attr "type" "ibr")
13090    (set_attr "modrm" "0")
13091    (set (attr "length")
13092            (if_then_else (and (ge (minus (match_dup 0) (pc))
13093                                   (const_int -126))
13094                               (lt (minus (match_dup 0) (pc))
13095                                   (const_int 128)))
13096              (const_int 2)
13097              (const_int 6)))])
13098
13099 (define_insn "*jcc_2"
13100   [(set (pc)
13101         (if_then_else (match_operator 1 "ix86_comparison_operator"
13102                                       [(reg FLAGS_REG) (const_int 0)])
13103                       (pc)
13104                       (label_ref (match_operand 0 "" ""))))]
13105   ""
13106   "%+j%c1\t%l0"
13107   [(set_attr "type" "ibr")
13108    (set_attr "modrm" "0")
13109    (set (attr "length")
13110            (if_then_else (and (ge (minus (match_dup 0) (pc))
13111                                   (const_int -126))
13112                               (lt (minus (match_dup 0) (pc))
13113                                   (const_int 128)))
13114              (const_int 2)
13115              (const_int 6)))])
13116
13117 ;; In general it is not safe to assume too much about CCmode registers,
13118 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13119 ;; conditions this is safe on x86, so help combine not create
13120 ;;
13121 ;;      seta    %al
13122 ;;      testb   %al, %al
13123 ;;      je      Lfoo
13124
13125 (define_split 
13126   [(set (pc)
13127         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13128                                       [(reg FLAGS_REG) (const_int 0)])
13129                           (const_int 0))
13130                       (label_ref (match_operand 1 "" ""))
13131                       (pc)))]
13132   ""
13133   [(set (pc)
13134         (if_then_else (match_dup 0)
13135                       (label_ref (match_dup 1))
13136                       (pc)))]
13137 {
13138   PUT_MODE (operands[0], VOIDmode);
13139 })
13140   
13141 (define_split 
13142   [(set (pc)
13143         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13144                                       [(reg FLAGS_REG) (const_int 0)])
13145                           (const_int 0))
13146                       (label_ref (match_operand 1 "" ""))
13147                       (pc)))]
13148   ""
13149   [(set (pc)
13150         (if_then_else (match_dup 0)
13151                       (label_ref (match_dup 1))
13152                       (pc)))]
13153 {
13154   rtx new_op0 = copy_rtx (operands[0]);
13155   operands[0] = new_op0;
13156   PUT_MODE (new_op0, VOIDmode);
13157   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13158                                              GET_MODE (XEXP (new_op0, 0))));
13159
13160   /* Make sure that (a) the CCmode we have for the flags is strong
13161      enough for the reversed compare or (b) we have a valid FP compare.  */
13162   if (! ix86_comparison_operator (new_op0, VOIDmode))
13163     FAIL;
13164 })
13165
13166 ;; Define combination compare-and-branch fp compare instructions to use
13167 ;; during early optimization.  Splitting the operation apart early makes
13168 ;; for bad code when we want to reverse the operation.
13169
13170 (define_insn "*fp_jcc_1_mixed"
13171   [(set (pc)
13172         (if_then_else (match_operator 0 "comparison_operator"
13173                         [(match_operand 1 "register_operand" "f,x")
13174                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13175           (label_ref (match_operand 3 "" ""))
13176           (pc)))
13177    (clobber (reg:CCFP FPSR_REG))
13178    (clobber (reg:CCFP FLAGS_REG))]
13179   "TARGET_MIX_SSE_I387
13180    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13181    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13183   "#")
13184
13185 (define_insn "*fp_jcc_1_sse"
13186   [(set (pc)
13187         (if_then_else (match_operator 0 "comparison_operator"
13188                         [(match_operand 1 "register_operand" "x")
13189                          (match_operand 2 "nonimmediate_operand" "xm")])
13190           (label_ref (match_operand 3 "" ""))
13191           (pc)))
13192    (clobber (reg:CCFP FPSR_REG))
13193    (clobber (reg:CCFP FLAGS_REG))]
13194   "TARGET_SSE_MATH
13195    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198   "#")
13199
13200 (define_insn "*fp_jcc_1_387"
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "comparison_operator"
13203                         [(match_operand 1 "register_operand" "f")
13204                          (match_operand 2 "register_operand" "f")])
13205           (label_ref (match_operand 3 "" ""))
13206           (pc)))
13207    (clobber (reg:CCFP FPSR_REG))
13208    (clobber (reg:CCFP FLAGS_REG))]
13209   "TARGET_CMOVE && TARGET_80387
13210    && FLOAT_MODE_P (GET_MODE (operands[1]))
13211    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13213   "#")
13214
13215 (define_insn "*fp_jcc_2_mixed"
13216   [(set (pc)
13217         (if_then_else (match_operator 0 "comparison_operator"
13218                         [(match_operand 1 "register_operand" "f,x")
13219                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13220           (pc)
13221           (label_ref (match_operand 3 "" ""))))
13222    (clobber (reg:CCFP FPSR_REG))
13223    (clobber (reg:CCFP FLAGS_REG))]
13224   "TARGET_MIX_SSE_I387
13225    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13226    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13227    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228   "#")
13229
13230 (define_insn "*fp_jcc_2_sse"
13231   [(set (pc)
13232         (if_then_else (match_operator 0 "comparison_operator"
13233                         [(match_operand 1 "register_operand" "x")
13234                          (match_operand 2 "nonimmediate_operand" "xm")])
13235           (pc)
13236           (label_ref (match_operand 3 "" ""))))
13237    (clobber (reg:CCFP FPSR_REG))
13238    (clobber (reg:CCFP FLAGS_REG))]
13239   "TARGET_SSE_MATH
13240    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13244
13245 (define_insn "*fp_jcc_2_387"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "register_operand" "f")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))]
13254   "TARGET_CMOVE && TARGET_80387
13255    && FLOAT_MODE_P (GET_MODE (operands[1]))
13256    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13258   "#")
13259
13260 (define_insn "*fp_jcc_3_387"
13261   [(set (pc)
13262         (if_then_else (match_operator 0 "comparison_operator"
13263                         [(match_operand 1 "register_operand" "f")
13264                          (match_operand 2 "nonimmediate_operand" "fm")])
13265           (label_ref (match_operand 3 "" ""))
13266           (pc)))
13267    (clobber (reg:CCFP FPSR_REG))
13268    (clobber (reg:CCFP FLAGS_REG))
13269    (clobber (match_scratch:HI 4 "=a"))]
13270   "TARGET_80387
13271    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13272    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13273    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13274    && SELECT_CC_MODE (GET_CODE (operands[0]),
13275                       operands[1], operands[2]) == CCFPmode
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13278
13279 (define_insn "*fp_jcc_4_387"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "nonimmediate_operand" "fm")])
13284           (pc)
13285           (label_ref (match_operand 3 "" ""))))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293    && SELECT_CC_MODE (GET_CODE (operands[0]),
13294                       operands[1], operands[2]) == CCFPmode
13295    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296   "#")
13297
13298 (define_insn "*fp_jcc_5_387"
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operand 1 "register_operand" "f")
13302                          (match_operand 2 "register_operand" "f")])
13303           (label_ref (match_operand 3 "" ""))
13304           (pc)))
13305    (clobber (reg:CCFP FPSR_REG))
13306    (clobber (reg:CCFP FLAGS_REG))
13307    (clobber (match_scratch:HI 4 "=a"))]
13308   "TARGET_80387
13309    && FLOAT_MODE_P (GET_MODE (operands[1]))
13310    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13312   "#")
13313
13314 (define_insn "*fp_jcc_6_387"
13315   [(set (pc)
13316         (if_then_else (match_operator 0 "comparison_operator"
13317                         [(match_operand 1 "register_operand" "f")
13318                          (match_operand 2 "register_operand" "f")])
13319           (pc)
13320           (label_ref (match_operand 3 "" ""))))
13321    (clobber (reg:CCFP FPSR_REG))
13322    (clobber (reg:CCFP FLAGS_REG))
13323    (clobber (match_scratch:HI 4 "=a"))]
13324   "TARGET_80387
13325    && FLOAT_MODE_P (GET_MODE (operands[1]))
13326    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13327    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13328   "#")
13329
13330 (define_insn "*fp_jcc_7_387"
13331   [(set (pc)
13332         (if_then_else (match_operator 0 "comparison_operator"
13333                         [(match_operand 1 "register_operand" "f")
13334                          (match_operand 2 "const0_operand" "X")])
13335           (label_ref (match_operand 3 "" ""))
13336           (pc)))
13337    (clobber (reg:CCFP FPSR_REG))
13338    (clobber (reg:CCFP FLAGS_REG))
13339    (clobber (match_scratch:HI 4 "=a"))]
13340   "TARGET_80387
13341    && FLOAT_MODE_P (GET_MODE (operands[1]))
13342    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13343    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13344    && SELECT_CC_MODE (GET_CODE (operands[0]),
13345                       operands[1], operands[2]) == CCFPmode
13346    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13347   "#")
13348
13349 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13350 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13351 ;; with a precedence over other operators and is always put in the first
13352 ;; place. Swap condition and operands to match ficom instruction.
13353
13354 (define_insn "*fp_jcc_8<mode>_387"
13355   [(set (pc)
13356         (if_then_else (match_operator 0 "comparison_operator"
13357                         [(match_operator 1 "float_operator"
13358                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13359                            (match_operand 3 "register_operand" "f,f")])
13360           (label_ref (match_operand 4 "" ""))
13361           (pc)))
13362    (clobber (reg:CCFP FPSR_REG))
13363    (clobber (reg:CCFP FLAGS_REG))
13364    (clobber (match_scratch:HI 5 "=a,a"))]
13365   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13366    && FLOAT_MODE_P (GET_MODE (operands[3]))
13367    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13368    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13369    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13370    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13371   "#")
13372
13373 (define_split
13374   [(set (pc)
13375         (if_then_else (match_operator 0 "comparison_operator"
13376                         [(match_operand 1 "register_operand" "")
13377                          (match_operand 2 "nonimmediate_operand" "")])
13378           (match_operand 3 "" "")
13379           (match_operand 4 "" "")))
13380    (clobber (reg:CCFP FPSR_REG))
13381    (clobber (reg:CCFP FLAGS_REG))]
13382   "reload_completed"
13383   [(const_int 0)]
13384 {
13385   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13386                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13387   DONE;
13388 })
13389
13390 (define_split
13391   [(set (pc)
13392         (if_then_else (match_operator 0 "comparison_operator"
13393                         [(match_operand 1 "register_operand" "")
13394                          (match_operand 2 "general_operand" "")])
13395           (match_operand 3 "" "")
13396           (match_operand 4 "" "")))
13397    (clobber (reg:CCFP FPSR_REG))
13398    (clobber (reg:CCFP FLAGS_REG))
13399    (clobber (match_scratch:HI 5 "=a"))]
13400   "reload_completed"
13401   [(const_int 0)]
13402 {
13403   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13404                         operands[3], operands[4], operands[5], NULL_RTX);
13405   DONE;
13406 })
13407
13408 (define_split
13409   [(set (pc)
13410         (if_then_else (match_operator 0 "comparison_operator"
13411                         [(match_operator 1 "float_operator"
13412                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13413                            (match_operand 3 "register_operand" "")])
13414           (match_operand 4 "" "")
13415           (match_operand 5 "" "")))
13416    (clobber (reg:CCFP FPSR_REG))
13417    (clobber (reg:CCFP FLAGS_REG))
13418    (clobber (match_scratch:HI 6 "=a"))]
13419   "reload_completed"
13420   [(const_int 0)]
13421 {
13422   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13423   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13424                         operands[3], operands[7],
13425                         operands[4], operands[5], operands[6], NULL_RTX);
13426   DONE;
13427 })
13428
13429 ;; %%% Kill this when reload knows how to do it.
13430 (define_split
13431   [(set (pc)
13432         (if_then_else (match_operator 0 "comparison_operator"
13433                         [(match_operator 1 "float_operator"
13434                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13435                            (match_operand 3 "register_operand" "")])
13436           (match_operand 4 "" "")
13437           (match_operand 5 "" "")))
13438    (clobber (reg:CCFP FPSR_REG))
13439    (clobber (reg:CCFP FLAGS_REG))
13440    (clobber (match_scratch:HI 6 "=a"))]
13441   "reload_completed"
13442   [(const_int 0)]
13443 {
13444   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13445   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13446   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13447                         operands[3], operands[7],
13448                         operands[4], operands[5], operands[6], operands[2]);
13449   DONE;
13450 })
13451 \f
13452 ;; Unconditional and other jump instructions
13453
13454 (define_insn "jump"
13455   [(set (pc)
13456         (label_ref (match_operand 0 "" "")))]
13457   ""
13458   "jmp\t%l0"
13459   [(set_attr "type" "ibr")
13460    (set (attr "length")
13461            (if_then_else (and (ge (minus (match_dup 0) (pc))
13462                                   (const_int -126))
13463                               (lt (minus (match_dup 0) (pc))
13464                                   (const_int 128)))
13465              (const_int 2)
13466              (const_int 5)))
13467    (set_attr "modrm" "0")])
13468
13469 (define_expand "indirect_jump"
13470   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13471   ""
13472   "")
13473
13474 (define_insn "*indirect_jump"
13475   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13476   "!TARGET_64BIT"
13477   "jmp\t%A0"
13478   [(set_attr "type" "ibr")
13479    (set_attr "length_immediate" "0")])
13480
13481 (define_insn "*indirect_jump_rtx64"
13482   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13483   "TARGET_64BIT"
13484   "jmp\t%A0"
13485   [(set_attr "type" "ibr")
13486    (set_attr "length_immediate" "0")])
13487
13488 (define_expand "tablejump"
13489   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13490               (use (label_ref (match_operand 1 "" "")))])]
13491   ""
13492 {
13493   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13494      relative.  Convert the relative address to an absolute address.  */
13495   if (flag_pic)
13496     {
13497       rtx op0, op1;
13498       enum rtx_code code;
13499
13500       if (TARGET_64BIT)
13501         {
13502           code = PLUS;
13503           op0 = operands[0];
13504           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13505         }
13506       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13507         {
13508           code = PLUS;
13509           op0 = operands[0];
13510           op1 = pic_offset_table_rtx;
13511         }
13512       else
13513         {
13514           code = MINUS;
13515           op0 = pic_offset_table_rtx;
13516           op1 = operands[0];
13517         }
13518
13519       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13520                                          OPTAB_DIRECT);
13521     }
13522 })
13523
13524 (define_insn "*tablejump_1"
13525   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13526    (use (label_ref (match_operand 1 "" "")))]
13527   "!TARGET_64BIT"
13528   "jmp\t%A0"
13529   [(set_attr "type" "ibr")
13530    (set_attr "length_immediate" "0")])
13531
13532 (define_insn "*tablejump_1_rtx64"
13533   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13534    (use (label_ref (match_operand 1 "" "")))]
13535   "TARGET_64BIT"
13536   "jmp\t%A0"
13537   [(set_attr "type" "ibr")
13538    (set_attr "length_immediate" "0")])
13539 \f
13540 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13541
13542 (define_peephole2
13543   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13544    (set (match_operand:QI 1 "register_operand" "")
13545         (match_operator:QI 2 "ix86_comparison_operator"
13546           [(reg FLAGS_REG) (const_int 0)]))
13547    (set (match_operand 3 "q_regs_operand" "")
13548         (zero_extend (match_dup 1)))]
13549   "(peep2_reg_dead_p (3, operands[1])
13550     || operands_match_p (operands[1], operands[3]))
13551    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13552   [(set (match_dup 4) (match_dup 0))
13553    (set (strict_low_part (match_dup 5))
13554         (match_dup 2))]
13555 {
13556   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13557   operands[5] = gen_lowpart (QImode, operands[3]);
13558   ix86_expand_clear (operands[3]);
13559 })
13560
13561 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13562
13563 (define_peephole2
13564   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13565    (set (match_operand:QI 1 "register_operand" "")
13566         (match_operator:QI 2 "ix86_comparison_operator"
13567           [(reg FLAGS_REG) (const_int 0)]))
13568    (parallel [(set (match_operand 3 "q_regs_operand" "")
13569                    (zero_extend (match_dup 1)))
13570               (clobber (reg:CC FLAGS_REG))])]
13571   "(peep2_reg_dead_p (3, operands[1])
13572     || operands_match_p (operands[1], operands[3]))
13573    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13574   [(set (match_dup 4) (match_dup 0))
13575    (set (strict_low_part (match_dup 5))
13576         (match_dup 2))]
13577 {
13578   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13579   operands[5] = gen_lowpart (QImode, operands[3]);
13580   ix86_expand_clear (operands[3]);
13581 })
13582 \f
13583 ;; Call instructions.
13584
13585 ;; The predicates normally associated with named expanders are not properly
13586 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13587 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13588
13589 ;; Call subroutine returning no value.
13590
13591 (define_expand "call_pop"
13592   [(parallel [(call (match_operand:QI 0 "" "")
13593                     (match_operand:SI 1 "" ""))
13594               (set (reg:SI SP_REG)
13595                    (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 3 "" "")))])]
13597   "!TARGET_64BIT"
13598 {
13599   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13600   DONE;
13601 })
13602
13603 (define_insn "*call_pop_0"
13604   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13605          (match_operand:SI 1 "" ""))
13606    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13607                             (match_operand:SI 2 "immediate_operand" "")))]
13608   "!TARGET_64BIT"
13609 {
13610   if (SIBLING_CALL_P (insn))
13611     return "jmp\t%P0";
13612   else
13613     return "call\t%P0";
13614 }
13615   [(set_attr "type" "call")])
13616   
13617 (define_insn "*call_pop_1"
13618   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13619          (match_operand:SI 1 "" ""))
13620    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13621                             (match_operand:SI 2 "immediate_operand" "i")))]
13622   "!TARGET_64BIT"
13623 {
13624   if (constant_call_address_operand (operands[0], Pmode))
13625     {
13626       if (SIBLING_CALL_P (insn))
13627         return "jmp\t%P0";
13628       else
13629         return "call\t%P0";
13630     }
13631   if (SIBLING_CALL_P (insn))
13632     return "jmp\t%A0";
13633   else
13634     return "call\t%A0";
13635 }
13636   [(set_attr "type" "call")])
13637
13638 (define_expand "call"
13639   [(call (match_operand:QI 0 "" "")
13640          (match_operand 1 "" ""))
13641    (use (match_operand 2 "" ""))]
13642   ""
13643 {
13644   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13645   DONE;
13646 })
13647
13648 (define_expand "sibcall"
13649   [(call (match_operand:QI 0 "" "")
13650          (match_operand 1 "" ""))
13651    (use (match_operand 2 "" ""))]
13652   ""
13653 {
13654   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13655   DONE;
13656 })
13657
13658 (define_insn "*call_0"
13659   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13660          (match_operand 1 "" ""))]
13661   ""
13662 {
13663   if (SIBLING_CALL_P (insn))
13664     return "jmp\t%P0";
13665   else
13666     return "call\t%P0";
13667 }
13668   [(set_attr "type" "call")])
13669
13670 (define_insn "*call_1"
13671   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13672          (match_operand 1 "" ""))]
13673   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13674 {
13675   if (constant_call_address_operand (operands[0], Pmode))
13676     return "call\t%P0";
13677   return "call\t%A0";
13678 }
13679   [(set_attr "type" "call")])
13680
13681 (define_insn "*sibcall_1"
13682   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13683          (match_operand 1 "" ""))]
13684   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13685 {
13686   if (constant_call_address_operand (operands[0], Pmode))
13687     return "jmp\t%P0";
13688   return "jmp\t%A0";
13689 }
13690   [(set_attr "type" "call")])
13691
13692 (define_insn "*call_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13694          (match_operand 1 "" ""))]
13695   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13696 {
13697   if (constant_call_address_operand (operands[0], Pmode))
13698     return "call\t%P0";
13699   return "call\t%A0";
13700 }
13701   [(set_attr "type" "call")])
13702
13703 (define_insn "*sibcall_1_rex64"
13704   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13705          (match_operand 1 "" ""))]
13706   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13707   "jmp\t%P0"
13708   [(set_attr "type" "call")])
13709
13710 (define_insn "*sibcall_1_rex64_v"
13711   [(call (mem:QI (reg:DI 40))
13712          (match_operand 0 "" ""))]
13713   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13714   "jmp\t*%%r11"
13715   [(set_attr "type" "call")])
13716
13717
13718 ;; Call subroutine, returning value in operand 0
13719
13720 (define_expand "call_value_pop"
13721   [(parallel [(set (match_operand 0 "" "")
13722                    (call (match_operand:QI 1 "" "")
13723                          (match_operand:SI 2 "" "")))
13724               (set (reg:SI SP_REG)
13725                    (plus:SI (reg:SI SP_REG)
13726                             (match_operand:SI 4 "" "")))])]
13727   "!TARGET_64BIT"
13728 {
13729   ix86_expand_call (operands[0], operands[1], operands[2],
13730                     operands[3], operands[4], 0);
13731   DONE;
13732 })
13733
13734 (define_expand "call_value"
13735   [(set (match_operand 0 "" "")
13736         (call (match_operand:QI 1 "" "")
13737               (match_operand:SI 2 "" "")))
13738    (use (match_operand:SI 3 "" ""))]
13739   ;; Operand 2 not used on the i386.
13740   ""
13741 {
13742   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13743   DONE;
13744 })
13745
13746 (define_expand "sibcall_value"
13747   [(set (match_operand 0 "" "")
13748         (call (match_operand:QI 1 "" "")
13749               (match_operand:SI 2 "" "")))
13750    (use (match_operand:SI 3 "" ""))]
13751   ;; Operand 2 not used on the i386.
13752   ""
13753 {
13754   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13755   DONE;
13756 })
13757
13758 ;; Call subroutine returning any type.
13759
13760 (define_expand "untyped_call"
13761   [(parallel [(call (match_operand 0 "" "")
13762                     (const_int 0))
13763               (match_operand 1 "" "")
13764               (match_operand 2 "" "")])]
13765   ""
13766 {
13767   int i;
13768
13769   /* In order to give reg-stack an easier job in validating two
13770      coprocessor registers as containing a possible return value,
13771      simply pretend the untyped call returns a complex long double
13772      value.  */
13773
13774   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13775                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13776                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13777                     NULL, 0);
13778
13779   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13780     {
13781       rtx set = XVECEXP (operands[2], 0, i);
13782       emit_move_insn (SET_DEST (set), SET_SRC (set));
13783     }
13784
13785   /* The optimizer does not know that the call sets the function value
13786      registers we stored in the result block.  We avoid problems by
13787      claiming that all hard registers are used and clobbered at this
13788      point.  */
13789   emit_insn (gen_blockage (const0_rtx));
13790
13791   DONE;
13792 })
13793 \f
13794 ;; Prologue and epilogue instructions
13795
13796 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13797 ;; all of memory.  This blocks insns from being moved across this point.
13798
13799 (define_insn "blockage"
13800   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13801   ""
13802   ""
13803   [(set_attr "length" "0")])
13804
13805 ;; Insn emitted into the body of a function to return from a function.
13806 ;; This is only done if the function's epilogue is known to be simple.
13807 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13808
13809 (define_expand "return"
13810   [(return)]
13811   "ix86_can_use_return_insn_p ()"
13812 {
13813   if (current_function_pops_args)
13814     {
13815       rtx popc = GEN_INT (current_function_pops_args);
13816       emit_jump_insn (gen_return_pop_internal (popc));
13817       DONE;
13818     }
13819 })
13820
13821 (define_insn "return_internal"
13822   [(return)]
13823   "reload_completed"
13824   "ret"
13825   [(set_attr "length" "1")
13826    (set_attr "length_immediate" "0")
13827    (set_attr "modrm" "0")])
13828
13829 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13830 ;; instruction Athlon and K8 have.
13831
13832 (define_insn "return_internal_long"
13833   [(return)
13834    (unspec [(const_int 0)] UNSPEC_REP)]
13835   "reload_completed"
13836   "rep {;} ret"
13837   [(set_attr "length" "1")
13838    (set_attr "length_immediate" "0")
13839    (set_attr "prefix_rep" "1")
13840    (set_attr "modrm" "0")])
13841
13842 (define_insn "return_pop_internal"
13843   [(return)
13844    (use (match_operand:SI 0 "const_int_operand" ""))]
13845   "reload_completed"
13846   "ret\t%0"
13847   [(set_attr "length" "3")
13848    (set_attr "length_immediate" "2")
13849    (set_attr "modrm" "0")])
13850
13851 (define_insn "return_indirect_internal"
13852   [(return)
13853    (use (match_operand:SI 0 "register_operand" "r"))]
13854   "reload_completed"
13855   "jmp\t%A0"
13856   [(set_attr "type" "ibr")
13857    (set_attr "length_immediate" "0")])
13858
13859 (define_insn "nop"
13860   [(const_int 0)]
13861   ""
13862   "nop"
13863   [(set_attr "length" "1")
13864    (set_attr "length_immediate" "0")
13865    (set_attr "modrm" "0")])
13866
13867 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13868 ;; branch prediction penalty for the third jump in a 16-byte
13869 ;; block on K8.
13870
13871 (define_insn "align"
13872   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13873   ""
13874 {
13875 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13876   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13877 #else
13878   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13879      The align insn is used to avoid 3 jump instructions in the row to improve
13880      branch prediction and the benefits hardly outweigh the cost of extra 8
13881      nops on the average inserted by full alignment pseudo operation.  */
13882 #endif
13883   return "";
13884 }
13885   [(set_attr "length" "16")])
13886
13887 (define_expand "prologue"
13888   [(const_int 1)]
13889   ""
13890   "ix86_expand_prologue (); DONE;")
13891
13892 (define_insn "set_got"
13893   [(set (match_operand:SI 0 "register_operand" "=r")
13894         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13895    (clobber (reg:CC FLAGS_REG))]
13896   "!TARGET_64BIT"
13897   { return output_set_got (operands[0], NULL_RTX); }
13898   [(set_attr "type" "multi")
13899    (set_attr "length" "12")])
13900
13901 (define_insn "set_got_labelled"
13902   [(set (match_operand:SI 0 "register_operand" "=r")
13903         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13904          UNSPEC_SET_GOT))
13905    (clobber (reg:CC FLAGS_REG))]
13906   "!TARGET_64BIT"
13907   { return output_set_got (operands[0], operands[1]); }
13908   [(set_attr "type" "multi")
13909    (set_attr "length" "12")])
13910
13911 (define_insn "set_got_rex64"
13912   [(set (match_operand:DI 0 "register_operand" "=r")
13913         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13914   "TARGET_64BIT"
13915   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13916   [(set_attr "type" "lea")
13917    (set_attr "length" "6")])
13918
13919 (define_expand "epilogue"
13920   [(const_int 1)]
13921   ""
13922   "ix86_expand_epilogue (1); DONE;")
13923
13924 (define_expand "sibcall_epilogue"
13925   [(const_int 1)]
13926   ""
13927   "ix86_expand_epilogue (0); DONE;")
13928
13929 (define_expand "eh_return"
13930   [(use (match_operand 0 "register_operand" ""))]
13931   ""
13932 {
13933   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13934
13935   /* Tricky bit: we write the address of the handler to which we will
13936      be returning into someone else's stack frame, one word below the
13937      stack address we wish to restore.  */
13938   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13939   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13940   tmp = gen_rtx_MEM (Pmode, tmp);
13941   emit_move_insn (tmp, ra);
13942
13943   if (Pmode == SImode)
13944     emit_jump_insn (gen_eh_return_si (sa));
13945   else
13946     emit_jump_insn (gen_eh_return_di (sa));
13947   emit_barrier ();
13948   DONE;
13949 })
13950
13951 (define_insn_and_split "eh_return_si"
13952   [(set (pc) 
13953         (unspec [(match_operand:SI 0 "register_operand" "c")]
13954                  UNSPEC_EH_RETURN))]
13955   "!TARGET_64BIT"
13956   "#"
13957   "reload_completed"
13958   [(const_int 1)]
13959   "ix86_expand_epilogue (2); DONE;")
13960
13961 (define_insn_and_split "eh_return_di"
13962   [(set (pc) 
13963         (unspec [(match_operand:DI 0 "register_operand" "c")]
13964                  UNSPEC_EH_RETURN))]
13965   "TARGET_64BIT"
13966   "#"
13967   "reload_completed"
13968   [(const_int 1)]
13969   "ix86_expand_epilogue (2); DONE;")
13970
13971 (define_insn "leave"
13972   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13973    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13974    (clobber (mem:BLK (scratch)))]
13975   "!TARGET_64BIT"
13976   "leave"
13977   [(set_attr "type" "leave")])
13978
13979 (define_insn "leave_rex64"
13980   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13981    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13982    (clobber (mem:BLK (scratch)))]
13983   "TARGET_64BIT"
13984   "leave"
13985   [(set_attr "type" "leave")])
13986 \f
13987 (define_expand "ffssi2"
13988   [(parallel
13989      [(set (match_operand:SI 0 "register_operand" "") 
13990            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13991       (clobber (match_scratch:SI 2 ""))
13992       (clobber (reg:CC FLAGS_REG))])]
13993   ""
13994   "")
13995
13996 (define_insn_and_split "*ffs_cmove"
13997   [(set (match_operand:SI 0 "register_operand" "=r") 
13998         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13999    (clobber (match_scratch:SI 2 "=&r"))
14000    (clobber (reg:CC FLAGS_REG))]
14001   "TARGET_CMOVE"
14002   "#"
14003   "&& reload_completed"
14004   [(set (match_dup 2) (const_int -1))
14005    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14006               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14007    (set (match_dup 0) (if_then_else:SI
14008                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14009                         (match_dup 2)
14010                         (match_dup 0)))
14011    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14012               (clobber (reg:CC FLAGS_REG))])]
14013   "")
14014
14015 (define_insn_and_split "*ffs_no_cmove"
14016   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14017         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:SI 2 "=&q"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   ""
14021   "#"
14022   "reload_completed"
14023   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14024               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025    (set (strict_low_part (match_dup 3))
14026         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028               (clobber (reg:CC FLAGS_REG))])
14029    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030               (clobber (reg:CC FLAGS_REG))])
14031    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14033 {
14034   operands[3] = gen_lowpart (QImode, operands[2]);
14035   ix86_expand_clear (operands[2]);
14036 })
14037
14038 (define_insn "*ffssi_1"
14039   [(set (reg:CCZ FLAGS_REG)
14040         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14041                      (const_int 0)))
14042    (set (match_operand:SI 0 "register_operand" "=r")
14043         (ctz:SI (match_dup 1)))]
14044   ""
14045   "bsf{l}\t{%1, %0|%0, %1}"
14046   [(set_attr "prefix_0f" "1")])
14047
14048 (define_expand "ffsdi2"
14049   [(parallel
14050      [(set (match_operand:DI 0 "register_operand" "") 
14051            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14052       (clobber (match_scratch:DI 2 ""))
14053       (clobber (reg:CC FLAGS_REG))])]
14054   "TARGET_64BIT && TARGET_CMOVE"
14055   "")
14056
14057 (define_insn_and_split "*ffs_rex64"
14058   [(set (match_operand:DI 0 "register_operand" "=r") 
14059         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14060    (clobber (match_scratch:DI 2 "=&r"))
14061    (clobber (reg:CC FLAGS_REG))]
14062   "TARGET_64BIT && TARGET_CMOVE"
14063   "#"
14064   "&& reload_completed"
14065   [(set (match_dup 2) (const_int -1))
14066    (parallel [(set (reg:CCZ FLAGS_REG)
14067                    (compare:CCZ (match_dup 1) (const_int 0)))
14068               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14069    (set (match_dup 0) (if_then_else:DI
14070                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14071                         (match_dup 2)
14072                         (match_dup 0)))
14073    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14074               (clobber (reg:CC FLAGS_REG))])]
14075   "")
14076
14077 (define_insn "*ffsdi_1"
14078   [(set (reg:CCZ FLAGS_REG)
14079         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14080                      (const_int 0)))
14081    (set (match_operand:DI 0 "register_operand" "=r")
14082         (ctz:DI (match_dup 1)))]
14083   "TARGET_64BIT"
14084   "bsf{q}\t{%1, %0|%0, %1}"
14085   [(set_attr "prefix_0f" "1")])
14086
14087 (define_insn "ctzsi2"
14088   [(set (match_operand:SI 0 "register_operand" "=r")
14089         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14090    (clobber (reg:CC FLAGS_REG))]
14091   ""
14092   "bsf{l}\t{%1, %0|%0, %1}"
14093   [(set_attr "prefix_0f" "1")])
14094
14095 (define_insn "ctzdi2"
14096   [(set (match_operand:DI 0 "register_operand" "=r")
14097         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14098    (clobber (reg:CC FLAGS_REG))]
14099   "TARGET_64BIT"
14100   "bsf{q}\t{%1, %0|%0, %1}"
14101   [(set_attr "prefix_0f" "1")])
14102
14103 (define_expand "clzsi2"
14104   [(parallel
14105      [(set (match_operand:SI 0 "register_operand" "")
14106            (minus:SI (const_int 31)
14107                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14108       (clobber (reg:CC FLAGS_REG))])
14109    (parallel
14110      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14111       (clobber (reg:CC FLAGS_REG))])]
14112   ""
14113   "")
14114
14115 (define_insn "*bsr"
14116   [(set (match_operand:SI 0 "register_operand" "=r")
14117         (minus:SI (const_int 31)
14118                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14119    (clobber (reg:CC FLAGS_REG))]
14120   ""
14121   "bsr{l}\t{%1, %0|%0, %1}"
14122   [(set_attr "prefix_0f" "1")])
14123
14124 (define_expand "clzdi2"
14125   [(parallel
14126      [(set (match_operand:DI 0 "register_operand" "")
14127            (minus:DI (const_int 63)
14128                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14129       (clobber (reg:CC FLAGS_REG))])
14130    (parallel
14131      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14132       (clobber (reg:CC FLAGS_REG))])]
14133   "TARGET_64BIT"
14134   "")
14135
14136 (define_insn "*bsr_rex64"
14137   [(set (match_operand:DI 0 "register_operand" "=r")
14138         (minus:DI (const_int 63)
14139                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14140    (clobber (reg:CC FLAGS_REG))]
14141   "TARGET_64BIT"
14142   "bsr{q}\t{%1, %0|%0, %1}"
14143   [(set_attr "prefix_0f" "1")])
14144 \f
14145 ;; Thread-local storage patterns for ELF.
14146 ;;
14147 ;; Note that these code sequences must appear exactly as shown
14148 ;; in order to allow linker relaxation.
14149
14150 (define_insn "*tls_global_dynamic_32_gnu"
14151   [(set (match_operand:SI 0 "register_operand" "=a")
14152         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14153                     (match_operand:SI 2 "tls_symbolic_operand" "")
14154                     (match_operand:SI 3 "call_insn_operand" "")]
14155                     UNSPEC_TLS_GD))
14156    (clobber (match_scratch:SI 4 "=d"))
14157    (clobber (match_scratch:SI 5 "=c"))
14158    (clobber (reg:CC FLAGS_REG))]
14159   "!TARGET_64BIT && TARGET_GNU_TLS"
14160   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14161   [(set_attr "type" "multi")
14162    (set_attr "length" "12")])
14163
14164 (define_insn "*tls_global_dynamic_32_sun"
14165   [(set (match_operand:SI 0 "register_operand" "=a")
14166         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14167                     (match_operand:SI 2 "tls_symbolic_operand" "")
14168                     (match_operand:SI 3 "call_insn_operand" "")]
14169                     UNSPEC_TLS_GD))
14170    (clobber (match_scratch:SI 4 "=d"))
14171    (clobber (match_scratch:SI 5 "=c"))
14172    (clobber (reg:CC FLAGS_REG))]
14173   "!TARGET_64BIT && TARGET_SUN_TLS"
14174   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14175         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14176   [(set_attr "type" "multi")
14177    (set_attr "length" "14")])
14178
14179 (define_expand "tls_global_dynamic_32"
14180   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14181                    (unspec:SI
14182                     [(match_dup 2)
14183                      (match_operand:SI 1 "tls_symbolic_operand" "")
14184                      (match_dup 3)]
14185                     UNSPEC_TLS_GD))
14186               (clobber (match_scratch:SI 4 ""))
14187               (clobber (match_scratch:SI 5 ""))
14188               (clobber (reg:CC FLAGS_REG))])]
14189   ""
14190 {
14191   if (flag_pic)
14192     operands[2] = pic_offset_table_rtx;
14193   else
14194     {
14195       operands[2] = gen_reg_rtx (Pmode);
14196       emit_insn (gen_set_got (operands[2]));
14197     }
14198   if (TARGET_GNU2_TLS)
14199     {
14200        emit_insn (gen_tls_dynamic_gnu2_32
14201                   (operands[0], operands[1], operands[2]));
14202        DONE;
14203     }
14204   operands[3] = ix86_tls_get_addr ();
14205 })
14206
14207 (define_insn "*tls_global_dynamic_64"
14208   [(set (match_operand:DI 0 "register_operand" "=a")
14209         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14210                  (match_operand:DI 3 "" "")))
14211    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14212               UNSPEC_TLS_GD)]
14213   "TARGET_64BIT"
14214   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14215   [(set_attr "type" "multi")
14216    (set_attr "length" "16")])
14217
14218 (define_expand "tls_global_dynamic_64"
14219   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14220                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14221               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14222                          UNSPEC_TLS_GD)])]
14223   ""
14224 {
14225   if (TARGET_GNU2_TLS)
14226     {
14227        emit_insn (gen_tls_dynamic_gnu2_64
14228                   (operands[0], operands[1]));
14229        DONE;
14230     }
14231   operands[2] = ix86_tls_get_addr ();
14232 })
14233
14234 (define_insn "*tls_local_dynamic_base_32_gnu"
14235   [(set (match_operand:SI 0 "register_operand" "=a")
14236         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14237                     (match_operand:SI 2 "call_insn_operand" "")]
14238                    UNSPEC_TLS_LD_BASE))
14239    (clobber (match_scratch:SI 3 "=d"))
14240    (clobber (match_scratch:SI 4 "=c"))
14241    (clobber (reg:CC FLAGS_REG))]
14242   "!TARGET_64BIT && TARGET_GNU_TLS"
14243   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14244   [(set_attr "type" "multi")
14245    (set_attr "length" "11")])
14246
14247 (define_insn "*tls_local_dynamic_base_32_sun"
14248   [(set (match_operand:SI 0 "register_operand" "=a")
14249         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14250                     (match_operand:SI 2 "call_insn_operand" "")]
14251                    UNSPEC_TLS_LD_BASE))
14252    (clobber (match_scratch:SI 3 "=d"))
14253    (clobber (match_scratch:SI 4 "=c"))
14254    (clobber (reg:CC FLAGS_REG))]
14255   "!TARGET_64BIT && TARGET_SUN_TLS"
14256   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14257         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14258   [(set_attr "type" "multi")
14259    (set_attr "length" "13")])
14260
14261 (define_expand "tls_local_dynamic_base_32"
14262   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14263                    (unspec:SI [(match_dup 1) (match_dup 2)]
14264                               UNSPEC_TLS_LD_BASE))
14265               (clobber (match_scratch:SI 3 ""))
14266               (clobber (match_scratch:SI 4 ""))
14267               (clobber (reg:CC FLAGS_REG))])]
14268   ""
14269 {
14270   if (flag_pic)
14271     operands[1] = pic_offset_table_rtx;
14272   else
14273     {
14274       operands[1] = gen_reg_rtx (Pmode);
14275       emit_insn (gen_set_got (operands[1]));
14276     }
14277   if (TARGET_GNU2_TLS)
14278     {
14279        emit_insn (gen_tls_dynamic_gnu2_32
14280                   (operands[0], ix86_tls_module_base (), operands[1]));
14281        DONE;
14282     }
14283   operands[2] = ix86_tls_get_addr ();
14284 })
14285
14286 (define_insn "*tls_local_dynamic_base_64"
14287   [(set (match_operand:DI 0 "register_operand" "=a")
14288         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14289                  (match_operand:DI 2 "" "")))
14290    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14291   "TARGET_64BIT"
14292   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14293   [(set_attr "type" "multi")
14294    (set_attr "length" "12")])
14295
14296 (define_expand "tls_local_dynamic_base_64"
14297   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14298                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14299               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14300   ""
14301 {
14302   if (TARGET_GNU2_TLS)
14303     {
14304        emit_insn (gen_tls_dynamic_gnu2_64
14305                   (operands[0], ix86_tls_module_base ()));
14306        DONE;
14307     }
14308   operands[1] = ix86_tls_get_addr ();
14309 })
14310
14311 ;; Local dynamic of a single variable is a lose.  Show combine how
14312 ;; to convert that back to global dynamic.
14313
14314 (define_insn_and_split "*tls_local_dynamic_32_once"
14315   [(set (match_operand:SI 0 "register_operand" "=a")
14316         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14317                              (match_operand:SI 2 "call_insn_operand" "")]
14318                             UNSPEC_TLS_LD_BASE)
14319                  (const:SI (unspec:SI
14320                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14321                             UNSPEC_DTPOFF))))
14322    (clobber (match_scratch:SI 4 "=d"))
14323    (clobber (match_scratch:SI 5 "=c"))
14324    (clobber (reg:CC FLAGS_REG))]
14325   ""
14326   "#"
14327   ""
14328   [(parallel [(set (match_dup 0)
14329                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14330                               UNSPEC_TLS_GD))
14331               (clobber (match_dup 4))
14332               (clobber (match_dup 5))
14333               (clobber (reg:CC FLAGS_REG))])]
14334   "")
14335
14336 ;; Load and add the thread base pointer from %gs:0.
14337
14338 (define_insn "*load_tp_si"
14339   [(set (match_operand:SI 0 "register_operand" "=r")
14340         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14341   "!TARGET_64BIT"
14342   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14343   [(set_attr "type" "imov")
14344    (set_attr "modrm" "0")
14345    (set_attr "length" "7")
14346    (set_attr "memory" "load")
14347    (set_attr "imm_disp" "false")])
14348
14349 (define_insn "*add_tp_si"
14350   [(set (match_operand:SI 0 "register_operand" "=r")
14351         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14352                  (match_operand:SI 1 "register_operand" "0")))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "!TARGET_64BIT"
14355   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14356   [(set_attr "type" "alu")
14357    (set_attr "modrm" "0")
14358    (set_attr "length" "7")
14359    (set_attr "memory" "load")
14360    (set_attr "imm_disp" "false")])
14361
14362 (define_insn "*load_tp_di"
14363   [(set (match_operand:DI 0 "register_operand" "=r")
14364         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14365   "TARGET_64BIT"
14366   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14367   [(set_attr "type" "imov")
14368    (set_attr "modrm" "0")
14369    (set_attr "length" "7")
14370    (set_attr "memory" "load")
14371    (set_attr "imm_disp" "false")])
14372
14373 (define_insn "*add_tp_di"
14374   [(set (match_operand:DI 0 "register_operand" "=r")
14375         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14376                  (match_operand:DI 1 "register_operand" "0")))
14377    (clobber (reg:CC FLAGS_REG))]
14378   "TARGET_64BIT"
14379   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14380   [(set_attr "type" "alu")
14381    (set_attr "modrm" "0")
14382    (set_attr "length" "7")
14383    (set_attr "memory" "load")
14384    (set_attr "imm_disp" "false")])
14385
14386 ;; GNU2 TLS patterns can be split.
14387
14388 (define_expand "tls_dynamic_gnu2_32"
14389   [(set (match_dup 3)
14390         (plus:SI (match_operand:SI 2 "register_operand" "")
14391                  (const:SI
14392                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14393                              UNSPEC_TLSDESC))))
14394    (parallel
14395     [(set (match_operand:SI 0 "register_operand" "")
14396           (unspec:SI [(match_dup 1) (match_dup 3)
14397                       (match_dup 2) (reg:SI SP_REG)]
14398                       UNSPEC_TLSDESC))
14399      (clobber (reg:CC FLAGS_REG))])]
14400   "!TARGET_64BIT && TARGET_GNU2_TLS"
14401 {
14402   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14403   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14404 })
14405
14406 (define_insn "*tls_dynamic_lea_32"
14407   [(set (match_operand:SI 0 "register_operand" "=r")
14408         (plus:SI (match_operand:SI 1 "register_operand" "b")
14409                  (const:SI
14410                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14411                               UNSPEC_TLSDESC))))]
14412   "!TARGET_64BIT && TARGET_GNU2_TLS"
14413   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14414   [(set_attr "type" "lea")
14415    (set_attr "mode" "SI")
14416    (set_attr "length" "6")
14417    (set_attr "length_address" "4")])
14418
14419 (define_insn "*tls_dynamic_call_32"
14420   [(set (match_operand:SI 0 "register_operand" "=a")
14421         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14422                     (match_operand:SI 2 "register_operand" "0")
14423                     ;; we have to make sure %ebx still points to the GOT
14424                     (match_operand:SI 3 "register_operand" "b")
14425                     (reg:SI SP_REG)]
14426                    UNSPEC_TLSDESC))
14427    (clobber (reg:CC FLAGS_REG))]
14428   "!TARGET_64BIT && TARGET_GNU2_TLS"
14429   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14430   [(set_attr "type" "call")
14431    (set_attr "length" "2")
14432    (set_attr "length_address" "0")])
14433
14434 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14435   [(set (match_operand:SI 0 "register_operand" "=&a")
14436         (plus:SI
14437          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14438                      (match_operand:SI 4 "" "")
14439                      (match_operand:SI 2 "register_operand" "b")
14440                      (reg:SI SP_REG)]
14441                     UNSPEC_TLSDESC)
14442          (const:SI (unspec:SI
14443                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14444                     UNSPEC_DTPOFF))))
14445    (clobber (reg:CC FLAGS_REG))]
14446   "!TARGET_64BIT && TARGET_GNU2_TLS"
14447   "#"
14448   ""
14449   [(set (match_dup 0) (match_dup 5))]
14450 {
14451   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14452   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14453 })
14454
14455 (define_expand "tls_dynamic_gnu2_64"
14456   [(set (match_dup 2)
14457         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14458                    UNSPEC_TLSDESC))
14459    (parallel
14460     [(set (match_operand:DI 0 "register_operand" "")
14461           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14462                      UNSPEC_TLSDESC))
14463      (clobber (reg:CC FLAGS_REG))])]
14464   "TARGET_64BIT && TARGET_GNU2_TLS"
14465 {
14466   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14467   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14468 })
14469
14470 (define_insn "*tls_dynamic_lea_64"
14471   [(set (match_operand:DI 0 "register_operand" "=r")
14472         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14473                    UNSPEC_TLSDESC))]
14474   "TARGET_64BIT && TARGET_GNU2_TLS"
14475   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14476   [(set_attr "type" "lea")
14477    (set_attr "mode" "DI")
14478    (set_attr "length" "7")
14479    (set_attr "length_address" "4")])
14480
14481 (define_insn "*tls_dynamic_call_64"
14482   [(set (match_operand:DI 0 "register_operand" "=a")
14483         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14484                     (match_operand:DI 2 "register_operand" "0")
14485                     (reg:DI SP_REG)]
14486                    UNSPEC_TLSDESC))
14487    (clobber (reg:CC FLAGS_REG))]
14488   "TARGET_64BIT && TARGET_GNU2_TLS"
14489   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14490   [(set_attr "type" "call")
14491    (set_attr "length" "2")
14492    (set_attr "length_address" "0")])
14493
14494 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14495   [(set (match_operand:DI 0 "register_operand" "=&a")
14496         (plus:DI
14497          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14498                      (match_operand:DI 3 "" "")
14499                      (reg:DI SP_REG)]
14500                     UNSPEC_TLSDESC)
14501          (const:DI (unspec:DI
14502                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14503                     UNSPEC_DTPOFF))))
14504    (clobber (reg:CC FLAGS_REG))]
14505   "TARGET_64BIT && TARGET_GNU2_TLS"
14506   "#"
14507   ""
14508   [(set (match_dup 0) (match_dup 4))]
14509 {
14510   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14511   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14512 })
14513
14514 ;;
14515 \f
14516 ;; These patterns match the binary 387 instructions for addM3, subM3,
14517 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14518 ;; SFmode.  The first is the normal insn, the second the same insn but
14519 ;; with one operand a conversion, and the third the same insn but with
14520 ;; the other operand a conversion.  The conversion may be SFmode or
14521 ;; SImode if the target mode DFmode, but only SImode if the target mode
14522 ;; is SFmode.
14523
14524 ;; Gcc is slightly more smart about handling normal two address instructions
14525 ;; so use special patterns for add and mull.
14526
14527 (define_insn "*fop_sf_comm_mixed"
14528   [(set (match_operand:SF 0 "register_operand" "=f,x")
14529         (match_operator:SF 3 "binary_fp_operator"
14530                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14531                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14532   "TARGET_MIX_SSE_I387
14533    && COMMUTATIVE_ARITH_P (operands[3])
14534    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14535   "* return output_387_binary_op (insn, operands);"
14536   [(set (attr "type") 
14537         (if_then_else (eq_attr "alternative" "1")
14538            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14539               (const_string "ssemul")
14540               (const_string "sseadd"))
14541            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14542               (const_string "fmul")
14543               (const_string "fop"))))
14544    (set_attr "mode" "SF")])
14545
14546 (define_insn "*fop_sf_comm_sse"
14547   [(set (match_operand:SF 0 "register_operand" "=x")
14548         (match_operator:SF 3 "binary_fp_operator"
14549                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14550                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14551   "TARGET_SSE_MATH
14552    && COMMUTATIVE_ARITH_P (operands[3])
14553    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14554   "* return output_387_binary_op (insn, operands);"
14555   [(set (attr "type") 
14556         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14557            (const_string "ssemul")
14558            (const_string "sseadd")))
14559    (set_attr "mode" "SF")])
14560
14561 (define_insn "*fop_sf_comm_i387"
14562   [(set (match_operand:SF 0 "register_operand" "=f")
14563         (match_operator:SF 3 "binary_fp_operator"
14564                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14565                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14566   "TARGET_80387
14567    && COMMUTATIVE_ARITH_P (operands[3])
14568    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14569   "* return output_387_binary_op (insn, operands);"
14570   [(set (attr "type") 
14571         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14572            (const_string "fmul")
14573            (const_string "fop")))
14574    (set_attr "mode" "SF")])
14575
14576 (define_insn "*fop_sf_1_mixed"
14577   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14578         (match_operator:SF 3 "binary_fp_operator"
14579                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14580                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14581   "TARGET_MIX_SSE_I387
14582    && !COMMUTATIVE_ARITH_P (operands[3])
14583    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14584   "* return output_387_binary_op (insn, operands);"
14585   [(set (attr "type") 
14586         (cond [(and (eq_attr "alternative" "2")
14587                     (match_operand:SF 3 "mult_operator" ""))
14588                  (const_string "ssemul")
14589                (and (eq_attr "alternative" "2")
14590                     (match_operand:SF 3 "div_operator" ""))
14591                  (const_string "ssediv")
14592                (eq_attr "alternative" "2")
14593                  (const_string "sseadd")
14594                (match_operand:SF 3 "mult_operator" "") 
14595                  (const_string "fmul")
14596                (match_operand:SF 3 "div_operator" "") 
14597                  (const_string "fdiv")
14598               ]
14599               (const_string "fop")))
14600    (set_attr "mode" "SF")])
14601
14602 (define_insn "*fop_sf_1_sse"
14603   [(set (match_operand:SF 0 "register_operand" "=x")
14604         (match_operator:SF 3 "binary_fp_operator"
14605                         [(match_operand:SF 1 "register_operand" "0")
14606                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14607   "TARGET_SSE_MATH
14608    && !COMMUTATIVE_ARITH_P (operands[3])"
14609   "* return output_387_binary_op (insn, operands);"
14610   [(set (attr "type") 
14611         (cond [(match_operand:SF 3 "mult_operator" "")
14612                  (const_string "ssemul")
14613                (match_operand:SF 3 "div_operator" "")
14614                  (const_string "ssediv")
14615               ]
14616               (const_string "sseadd")))
14617    (set_attr "mode" "SF")])
14618
14619 ;; This pattern is not fully shadowed by the pattern above.
14620 (define_insn "*fop_sf_1_i387"
14621   [(set (match_operand:SF 0 "register_operand" "=f,f")
14622         (match_operator:SF 3 "binary_fp_operator"
14623                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14624                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14625   "TARGET_80387 && !TARGET_SSE_MATH
14626    && !COMMUTATIVE_ARITH_P (operands[3])
14627    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14628   "* return output_387_binary_op (insn, operands);"
14629   [(set (attr "type") 
14630         (cond [(match_operand:SF 3 "mult_operator" "") 
14631                  (const_string "fmul")
14632                (match_operand:SF 3 "div_operator" "") 
14633                  (const_string "fdiv")
14634               ]
14635               (const_string "fop")))
14636    (set_attr "mode" "SF")])
14637
14638 ;; ??? Add SSE splitters for these!
14639 (define_insn "*fop_sf_2<mode>_i387"
14640   [(set (match_operand:SF 0 "register_operand" "=f,f")
14641         (match_operator:SF 3 "binary_fp_operator"
14642           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14643            (match_operand:SF 2 "register_operand" "0,0")]))]
14644   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14645   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14646   [(set (attr "type") 
14647         (cond [(match_operand:SF 3 "mult_operator" "") 
14648                  (const_string "fmul")
14649                (match_operand:SF 3 "div_operator" "") 
14650                  (const_string "fdiv")
14651               ]
14652               (const_string "fop")))
14653    (set_attr "fp_int_src" "true")
14654    (set_attr "mode" "<MODE>")])
14655
14656 (define_insn "*fop_sf_3<mode>_i387"
14657   [(set (match_operand:SF 0 "register_operand" "=f,f")
14658         (match_operator:SF 3 "binary_fp_operator"
14659           [(match_operand:SF 1 "register_operand" "0,0")
14660            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14661   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14662   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14663   [(set (attr "type") 
14664         (cond [(match_operand:SF 3 "mult_operator" "") 
14665                  (const_string "fmul")
14666                (match_operand:SF 3 "div_operator" "") 
14667                  (const_string "fdiv")
14668               ]
14669               (const_string "fop")))
14670    (set_attr "fp_int_src" "true")
14671    (set_attr "mode" "<MODE>")])
14672
14673 (define_insn "*fop_df_comm_mixed"
14674   [(set (match_operand:DF 0 "register_operand" "=f,Y")
14675         (match_operator:DF 3 "binary_fp_operator"
14676                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14677                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14678   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14679    && COMMUTATIVE_ARITH_P (operands[3])
14680    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14681   "* return output_387_binary_op (insn, operands);"
14682   [(set (attr "type") 
14683         (if_then_else (eq_attr "alternative" "1")
14684            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14685               (const_string "ssemul")
14686               (const_string "sseadd"))
14687            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14688               (const_string "fmul")
14689               (const_string "fop"))))
14690    (set_attr "mode" "DF")])
14691
14692 (define_insn "*fop_df_comm_sse"
14693   [(set (match_operand:DF 0 "register_operand" "=Y")
14694         (match_operator:DF 3 "binary_fp_operator"
14695                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14696                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14697   "TARGET_SSE2 && TARGET_SSE_MATH
14698    && COMMUTATIVE_ARITH_P (operands[3])
14699    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14700   "* return output_387_binary_op (insn, operands);"
14701   [(set (attr "type") 
14702         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14703            (const_string "ssemul")
14704            (const_string "sseadd")))
14705    (set_attr "mode" "DF")])
14706
14707 (define_insn "*fop_df_comm_i387"
14708   [(set (match_operand:DF 0 "register_operand" "=f")
14709         (match_operator:DF 3 "binary_fp_operator"
14710                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14711                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14712   "TARGET_80387
14713    && COMMUTATIVE_ARITH_P (operands[3])
14714    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14715   "* return output_387_binary_op (insn, operands);"
14716   [(set (attr "type") 
14717         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14718            (const_string "fmul")
14719            (const_string "fop")))
14720    (set_attr "mode" "DF")])
14721
14722 (define_insn "*fop_df_1_mixed"
14723   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14724         (match_operator:DF 3 "binary_fp_operator"
14725                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14726                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14727   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14728    && !COMMUTATIVE_ARITH_P (operands[3])
14729    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14730   "* return output_387_binary_op (insn, operands);"
14731   [(set (attr "type") 
14732         (cond [(and (eq_attr "alternative" "2")
14733                     (match_operand:SF 3 "mult_operator" ""))
14734                  (const_string "ssemul")
14735                (and (eq_attr "alternative" "2")
14736                     (match_operand:SF 3 "div_operator" ""))
14737                  (const_string "ssediv")
14738                (eq_attr "alternative" "2")
14739                  (const_string "sseadd")
14740                (match_operand:DF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:DF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "mode" "DF")])
14747
14748 (define_insn "*fop_df_1_sse"
14749   [(set (match_operand:DF 0 "register_operand" "=Y")
14750         (match_operator:DF 3 "binary_fp_operator"
14751                         [(match_operand:DF 1 "register_operand" "0")
14752                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14753   "TARGET_SSE2 && TARGET_SSE_MATH
14754    && !COMMUTATIVE_ARITH_P (operands[3])"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set_attr "mode" "DF")
14757    (set (attr "type") 
14758         (cond [(match_operand:SF 3 "mult_operator" "")
14759                  (const_string "ssemul")
14760                (match_operand:SF 3 "div_operator" "")
14761                  (const_string "ssediv")
14762               ]
14763               (const_string "sseadd")))])
14764
14765 ;; This pattern is not fully shadowed by the pattern above.
14766 (define_insn "*fop_df_1_i387"
14767   [(set (match_operand:DF 0 "register_operand" "=f,f")
14768         (match_operator:DF 3 "binary_fp_operator"
14769                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14770                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14771   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14772    && !COMMUTATIVE_ARITH_P (operands[3])
14773    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14774   "* return output_387_binary_op (insn, operands);"
14775   [(set (attr "type") 
14776         (cond [(match_operand:DF 3 "mult_operator" "") 
14777                  (const_string "fmul")
14778                (match_operand:DF 3 "div_operator" "")
14779                  (const_string "fdiv")
14780               ]
14781               (const_string "fop")))
14782    (set_attr "mode" "DF")])
14783
14784 ;; ??? Add SSE splitters for these!
14785 (define_insn "*fop_df_2<mode>_i387"
14786   [(set (match_operand:DF 0 "register_operand" "=f,f")
14787         (match_operator:DF 3 "binary_fp_operator"
14788            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14789             (match_operand:DF 2 "register_operand" "0,0")]))]
14790   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14791    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14792   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14793   [(set (attr "type") 
14794         (cond [(match_operand:DF 3 "mult_operator" "") 
14795                  (const_string "fmul")
14796                (match_operand:DF 3 "div_operator" "") 
14797                  (const_string "fdiv")
14798               ]
14799               (const_string "fop")))
14800    (set_attr "fp_int_src" "true")
14801    (set_attr "mode" "<MODE>")])
14802
14803 (define_insn "*fop_df_3<mode>_i387"
14804   [(set (match_operand:DF 0 "register_operand" "=f,f")
14805         (match_operator:DF 3 "binary_fp_operator"
14806            [(match_operand:DF 1 "register_operand" "0,0")
14807             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14808   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14809    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14810   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14811   [(set (attr "type") 
14812         (cond [(match_operand:DF 3 "mult_operator" "") 
14813                  (const_string "fmul")
14814                (match_operand:DF 3 "div_operator" "") 
14815                  (const_string "fdiv")
14816               ]
14817               (const_string "fop")))
14818    (set_attr "fp_int_src" "true")
14819    (set_attr "mode" "<MODE>")])
14820
14821 (define_insn "*fop_df_4_i387"
14822   [(set (match_operand:DF 0 "register_operand" "=f,f")
14823         (match_operator:DF 3 "binary_fp_operator"
14824            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14825             (match_operand:DF 2 "register_operand" "0,f")]))]
14826   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14827    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14828   "* return output_387_binary_op (insn, operands);"
14829   [(set (attr "type") 
14830         (cond [(match_operand:DF 3 "mult_operator" "") 
14831                  (const_string "fmul")
14832                (match_operand:DF 3 "div_operator" "") 
14833                  (const_string "fdiv")
14834               ]
14835               (const_string "fop")))
14836    (set_attr "mode" "SF")])
14837
14838 (define_insn "*fop_df_5_i387"
14839   [(set (match_operand:DF 0 "register_operand" "=f,f")
14840         (match_operator:DF 3 "binary_fp_operator"
14841           [(match_operand:DF 1 "register_operand" "0,f")
14842            (float_extend:DF
14843             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14844   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14845   "* return output_387_binary_op (insn, operands);"
14846   [(set (attr "type") 
14847         (cond [(match_operand:DF 3 "mult_operator" "") 
14848                  (const_string "fmul")
14849                (match_operand:DF 3 "div_operator" "") 
14850                  (const_string "fdiv")
14851               ]
14852               (const_string "fop")))
14853    (set_attr "mode" "SF")])
14854
14855 (define_insn "*fop_df_6_i387"
14856   [(set (match_operand:DF 0 "register_operand" "=f,f")
14857         (match_operator:DF 3 "binary_fp_operator"
14858           [(float_extend:DF
14859             (match_operand:SF 1 "register_operand" "0,f"))
14860            (float_extend:DF
14861             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14862   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14863   "* return output_387_binary_op (insn, operands);"
14864   [(set (attr "type") 
14865         (cond [(match_operand:DF 3 "mult_operator" "") 
14866                  (const_string "fmul")
14867                (match_operand:DF 3 "div_operator" "") 
14868                  (const_string "fdiv")
14869               ]
14870               (const_string "fop")))
14871    (set_attr "mode" "SF")])
14872
14873 (define_insn "*fop_xf_comm_i387"
14874   [(set (match_operand:XF 0 "register_operand" "=f")
14875         (match_operator:XF 3 "binary_fp_operator"
14876                         [(match_operand:XF 1 "register_operand" "%0")
14877                          (match_operand:XF 2 "register_operand" "f")]))]
14878   "TARGET_80387
14879    && COMMUTATIVE_ARITH_P (operands[3])"
14880   "* return output_387_binary_op (insn, operands);"
14881   [(set (attr "type") 
14882         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14883            (const_string "fmul")
14884            (const_string "fop")))
14885    (set_attr "mode" "XF")])
14886
14887 (define_insn "*fop_xf_1_i387"
14888   [(set (match_operand:XF 0 "register_operand" "=f,f")
14889         (match_operator:XF 3 "binary_fp_operator"
14890                         [(match_operand:XF 1 "register_operand" "0,f")
14891                          (match_operand:XF 2 "register_operand" "f,0")]))]
14892   "TARGET_80387
14893    && !COMMUTATIVE_ARITH_P (operands[3])"
14894   "* return output_387_binary_op (insn, operands);"
14895   [(set (attr "type") 
14896         (cond [(match_operand:XF 3 "mult_operator" "") 
14897                  (const_string "fmul")
14898                (match_operand:XF 3 "div_operator" "") 
14899                  (const_string "fdiv")
14900               ]
14901               (const_string "fop")))
14902    (set_attr "mode" "XF")])
14903
14904 (define_insn "*fop_xf_2<mode>_i387"
14905   [(set (match_operand:XF 0 "register_operand" "=f,f")
14906         (match_operator:XF 3 "binary_fp_operator"
14907            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14908             (match_operand:XF 2 "register_operand" "0,0")]))]
14909   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14910   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14911   [(set (attr "type") 
14912         (cond [(match_operand:XF 3 "mult_operator" "") 
14913                  (const_string "fmul")
14914                (match_operand:XF 3 "div_operator" "") 
14915                  (const_string "fdiv")
14916               ]
14917               (const_string "fop")))
14918    (set_attr "fp_int_src" "true")
14919    (set_attr "mode" "<MODE>")])
14920
14921 (define_insn "*fop_xf_3<mode>_i387"
14922   [(set (match_operand:XF 0 "register_operand" "=f,f")
14923         (match_operator:XF 3 "binary_fp_operator"
14924           [(match_operand:XF 1 "register_operand" "0,0")
14925            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14926   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14927   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14928   [(set (attr "type") 
14929         (cond [(match_operand:XF 3 "mult_operator" "") 
14930                  (const_string "fmul")
14931                (match_operand:XF 3 "div_operator" "") 
14932                  (const_string "fdiv")
14933               ]
14934               (const_string "fop")))
14935    (set_attr "fp_int_src" "true")
14936    (set_attr "mode" "<MODE>")])
14937
14938 (define_insn "*fop_xf_4_i387"
14939   [(set (match_operand:XF 0 "register_operand" "=f,f")
14940         (match_operator:XF 3 "binary_fp_operator"
14941            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14942             (match_operand:XF 2 "register_operand" "0,f")]))]
14943   "TARGET_80387"
14944   "* return output_387_binary_op (insn, operands);"
14945   [(set (attr "type") 
14946         (cond [(match_operand:XF 3 "mult_operator" "") 
14947                  (const_string "fmul")
14948                (match_operand:XF 3 "div_operator" "") 
14949                  (const_string "fdiv")
14950               ]
14951               (const_string "fop")))
14952    (set_attr "mode" "SF")])
14953
14954 (define_insn "*fop_xf_5_i387"
14955   [(set (match_operand:XF 0 "register_operand" "=f,f")
14956         (match_operator:XF 3 "binary_fp_operator"
14957           [(match_operand:XF 1 "register_operand" "0,f")
14958            (float_extend:XF
14959             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14960   "TARGET_80387"
14961   "* return output_387_binary_op (insn, operands);"
14962   [(set (attr "type") 
14963         (cond [(match_operand:XF 3 "mult_operator" "") 
14964                  (const_string "fmul")
14965                (match_operand:XF 3 "div_operator" "") 
14966                  (const_string "fdiv")
14967               ]
14968               (const_string "fop")))
14969    (set_attr "mode" "SF")])
14970
14971 (define_insn "*fop_xf_6_i387"
14972   [(set (match_operand:XF 0 "register_operand" "=f,f")
14973         (match_operator:XF 3 "binary_fp_operator"
14974           [(float_extend:XF
14975             (match_operand 1 "register_operand" "0,f"))
14976            (float_extend:XF
14977             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14978   "TARGET_80387"
14979   "* return output_387_binary_op (insn, operands);"
14980   [(set (attr "type") 
14981         (cond [(match_operand:XF 3 "mult_operator" "") 
14982                  (const_string "fmul")
14983                (match_operand:XF 3 "div_operator" "") 
14984                  (const_string "fdiv")
14985               ]
14986               (const_string "fop")))
14987    (set_attr "mode" "SF")])
14988
14989 (define_split
14990   [(set (match_operand 0 "register_operand" "")
14991         (match_operator 3 "binary_fp_operator"
14992            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14993             (match_operand 2 "register_operand" "")]))]
14994   "TARGET_80387 && reload_completed
14995    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14996   [(const_int 0)]
14997
14998   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14999   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15000   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15001                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15002                                           GET_MODE (operands[3]),
15003                                           operands[4],
15004                                           operands[2])));
15005   ix86_free_from_memory (GET_MODE (operands[1]));
15006   DONE;
15007 })
15008
15009 (define_split
15010   [(set (match_operand 0 "register_operand" "")
15011         (match_operator 3 "binary_fp_operator"
15012            [(match_operand 1 "register_operand" "")
15013             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15014   "TARGET_80387 && reload_completed
15015    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15016   [(const_int 0)]
15017 {
15018   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15019   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15020   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15021                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15022                                           GET_MODE (operands[3]),
15023                                           operands[1],
15024                                           operands[4])));
15025   ix86_free_from_memory (GET_MODE (operands[2]));
15026   DONE;
15027 })
15028 \f
15029 ;; FPU special functions.
15030
15031 (define_expand "sqrtsf2"
15032   [(set (match_operand:SF 0 "register_operand" "")
15033         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15034   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15035 {
15036   if (!TARGET_SSE_MATH)
15037     operands[1] = force_reg (SFmode, operands[1]);
15038 })
15039
15040 (define_insn "*sqrtsf2_mixed"
15041   [(set (match_operand:SF 0 "register_operand" "=f,x")
15042         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15043   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15044   "@
15045    fsqrt
15046    sqrtss\t{%1, %0|%0, %1}"
15047   [(set_attr "type" "fpspc,sse")
15048    (set_attr "mode" "SF,SF")
15049    (set_attr "athlon_decode" "direct,*")])
15050
15051 (define_insn "*sqrtsf2_sse"
15052   [(set (match_operand:SF 0 "register_operand" "=x")
15053         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15054   "TARGET_SSE_MATH"
15055   "sqrtss\t{%1, %0|%0, %1}"
15056   [(set_attr "type" "sse")
15057    (set_attr "mode" "SF")
15058    (set_attr "athlon_decode" "*")])
15059
15060 (define_insn "*sqrtsf2_i387"
15061   [(set (match_operand:SF 0 "register_operand" "=f")
15062         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15063   "TARGET_USE_FANCY_MATH_387"
15064   "fsqrt"
15065   [(set_attr "type" "fpspc")
15066    (set_attr "mode" "SF")
15067    (set_attr "athlon_decode" "direct")])
15068
15069 (define_expand "sqrtdf2"
15070   [(set (match_operand:DF 0 "register_operand" "")
15071         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15072   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15073 {
15074   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15075     operands[1] = force_reg (DFmode, operands[1]);
15076 })
15077
15078 (define_insn "*sqrtdf2_mixed"
15079   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15080         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15081   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15082   "@
15083    fsqrt
15084    sqrtsd\t{%1, %0|%0, %1}"
15085   [(set_attr "type" "fpspc,sse")
15086    (set_attr "mode" "DF,DF")
15087    (set_attr "athlon_decode" "direct,*")])
15088
15089 (define_insn "*sqrtdf2_sse"
15090   [(set (match_operand:DF 0 "register_operand" "=Y")
15091         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15092   "TARGET_SSE2 && TARGET_SSE_MATH"
15093   "sqrtsd\t{%1, %0|%0, %1}"
15094   [(set_attr "type" "sse")
15095    (set_attr "mode" "DF")
15096    (set_attr "athlon_decode" "*")])
15097
15098 (define_insn "*sqrtdf2_i387"
15099   [(set (match_operand:DF 0 "register_operand" "=f")
15100         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15101   "TARGET_USE_FANCY_MATH_387"
15102   "fsqrt"
15103   [(set_attr "type" "fpspc")
15104    (set_attr "mode" "DF")
15105    (set_attr "athlon_decode" "direct")])
15106
15107 (define_insn "*sqrtextendsfdf2_i387"
15108   [(set (match_operand:DF 0 "register_operand" "=f")
15109         (sqrt:DF (float_extend:DF
15110                   (match_operand:SF 1 "register_operand" "0"))))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15113   "fsqrt"
15114   [(set_attr "type" "fpspc")
15115    (set_attr "mode" "DF")
15116    (set_attr "athlon_decode" "direct")])
15117
15118 (define_insn "sqrtxf2"
15119   [(set (match_operand:XF 0 "register_operand" "=f")
15120         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15121   "TARGET_USE_FANCY_MATH_387 
15122    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15123   "fsqrt"
15124   [(set_attr "type" "fpspc")
15125    (set_attr "mode" "XF")
15126    (set_attr "athlon_decode" "direct")])
15127
15128 (define_insn "*sqrtextendsfxf2_i387"
15129   [(set (match_operand:XF 0 "register_operand" "=f")
15130         (sqrt:XF (float_extend:XF
15131                   (match_operand:SF 1 "register_operand" "0"))))]
15132   "TARGET_USE_FANCY_MATH_387"
15133   "fsqrt"
15134   [(set_attr "type" "fpspc")
15135    (set_attr "mode" "XF")
15136    (set_attr "athlon_decode" "direct")])
15137
15138 (define_insn "*sqrtextenddfxf2_i387"
15139   [(set (match_operand:XF 0 "register_operand" "=f")
15140         (sqrt:XF (float_extend:XF
15141                   (match_operand:DF 1 "register_operand" "0"))))]
15142   "TARGET_USE_FANCY_MATH_387"
15143   "fsqrt"
15144   [(set_attr "type" "fpspc")
15145    (set_attr "mode" "XF")
15146    (set_attr "athlon_decode" "direct")])
15147
15148 (define_insn "fpremxf4"
15149   [(set (match_operand:XF 0 "register_operand" "=f")
15150         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15151                     (match_operand:XF 3 "register_operand" "1")]
15152                    UNSPEC_FPREM_F))
15153    (set (match_operand:XF 1 "register_operand" "=u")
15154         (unspec:XF [(match_dup 2) (match_dup 3)]
15155                    UNSPEC_FPREM_U))
15156    (set (reg:CCFP FPSR_REG)
15157         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15158   "TARGET_USE_FANCY_MATH_387
15159    && flag_unsafe_math_optimizations"
15160   "fprem"
15161   [(set_attr "type" "fpspc")
15162    (set_attr "mode" "XF")])
15163
15164 (define_expand "fmodsf3"
15165   [(use (match_operand:SF 0 "register_operand" ""))
15166    (use (match_operand:SF 1 "register_operand" ""))
15167    (use (match_operand:SF 2 "register_operand" ""))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15170    && flag_unsafe_math_optimizations"
15171 {
15172   rtx label = gen_label_rtx ();
15173
15174   rtx op1 = gen_reg_rtx (XFmode);
15175   rtx op2 = gen_reg_rtx (XFmode);
15176
15177   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15178   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15179
15180   emit_label (label);
15181
15182   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15183   ix86_emit_fp_unordered_jump (label);
15184
15185   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15186   DONE;
15187 })
15188
15189 (define_expand "fmoddf3"
15190   [(use (match_operand:DF 0 "register_operand" ""))
15191    (use (match_operand:DF 1 "register_operand" ""))
15192    (use (match_operand:DF 2 "register_operand" ""))]
15193   "TARGET_USE_FANCY_MATH_387
15194    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15195    && flag_unsafe_math_optimizations"
15196 {
15197   rtx label = gen_label_rtx ();
15198
15199   rtx op1 = gen_reg_rtx (XFmode);
15200   rtx op2 = gen_reg_rtx (XFmode);
15201
15202   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15203   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15204
15205   emit_label (label);
15206
15207   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15208   ix86_emit_fp_unordered_jump (label);
15209
15210   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15211   DONE;
15212 })
15213
15214 (define_expand "fmodxf3"
15215   [(use (match_operand:XF 0 "register_operand" ""))
15216    (use (match_operand:XF 1 "register_operand" ""))
15217    (use (match_operand:XF 2 "register_operand" ""))]
15218   "TARGET_USE_FANCY_MATH_387
15219    && flag_unsafe_math_optimizations"
15220 {
15221   rtx label = gen_label_rtx ();
15222
15223   emit_label (label);
15224
15225   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15226                            operands[1], operands[2]));
15227   ix86_emit_fp_unordered_jump (label);
15228
15229   emit_move_insn (operands[0], operands[1]);
15230   DONE;
15231 })
15232
15233 (define_insn "fprem1xf4"
15234   [(set (match_operand:XF 0 "register_operand" "=f")
15235         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15236                     (match_operand:XF 3 "register_operand" "1")]
15237                    UNSPEC_FPREM1_F))
15238    (set (match_operand:XF 1 "register_operand" "=u")
15239         (unspec:XF [(match_dup 2) (match_dup 3)]
15240                    UNSPEC_FPREM1_U))
15241    (set (reg:CCFP FPSR_REG)
15242         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15243   "TARGET_USE_FANCY_MATH_387
15244    && flag_unsafe_math_optimizations"
15245   "fprem1"
15246   [(set_attr "type" "fpspc")
15247    (set_attr "mode" "XF")])
15248
15249 (define_expand "dremsf3"
15250   [(use (match_operand:SF 0 "register_operand" ""))
15251    (use (match_operand:SF 1 "register_operand" ""))
15252    (use (match_operand:SF 2 "register_operand" ""))]
15253   "TARGET_USE_FANCY_MATH_387
15254    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15255    && flag_unsafe_math_optimizations"
15256 {
15257   rtx label = gen_label_rtx ();
15258
15259   rtx op1 = gen_reg_rtx (XFmode);
15260   rtx op2 = gen_reg_rtx (XFmode);
15261
15262   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15263   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15264
15265   emit_label (label);
15266
15267   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15268   ix86_emit_fp_unordered_jump (label);
15269
15270   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15271   DONE;
15272 })
15273
15274 (define_expand "dremdf3"
15275   [(use (match_operand:DF 0 "register_operand" ""))
15276    (use (match_operand:DF 1 "register_operand" ""))
15277    (use (match_operand:DF 2 "register_operand" ""))]
15278   "TARGET_USE_FANCY_MATH_387
15279    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15280    && flag_unsafe_math_optimizations"
15281 {
15282   rtx label = gen_label_rtx ();
15283
15284   rtx op1 = gen_reg_rtx (XFmode);
15285   rtx op2 = gen_reg_rtx (XFmode);
15286
15287   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15288   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15289
15290   emit_label (label);
15291
15292   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15293   ix86_emit_fp_unordered_jump (label);
15294
15295   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15296   DONE;
15297 })
15298
15299 (define_expand "dremxf3"
15300   [(use (match_operand:XF 0 "register_operand" ""))
15301    (use (match_operand:XF 1 "register_operand" ""))
15302    (use (match_operand:XF 2 "register_operand" ""))]
15303   "TARGET_USE_FANCY_MATH_387
15304    && flag_unsafe_math_optimizations"
15305 {
15306   rtx label = gen_label_rtx ();
15307
15308   emit_label (label);
15309
15310   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15311                             operands[1], operands[2]));
15312   ix86_emit_fp_unordered_jump (label);
15313
15314   emit_move_insn (operands[0], operands[1]);
15315   DONE;
15316 })
15317
15318 (define_insn "*sindf2"
15319   [(set (match_operand:DF 0 "register_operand" "=f")
15320         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15323    && flag_unsafe_math_optimizations"
15324   "fsin"
15325   [(set_attr "type" "fpspc")
15326    (set_attr "mode" "DF")])
15327
15328 (define_insn "*sinsf2"
15329   [(set (match_operand:SF 0 "register_operand" "=f")
15330         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15333    && flag_unsafe_math_optimizations"
15334   "fsin"
15335   [(set_attr "type" "fpspc")
15336    (set_attr "mode" "SF")])
15337
15338 (define_insn "*sinextendsfdf2"
15339   [(set (match_operand:DF 0 "register_operand" "=f")
15340         (unspec:DF [(float_extend:DF
15341                      (match_operand:SF 1 "register_operand" "0"))]
15342                    UNSPEC_SIN))]
15343   "TARGET_USE_FANCY_MATH_387
15344    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15345    && flag_unsafe_math_optimizations"
15346   "fsin"
15347   [(set_attr "type" "fpspc")
15348    (set_attr "mode" "DF")])
15349
15350 (define_insn "*sinxf2"
15351   [(set (match_operand:XF 0 "register_operand" "=f")
15352         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15353   "TARGET_USE_FANCY_MATH_387
15354    && flag_unsafe_math_optimizations"
15355   "fsin"
15356   [(set_attr "type" "fpspc")
15357    (set_attr "mode" "XF")])
15358
15359 (define_insn "*cosdf2"
15360   [(set (match_operand:DF 0 "register_operand" "=f")
15361         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15362   "TARGET_USE_FANCY_MATH_387
15363    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15364    && flag_unsafe_math_optimizations"
15365   "fcos"
15366   [(set_attr "type" "fpspc")
15367    (set_attr "mode" "DF")])
15368
15369 (define_insn "*cossf2"
15370   [(set (match_operand:SF 0 "register_operand" "=f")
15371         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15372   "TARGET_USE_FANCY_MATH_387
15373    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15374    && flag_unsafe_math_optimizations"
15375   "fcos"
15376   [(set_attr "type" "fpspc")
15377    (set_attr "mode" "SF")])
15378
15379 (define_insn "*cosextendsfdf2"
15380   [(set (match_operand:DF 0 "register_operand" "=f")
15381         (unspec:DF [(float_extend:DF
15382                      (match_operand:SF 1 "register_operand" "0"))]
15383                    UNSPEC_COS))]
15384   "TARGET_USE_FANCY_MATH_387
15385    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15386    && flag_unsafe_math_optimizations"
15387   "fcos"
15388   [(set_attr "type" "fpspc")
15389    (set_attr "mode" "DF")])
15390
15391 (define_insn "*cosxf2"
15392   [(set (match_operand:XF 0 "register_operand" "=f")
15393         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15394   "TARGET_USE_FANCY_MATH_387
15395    && flag_unsafe_math_optimizations"
15396   "fcos"
15397   [(set_attr "type" "fpspc")
15398    (set_attr "mode" "XF")])
15399
15400 ;; With sincos pattern defined, sin and cos builtin function will be
15401 ;; expanded to sincos pattern with one of its outputs left unused. 
15402 ;; Cse pass  will detected, if two sincos patterns can be combined,
15403 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15404 ;; depending on the unused output.
15405
15406 (define_insn "sincosdf3"
15407   [(set (match_operand:DF 0 "register_operand" "=f")
15408         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15409                    UNSPEC_SINCOS_COS))
15410    (set (match_operand:DF 1 "register_operand" "=u")
15411         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15412   "TARGET_USE_FANCY_MATH_387
15413    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15414    && flag_unsafe_math_optimizations"
15415   "fsincos"
15416   [(set_attr "type" "fpspc")
15417    (set_attr "mode" "DF")])
15418
15419 (define_split
15420   [(set (match_operand:DF 0 "register_operand" "")
15421         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15422                    UNSPEC_SINCOS_COS))
15423    (set (match_operand:DF 1 "register_operand" "")
15424         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15425   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15426    && !reload_completed && !reload_in_progress"
15427   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15428   "")
15429
15430 (define_split
15431   [(set (match_operand:DF 0 "register_operand" "")
15432         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15433                    UNSPEC_SINCOS_COS))
15434    (set (match_operand:DF 1 "register_operand" "")
15435         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15436   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15437    && !reload_completed && !reload_in_progress"
15438   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15439   "")
15440
15441 (define_insn "sincossf3"
15442   [(set (match_operand:SF 0 "register_operand" "=f")
15443         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15444                    UNSPEC_SINCOS_COS))
15445    (set (match_operand:SF 1 "register_operand" "=u")
15446         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15447   "TARGET_USE_FANCY_MATH_387
15448    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15449    && flag_unsafe_math_optimizations"
15450   "fsincos"
15451   [(set_attr "type" "fpspc")
15452    (set_attr "mode" "SF")])
15453
15454 (define_split
15455   [(set (match_operand:SF 0 "register_operand" "")
15456         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15457                    UNSPEC_SINCOS_COS))
15458    (set (match_operand:SF 1 "register_operand" "")
15459         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15460   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15461    && !reload_completed && !reload_in_progress"
15462   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15463   "")
15464
15465 (define_split
15466   [(set (match_operand:SF 0 "register_operand" "")
15467         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15468                    UNSPEC_SINCOS_COS))
15469    (set (match_operand:SF 1 "register_operand" "")
15470         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15471   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15472    && !reload_completed && !reload_in_progress"
15473   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15474   "")
15475
15476 (define_insn "*sincosextendsfdf3"
15477   [(set (match_operand:DF 0 "register_operand" "=f")
15478         (unspec:DF [(float_extend:DF
15479                      (match_operand:SF 2 "register_operand" "0"))]
15480                    UNSPEC_SINCOS_COS))
15481    (set (match_operand:DF 1 "register_operand" "=u")
15482         (unspec:DF [(float_extend:DF
15483                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15484   "TARGET_USE_FANCY_MATH_387
15485    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15486    && flag_unsafe_math_optimizations"
15487   "fsincos"
15488   [(set_attr "type" "fpspc")
15489    (set_attr "mode" "DF")])
15490
15491 (define_split
15492   [(set (match_operand:DF 0 "register_operand" "")
15493         (unspec:DF [(float_extend:DF
15494                      (match_operand:SF 2 "register_operand" ""))]
15495                    UNSPEC_SINCOS_COS))
15496    (set (match_operand:DF 1 "register_operand" "")
15497         (unspec:DF [(float_extend:DF
15498                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15499   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15500    && !reload_completed && !reload_in_progress"
15501   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15502                                    (match_dup 2))] UNSPEC_SIN))]
15503   "")
15504
15505 (define_split
15506   [(set (match_operand:DF 0 "register_operand" "")
15507         (unspec:DF [(float_extend:DF
15508                      (match_operand:SF 2 "register_operand" ""))]
15509                    UNSPEC_SINCOS_COS))
15510    (set (match_operand:DF 1 "register_operand" "")
15511         (unspec:DF [(float_extend:DF
15512                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15513   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15514    && !reload_completed && !reload_in_progress"
15515   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15516                                    (match_dup 2))] UNSPEC_COS))]
15517   "")
15518
15519 (define_insn "sincosxf3"
15520   [(set (match_operand:XF 0 "register_operand" "=f")
15521         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15522                    UNSPEC_SINCOS_COS))
15523    (set (match_operand:XF 1 "register_operand" "=u")
15524         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15525   "TARGET_USE_FANCY_MATH_387
15526    && flag_unsafe_math_optimizations"
15527   "fsincos"
15528   [(set_attr "type" "fpspc")
15529    (set_attr "mode" "XF")])
15530
15531 (define_split
15532   [(set (match_operand:XF 0 "register_operand" "")
15533         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15534                    UNSPEC_SINCOS_COS))
15535    (set (match_operand:XF 1 "register_operand" "")
15536         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15537   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15538    && !reload_completed && !reload_in_progress"
15539   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15540   "")
15541
15542 (define_split
15543   [(set (match_operand:XF 0 "register_operand" "")
15544         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15545                    UNSPEC_SINCOS_COS))
15546    (set (match_operand:XF 1 "register_operand" "")
15547         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15548   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15549    && !reload_completed && !reload_in_progress"
15550   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15551   "")
15552
15553 (define_insn "*tandf3_1"
15554   [(set (match_operand:DF 0 "register_operand" "=f")
15555         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15556                    UNSPEC_TAN_ONE))
15557    (set (match_operand:DF 1 "register_operand" "=u")
15558         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15559   "TARGET_USE_FANCY_MATH_387
15560    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15561    && flag_unsafe_math_optimizations"
15562   "fptan"
15563   [(set_attr "type" "fpspc")
15564    (set_attr "mode" "DF")])
15565
15566 ;; optimize sequence: fptan
15567 ;;                    fstp    %st(0)
15568 ;;                    fld1
15569 ;; into fptan insn.
15570
15571 (define_peephole2
15572   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15573                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15574                              UNSPEC_TAN_ONE))
15575              (set (match_operand:DF 1 "register_operand" "")
15576                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15577    (set (match_dup 0)
15578         (match_operand:DF 3 "immediate_operand" ""))]
15579   "standard_80387_constant_p (operands[3]) == 2"
15580   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15581              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15582   "")
15583
15584 (define_expand "tandf2"
15585   [(parallel [(set (match_dup 2)
15586                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15587                               UNSPEC_TAN_ONE))
15588               (set (match_operand:DF 0 "register_operand" "")
15589                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15590   "TARGET_USE_FANCY_MATH_387
15591    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15592    && flag_unsafe_math_optimizations"
15593 {
15594   operands[2] = gen_reg_rtx (DFmode);
15595 })
15596
15597 (define_insn "*tansf3_1"
15598   [(set (match_operand:SF 0 "register_operand" "=f")
15599         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15600                    UNSPEC_TAN_ONE))
15601    (set (match_operand:SF 1 "register_operand" "=u")
15602         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15603   "TARGET_USE_FANCY_MATH_387
15604    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15605    && flag_unsafe_math_optimizations"
15606   "fptan"
15607   [(set_attr "type" "fpspc")
15608    (set_attr "mode" "SF")])
15609
15610 ;; optimize sequence: fptan
15611 ;;                    fstp    %st(0)
15612 ;;                    fld1
15613 ;; into fptan insn.
15614
15615 (define_peephole2
15616   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15617                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15618                              UNSPEC_TAN_ONE))
15619              (set (match_operand:SF 1 "register_operand" "")
15620                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15621    (set (match_dup 0)
15622         (match_operand:SF 3 "immediate_operand" ""))]
15623   "standard_80387_constant_p (operands[3]) == 2"
15624   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15625              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15626   "")
15627
15628 (define_expand "tansf2"
15629   [(parallel [(set (match_dup 2)
15630                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15631                               UNSPEC_TAN_ONE))
15632               (set (match_operand:SF 0 "register_operand" "")
15633                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15634   "TARGET_USE_FANCY_MATH_387
15635    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15636    && flag_unsafe_math_optimizations"
15637 {
15638   operands[2] = gen_reg_rtx (SFmode);
15639 })
15640
15641 (define_insn "*tanxf3_1"
15642   [(set (match_operand:XF 0 "register_operand" "=f")
15643         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15644                    UNSPEC_TAN_ONE))
15645    (set (match_operand:XF 1 "register_operand" "=u")
15646         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15647   "TARGET_USE_FANCY_MATH_387
15648    && flag_unsafe_math_optimizations"
15649   "fptan"
15650   [(set_attr "type" "fpspc")
15651    (set_attr "mode" "XF")])
15652
15653 ;; optimize sequence: fptan
15654 ;;                    fstp    %st(0)
15655 ;;                    fld1
15656 ;; into fptan insn.
15657
15658 (define_peephole2
15659   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15660                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15661                              UNSPEC_TAN_ONE))
15662              (set (match_operand:XF 1 "register_operand" "")
15663                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15664    (set (match_dup 0)
15665         (match_operand:XF 3 "immediate_operand" ""))]
15666   "standard_80387_constant_p (operands[3]) == 2"
15667   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15668              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15669   "")
15670
15671 (define_expand "tanxf2"
15672   [(parallel [(set (match_dup 2)
15673                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15674                               UNSPEC_TAN_ONE))
15675               (set (match_operand:XF 0 "register_operand" "")
15676                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15677   "TARGET_USE_FANCY_MATH_387
15678    && flag_unsafe_math_optimizations"
15679 {
15680   operands[2] = gen_reg_rtx (XFmode);
15681 })
15682
15683 (define_insn "atan2df3_1"
15684   [(set (match_operand:DF 0 "register_operand" "=f")
15685         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15686                     (match_operand:DF 1 "register_operand" "u")]
15687                    UNSPEC_FPATAN))
15688    (clobber (match_scratch:DF 3 "=1"))]
15689   "TARGET_USE_FANCY_MATH_387
15690    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15691    && flag_unsafe_math_optimizations"
15692   "fpatan"
15693   [(set_attr "type" "fpspc")
15694    (set_attr "mode" "DF")])
15695
15696 (define_expand "atan2df3"
15697   [(use (match_operand:DF 0 "register_operand" ""))
15698    (use (match_operand:DF 2 "register_operand" ""))
15699    (use (match_operand:DF 1 "register_operand" ""))]
15700   "TARGET_USE_FANCY_MATH_387
15701    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15702    && flag_unsafe_math_optimizations"
15703 {
15704   rtx copy = gen_reg_rtx (DFmode);
15705   emit_move_insn (copy, operands[1]);
15706   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15707   DONE;
15708 })
15709
15710 (define_expand "atandf2"
15711   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15712                    (unspec:DF [(match_dup 2)
15713                                (match_operand:DF 1 "register_operand" "")]
15714                     UNSPEC_FPATAN))
15715               (clobber (match_scratch:DF 3 ""))])]
15716   "TARGET_USE_FANCY_MATH_387
15717    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15718    && flag_unsafe_math_optimizations"
15719 {
15720   operands[2] = gen_reg_rtx (DFmode);
15721   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15722 })
15723
15724 (define_insn "atan2sf3_1"
15725   [(set (match_operand:SF 0 "register_operand" "=f")
15726         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15727                     (match_operand:SF 1 "register_operand" "u")]
15728                    UNSPEC_FPATAN))
15729    (clobber (match_scratch:SF 3 "=1"))]
15730   "TARGET_USE_FANCY_MATH_387
15731    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15732    && flag_unsafe_math_optimizations"
15733   "fpatan"
15734   [(set_attr "type" "fpspc")
15735    (set_attr "mode" "SF")])
15736
15737 (define_expand "atan2sf3"
15738   [(use (match_operand:SF 0 "register_operand" ""))
15739    (use (match_operand:SF 2 "register_operand" ""))
15740    (use (match_operand:SF 1 "register_operand" ""))]
15741   "TARGET_USE_FANCY_MATH_387
15742    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15743    && flag_unsafe_math_optimizations"
15744 {
15745   rtx copy = gen_reg_rtx (SFmode);
15746   emit_move_insn (copy, operands[1]);
15747   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15748   DONE;
15749 })
15750
15751 (define_expand "atansf2"
15752   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15753                    (unspec:SF [(match_dup 2)
15754                                (match_operand:SF 1 "register_operand" "")]
15755                     UNSPEC_FPATAN))
15756               (clobber (match_scratch:SF 3 ""))])]
15757   "TARGET_USE_FANCY_MATH_387
15758    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15759    && flag_unsafe_math_optimizations"
15760 {
15761   operands[2] = gen_reg_rtx (SFmode);
15762   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15763 })
15764
15765 (define_insn "atan2xf3_1"
15766   [(set (match_operand:XF 0 "register_operand" "=f")
15767         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15768                     (match_operand:XF 1 "register_operand" "u")]
15769                    UNSPEC_FPATAN))
15770    (clobber (match_scratch:XF 3 "=1"))]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15773   "fpatan"
15774   [(set_attr "type" "fpspc")
15775    (set_attr "mode" "XF")])
15776
15777 (define_expand "atan2xf3"
15778   [(use (match_operand:XF 0 "register_operand" ""))
15779    (use (match_operand:XF 2 "register_operand" ""))
15780    (use (match_operand:XF 1 "register_operand" ""))]
15781   "TARGET_USE_FANCY_MATH_387
15782    && flag_unsafe_math_optimizations"
15783 {
15784   rtx copy = gen_reg_rtx (XFmode);
15785   emit_move_insn (copy, operands[1]);
15786   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15787   DONE;
15788 })
15789
15790 (define_expand "atanxf2"
15791   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15792                    (unspec:XF [(match_dup 2)
15793                                (match_operand:XF 1 "register_operand" "")]
15794                     UNSPEC_FPATAN))
15795               (clobber (match_scratch:XF 3 ""))])]
15796   "TARGET_USE_FANCY_MATH_387
15797    && flag_unsafe_math_optimizations"
15798 {
15799   operands[2] = gen_reg_rtx (XFmode);
15800   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15801 })
15802
15803 (define_expand "asindf2"
15804   [(set (match_dup 2)
15805         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15806    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15807    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15808    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15809    (parallel [(set (match_dup 7)
15810                    (unspec:XF [(match_dup 6) (match_dup 2)]
15811                               UNSPEC_FPATAN))
15812               (clobber (match_scratch:XF 8 ""))])
15813    (set (match_operand:DF 0 "register_operand" "")
15814         (float_truncate:DF (match_dup 7)))]
15815   "TARGET_USE_FANCY_MATH_387
15816    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15817    && flag_unsafe_math_optimizations"
15818 {
15819   int i;
15820
15821   for (i=2; i<8; i++)
15822     operands[i] = gen_reg_rtx (XFmode);
15823
15824   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15825 })
15826
15827 (define_expand "asinsf2"
15828   [(set (match_dup 2)
15829         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15830    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15831    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15832    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15833    (parallel [(set (match_dup 7)
15834                    (unspec:XF [(match_dup 6) (match_dup 2)]
15835                               UNSPEC_FPATAN))
15836               (clobber (match_scratch:XF 8 ""))])
15837    (set (match_operand:SF 0 "register_operand" "")
15838         (float_truncate:SF (match_dup 7)))]
15839   "TARGET_USE_FANCY_MATH_387
15840    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15841    && flag_unsafe_math_optimizations"
15842 {
15843   int i;
15844
15845   for (i=2; i<8; i++)
15846     operands[i] = gen_reg_rtx (XFmode);
15847
15848   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15849 })
15850
15851 (define_expand "asinxf2"
15852   [(set (match_dup 2)
15853         (mult:XF (match_operand:XF 1 "register_operand" "")
15854                  (match_dup 1)))
15855    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15856    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15857    (parallel [(set (match_operand:XF 0 "register_operand" "")
15858                    (unspec:XF [(match_dup 5) (match_dup 1)]
15859                               UNSPEC_FPATAN))
15860               (clobber (match_scratch:XF 6 ""))])]
15861   "TARGET_USE_FANCY_MATH_387
15862    && flag_unsafe_math_optimizations"
15863 {
15864   int i;
15865
15866   for (i=2; i<6; i++)
15867     operands[i] = gen_reg_rtx (XFmode);
15868
15869   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15870 })
15871
15872 (define_expand "acosdf2"
15873   [(set (match_dup 2)
15874         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15875    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15876    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15877    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15878    (parallel [(set (match_dup 7)
15879                    (unspec:XF [(match_dup 2) (match_dup 6)]
15880                               UNSPEC_FPATAN))
15881               (clobber (match_scratch:XF 8 ""))])
15882    (set (match_operand:DF 0 "register_operand" "")
15883         (float_truncate:DF (match_dup 7)))]
15884   "TARGET_USE_FANCY_MATH_387
15885    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15886    && flag_unsafe_math_optimizations"
15887 {
15888   int i;
15889
15890   for (i=2; i<8; i++)
15891     operands[i] = gen_reg_rtx (XFmode);
15892
15893   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15894 })
15895
15896 (define_expand "acossf2"
15897   [(set (match_dup 2)
15898         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15899    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15900    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15901    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15902    (parallel [(set (match_dup 7)
15903                    (unspec:XF [(match_dup 2) (match_dup 6)]
15904                               UNSPEC_FPATAN))
15905               (clobber (match_scratch:XF 8 ""))])
15906    (set (match_operand:SF 0 "register_operand" "")
15907         (float_truncate:SF (match_dup 7)))]
15908   "TARGET_USE_FANCY_MATH_387
15909    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15910    && flag_unsafe_math_optimizations"
15911 {
15912   int i;
15913
15914   for (i=2; i<8; i++)
15915     operands[i] = gen_reg_rtx (XFmode);
15916
15917   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15918 })
15919
15920 (define_expand "acosxf2"
15921   [(set (match_dup 2)
15922         (mult:XF (match_operand:XF 1 "register_operand" "")
15923                  (match_dup 1)))
15924    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15925    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15926    (parallel [(set (match_operand:XF 0 "register_operand" "")
15927                    (unspec:XF [(match_dup 1) (match_dup 5)]
15928                               UNSPEC_FPATAN))
15929               (clobber (match_scratch:XF 6 ""))])]
15930   "TARGET_USE_FANCY_MATH_387
15931    && flag_unsafe_math_optimizations"
15932 {
15933   int i;
15934
15935   for (i=2; i<6; i++)
15936     operands[i] = gen_reg_rtx (XFmode);
15937
15938   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15939 })
15940
15941 (define_insn "fyl2x_xf3"
15942   [(set (match_operand:XF 0 "register_operand" "=f")
15943         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15944                     (match_operand:XF 1 "register_operand" "u")]
15945                    UNSPEC_FYL2X))
15946    (clobber (match_scratch:XF 3 "=1"))]
15947   "TARGET_USE_FANCY_MATH_387
15948    && flag_unsafe_math_optimizations"
15949   "fyl2x"
15950   [(set_attr "type" "fpspc")
15951    (set_attr "mode" "XF")])
15952
15953 (define_expand "logsf2"
15954   [(set (match_dup 2)
15955         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15956    (parallel [(set (match_dup 4)
15957                    (unspec:XF [(match_dup 2)
15958                                (match_dup 3)] UNSPEC_FYL2X))
15959               (clobber (match_scratch:XF 5 ""))])
15960    (set (match_operand:SF 0 "register_operand" "")
15961         (float_truncate:SF (match_dup 4)))]
15962   "TARGET_USE_FANCY_MATH_387
15963    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15964    && flag_unsafe_math_optimizations"
15965 {
15966   rtx temp;
15967
15968   operands[2] = gen_reg_rtx (XFmode);
15969   operands[3] = gen_reg_rtx (XFmode);
15970   operands[4] = gen_reg_rtx (XFmode);
15971
15972   temp = standard_80387_constant_rtx (4); /* fldln2 */
15973   emit_move_insn (operands[3], temp);
15974 })
15975
15976 (define_expand "logdf2"
15977   [(set (match_dup 2)
15978         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15979    (parallel [(set (match_dup 4)
15980                    (unspec:XF [(match_dup 2)
15981                                (match_dup 3)] UNSPEC_FYL2X))
15982               (clobber (match_scratch:XF 5 ""))])
15983    (set (match_operand:DF 0 "register_operand" "")
15984         (float_truncate:DF (match_dup 4)))]
15985   "TARGET_USE_FANCY_MATH_387
15986    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987    && flag_unsafe_math_optimizations"
15988 {
15989   rtx temp;
15990
15991   operands[2] = gen_reg_rtx (XFmode);
15992   operands[3] = gen_reg_rtx (XFmode);
15993   operands[4] = gen_reg_rtx (XFmode);
15994
15995   temp = standard_80387_constant_rtx (4); /* fldln2 */
15996   emit_move_insn (operands[3], temp);
15997 })
15998
15999 (define_expand "logxf2"
16000   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16001                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16002                                (match_dup 2)] UNSPEC_FYL2X))
16003               (clobber (match_scratch:XF 3 ""))])]
16004   "TARGET_USE_FANCY_MATH_387
16005    && flag_unsafe_math_optimizations"
16006 {
16007   rtx temp;
16008
16009   operands[2] = gen_reg_rtx (XFmode);
16010   temp = standard_80387_constant_rtx (4); /* fldln2 */
16011   emit_move_insn (operands[2], temp);
16012 })
16013
16014 (define_expand "log10sf2"
16015   [(set (match_dup 2)
16016         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16017    (parallel [(set (match_dup 4)
16018                    (unspec:XF [(match_dup 2)
16019                                (match_dup 3)] UNSPEC_FYL2X))
16020               (clobber (match_scratch:XF 5 ""))])
16021    (set (match_operand:SF 0 "register_operand" "")
16022         (float_truncate:SF (match_dup 4)))]
16023   "TARGET_USE_FANCY_MATH_387
16024    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16025    && flag_unsafe_math_optimizations"
16026 {
16027   rtx temp;
16028
16029   operands[2] = gen_reg_rtx (XFmode);
16030   operands[3] = gen_reg_rtx (XFmode);
16031   operands[4] = gen_reg_rtx (XFmode);
16032
16033   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16034   emit_move_insn (operands[3], temp);
16035 })
16036
16037 (define_expand "log10df2"
16038   [(set (match_dup 2)
16039         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16040    (parallel [(set (match_dup 4)
16041                    (unspec:XF [(match_dup 2)
16042                                (match_dup 3)] UNSPEC_FYL2X))
16043               (clobber (match_scratch:XF 5 ""))])
16044    (set (match_operand:DF 0 "register_operand" "")
16045         (float_truncate:DF (match_dup 4)))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048    && flag_unsafe_math_optimizations"
16049 {
16050   rtx temp;
16051
16052   operands[2] = gen_reg_rtx (XFmode);
16053   operands[3] = gen_reg_rtx (XFmode);
16054   operands[4] = gen_reg_rtx (XFmode);
16055
16056   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16057   emit_move_insn (operands[3], temp);
16058 })
16059
16060 (define_expand "log10xf2"
16061   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16062                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16063                                (match_dup 2)] UNSPEC_FYL2X))
16064               (clobber (match_scratch:XF 3 ""))])]
16065   "TARGET_USE_FANCY_MATH_387
16066    && flag_unsafe_math_optimizations"
16067 {
16068   rtx temp;
16069
16070   operands[2] = gen_reg_rtx (XFmode);
16071   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16072   emit_move_insn (operands[2], temp);
16073 })
16074
16075 (define_expand "log2sf2"
16076   [(set (match_dup 2)
16077         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16078    (parallel [(set (match_dup 4)
16079                    (unspec:XF [(match_dup 2)
16080                                (match_dup 3)] UNSPEC_FYL2X))
16081               (clobber (match_scratch:XF 5 ""))])
16082    (set (match_operand:SF 0 "register_operand" "")
16083         (float_truncate:SF (match_dup 4)))]
16084   "TARGET_USE_FANCY_MATH_387
16085    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16086    && flag_unsafe_math_optimizations"
16087 {
16088   operands[2] = gen_reg_rtx (XFmode);
16089   operands[3] = gen_reg_rtx (XFmode);
16090   operands[4] = gen_reg_rtx (XFmode);
16091
16092   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16093 })
16094
16095 (define_expand "log2df2"
16096   [(set (match_dup 2)
16097         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16098    (parallel [(set (match_dup 4)
16099                    (unspec:XF [(match_dup 2)
16100                                (match_dup 3)] UNSPEC_FYL2X))
16101               (clobber (match_scratch:XF 5 ""))])
16102    (set (match_operand:DF 0 "register_operand" "")
16103         (float_truncate:DF (match_dup 4)))]
16104   "TARGET_USE_FANCY_MATH_387
16105    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16106    && flag_unsafe_math_optimizations"
16107 {
16108   operands[2] = gen_reg_rtx (XFmode);
16109   operands[3] = gen_reg_rtx (XFmode);
16110   operands[4] = gen_reg_rtx (XFmode);
16111
16112   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16113 })
16114
16115 (define_expand "log2xf2"
16116   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16117                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16118                                (match_dup 2)] UNSPEC_FYL2X))
16119               (clobber (match_scratch:XF 3 ""))])]
16120   "TARGET_USE_FANCY_MATH_387
16121    && flag_unsafe_math_optimizations"
16122 {
16123   operands[2] = gen_reg_rtx (XFmode);
16124   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16125 })
16126
16127 (define_insn "fyl2xp1_xf3"
16128   [(set (match_operand:XF 0 "register_operand" "=f")
16129         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16130                     (match_operand:XF 1 "register_operand" "u")]
16131                    UNSPEC_FYL2XP1))
16132    (clobber (match_scratch:XF 3 "=1"))]
16133   "TARGET_USE_FANCY_MATH_387
16134    && flag_unsafe_math_optimizations"
16135   "fyl2xp1"
16136   [(set_attr "type" "fpspc")
16137    (set_attr "mode" "XF")])
16138
16139 (define_expand "log1psf2"
16140   [(use (match_operand:SF 0 "register_operand" ""))
16141    (use (match_operand:SF 1 "register_operand" ""))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16144    && flag_unsafe_math_optimizations"
16145 {
16146   rtx op0 = gen_reg_rtx (XFmode);
16147   rtx op1 = gen_reg_rtx (XFmode);
16148
16149   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16150   ix86_emit_i387_log1p (op0, op1);
16151   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16152   DONE;
16153 })
16154
16155 (define_expand "log1pdf2"
16156   [(use (match_operand:DF 0 "register_operand" ""))
16157    (use (match_operand:DF 1 "register_operand" ""))]
16158   "TARGET_USE_FANCY_MATH_387
16159    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16160    && flag_unsafe_math_optimizations"
16161 {
16162   rtx op0 = gen_reg_rtx (XFmode);
16163   rtx op1 = gen_reg_rtx (XFmode);
16164
16165   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16166   ix86_emit_i387_log1p (op0, op1);
16167   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16168   DONE;
16169 })
16170
16171 (define_expand "log1pxf2"
16172   [(use (match_operand:XF 0 "register_operand" ""))
16173    (use (match_operand:XF 1 "register_operand" ""))]
16174   "TARGET_USE_FANCY_MATH_387
16175    && flag_unsafe_math_optimizations"
16176 {
16177   ix86_emit_i387_log1p (operands[0], operands[1]);
16178   DONE;
16179 })
16180
16181 (define_insn "*fxtractxf3"
16182   [(set (match_operand:XF 0 "register_operand" "=f")
16183         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16184                    UNSPEC_XTRACT_FRACT))
16185    (set (match_operand:XF 1 "register_operand" "=u")
16186         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189   "fxtract"
16190   [(set_attr "type" "fpspc")
16191    (set_attr "mode" "XF")])
16192
16193 (define_expand "logbsf2"
16194   [(set (match_dup 2)
16195         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16196    (parallel [(set (match_dup 3)
16197                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16198               (set (match_dup 4)
16199                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16200    (set (match_operand:SF 0 "register_operand" "")
16201         (float_truncate:SF (match_dup 4)))]
16202   "TARGET_USE_FANCY_MATH_387
16203    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16204    && flag_unsafe_math_optimizations"
16205 {
16206   operands[2] = gen_reg_rtx (XFmode);
16207   operands[3] = gen_reg_rtx (XFmode);
16208   operands[4] = gen_reg_rtx (XFmode);
16209 })
16210
16211 (define_expand "logbdf2"
16212   [(set (match_dup 2)
16213         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16214    (parallel [(set (match_dup 3)
16215                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16216               (set (match_dup 4)
16217                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16218    (set (match_operand:DF 0 "register_operand" "")
16219         (float_truncate:DF (match_dup 4)))]
16220   "TARGET_USE_FANCY_MATH_387
16221    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16222    && flag_unsafe_math_optimizations"
16223 {
16224   operands[2] = gen_reg_rtx (XFmode);
16225   operands[3] = gen_reg_rtx (XFmode);
16226   operands[4] = gen_reg_rtx (XFmode);
16227 })
16228
16229 (define_expand "logbxf2"
16230   [(parallel [(set (match_dup 2)
16231                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16232                               UNSPEC_XTRACT_FRACT))
16233               (set (match_operand:XF 0 "register_operand" "")
16234                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16235   "TARGET_USE_FANCY_MATH_387
16236    && flag_unsafe_math_optimizations"
16237 {
16238   operands[2] = gen_reg_rtx (XFmode);
16239 })
16240
16241 (define_expand "ilogbsi2"
16242   [(parallel [(set (match_dup 2)
16243                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16244                               UNSPEC_XTRACT_FRACT))
16245               (set (match_operand:XF 3 "register_operand" "")
16246                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16247    (parallel [(set (match_operand:SI 0 "register_operand" "")
16248                    (fix:SI (match_dup 3)))
16249               (clobber (reg:CC FLAGS_REG))])]
16250   "TARGET_USE_FANCY_MATH_387
16251    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16252    && flag_unsafe_math_optimizations"
16253 {
16254   operands[2] = gen_reg_rtx (XFmode);
16255   operands[3] = gen_reg_rtx (XFmode);
16256 })
16257
16258 (define_insn "*f2xm1xf2"
16259   [(set (match_operand:XF 0 "register_operand" "=f")
16260         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16261          UNSPEC_F2XM1))]
16262   "TARGET_USE_FANCY_MATH_387
16263    && flag_unsafe_math_optimizations"
16264   "f2xm1"
16265   [(set_attr "type" "fpspc")
16266    (set_attr "mode" "XF")])
16267
16268 (define_insn "*fscalexf4"
16269   [(set (match_operand:XF 0 "register_operand" "=f")
16270         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16271                     (match_operand:XF 3 "register_operand" "1")]
16272                    UNSPEC_FSCALE_FRACT))
16273    (set (match_operand:XF 1 "register_operand" "=u")
16274         (unspec:XF [(match_dup 2) (match_dup 3)]
16275                    UNSPEC_FSCALE_EXP))]
16276   "TARGET_USE_FANCY_MATH_387
16277    && flag_unsafe_math_optimizations"
16278   "fscale"
16279   [(set_attr "type" "fpspc")
16280    (set_attr "mode" "XF")])
16281
16282 (define_expand "expsf2"
16283   [(set (match_dup 2)
16284         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16285    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16286    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16287    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16288    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16289    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16290    (parallel [(set (match_dup 10)
16291                    (unspec:XF [(match_dup 9) (match_dup 5)]
16292                               UNSPEC_FSCALE_FRACT))
16293               (set (match_dup 11)
16294                    (unspec:XF [(match_dup 9) (match_dup 5)]
16295                               UNSPEC_FSCALE_EXP))])
16296    (set (match_operand:SF 0 "register_operand" "")
16297         (float_truncate:SF (match_dup 10)))]
16298   "TARGET_USE_FANCY_MATH_387
16299    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16300    && flag_unsafe_math_optimizations"
16301 {
16302   rtx temp;
16303   int i;
16304
16305   for (i=2; i<12; i++)
16306     operands[i] = gen_reg_rtx (XFmode);
16307   temp = standard_80387_constant_rtx (5); /* fldl2e */
16308   emit_move_insn (operands[3], temp);
16309   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16310 })
16311
16312 (define_expand "expdf2"
16313   [(set (match_dup 2)
16314         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16315    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16316    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16317    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16318    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16319    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16320    (parallel [(set (match_dup 10)
16321                    (unspec:XF [(match_dup 9) (match_dup 5)]
16322                               UNSPEC_FSCALE_FRACT))
16323               (set (match_dup 11)
16324                    (unspec:XF [(match_dup 9) (match_dup 5)]
16325                               UNSPEC_FSCALE_EXP))])
16326    (set (match_operand:DF 0 "register_operand" "")
16327         (float_truncate:DF (match_dup 10)))]
16328   "TARGET_USE_FANCY_MATH_387
16329    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16330    && flag_unsafe_math_optimizations"
16331 {
16332   rtx temp;
16333   int i;
16334
16335   for (i=2; i<12; i++)
16336     operands[i] = gen_reg_rtx (XFmode);
16337   temp = standard_80387_constant_rtx (5); /* fldl2e */
16338   emit_move_insn (operands[3], temp);
16339   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16340 })
16341
16342 (define_expand "expxf2"
16343   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16344                                (match_dup 2)))
16345    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16346    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16347    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16348    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16349    (parallel [(set (match_operand:XF 0 "register_operand" "")
16350                    (unspec:XF [(match_dup 8) (match_dup 4)]
16351                               UNSPEC_FSCALE_FRACT))
16352               (set (match_dup 9)
16353                    (unspec:XF [(match_dup 8) (match_dup 4)]
16354                               UNSPEC_FSCALE_EXP))])]
16355   "TARGET_USE_FANCY_MATH_387
16356    && flag_unsafe_math_optimizations"
16357 {
16358   rtx temp;
16359   int i;
16360
16361   for (i=2; i<10; i++)
16362     operands[i] = gen_reg_rtx (XFmode);
16363   temp = standard_80387_constant_rtx (5); /* fldl2e */
16364   emit_move_insn (operands[2], temp);
16365   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16366 })
16367
16368 (define_expand "exp10sf2"
16369   [(set (match_dup 2)
16370         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16371    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16372    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16373    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16374    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16375    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16376    (parallel [(set (match_dup 10)
16377                    (unspec:XF [(match_dup 9) (match_dup 5)]
16378                               UNSPEC_FSCALE_FRACT))
16379               (set (match_dup 11)
16380                    (unspec:XF [(match_dup 9) (match_dup 5)]
16381                               UNSPEC_FSCALE_EXP))])
16382    (set (match_operand:SF 0 "register_operand" "")
16383         (float_truncate:SF (match_dup 10)))]
16384   "TARGET_USE_FANCY_MATH_387
16385    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16386    && flag_unsafe_math_optimizations"
16387 {
16388   rtx temp;
16389   int i;
16390
16391   for (i=2; i<12; i++)
16392     operands[i] = gen_reg_rtx (XFmode);
16393   temp = standard_80387_constant_rtx (6); /* fldl2t */
16394   emit_move_insn (operands[3], temp);
16395   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16396 })
16397
16398 (define_expand "exp10df2"
16399   [(set (match_dup 2)
16400         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16401    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16402    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16403    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16404    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16405    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16406    (parallel [(set (match_dup 10)
16407                    (unspec:XF [(match_dup 9) (match_dup 5)]
16408                               UNSPEC_FSCALE_FRACT))
16409               (set (match_dup 11)
16410                    (unspec:XF [(match_dup 9) (match_dup 5)]
16411                               UNSPEC_FSCALE_EXP))])
16412    (set (match_operand:DF 0 "register_operand" "")
16413         (float_truncate:DF (match_dup 10)))]
16414   "TARGET_USE_FANCY_MATH_387
16415    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16416    && flag_unsafe_math_optimizations"
16417 {
16418   rtx temp;
16419   int i;
16420
16421   for (i=2; i<12; i++)
16422     operands[i] = gen_reg_rtx (XFmode);
16423   temp = standard_80387_constant_rtx (6); /* fldl2t */
16424   emit_move_insn (operands[3], temp);
16425   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16426 })
16427
16428 (define_expand "exp10xf2"
16429   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16430                                (match_dup 2)))
16431    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16432    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16433    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16434    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16435    (parallel [(set (match_operand:XF 0 "register_operand" "")
16436                    (unspec:XF [(match_dup 8) (match_dup 4)]
16437                               UNSPEC_FSCALE_FRACT))
16438               (set (match_dup 9)
16439                    (unspec:XF [(match_dup 8) (match_dup 4)]
16440                               UNSPEC_FSCALE_EXP))])]
16441   "TARGET_USE_FANCY_MATH_387
16442    && flag_unsafe_math_optimizations"
16443 {
16444   rtx temp;
16445   int i;
16446
16447   for (i=2; i<10; i++)
16448     operands[i] = gen_reg_rtx (XFmode);
16449   temp = standard_80387_constant_rtx (6); /* fldl2t */
16450   emit_move_insn (operands[2], temp);
16451   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16452 })
16453
16454 (define_expand "exp2sf2"
16455   [(set (match_dup 2)
16456         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16457    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16458    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16459    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16460    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16461    (parallel [(set (match_dup 8)
16462                    (unspec:XF [(match_dup 7) (match_dup 3)]
16463                               UNSPEC_FSCALE_FRACT))
16464               (set (match_dup 9)
16465                    (unspec:XF [(match_dup 7) (match_dup 3)]
16466                               UNSPEC_FSCALE_EXP))])
16467    (set (match_operand:SF 0 "register_operand" "")
16468         (float_truncate:SF (match_dup 8)))]
16469   "TARGET_USE_FANCY_MATH_387
16470    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16471    && flag_unsafe_math_optimizations"
16472 {
16473   int i;
16474
16475   for (i=2; i<10; i++)
16476     operands[i] = gen_reg_rtx (XFmode);
16477   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16478 })
16479
16480 (define_expand "exp2df2"
16481   [(set (match_dup 2)
16482         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16483    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16484    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16485    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16486    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16487    (parallel [(set (match_dup 8)
16488                    (unspec:XF [(match_dup 7) (match_dup 3)]
16489                               UNSPEC_FSCALE_FRACT))
16490               (set (match_dup 9)
16491                    (unspec:XF [(match_dup 7) (match_dup 3)]
16492                               UNSPEC_FSCALE_EXP))])
16493    (set (match_operand:DF 0 "register_operand" "")
16494         (float_truncate:DF (match_dup 8)))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16497    && flag_unsafe_math_optimizations"
16498 {
16499   int i;
16500
16501   for (i=2; i<10; i++)
16502     operands[i] = gen_reg_rtx (XFmode);
16503   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16504 })
16505
16506 (define_expand "exp2xf2"
16507   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16508    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16509    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16510    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16511    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16512    (parallel [(set (match_operand:XF 0 "register_operand" "")
16513                    (unspec:XF [(match_dup 7) (match_dup 3)]
16514                               UNSPEC_FSCALE_FRACT))
16515               (set (match_dup 8)
16516                    (unspec:XF [(match_dup 7) (match_dup 3)]
16517                               UNSPEC_FSCALE_EXP))])]
16518   "TARGET_USE_FANCY_MATH_387
16519    && flag_unsafe_math_optimizations"
16520 {
16521   int i;
16522
16523   for (i=2; i<9; i++)
16524     operands[i] = gen_reg_rtx (XFmode);
16525   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16526 })
16527
16528 (define_expand "expm1df2"
16529   [(set (match_dup 2)
16530         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16531    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16532    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16533    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16534    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16535    (parallel [(set (match_dup 8)
16536                    (unspec:XF [(match_dup 7) (match_dup 5)]
16537                               UNSPEC_FSCALE_FRACT))
16538                    (set (match_dup 9)
16539                    (unspec:XF [(match_dup 7) (match_dup 5)]
16540                               UNSPEC_FSCALE_EXP))])
16541    (parallel [(set (match_dup 11)
16542                    (unspec:XF [(match_dup 10) (match_dup 9)]
16543                               UNSPEC_FSCALE_FRACT))
16544               (set (match_dup 12)
16545                    (unspec:XF [(match_dup 10) (match_dup 9)]
16546                               UNSPEC_FSCALE_EXP))])
16547    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16548    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16549    (set (match_operand:DF 0 "register_operand" "")
16550         (float_truncate:DF (match_dup 14)))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16553    && flag_unsafe_math_optimizations"
16554 {
16555   rtx temp;
16556   int i;
16557
16558   for (i=2; i<15; i++)
16559     operands[i] = gen_reg_rtx (XFmode);
16560   temp = standard_80387_constant_rtx (5); /* fldl2e */
16561   emit_move_insn (operands[3], temp);
16562   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16563 })
16564
16565 (define_expand "expm1sf2"
16566   [(set (match_dup 2)
16567         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16568    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16569    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16570    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16571    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16572    (parallel [(set (match_dup 8)
16573                    (unspec:XF [(match_dup 7) (match_dup 5)]
16574                               UNSPEC_FSCALE_FRACT))
16575                    (set (match_dup 9)
16576                    (unspec:XF [(match_dup 7) (match_dup 5)]
16577                               UNSPEC_FSCALE_EXP))])
16578    (parallel [(set (match_dup 11)
16579                    (unspec:XF [(match_dup 10) (match_dup 9)]
16580                               UNSPEC_FSCALE_FRACT))
16581               (set (match_dup 12)
16582                    (unspec:XF [(match_dup 10) (match_dup 9)]
16583                               UNSPEC_FSCALE_EXP))])
16584    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16585    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16586    (set (match_operand:SF 0 "register_operand" "")
16587         (float_truncate:SF (match_dup 14)))]
16588   "TARGET_USE_FANCY_MATH_387
16589    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16590    && flag_unsafe_math_optimizations"
16591 {
16592   rtx temp;
16593   int i;
16594
16595   for (i=2; i<15; i++)
16596     operands[i] = gen_reg_rtx (XFmode);
16597   temp = standard_80387_constant_rtx (5); /* fldl2e */
16598   emit_move_insn (operands[3], temp);
16599   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16600 })
16601
16602 (define_expand "expm1xf2"
16603   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16604                                (match_dup 2)))
16605    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16606    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16607    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16608    (parallel [(set (match_dup 7)
16609                    (unspec:XF [(match_dup 6) (match_dup 4)]
16610                               UNSPEC_FSCALE_FRACT))
16611                    (set (match_dup 8)
16612                    (unspec:XF [(match_dup 6) (match_dup 4)]
16613                               UNSPEC_FSCALE_EXP))])
16614    (parallel [(set (match_dup 10)
16615                    (unspec:XF [(match_dup 9) (match_dup 8)]
16616                               UNSPEC_FSCALE_FRACT))
16617               (set (match_dup 11)
16618                    (unspec:XF [(match_dup 9) (match_dup 8)]
16619                               UNSPEC_FSCALE_EXP))])
16620    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16621    (set (match_operand:XF 0 "register_operand" "")
16622         (plus:XF (match_dup 12) (match_dup 7)))]
16623   "TARGET_USE_FANCY_MATH_387
16624    && flag_unsafe_math_optimizations"
16625 {
16626   rtx temp;
16627   int i;
16628
16629   for (i=2; i<13; i++)
16630     operands[i] = gen_reg_rtx (XFmode);
16631   temp = standard_80387_constant_rtx (5); /* fldl2e */
16632   emit_move_insn (operands[2], temp);
16633   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16634 })
16635
16636 (define_expand "ldexpdf3"
16637   [(set (match_dup 3)
16638         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16639    (set (match_dup 4)
16640         (float:XF (match_operand:SI 2 "register_operand" "")))
16641    (parallel [(set (match_dup 5)
16642                    (unspec:XF [(match_dup 3) (match_dup 4)]
16643                               UNSPEC_FSCALE_FRACT))
16644               (set (match_dup 6)
16645                    (unspec:XF [(match_dup 3) (match_dup 4)]
16646                               UNSPEC_FSCALE_EXP))])
16647    (set (match_operand:DF 0 "register_operand" "")
16648         (float_truncate:DF (match_dup 5)))]
16649   "TARGET_USE_FANCY_MATH_387
16650    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16651    && flag_unsafe_math_optimizations"
16652 {
16653   int i;
16654
16655   for (i=3; i<7; i++)
16656     operands[i] = gen_reg_rtx (XFmode);
16657 })
16658
16659 (define_expand "ldexpsf3"
16660   [(set (match_dup 3)
16661         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16662    (set (match_dup 4)
16663         (float:XF (match_operand:SI 2 "register_operand" "")))
16664    (parallel [(set (match_dup 5)
16665                    (unspec:XF [(match_dup 3) (match_dup 4)]
16666                               UNSPEC_FSCALE_FRACT))
16667               (set (match_dup 6)
16668                    (unspec:XF [(match_dup 3) (match_dup 4)]
16669                               UNSPEC_FSCALE_EXP))])
16670    (set (match_operand:SF 0 "register_operand" "")
16671         (float_truncate:SF (match_dup 5)))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16674    && flag_unsafe_math_optimizations"
16675 {
16676   int i;
16677
16678   for (i=3; i<7; i++)
16679     operands[i] = gen_reg_rtx (XFmode);
16680 })
16681
16682 (define_expand "ldexpxf3"
16683   [(set (match_dup 3)
16684         (float:XF (match_operand:SI 2 "register_operand" "")))
16685    (parallel [(set (match_operand:XF 0 " register_operand" "")
16686                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16687                                (match_dup 3)]
16688                               UNSPEC_FSCALE_FRACT))
16689               (set (match_dup 4)
16690                    (unspec:XF [(match_dup 1) (match_dup 3)]
16691                               UNSPEC_FSCALE_EXP))])]
16692   "TARGET_USE_FANCY_MATH_387
16693    && flag_unsafe_math_optimizations"
16694 {
16695   int i;
16696
16697   for (i=3; i<5; i++)
16698     operands[i] = gen_reg_rtx (XFmode);
16699 })
16700 \f
16701
16702 (define_insn "frndintxf2"
16703   [(set (match_operand:XF 0 "register_operand" "=f")
16704         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16705          UNSPEC_FRNDINT))]
16706   "TARGET_USE_FANCY_MATH_387
16707    && flag_unsafe_math_optimizations"
16708   "frndint"
16709   [(set_attr "type" "fpspc")
16710    (set_attr "mode" "XF")])
16711
16712 (define_expand "rintdf2"
16713   [(use (match_operand:DF 0 "register_operand" ""))
16714    (use (match_operand:DF 1 "register_operand" ""))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16717    && flag_unsafe_math_optimizations"
16718 {
16719   rtx op0 = gen_reg_rtx (XFmode);
16720   rtx op1 = gen_reg_rtx (XFmode);
16721
16722   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16723   emit_insn (gen_frndintxf2 (op0, op1));
16724
16725   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16726   DONE;
16727 })
16728
16729 (define_expand "rintsf2"
16730   [(use (match_operand:SF 0 "register_operand" ""))
16731    (use (match_operand:SF 1 "register_operand" ""))]
16732   "TARGET_USE_FANCY_MATH_387
16733    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16734    && flag_unsafe_math_optimizations"
16735 {
16736   rtx op0 = gen_reg_rtx (XFmode);
16737   rtx op1 = gen_reg_rtx (XFmode);
16738
16739   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16740   emit_insn (gen_frndintxf2 (op0, op1));
16741
16742   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16743   DONE;
16744 })
16745
16746 (define_expand "rintxf2"
16747   [(use (match_operand:XF 0 "register_operand" ""))
16748    (use (match_operand:XF 1 "register_operand" ""))]
16749   "TARGET_USE_FANCY_MATH_387
16750    && flag_unsafe_math_optimizations"
16751 {
16752   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16753   DONE;
16754 })
16755
16756 (define_insn_and_split "*fistdi2_1"
16757   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16758         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16759          UNSPEC_FIST))]
16760   "TARGET_USE_FANCY_MATH_387
16761    && flag_unsafe_math_optimizations
16762    && !(reload_completed || reload_in_progress)"
16763   "#"
16764   "&& 1"
16765   [(const_int 0)]
16766 {
16767   if (memory_operand (operands[0], VOIDmode))
16768     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16769   else
16770     {
16771       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16772       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16773                                          operands[2]));
16774     }
16775   DONE;
16776 }
16777   [(set_attr "type" "fpspc")
16778    (set_attr "mode" "DI")])
16779
16780 (define_insn "fistdi2"
16781   [(set (match_operand:DI 0 "memory_operand" "=m")
16782         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16783          UNSPEC_FIST))
16784    (clobber (match_scratch:XF 2 "=&1f"))]
16785   "TARGET_USE_FANCY_MATH_387
16786    && flag_unsafe_math_optimizations"
16787   "* return output_fix_trunc (insn, operands, 0);"
16788   [(set_attr "type" "fpspc")
16789    (set_attr "mode" "DI")])
16790
16791 (define_insn "fistdi2_with_temp"
16792   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16793         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16794          UNSPEC_FIST))
16795    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16796    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16797   "TARGET_USE_FANCY_MATH_387
16798    && flag_unsafe_math_optimizations"
16799   "#"
16800   [(set_attr "type" "fpspc")
16801    (set_attr "mode" "DI")])
16802
16803 (define_split 
16804   [(set (match_operand:DI 0 "register_operand" "")
16805         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16806          UNSPEC_FIST))
16807    (clobber (match_operand:DI 2 "memory_operand" ""))
16808    (clobber (match_scratch 3 ""))]
16809   "reload_completed"
16810   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16811               (clobber (match_dup 3))])
16812    (set (match_dup 0) (match_dup 2))]
16813   "")
16814
16815 (define_split 
16816   [(set (match_operand:DI 0 "memory_operand" "")
16817         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16818          UNSPEC_FIST))
16819    (clobber (match_operand:DI 2 "memory_operand" ""))
16820    (clobber (match_scratch 3 ""))]
16821   "reload_completed"
16822   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16823               (clobber (match_dup 3))])]
16824   "")
16825
16826 (define_insn_and_split "*fist<mode>2_1"
16827   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16828         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16829          UNSPEC_FIST))]
16830   "TARGET_USE_FANCY_MATH_387
16831    && flag_unsafe_math_optimizations
16832    && !(reload_completed || reload_in_progress)"
16833   "#"
16834   "&& 1"
16835   [(const_int 0)]
16836 {
16837   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16838   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16839                                         operands[2]));
16840   DONE;
16841 }
16842   [(set_attr "type" "fpspc")
16843    (set_attr "mode" "<MODE>")])
16844
16845 (define_insn "fist<mode>2"
16846   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16847         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16848          UNSPEC_FIST))]
16849   "TARGET_USE_FANCY_MATH_387
16850    && flag_unsafe_math_optimizations"
16851   "* return output_fix_trunc (insn, operands, 0);"
16852   [(set_attr "type" "fpspc")
16853    (set_attr "mode" "<MODE>")])
16854
16855 (define_insn "fist<mode>2_with_temp"
16856   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16857         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16858          UNSPEC_FIST))
16859    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16860   "TARGET_USE_FANCY_MATH_387
16861    && flag_unsafe_math_optimizations"
16862   "#"
16863   [(set_attr "type" "fpspc")
16864    (set_attr "mode" "<MODE>")])
16865
16866 (define_split 
16867   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16868         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16869          UNSPEC_FIST))
16870    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16871   "reload_completed"
16872   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16873                        UNSPEC_FIST))
16874    (set (match_dup 0) (match_dup 2))]
16875   "")
16876
16877 (define_split 
16878   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16879         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16880          UNSPEC_FIST))
16881    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16882   "reload_completed"
16883   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16884                        UNSPEC_FIST))]
16885   "")
16886
16887 (define_expand "lrint<mode>2"
16888   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16889         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16890          UNSPEC_FIST))]
16891   "TARGET_USE_FANCY_MATH_387
16892    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16893    && flag_unsafe_math_optimizations"
16894   "")
16895
16896 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16897 (define_insn_and_split "frndintxf2_floor"
16898   [(set (match_operand:XF 0 "register_operand" "=f")
16899         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16900          UNSPEC_FRNDINT_FLOOR))
16901    (clobber (reg:CC FLAGS_REG))]
16902   "TARGET_USE_FANCY_MATH_387
16903    && flag_unsafe_math_optimizations
16904    && !(reload_completed || reload_in_progress)"
16905   "#"
16906   "&& 1"
16907   [(const_int 0)]
16908 {
16909   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16910
16911   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16912   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16913
16914   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16915                                         operands[2], operands[3]));
16916   DONE;
16917 }
16918   [(set_attr "type" "frndint")
16919    (set_attr "i387_cw" "floor")
16920    (set_attr "mode" "XF")])
16921
16922 (define_insn "frndintxf2_floor_i387"
16923   [(set (match_operand:XF 0 "register_operand" "=f")
16924         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16925          UNSPEC_FRNDINT_FLOOR))
16926    (use (match_operand:HI 2 "memory_operand" "m"))
16927    (use (match_operand:HI 3 "memory_operand" "m"))]
16928   "TARGET_USE_FANCY_MATH_387
16929    && flag_unsafe_math_optimizations"
16930   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16931   [(set_attr "type" "frndint")
16932    (set_attr "i387_cw" "floor")
16933    (set_attr "mode" "XF")])
16934
16935 (define_expand "floorxf2"
16936   [(use (match_operand:XF 0 "register_operand" ""))
16937    (use (match_operand:XF 1 "register_operand" ""))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations"
16940 {
16941   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16942   DONE;
16943 })
16944
16945 (define_expand "floordf2"
16946   [(use (match_operand:DF 0 "register_operand" ""))
16947    (use (match_operand:DF 1 "register_operand" ""))]
16948   "TARGET_USE_FANCY_MATH_387
16949    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16950    && flag_unsafe_math_optimizations"
16951 {
16952   rtx op0 = gen_reg_rtx (XFmode);
16953   rtx op1 = gen_reg_rtx (XFmode);
16954
16955   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16956   emit_insn (gen_frndintxf2_floor (op0, op1));
16957
16958   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16959   DONE;
16960 })
16961
16962 (define_expand "floorsf2"
16963   [(use (match_operand:SF 0 "register_operand" ""))
16964    (use (match_operand:SF 1 "register_operand" ""))]
16965   "TARGET_USE_FANCY_MATH_387
16966    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16967    && flag_unsafe_math_optimizations"
16968 {
16969   rtx op0 = gen_reg_rtx (XFmode);
16970   rtx op1 = gen_reg_rtx (XFmode);
16971
16972   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16973   emit_insn (gen_frndintxf2_floor (op0, op1));
16974
16975   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16976   DONE;
16977 })
16978
16979 (define_insn_and_split "*fist<mode>2_floor_1"
16980   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16981         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16982          UNSPEC_FIST_FLOOR))
16983    (clobber (reg:CC FLAGS_REG))]
16984   "TARGET_USE_FANCY_MATH_387
16985    && flag_unsafe_math_optimizations
16986    && !(reload_completed || reload_in_progress)"
16987   "#"
16988   "&& 1"
16989   [(const_int 0)]
16990 {
16991   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16992
16993   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16994   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16995   if (memory_operand (operands[0], VOIDmode))
16996     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16997                                       operands[2], operands[3]));
16998   else
16999     {
17000       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17001       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17002                                                   operands[2], operands[3],
17003                                                   operands[4]));
17004     }
17005   DONE;
17006 }
17007   [(set_attr "type" "fistp")
17008    (set_attr "i387_cw" "floor")
17009    (set_attr "mode" "<MODE>")])
17010
17011 (define_insn "fistdi2_floor"
17012   [(set (match_operand:DI 0 "memory_operand" "=m")
17013         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17014          UNSPEC_FIST_FLOOR))
17015    (use (match_operand:HI 2 "memory_operand" "m"))
17016    (use (match_operand:HI 3 "memory_operand" "m"))
17017    (clobber (match_scratch:XF 4 "=&1f"))]
17018   "TARGET_USE_FANCY_MATH_387
17019    && flag_unsafe_math_optimizations"
17020   "* return output_fix_trunc (insn, operands, 0);"
17021   [(set_attr "type" "fistp")
17022    (set_attr "i387_cw" "floor")
17023    (set_attr "mode" "DI")])
17024
17025 (define_insn "fistdi2_floor_with_temp"
17026   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17027         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17028          UNSPEC_FIST_FLOOR))
17029    (use (match_operand:HI 2 "memory_operand" "m,m"))
17030    (use (match_operand:HI 3 "memory_operand" "m,m"))
17031    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17032    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17033   "TARGET_USE_FANCY_MATH_387
17034    && flag_unsafe_math_optimizations"
17035   "#"
17036   [(set_attr "type" "fistp")
17037    (set_attr "i387_cw" "floor")
17038    (set_attr "mode" "DI")])
17039
17040 (define_split 
17041   [(set (match_operand:DI 0 "register_operand" "")
17042         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17043          UNSPEC_FIST_FLOOR))
17044    (use (match_operand:HI 2 "memory_operand" ""))
17045    (use (match_operand:HI 3 "memory_operand" ""))
17046    (clobber (match_operand:DI 4 "memory_operand" ""))
17047    (clobber (match_scratch 5 ""))]
17048   "reload_completed"
17049   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17050               (use (match_dup 2))
17051               (use (match_dup 3))
17052               (clobber (match_dup 5))])
17053    (set (match_dup 0) (match_dup 4))]
17054   "")
17055
17056 (define_split 
17057   [(set (match_operand:DI 0 "memory_operand" "")
17058         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17059          UNSPEC_FIST_FLOOR))
17060    (use (match_operand:HI 2 "memory_operand" ""))
17061    (use (match_operand:HI 3 "memory_operand" ""))
17062    (clobber (match_operand:DI 4 "memory_operand" ""))
17063    (clobber (match_scratch 5 ""))]
17064   "reload_completed"
17065   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17066               (use (match_dup 2))
17067               (use (match_dup 3))
17068               (clobber (match_dup 5))])]
17069   "")
17070
17071 (define_insn "fist<mode>2_floor"
17072   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17073         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17074          UNSPEC_FIST_FLOOR))
17075    (use (match_operand:HI 2 "memory_operand" "m"))
17076    (use (match_operand:HI 3 "memory_operand" "m"))]
17077   "TARGET_USE_FANCY_MATH_387
17078    && flag_unsafe_math_optimizations"
17079   "* return output_fix_trunc (insn, operands, 0);"
17080   [(set_attr "type" "fistp")
17081    (set_attr "i387_cw" "floor")
17082    (set_attr "mode" "<MODE>")])
17083
17084 (define_insn "fist<mode>2_floor_with_temp"
17085   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17086         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17087          UNSPEC_FIST_FLOOR))
17088    (use (match_operand:HI 2 "memory_operand" "m,m"))
17089    (use (match_operand:HI 3 "memory_operand" "m,m"))
17090    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17091   "TARGET_USE_FANCY_MATH_387
17092    && flag_unsafe_math_optimizations"
17093   "#"
17094   [(set_attr "type" "fistp")
17095    (set_attr "i387_cw" "floor")
17096    (set_attr "mode" "<MODE>")])
17097
17098 (define_split 
17099   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17100         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17101          UNSPEC_FIST_FLOOR))
17102    (use (match_operand:HI 2 "memory_operand" ""))
17103    (use (match_operand:HI 3 "memory_operand" ""))
17104    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17105   "reload_completed"
17106   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17107                                   UNSPEC_FIST_FLOOR))
17108               (use (match_dup 2))
17109               (use (match_dup 3))])
17110    (set (match_dup 0) (match_dup 4))]
17111   "")
17112
17113 (define_split 
17114   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17115         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17116          UNSPEC_FIST_FLOOR))
17117    (use (match_operand:HI 2 "memory_operand" ""))
17118    (use (match_operand:HI 3 "memory_operand" ""))
17119    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17120   "reload_completed"
17121   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17122                                   UNSPEC_FIST_FLOOR))
17123               (use (match_dup 2))
17124               (use (match_dup 3))])]
17125   "")
17126
17127 (define_expand "lfloor<mode>2"
17128   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17129                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17130                     UNSPEC_FIST_FLOOR))
17131               (clobber (reg:CC FLAGS_REG))])]
17132   "TARGET_USE_FANCY_MATH_387
17133    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17134    && flag_unsafe_math_optimizations"
17135   "")
17136
17137 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17138 (define_insn_and_split "frndintxf2_ceil"
17139   [(set (match_operand:XF 0 "register_operand" "=f")
17140         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17141          UNSPEC_FRNDINT_CEIL))
17142    (clobber (reg:CC FLAGS_REG))]
17143   "TARGET_USE_FANCY_MATH_387
17144    && flag_unsafe_math_optimizations
17145    && !(reload_completed || reload_in_progress)"
17146   "#"
17147   "&& 1"
17148   [(const_int 0)]
17149 {
17150   ix86_optimize_mode_switching[I387_CEIL] = 1;
17151
17152   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17153   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17154
17155   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17156                                        operands[2], operands[3]));
17157   DONE;
17158 }
17159   [(set_attr "type" "frndint")
17160    (set_attr "i387_cw" "ceil")
17161    (set_attr "mode" "XF")])
17162
17163 (define_insn "frndintxf2_ceil_i387"
17164   [(set (match_operand:XF 0 "register_operand" "=f")
17165         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17166          UNSPEC_FRNDINT_CEIL))
17167    (use (match_operand:HI 2 "memory_operand" "m"))
17168    (use (match_operand:HI 3 "memory_operand" "m"))]
17169   "TARGET_USE_FANCY_MATH_387
17170    && flag_unsafe_math_optimizations"
17171   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17172   [(set_attr "type" "frndint")
17173    (set_attr "i387_cw" "ceil")
17174    (set_attr "mode" "XF")])
17175
17176 (define_expand "ceilxf2"
17177   [(use (match_operand:XF 0 "register_operand" ""))
17178    (use (match_operand:XF 1 "register_operand" ""))]
17179   "TARGET_USE_FANCY_MATH_387
17180    && flag_unsafe_math_optimizations"
17181 {
17182   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17183   DONE;
17184 })
17185
17186 (define_expand "ceildf2"
17187   [(use (match_operand:DF 0 "register_operand" ""))
17188    (use (match_operand:DF 1 "register_operand" ""))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17191    && flag_unsafe_math_optimizations"
17192 {
17193   rtx op0 = gen_reg_rtx (XFmode);
17194   rtx op1 = gen_reg_rtx (XFmode);
17195
17196   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17197   emit_insn (gen_frndintxf2_ceil (op0, op1));
17198
17199   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17200   DONE;
17201 })
17202
17203 (define_expand "ceilsf2"
17204   [(use (match_operand:SF 0 "register_operand" ""))
17205    (use (match_operand:SF 1 "register_operand" ""))]
17206   "TARGET_USE_FANCY_MATH_387
17207    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17208    && flag_unsafe_math_optimizations"
17209 {
17210   rtx op0 = gen_reg_rtx (XFmode);
17211   rtx op1 = gen_reg_rtx (XFmode);
17212
17213   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17214   emit_insn (gen_frndintxf2_ceil (op0, op1));
17215
17216   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17217   DONE;
17218 })
17219
17220 (define_insn_and_split "*fist<mode>2_ceil_1"
17221   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17222         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17223          UNSPEC_FIST_CEIL))
17224    (clobber (reg:CC FLAGS_REG))]
17225   "TARGET_USE_FANCY_MATH_387
17226    && flag_unsafe_math_optimizations
17227    && !(reload_completed || reload_in_progress)"
17228   "#"
17229   "&& 1"
17230   [(const_int 0)]
17231 {
17232   ix86_optimize_mode_switching[I387_CEIL] = 1;
17233
17234   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17235   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17236   if (memory_operand (operands[0], VOIDmode))
17237     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17238                                      operands[2], operands[3]));
17239   else
17240     {
17241       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17242       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17243                                                  operands[2], operands[3],
17244                                                  operands[4]));
17245     }
17246   DONE;
17247 }
17248   [(set_attr "type" "fistp")
17249    (set_attr "i387_cw" "ceil")
17250    (set_attr "mode" "<MODE>")])
17251
17252 (define_insn "fistdi2_ceil"
17253   [(set (match_operand:DI 0 "memory_operand" "=m")
17254         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17255          UNSPEC_FIST_CEIL))
17256    (use (match_operand:HI 2 "memory_operand" "m"))
17257    (use (match_operand:HI 3 "memory_operand" "m"))
17258    (clobber (match_scratch:XF 4 "=&1f"))]
17259   "TARGET_USE_FANCY_MATH_387
17260    && flag_unsafe_math_optimizations"
17261   "* return output_fix_trunc (insn, operands, 0);"
17262   [(set_attr "type" "fistp")
17263    (set_attr "i387_cw" "ceil")
17264    (set_attr "mode" "DI")])
17265
17266 (define_insn "fistdi2_ceil_with_temp"
17267   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17268         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17269          UNSPEC_FIST_CEIL))
17270    (use (match_operand:HI 2 "memory_operand" "m,m"))
17271    (use (match_operand:HI 3 "memory_operand" "m,m"))
17272    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17273    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17274   "TARGET_USE_FANCY_MATH_387
17275    && flag_unsafe_math_optimizations"
17276   "#"
17277   [(set_attr "type" "fistp")
17278    (set_attr "i387_cw" "ceil")
17279    (set_attr "mode" "DI")])
17280
17281 (define_split 
17282   [(set (match_operand:DI 0 "register_operand" "")
17283         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17284          UNSPEC_FIST_CEIL))
17285    (use (match_operand:HI 2 "memory_operand" ""))
17286    (use (match_operand:HI 3 "memory_operand" ""))
17287    (clobber (match_operand:DI 4 "memory_operand" ""))
17288    (clobber (match_scratch 5 ""))]
17289   "reload_completed"
17290   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17291               (use (match_dup 2))
17292               (use (match_dup 3))
17293               (clobber (match_dup 5))])
17294    (set (match_dup 0) (match_dup 4))]
17295   "")
17296
17297 (define_split 
17298   [(set (match_operand:DI 0 "memory_operand" "")
17299         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17300          UNSPEC_FIST_CEIL))
17301    (use (match_operand:HI 2 "memory_operand" ""))
17302    (use (match_operand:HI 3 "memory_operand" ""))
17303    (clobber (match_operand:DI 4 "memory_operand" ""))
17304    (clobber (match_scratch 5 ""))]
17305   "reload_completed"
17306   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17307               (use (match_dup 2))
17308               (use (match_dup 3))
17309               (clobber (match_dup 5))])]
17310   "")
17311
17312 (define_insn "fist<mode>2_ceil"
17313   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17314         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17315          UNSPEC_FIST_CEIL))
17316    (use (match_operand:HI 2 "memory_operand" "m"))
17317    (use (match_operand:HI 3 "memory_operand" "m"))]
17318   "TARGET_USE_FANCY_MATH_387
17319    && flag_unsafe_math_optimizations"
17320   "* return output_fix_trunc (insn, operands, 0);"
17321   [(set_attr "type" "fistp")
17322    (set_attr "i387_cw" "ceil")
17323    (set_attr "mode" "<MODE>")])
17324
17325 (define_insn "fist<mode>2_ceil_with_temp"
17326   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17328          UNSPEC_FIST_CEIL))
17329    (use (match_operand:HI 2 "memory_operand" "m,m"))
17330    (use (match_operand:HI 3 "memory_operand" "m,m"))
17331    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17332   "TARGET_USE_FANCY_MATH_387
17333    && flag_unsafe_math_optimizations"
17334   "#"
17335   [(set_attr "type" "fistp")
17336    (set_attr "i387_cw" "ceil")
17337    (set_attr "mode" "<MODE>")])
17338
17339 (define_split 
17340   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17341         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17342          UNSPEC_FIST_CEIL))
17343    (use (match_operand:HI 2 "memory_operand" ""))
17344    (use (match_operand:HI 3 "memory_operand" ""))
17345    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17346   "reload_completed"
17347   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17348                                   UNSPEC_FIST_CEIL))
17349               (use (match_dup 2))
17350               (use (match_dup 3))])
17351    (set (match_dup 0) (match_dup 4))]
17352   "")
17353
17354 (define_split 
17355   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17356         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17357          UNSPEC_FIST_CEIL))
17358    (use (match_operand:HI 2 "memory_operand" ""))
17359    (use (match_operand:HI 3 "memory_operand" ""))
17360    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17361   "reload_completed"
17362   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17363                                   UNSPEC_FIST_CEIL))
17364               (use (match_dup 2))
17365               (use (match_dup 3))])]
17366   "")
17367
17368 (define_expand "lceil<mode>2"
17369   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17370                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17371                     UNSPEC_FIST_CEIL))
17372               (clobber (reg:CC FLAGS_REG))])]
17373   "TARGET_USE_FANCY_MATH_387
17374    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17375    && flag_unsafe_math_optimizations"
17376   "")
17377
17378 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17379 (define_insn_and_split "frndintxf2_trunc"
17380   [(set (match_operand:XF 0 "register_operand" "=f")
17381         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17382          UNSPEC_FRNDINT_TRUNC))
17383    (clobber (reg:CC FLAGS_REG))]
17384   "TARGET_USE_FANCY_MATH_387
17385    && flag_unsafe_math_optimizations
17386    && !(reload_completed || reload_in_progress)"
17387   "#"
17388   "&& 1"
17389   [(const_int 0)]
17390 {
17391   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17392
17393   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17394   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17395
17396   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17397                                         operands[2], operands[3]));
17398   DONE;
17399 }
17400   [(set_attr "type" "frndint")
17401    (set_attr "i387_cw" "trunc")
17402    (set_attr "mode" "XF")])
17403
17404 (define_insn "frndintxf2_trunc_i387"
17405   [(set (match_operand:XF 0 "register_operand" "=f")
17406         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17407          UNSPEC_FRNDINT_TRUNC))
17408    (use (match_operand:HI 2 "memory_operand" "m"))
17409    (use (match_operand:HI 3 "memory_operand" "m"))]
17410   "TARGET_USE_FANCY_MATH_387
17411    && flag_unsafe_math_optimizations"
17412   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17413   [(set_attr "type" "frndint")
17414    (set_attr "i387_cw" "trunc")
17415    (set_attr "mode" "XF")])
17416
17417 (define_expand "btruncxf2"
17418   [(use (match_operand:XF 0 "register_operand" ""))
17419    (use (match_operand:XF 1 "register_operand" ""))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && flag_unsafe_math_optimizations"
17422 {
17423   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17424   DONE;
17425 })
17426
17427 (define_expand "btruncdf2"
17428   [(use (match_operand:DF 0 "register_operand" ""))
17429    (use (match_operand:DF 1 "register_operand" ""))]
17430   "TARGET_USE_FANCY_MATH_387
17431    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17432    && flag_unsafe_math_optimizations"
17433 {
17434   rtx op0 = gen_reg_rtx (XFmode);
17435   rtx op1 = gen_reg_rtx (XFmode);
17436
17437   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17438   emit_insn (gen_frndintxf2_trunc (op0, op1));
17439
17440   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17441   DONE;
17442 })
17443
17444 (define_expand "btruncsf2"
17445   [(use (match_operand:SF 0 "register_operand" ""))
17446    (use (match_operand:SF 1 "register_operand" ""))]
17447   "TARGET_USE_FANCY_MATH_387
17448    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17449    && flag_unsafe_math_optimizations"
17450 {
17451   rtx op0 = gen_reg_rtx (XFmode);
17452   rtx op1 = gen_reg_rtx (XFmode);
17453
17454   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17455   emit_insn (gen_frndintxf2_trunc (op0, op1));
17456
17457   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17458   DONE;
17459 })
17460
17461 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17462 (define_insn_and_split "frndintxf2_mask_pm"
17463   [(set (match_operand:XF 0 "register_operand" "=f")
17464         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17465          UNSPEC_FRNDINT_MASK_PM))
17466    (clobber (reg:CC FLAGS_REG))]
17467   "TARGET_USE_FANCY_MATH_387
17468    && flag_unsafe_math_optimizations
17469    && !(reload_completed || reload_in_progress)"
17470   "#"
17471   "&& 1"
17472   [(const_int 0)]
17473 {
17474   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17475
17476   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17477   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17478
17479   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17480                                           operands[2], operands[3]));
17481   DONE;
17482 }
17483   [(set_attr "type" "frndint")
17484    (set_attr "i387_cw" "mask_pm")
17485    (set_attr "mode" "XF")])
17486
17487 (define_insn "frndintxf2_mask_pm_i387"
17488   [(set (match_operand:XF 0 "register_operand" "=f")
17489         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17490          UNSPEC_FRNDINT_MASK_PM))
17491    (use (match_operand:HI 2 "memory_operand" "m"))
17492    (use (match_operand:HI 3 "memory_operand" "m"))]
17493   "TARGET_USE_FANCY_MATH_387
17494    && flag_unsafe_math_optimizations"
17495   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17496   [(set_attr "type" "frndint")
17497    (set_attr "i387_cw" "mask_pm")
17498    (set_attr "mode" "XF")])
17499
17500 (define_expand "nearbyintxf2"
17501   [(use (match_operand:XF 0 "register_operand" ""))
17502    (use (match_operand:XF 1 "register_operand" ""))]
17503   "TARGET_USE_FANCY_MATH_387
17504    && flag_unsafe_math_optimizations"
17505 {
17506   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17507
17508   DONE;
17509 })
17510
17511 (define_expand "nearbyintdf2"
17512   [(use (match_operand:DF 0 "register_operand" ""))
17513    (use (match_operand:DF 1 "register_operand" ""))]
17514   "TARGET_USE_FANCY_MATH_387
17515    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17516    && flag_unsafe_math_optimizations"
17517 {
17518   rtx op0 = gen_reg_rtx (XFmode);
17519   rtx op1 = gen_reg_rtx (XFmode);
17520
17521   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17522   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17523
17524   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17525   DONE;
17526 })
17527
17528 (define_expand "nearbyintsf2"
17529   [(use (match_operand:SF 0 "register_operand" ""))
17530    (use (match_operand:SF 1 "register_operand" ""))]
17531   "TARGET_USE_FANCY_MATH_387
17532    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17533    && flag_unsafe_math_optimizations"
17534 {
17535   rtx op0 = gen_reg_rtx (XFmode);
17536   rtx op1 = gen_reg_rtx (XFmode);
17537
17538   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17539   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17540
17541   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17542   DONE;
17543 })
17544
17545 \f
17546 ;; Block operation instructions
17547
17548 (define_insn "cld"
17549  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17550  ""
17551  "cld"
17552   [(set_attr "type" "cld")])
17553
17554 (define_expand "movmemsi"
17555   [(use (match_operand:BLK 0 "memory_operand" ""))
17556    (use (match_operand:BLK 1 "memory_operand" ""))
17557    (use (match_operand:SI 2 "nonmemory_operand" ""))
17558    (use (match_operand:SI 3 "const_int_operand" ""))]
17559   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17560 {
17561  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17562    DONE;
17563  else
17564    FAIL;
17565 })
17566
17567 (define_expand "movmemdi"
17568   [(use (match_operand:BLK 0 "memory_operand" ""))
17569    (use (match_operand:BLK 1 "memory_operand" ""))
17570    (use (match_operand:DI 2 "nonmemory_operand" ""))
17571    (use (match_operand:DI 3 "const_int_operand" ""))]
17572   "TARGET_64BIT"
17573 {
17574  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17575    DONE;
17576  else
17577    FAIL;
17578 })
17579
17580 ;; Most CPUs don't like single string operations
17581 ;; Handle this case here to simplify previous expander.
17582
17583 (define_expand "strmov"
17584   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17585    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17586    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17587               (clobber (reg:CC FLAGS_REG))])
17588    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17589               (clobber (reg:CC FLAGS_REG))])]
17590   ""
17591 {
17592   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17593
17594   /* If .md ever supports :P for Pmode, these can be directly
17595      in the pattern above.  */
17596   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17597   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17598
17599   if (TARGET_SINGLE_STRINGOP || optimize_size)
17600     {
17601       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17602                                       operands[2], operands[3],
17603                                       operands[5], operands[6]));
17604       DONE;
17605     }
17606
17607   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17608 })
17609
17610 (define_expand "strmov_singleop"
17611   [(parallel [(set (match_operand 1 "memory_operand" "")
17612                    (match_operand 3 "memory_operand" ""))
17613               (set (match_operand 0 "register_operand" "")
17614                    (match_operand 4 "" ""))
17615               (set (match_operand 2 "register_operand" "")
17616                    (match_operand 5 "" ""))
17617               (use (reg:SI DIRFLAG_REG))])]
17618   "TARGET_SINGLE_STRINGOP || optimize_size"
17619   "")
17620
17621 (define_insn "*strmovdi_rex_1"
17622   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17623         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17624    (set (match_operand:DI 0 "register_operand" "=D")
17625         (plus:DI (match_dup 2)
17626                  (const_int 8)))
17627    (set (match_operand:DI 1 "register_operand" "=S")
17628         (plus:DI (match_dup 3)
17629                  (const_int 8)))
17630    (use (reg:SI DIRFLAG_REG))]
17631   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17632   "movsq"
17633   [(set_attr "type" "str")
17634    (set_attr "mode" "DI")
17635    (set_attr "memory" "both")])
17636
17637 (define_insn "*strmovsi_1"
17638   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17639         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17640    (set (match_operand:SI 0 "register_operand" "=D")
17641         (plus:SI (match_dup 2)
17642                  (const_int 4)))
17643    (set (match_operand:SI 1 "register_operand" "=S")
17644         (plus:SI (match_dup 3)
17645                  (const_int 4)))
17646    (use (reg:SI DIRFLAG_REG))]
17647   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17648   "{movsl|movsd}"
17649   [(set_attr "type" "str")
17650    (set_attr "mode" "SI")
17651    (set_attr "memory" "both")])
17652
17653 (define_insn "*strmovsi_rex_1"
17654   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17655         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17656    (set (match_operand:DI 0 "register_operand" "=D")
17657         (plus:DI (match_dup 2)
17658                  (const_int 4)))
17659    (set (match_operand:DI 1 "register_operand" "=S")
17660         (plus:DI (match_dup 3)
17661                  (const_int 4)))
17662    (use (reg:SI DIRFLAG_REG))]
17663   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17664   "{movsl|movsd}"
17665   [(set_attr "type" "str")
17666    (set_attr "mode" "SI")
17667    (set_attr "memory" "both")])
17668
17669 (define_insn "*strmovhi_1"
17670   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17671         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17672    (set (match_operand:SI 0 "register_operand" "=D")
17673         (plus:SI (match_dup 2)
17674                  (const_int 2)))
17675    (set (match_operand:SI 1 "register_operand" "=S")
17676         (plus:SI (match_dup 3)
17677                  (const_int 2)))
17678    (use (reg:SI DIRFLAG_REG))]
17679   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17680   "movsw"
17681   [(set_attr "type" "str")
17682    (set_attr "memory" "both")
17683    (set_attr "mode" "HI")])
17684
17685 (define_insn "*strmovhi_rex_1"
17686   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17687         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17688    (set (match_operand:DI 0 "register_operand" "=D")
17689         (plus:DI (match_dup 2)
17690                  (const_int 2)))
17691    (set (match_operand:DI 1 "register_operand" "=S")
17692         (plus:DI (match_dup 3)
17693                  (const_int 2)))
17694    (use (reg:SI DIRFLAG_REG))]
17695   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17696   "movsw"
17697   [(set_attr "type" "str")
17698    (set_attr "memory" "both")
17699    (set_attr "mode" "HI")])
17700
17701 (define_insn "*strmovqi_1"
17702   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17703         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17704    (set (match_operand:SI 0 "register_operand" "=D")
17705         (plus:SI (match_dup 2)
17706                  (const_int 1)))
17707    (set (match_operand:SI 1 "register_operand" "=S")
17708         (plus:SI (match_dup 3)
17709                  (const_int 1)))
17710    (use (reg:SI DIRFLAG_REG))]
17711   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17712   "movsb"
17713   [(set_attr "type" "str")
17714    (set_attr "memory" "both")
17715    (set_attr "mode" "QI")])
17716
17717 (define_insn "*strmovqi_rex_1"
17718   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17719         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17720    (set (match_operand:DI 0 "register_operand" "=D")
17721         (plus:DI (match_dup 2)
17722                  (const_int 1)))
17723    (set (match_operand:DI 1 "register_operand" "=S")
17724         (plus:DI (match_dup 3)
17725                  (const_int 1)))
17726    (use (reg:SI DIRFLAG_REG))]
17727   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17728   "movsb"
17729   [(set_attr "type" "str")
17730    (set_attr "memory" "both")
17731    (set_attr "mode" "QI")])
17732
17733 (define_expand "rep_mov"
17734   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17735               (set (match_operand 0 "register_operand" "")
17736                    (match_operand 5 "" ""))
17737               (set (match_operand 2 "register_operand" "")
17738                    (match_operand 6 "" ""))
17739               (set (match_operand 1 "memory_operand" "")
17740                    (match_operand 3 "memory_operand" ""))
17741               (use (match_dup 4))
17742               (use (reg:SI DIRFLAG_REG))])]
17743   ""
17744   "")
17745
17746 (define_insn "*rep_movdi_rex64"
17747   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17748    (set (match_operand:DI 0 "register_operand" "=D") 
17749         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17750                             (const_int 3))
17751                  (match_operand:DI 3 "register_operand" "0")))
17752    (set (match_operand:DI 1 "register_operand" "=S") 
17753         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17754                  (match_operand:DI 4 "register_operand" "1")))
17755    (set (mem:BLK (match_dup 3))
17756         (mem:BLK (match_dup 4)))
17757    (use (match_dup 5))
17758    (use (reg:SI DIRFLAG_REG))]
17759   "TARGET_64BIT"
17760   "{rep\;movsq|rep movsq}"
17761   [(set_attr "type" "str")
17762    (set_attr "prefix_rep" "1")
17763    (set_attr "memory" "both")
17764    (set_attr "mode" "DI")])
17765
17766 (define_insn "*rep_movsi"
17767   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17768    (set (match_operand:SI 0 "register_operand" "=D") 
17769         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17770                             (const_int 2))
17771                  (match_operand:SI 3 "register_operand" "0")))
17772    (set (match_operand:SI 1 "register_operand" "=S") 
17773         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17774                  (match_operand:SI 4 "register_operand" "1")))
17775    (set (mem:BLK (match_dup 3))
17776         (mem:BLK (match_dup 4)))
17777    (use (match_dup 5))
17778    (use (reg:SI DIRFLAG_REG))]
17779   "!TARGET_64BIT"
17780   "{rep\;movsl|rep movsd}"
17781   [(set_attr "type" "str")
17782    (set_attr "prefix_rep" "1")
17783    (set_attr "memory" "both")
17784    (set_attr "mode" "SI")])
17785
17786 (define_insn "*rep_movsi_rex64"
17787   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17788    (set (match_operand:DI 0 "register_operand" "=D") 
17789         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17790                             (const_int 2))
17791                  (match_operand:DI 3 "register_operand" "0")))
17792    (set (match_operand:DI 1 "register_operand" "=S") 
17793         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17794                  (match_operand:DI 4 "register_operand" "1")))
17795    (set (mem:BLK (match_dup 3))
17796         (mem:BLK (match_dup 4)))
17797    (use (match_dup 5))
17798    (use (reg:SI DIRFLAG_REG))]
17799   "TARGET_64BIT"
17800   "{rep\;movsl|rep movsd}"
17801   [(set_attr "type" "str")
17802    (set_attr "prefix_rep" "1")
17803    (set_attr "memory" "both")
17804    (set_attr "mode" "SI")])
17805
17806 (define_insn "*rep_movqi"
17807   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17808    (set (match_operand:SI 0 "register_operand" "=D") 
17809         (plus:SI (match_operand:SI 3 "register_operand" "0")
17810                  (match_operand:SI 5 "register_operand" "2")))
17811    (set (match_operand:SI 1 "register_operand" "=S") 
17812         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17813    (set (mem:BLK (match_dup 3))
17814         (mem:BLK (match_dup 4)))
17815    (use (match_dup 5))
17816    (use (reg:SI DIRFLAG_REG))]
17817   "!TARGET_64BIT"
17818   "{rep\;movsb|rep movsb}"
17819   [(set_attr "type" "str")
17820    (set_attr "prefix_rep" "1")
17821    (set_attr "memory" "both")
17822    (set_attr "mode" "SI")])
17823
17824 (define_insn "*rep_movqi_rex64"
17825   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17826    (set (match_operand:DI 0 "register_operand" "=D") 
17827         (plus:DI (match_operand:DI 3 "register_operand" "0")
17828                  (match_operand:DI 5 "register_operand" "2")))
17829    (set (match_operand:DI 1 "register_operand" "=S") 
17830         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17831    (set (mem:BLK (match_dup 3))
17832         (mem:BLK (match_dup 4)))
17833    (use (match_dup 5))
17834    (use (reg:SI DIRFLAG_REG))]
17835   "TARGET_64BIT"
17836   "{rep\;movsb|rep movsb}"
17837   [(set_attr "type" "str")
17838    (set_attr "prefix_rep" "1")
17839    (set_attr "memory" "both")
17840    (set_attr "mode" "SI")])
17841
17842 (define_expand "setmemsi"
17843    [(use (match_operand:BLK 0 "memory_operand" ""))
17844     (use (match_operand:SI 1 "nonmemory_operand" ""))
17845     (use (match_operand 2 "const_int_operand" ""))
17846     (use (match_operand 3 "const_int_operand" ""))]
17847   ""
17848 {
17849  /* If value to set is not zero, use the library routine.  */
17850  if (operands[2] != const0_rtx)
17851    FAIL;
17852
17853  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17854    DONE;
17855  else
17856    FAIL;
17857 })
17858
17859 (define_expand "setmemdi"
17860    [(use (match_operand:BLK 0 "memory_operand" ""))
17861     (use (match_operand:DI 1 "nonmemory_operand" ""))
17862     (use (match_operand 2 "const_int_operand" ""))
17863     (use (match_operand 3 "const_int_operand" ""))]
17864   "TARGET_64BIT"
17865 {
17866  /* If value to set is not zero, use the library routine.  */
17867  if (operands[2] != const0_rtx)
17868    FAIL;
17869
17870  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17871    DONE;
17872  else
17873    FAIL;
17874 })
17875
17876 ;; Most CPUs don't like single string operations
17877 ;; Handle this case here to simplify previous expander.
17878
17879 (define_expand "strset"
17880   [(set (match_operand 1 "memory_operand" "")
17881         (match_operand 2 "register_operand" ""))
17882    (parallel [(set (match_operand 0 "register_operand" "")
17883                    (match_dup 3))
17884               (clobber (reg:CC FLAGS_REG))])]
17885   ""
17886 {
17887   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17888     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17889
17890   /* If .md ever supports :P for Pmode, this can be directly
17891      in the pattern above.  */
17892   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17893                               GEN_INT (GET_MODE_SIZE (GET_MODE
17894                                                       (operands[2]))));
17895   if (TARGET_SINGLE_STRINGOP || optimize_size)
17896     {
17897       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17898                                       operands[3]));
17899       DONE;
17900     }
17901 })
17902
17903 (define_expand "strset_singleop"
17904   [(parallel [(set (match_operand 1 "memory_operand" "")
17905                    (match_operand 2 "register_operand" ""))
17906               (set (match_operand 0 "register_operand" "")
17907                    (match_operand 3 "" ""))
17908               (use (reg:SI DIRFLAG_REG))])]
17909   "TARGET_SINGLE_STRINGOP || optimize_size"
17910   "")
17911
17912 (define_insn "*strsetdi_rex_1"
17913   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17914         (match_operand:DI 2 "register_operand" "a"))
17915    (set (match_operand:DI 0 "register_operand" "=D")
17916         (plus:DI (match_dup 1)
17917                  (const_int 8)))
17918    (use (reg:SI DIRFLAG_REG))]
17919   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17920   "stosq"
17921   [(set_attr "type" "str")
17922    (set_attr "memory" "store")
17923    (set_attr "mode" "DI")])
17924
17925 (define_insn "*strsetsi_1"
17926   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17927         (match_operand:SI 2 "register_operand" "a"))
17928    (set (match_operand:SI 0 "register_operand" "=D")
17929         (plus:SI (match_dup 1)
17930                  (const_int 4)))
17931    (use (reg:SI DIRFLAG_REG))]
17932   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17933   "{stosl|stosd}"
17934   [(set_attr "type" "str")
17935    (set_attr "memory" "store")
17936    (set_attr "mode" "SI")])
17937
17938 (define_insn "*strsetsi_rex_1"
17939   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17940         (match_operand:SI 2 "register_operand" "a"))
17941    (set (match_operand:DI 0 "register_operand" "=D")
17942         (plus:DI (match_dup 1)
17943                  (const_int 4)))
17944    (use (reg:SI DIRFLAG_REG))]
17945   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17946   "{stosl|stosd}"
17947   [(set_attr "type" "str")
17948    (set_attr "memory" "store")
17949    (set_attr "mode" "SI")])
17950
17951 (define_insn "*strsethi_1"
17952   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17953         (match_operand:HI 2 "register_operand" "a"))
17954    (set (match_operand:SI 0 "register_operand" "=D")
17955         (plus:SI (match_dup 1)
17956                  (const_int 2)))
17957    (use (reg:SI DIRFLAG_REG))]
17958   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17959   "stosw"
17960   [(set_attr "type" "str")
17961    (set_attr "memory" "store")
17962    (set_attr "mode" "HI")])
17963
17964 (define_insn "*strsethi_rex_1"
17965   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17966         (match_operand:HI 2 "register_operand" "a"))
17967    (set (match_operand:DI 0 "register_operand" "=D")
17968         (plus:DI (match_dup 1)
17969                  (const_int 2)))
17970    (use (reg:SI DIRFLAG_REG))]
17971   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17972   "stosw"
17973   [(set_attr "type" "str")
17974    (set_attr "memory" "store")
17975    (set_attr "mode" "HI")])
17976
17977 (define_insn "*strsetqi_1"
17978   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17979         (match_operand:QI 2 "register_operand" "a"))
17980    (set (match_operand:SI 0 "register_operand" "=D")
17981         (plus:SI (match_dup 1)
17982                  (const_int 1)))
17983    (use (reg:SI DIRFLAG_REG))]
17984   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17985   "stosb"
17986   [(set_attr "type" "str")
17987    (set_attr "memory" "store")
17988    (set_attr "mode" "QI")])
17989
17990 (define_insn "*strsetqi_rex_1"
17991   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17992         (match_operand:QI 2 "register_operand" "a"))
17993    (set (match_operand:DI 0 "register_operand" "=D")
17994         (plus:DI (match_dup 1)
17995                  (const_int 1)))
17996    (use (reg:SI DIRFLAG_REG))]
17997   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17998   "stosb"
17999   [(set_attr "type" "str")
18000    (set_attr "memory" "store")
18001    (set_attr "mode" "QI")])
18002
18003 (define_expand "rep_stos"
18004   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18005               (set (match_operand 0 "register_operand" "")
18006                    (match_operand 4 "" ""))
18007               (set (match_operand 2 "memory_operand" "") (const_int 0))
18008               (use (match_operand 3 "register_operand" ""))
18009               (use (match_dup 1))
18010               (use (reg:SI DIRFLAG_REG))])]
18011   ""
18012   "")
18013
18014 (define_insn "*rep_stosdi_rex64"
18015   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18016    (set (match_operand:DI 0 "register_operand" "=D") 
18017         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18018                             (const_int 3))
18019                  (match_operand:DI 3 "register_operand" "0")))
18020    (set (mem:BLK (match_dup 3))
18021         (const_int 0))
18022    (use (match_operand:DI 2 "register_operand" "a"))
18023    (use (match_dup 4))
18024    (use (reg:SI DIRFLAG_REG))]
18025   "TARGET_64BIT"
18026   "{rep\;stosq|rep stosq}"
18027   [(set_attr "type" "str")
18028    (set_attr "prefix_rep" "1")
18029    (set_attr "memory" "store")
18030    (set_attr "mode" "DI")])
18031
18032 (define_insn "*rep_stossi"
18033   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18034    (set (match_operand:SI 0 "register_operand" "=D") 
18035         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18036                             (const_int 2))
18037                  (match_operand:SI 3 "register_operand" "0")))
18038    (set (mem:BLK (match_dup 3))
18039         (const_int 0))
18040    (use (match_operand:SI 2 "register_operand" "a"))
18041    (use (match_dup 4))
18042    (use (reg:SI DIRFLAG_REG))]
18043   "!TARGET_64BIT"
18044   "{rep\;stosl|rep stosd}"
18045   [(set_attr "type" "str")
18046    (set_attr "prefix_rep" "1")
18047    (set_attr "memory" "store")
18048    (set_attr "mode" "SI")])
18049
18050 (define_insn "*rep_stossi_rex64"
18051   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18052    (set (match_operand:DI 0 "register_operand" "=D") 
18053         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18054                             (const_int 2))
18055                  (match_operand:DI 3 "register_operand" "0")))
18056    (set (mem:BLK (match_dup 3))
18057         (const_int 0))
18058    (use (match_operand:SI 2 "register_operand" "a"))
18059    (use (match_dup 4))
18060    (use (reg:SI DIRFLAG_REG))]
18061   "TARGET_64BIT"
18062   "{rep\;stosl|rep stosd}"
18063   [(set_attr "type" "str")
18064    (set_attr "prefix_rep" "1")
18065    (set_attr "memory" "store")
18066    (set_attr "mode" "SI")])
18067
18068 (define_insn "*rep_stosqi"
18069   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18070    (set (match_operand:SI 0 "register_operand" "=D") 
18071         (plus:SI (match_operand:SI 3 "register_operand" "0")
18072                  (match_operand:SI 4 "register_operand" "1")))
18073    (set (mem:BLK (match_dup 3))
18074         (const_int 0))
18075    (use (match_operand:QI 2 "register_operand" "a"))
18076    (use (match_dup 4))
18077    (use (reg:SI DIRFLAG_REG))]
18078   "!TARGET_64BIT"
18079   "{rep\;stosb|rep stosb}"
18080   [(set_attr "type" "str")
18081    (set_attr "prefix_rep" "1")
18082    (set_attr "memory" "store")
18083    (set_attr "mode" "QI")])
18084
18085 (define_insn "*rep_stosqi_rex64"
18086   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18087    (set (match_operand:DI 0 "register_operand" "=D") 
18088         (plus:DI (match_operand:DI 3 "register_operand" "0")
18089                  (match_operand:DI 4 "register_operand" "1")))
18090    (set (mem:BLK (match_dup 3))
18091         (const_int 0))
18092    (use (match_operand:QI 2 "register_operand" "a"))
18093    (use (match_dup 4))
18094    (use (reg:SI DIRFLAG_REG))]
18095   "TARGET_64BIT"
18096   "{rep\;stosb|rep stosb}"
18097   [(set_attr "type" "str")
18098    (set_attr "prefix_rep" "1")
18099    (set_attr "memory" "store")
18100    (set_attr "mode" "QI")])
18101
18102 (define_expand "cmpstrnsi"
18103   [(set (match_operand:SI 0 "register_operand" "")
18104         (compare:SI (match_operand:BLK 1 "general_operand" "")
18105                     (match_operand:BLK 2 "general_operand" "")))
18106    (use (match_operand 3 "general_operand" ""))
18107    (use (match_operand 4 "immediate_operand" ""))]
18108   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18109 {
18110   rtx addr1, addr2, out, outlow, count, countreg, align;
18111
18112   /* Can't use this if the user has appropriated esi or edi.  */
18113   if (global_regs[4] || global_regs[5])
18114     FAIL;
18115
18116   out = operands[0];
18117   if (GET_CODE (out) != REG)
18118     out = gen_reg_rtx (SImode);
18119
18120   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18121   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18122   if (addr1 != XEXP (operands[1], 0))
18123     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18124   if (addr2 != XEXP (operands[2], 0))
18125     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18126
18127   count = operands[3];
18128   countreg = ix86_zero_extend_to_Pmode (count);
18129
18130   /* %%% Iff we are testing strict equality, we can use known alignment
18131      to good advantage.  This may be possible with combine, particularly
18132      once cc0 is dead.  */
18133   align = operands[4];
18134
18135   emit_insn (gen_cld ());
18136   if (GET_CODE (count) == CONST_INT)
18137     {
18138       if (INTVAL (count) == 0)
18139         {
18140           emit_move_insn (operands[0], const0_rtx);
18141           DONE;
18142         }
18143       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18144                                      operands[1], operands[2]));
18145     }
18146   else
18147     {
18148       if (TARGET_64BIT)
18149         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18150       else
18151         emit_insn (gen_cmpsi_1 (countreg, countreg));
18152       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18153                                   operands[1], operands[2]));
18154     }
18155
18156   outlow = gen_lowpart (QImode, out);
18157   emit_insn (gen_cmpintqi (outlow));
18158   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18159
18160   if (operands[0] != out)
18161     emit_move_insn (operands[0], out);
18162
18163   DONE;
18164 })
18165
18166 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18167
18168 (define_expand "cmpintqi"
18169   [(set (match_dup 1)
18170         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18171    (set (match_dup 2)
18172         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18173    (parallel [(set (match_operand:QI 0 "register_operand" "")
18174                    (minus:QI (match_dup 1)
18175                              (match_dup 2)))
18176               (clobber (reg:CC FLAGS_REG))])]
18177   ""
18178   "operands[1] = gen_reg_rtx (QImode);
18179    operands[2] = gen_reg_rtx (QImode);")
18180
18181 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18182 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18183
18184 (define_expand "cmpstrnqi_nz_1"
18185   [(parallel [(set (reg:CC FLAGS_REG)
18186                    (compare:CC (match_operand 4 "memory_operand" "")
18187                                (match_operand 5 "memory_operand" "")))
18188               (use (match_operand 2 "register_operand" ""))
18189               (use (match_operand:SI 3 "immediate_operand" ""))
18190               (use (reg:SI DIRFLAG_REG))
18191               (clobber (match_operand 0 "register_operand" ""))
18192               (clobber (match_operand 1 "register_operand" ""))
18193               (clobber (match_dup 2))])]
18194   ""
18195   "")
18196
18197 (define_insn "*cmpstrnqi_nz_1"
18198   [(set (reg:CC FLAGS_REG)
18199         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18200                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18201    (use (match_operand:SI 6 "register_operand" "2"))
18202    (use (match_operand:SI 3 "immediate_operand" "i"))
18203    (use (reg:SI DIRFLAG_REG))
18204    (clobber (match_operand:SI 0 "register_operand" "=S"))
18205    (clobber (match_operand:SI 1 "register_operand" "=D"))
18206    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18207   "!TARGET_64BIT"
18208   "repz{\;| }cmpsb"
18209   [(set_attr "type" "str")
18210    (set_attr "mode" "QI")
18211    (set_attr "prefix_rep" "1")])
18212
18213 (define_insn "*cmpstrnqi_nz_rex_1"
18214   [(set (reg:CC FLAGS_REG)
18215         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18216                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18217    (use (match_operand:DI 6 "register_operand" "2"))
18218    (use (match_operand:SI 3 "immediate_operand" "i"))
18219    (use (reg:SI DIRFLAG_REG))
18220    (clobber (match_operand:DI 0 "register_operand" "=S"))
18221    (clobber (match_operand:DI 1 "register_operand" "=D"))
18222    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18223   "TARGET_64BIT"
18224   "repz{\;| }cmpsb"
18225   [(set_attr "type" "str")
18226    (set_attr "mode" "QI")
18227    (set_attr "prefix_rep" "1")])
18228
18229 ;; The same, but the count is not known to not be zero.
18230
18231 (define_expand "cmpstrnqi_1"
18232   [(parallel [(set (reg:CC FLAGS_REG)
18233                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18234                                      (const_int 0))
18235                   (compare:CC (match_operand 4 "memory_operand" "")
18236                               (match_operand 5 "memory_operand" ""))
18237                   (const_int 0)))
18238               (use (match_operand:SI 3 "immediate_operand" ""))
18239               (use (reg:CC FLAGS_REG))
18240               (use (reg:SI DIRFLAG_REG))
18241               (clobber (match_operand 0 "register_operand" ""))
18242               (clobber (match_operand 1 "register_operand" ""))
18243               (clobber (match_dup 2))])]
18244   ""
18245   "")
18246
18247 (define_insn "*cmpstrnqi_1"
18248   [(set (reg:CC FLAGS_REG)
18249         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18250                              (const_int 0))
18251           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18252                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18253           (const_int 0)))
18254    (use (match_operand:SI 3 "immediate_operand" "i"))
18255    (use (reg:CC FLAGS_REG))
18256    (use (reg:SI DIRFLAG_REG))
18257    (clobber (match_operand:SI 0 "register_operand" "=S"))
18258    (clobber (match_operand:SI 1 "register_operand" "=D"))
18259    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18260   "!TARGET_64BIT"
18261   "repz{\;| }cmpsb"
18262   [(set_attr "type" "str")
18263    (set_attr "mode" "QI")
18264    (set_attr "prefix_rep" "1")])
18265
18266 (define_insn "*cmpstrnqi_rex_1"
18267   [(set (reg:CC FLAGS_REG)
18268         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18269                              (const_int 0))
18270           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18271                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18272           (const_int 0)))
18273    (use (match_operand:SI 3 "immediate_operand" "i"))
18274    (use (reg:CC FLAGS_REG))
18275    (use (reg:SI DIRFLAG_REG))
18276    (clobber (match_operand:DI 0 "register_operand" "=S"))
18277    (clobber (match_operand:DI 1 "register_operand" "=D"))
18278    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18279   "TARGET_64BIT"
18280   "repz{\;| }cmpsb"
18281   [(set_attr "type" "str")
18282    (set_attr "mode" "QI")
18283    (set_attr "prefix_rep" "1")])
18284
18285 (define_expand "strlensi"
18286   [(set (match_operand:SI 0 "register_operand" "")
18287         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18288                     (match_operand:QI 2 "immediate_operand" "")
18289                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18290   ""
18291 {
18292  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18293    DONE;
18294  else
18295    FAIL;
18296 })
18297
18298 (define_expand "strlendi"
18299   [(set (match_operand:DI 0 "register_operand" "")
18300         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18301                     (match_operand:QI 2 "immediate_operand" "")
18302                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18303   ""
18304 {
18305  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18306    DONE;
18307  else
18308    FAIL;
18309 })
18310
18311 (define_expand "strlenqi_1"
18312   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18313               (use (reg:SI DIRFLAG_REG))
18314               (clobber (match_operand 1 "register_operand" ""))
18315               (clobber (reg:CC FLAGS_REG))])]
18316   ""
18317   "")
18318
18319 (define_insn "*strlenqi_1"
18320   [(set (match_operand:SI 0 "register_operand" "=&c")
18321         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18322                     (match_operand:QI 2 "register_operand" "a")
18323                     (match_operand:SI 3 "immediate_operand" "i")
18324                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18325    (use (reg:SI DIRFLAG_REG))
18326    (clobber (match_operand:SI 1 "register_operand" "=D"))
18327    (clobber (reg:CC FLAGS_REG))]
18328   "!TARGET_64BIT"
18329   "repnz{\;| }scasb"
18330   [(set_attr "type" "str")
18331    (set_attr "mode" "QI")
18332    (set_attr "prefix_rep" "1")])
18333
18334 (define_insn "*strlenqi_rex_1"
18335   [(set (match_operand:DI 0 "register_operand" "=&c")
18336         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18337                     (match_operand:QI 2 "register_operand" "a")
18338                     (match_operand:DI 3 "immediate_operand" "i")
18339                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18340    (use (reg:SI DIRFLAG_REG))
18341    (clobber (match_operand:DI 1 "register_operand" "=D"))
18342    (clobber (reg:CC FLAGS_REG))]
18343   "TARGET_64BIT"
18344   "repnz{\;| }scasb"
18345   [(set_attr "type" "str")
18346    (set_attr "mode" "QI")
18347    (set_attr "prefix_rep" "1")])
18348
18349 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18350 ;; handled in combine, but it is not currently up to the task.
18351 ;; When used for their truth value, the cmpstrn* expanders generate
18352 ;; code like this:
18353 ;;
18354 ;;   repz cmpsb
18355 ;;   seta       %al
18356 ;;   setb       %dl
18357 ;;   cmpb       %al, %dl
18358 ;;   jcc        label
18359 ;;
18360 ;; The intermediate three instructions are unnecessary.
18361
18362 ;; This one handles cmpstrn*_nz_1...
18363 (define_peephole2
18364   [(parallel[
18365      (set (reg:CC FLAGS_REG)
18366           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18367                       (mem:BLK (match_operand 5 "register_operand" ""))))
18368      (use (match_operand 6 "register_operand" ""))
18369      (use (match_operand:SI 3 "immediate_operand" ""))
18370      (use (reg:SI DIRFLAG_REG))
18371      (clobber (match_operand 0 "register_operand" ""))
18372      (clobber (match_operand 1 "register_operand" ""))
18373      (clobber (match_operand 2 "register_operand" ""))])
18374    (set (match_operand:QI 7 "register_operand" "")
18375         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18376    (set (match_operand:QI 8 "register_operand" "")
18377         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18378    (set (reg FLAGS_REG)
18379         (compare (match_dup 7) (match_dup 8)))
18380   ]
18381   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18382   [(parallel[
18383      (set (reg:CC FLAGS_REG)
18384           (compare:CC (mem:BLK (match_dup 4))
18385                       (mem:BLK (match_dup 5))))
18386      (use (match_dup 6))
18387      (use (match_dup 3))
18388      (use (reg:SI DIRFLAG_REG))
18389      (clobber (match_dup 0))
18390      (clobber (match_dup 1))
18391      (clobber (match_dup 2))])]
18392   "")
18393
18394 ;; ...and this one handles cmpstrn*_1.
18395 (define_peephole2
18396   [(parallel[
18397      (set (reg:CC FLAGS_REG)
18398           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18399                                (const_int 0))
18400             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18401                         (mem:BLK (match_operand 5 "register_operand" "")))
18402             (const_int 0)))
18403      (use (match_operand:SI 3 "immediate_operand" ""))
18404      (use (reg:CC FLAGS_REG))
18405      (use (reg:SI DIRFLAG_REG))
18406      (clobber (match_operand 0 "register_operand" ""))
18407      (clobber (match_operand 1 "register_operand" ""))
18408      (clobber (match_operand 2 "register_operand" ""))])
18409    (set (match_operand:QI 7 "register_operand" "")
18410         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18411    (set (match_operand:QI 8 "register_operand" "")
18412         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18413    (set (reg FLAGS_REG)
18414         (compare (match_dup 7) (match_dup 8)))
18415   ]
18416   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18417   [(parallel[
18418      (set (reg:CC FLAGS_REG)
18419           (if_then_else:CC (ne (match_dup 6)
18420                                (const_int 0))
18421             (compare:CC (mem:BLK (match_dup 4))
18422                         (mem:BLK (match_dup 5)))
18423             (const_int 0)))
18424      (use (match_dup 3))
18425      (use (reg:CC FLAGS_REG))
18426      (use (reg:SI DIRFLAG_REG))
18427      (clobber (match_dup 0))
18428      (clobber (match_dup 1))
18429      (clobber (match_dup 2))])]
18430   "")
18431
18432
18433 \f
18434 ;; Conditional move instructions.
18435
18436 (define_expand "movdicc"
18437   [(set (match_operand:DI 0 "register_operand" "")
18438         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18439                          (match_operand:DI 2 "general_operand" "")
18440                          (match_operand:DI 3 "general_operand" "")))]
18441   "TARGET_64BIT"
18442   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18443
18444 (define_insn "x86_movdicc_0_m1_rex64"
18445   [(set (match_operand:DI 0 "register_operand" "=r")
18446         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18447           (const_int -1)
18448           (const_int 0)))
18449    (clobber (reg:CC FLAGS_REG))]
18450   "TARGET_64BIT"
18451   "sbb{q}\t%0, %0"
18452   ; Since we don't have the proper number of operands for an alu insn,
18453   ; fill in all the blanks.
18454   [(set_attr "type" "alu")
18455    (set_attr "pent_pair" "pu")
18456    (set_attr "memory" "none")
18457    (set_attr "imm_disp" "false")
18458    (set_attr "mode" "DI")
18459    (set_attr "length_immediate" "0")])
18460
18461 (define_insn "*movdicc_c_rex64"
18462   [(set (match_operand:DI 0 "register_operand" "=r,r")
18463         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18464                                 [(reg FLAGS_REG) (const_int 0)])
18465                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18466                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18467   "TARGET_64BIT && TARGET_CMOVE
18468    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18469   "@
18470    cmov%O2%C1\t{%2, %0|%0, %2}
18471    cmov%O2%c1\t{%3, %0|%0, %3}"
18472   [(set_attr "type" "icmov")
18473    (set_attr "mode" "DI")])
18474
18475 (define_expand "movsicc"
18476   [(set (match_operand:SI 0 "register_operand" "")
18477         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18478                          (match_operand:SI 2 "general_operand" "")
18479                          (match_operand:SI 3 "general_operand" "")))]
18480   ""
18481   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18482
18483 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18484 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18485 ;; So just document what we're doing explicitly.
18486
18487 (define_insn "x86_movsicc_0_m1"
18488   [(set (match_operand:SI 0 "register_operand" "=r")
18489         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18490           (const_int -1)
18491           (const_int 0)))
18492    (clobber (reg:CC FLAGS_REG))]
18493   ""
18494   "sbb{l}\t%0, %0"
18495   ; Since we don't have the proper number of operands for an alu insn,
18496   ; fill in all the blanks.
18497   [(set_attr "type" "alu")
18498    (set_attr "pent_pair" "pu")
18499    (set_attr "memory" "none")
18500    (set_attr "imm_disp" "false")
18501    (set_attr "mode" "SI")
18502    (set_attr "length_immediate" "0")])
18503
18504 (define_insn "*movsicc_noc"
18505   [(set (match_operand:SI 0 "register_operand" "=r,r")
18506         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18507                                 [(reg FLAGS_REG) (const_int 0)])
18508                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18509                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18510   "TARGET_CMOVE
18511    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18512   "@
18513    cmov%O2%C1\t{%2, %0|%0, %2}
18514    cmov%O2%c1\t{%3, %0|%0, %3}"
18515   [(set_attr "type" "icmov")
18516    (set_attr "mode" "SI")])
18517
18518 (define_expand "movhicc"
18519   [(set (match_operand:HI 0 "register_operand" "")
18520         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18521                          (match_operand:HI 2 "general_operand" "")
18522                          (match_operand:HI 3 "general_operand" "")))]
18523   "TARGET_HIMODE_MATH"
18524   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18525
18526 (define_insn "*movhicc_noc"
18527   [(set (match_operand:HI 0 "register_operand" "=r,r")
18528         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18529                                 [(reg FLAGS_REG) (const_int 0)])
18530                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18531                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18532   "TARGET_CMOVE
18533    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18534   "@
18535    cmov%O2%C1\t{%2, %0|%0, %2}
18536    cmov%O2%c1\t{%3, %0|%0, %3}"
18537   [(set_attr "type" "icmov")
18538    (set_attr "mode" "HI")])
18539
18540 (define_expand "movqicc"
18541   [(set (match_operand:QI 0 "register_operand" "")
18542         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18543                          (match_operand:QI 2 "general_operand" "")
18544                          (match_operand:QI 3 "general_operand" "")))]
18545   "TARGET_QIMODE_MATH"
18546   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18547
18548 (define_insn_and_split "*movqicc_noc"
18549   [(set (match_operand:QI 0 "register_operand" "=r,r")
18550         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18551                                 [(match_operand 4 "flags_reg_operand" "")
18552                                  (const_int 0)])
18553                       (match_operand:QI 2 "register_operand" "r,0")
18554                       (match_operand:QI 3 "register_operand" "0,r")))]
18555   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18556   "#"
18557   "&& reload_completed"
18558   [(set (match_dup 0)
18559         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18560                       (match_dup 2)
18561                       (match_dup 3)))]
18562   "operands[0] = gen_lowpart (SImode, operands[0]);
18563    operands[2] = gen_lowpart (SImode, operands[2]);
18564    operands[3] = gen_lowpart (SImode, operands[3]);"
18565   [(set_attr "type" "icmov")
18566    (set_attr "mode" "SI")])
18567
18568 (define_expand "movsfcc"
18569   [(set (match_operand:SF 0 "register_operand" "")
18570         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18571                          (match_operand:SF 2 "register_operand" "")
18572                          (match_operand:SF 3 "register_operand" "")))]
18573   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18574   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18575
18576 (define_insn "*movsfcc_1_387"
18577   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18578         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18579                                 [(reg FLAGS_REG) (const_int 0)])
18580                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18581                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18582   "TARGET_80387 && TARGET_CMOVE
18583    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18584   "@
18585    fcmov%F1\t{%2, %0|%0, %2}
18586    fcmov%f1\t{%3, %0|%0, %3}
18587    cmov%O2%C1\t{%2, %0|%0, %2}
18588    cmov%O2%c1\t{%3, %0|%0, %3}"
18589   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18590    (set_attr "mode" "SF,SF,SI,SI")])
18591
18592 (define_expand "movdfcc"
18593   [(set (match_operand:DF 0 "register_operand" "")
18594         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18595                          (match_operand:DF 2 "register_operand" "")
18596                          (match_operand:DF 3 "register_operand" "")))]
18597   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18598   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18599
18600 (define_insn "*movdfcc_1"
18601   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18602         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18603                                 [(reg FLAGS_REG) (const_int 0)])
18604                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18605                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18606   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18607    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18608   "@
18609    fcmov%F1\t{%2, %0|%0, %2}
18610    fcmov%f1\t{%3, %0|%0, %3}
18611    #
18612    #"
18613   [(set_attr "type" "fcmov,fcmov,multi,multi")
18614    (set_attr "mode" "DF")])
18615
18616 (define_insn "*movdfcc_1_rex64"
18617   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18618         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18619                                 [(reg FLAGS_REG) (const_int 0)])
18620                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18621                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18622   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18623    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18624   "@
18625    fcmov%F1\t{%2, %0|%0, %2}
18626    fcmov%f1\t{%3, %0|%0, %3}
18627    cmov%O2%C1\t{%2, %0|%0, %2}
18628    cmov%O2%c1\t{%3, %0|%0, %3}"
18629   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18630    (set_attr "mode" "DF")])
18631
18632 (define_split
18633   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18634         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18635                                 [(match_operand 4 "flags_reg_operand" "")
18636                                  (const_int 0)])
18637                       (match_operand:DF 2 "nonimmediate_operand" "")
18638                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18639   "!TARGET_64BIT && reload_completed"
18640   [(set (match_dup 2)
18641         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18642                       (match_dup 5)
18643                       (match_dup 7)))
18644    (set (match_dup 3)
18645         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18646                       (match_dup 6)
18647                       (match_dup 8)))]
18648   "split_di (operands+2, 1, operands+5, operands+6);
18649    split_di (operands+3, 1, operands+7, operands+8);
18650    split_di (operands, 1, operands+2, operands+3);")
18651
18652 (define_expand "movxfcc"
18653   [(set (match_operand:XF 0 "register_operand" "")
18654         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18655                          (match_operand:XF 2 "register_operand" "")
18656                          (match_operand:XF 3 "register_operand" "")))]
18657   "TARGET_80387 && TARGET_CMOVE"
18658   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18659
18660 (define_insn "*movxfcc_1"
18661   [(set (match_operand:XF 0 "register_operand" "=f,f")
18662         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18663                                 [(reg FLAGS_REG) (const_int 0)])
18664                       (match_operand:XF 2 "register_operand" "f,0")
18665                       (match_operand:XF 3 "register_operand" "0,f")))]
18666   "TARGET_80387 && TARGET_CMOVE"
18667   "@
18668    fcmov%F1\t{%2, %0|%0, %2}
18669    fcmov%f1\t{%3, %0|%0, %3}"
18670   [(set_attr "type" "fcmov")
18671    (set_attr "mode" "XF")])
18672
18673 ;; These versions of the min/max patterns are intentionally ignorant of
18674 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18675 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18676 ;; are undefined in this condition, we're certain this is correct.
18677
18678 (define_insn "sminsf3"
18679   [(set (match_operand:SF 0 "register_operand" "=x")
18680         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18681                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18682   "TARGET_SSE_MATH"
18683   "minss\t{%2, %0|%0, %2}"
18684   [(set_attr "type" "sseadd")
18685    (set_attr "mode" "SF")])
18686
18687 (define_insn "smaxsf3"
18688   [(set (match_operand:SF 0 "register_operand" "=x")
18689         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18690                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18691   "TARGET_SSE_MATH"
18692   "maxss\t{%2, %0|%0, %2}"
18693   [(set_attr "type" "sseadd")
18694    (set_attr "mode" "SF")])
18695
18696 (define_insn "smindf3"
18697   [(set (match_operand:DF 0 "register_operand" "=x")
18698         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18699                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18700   "TARGET_SSE2 && TARGET_SSE_MATH"
18701   "minsd\t{%2, %0|%0, %2}"
18702   [(set_attr "type" "sseadd")
18703    (set_attr "mode" "DF")])
18704
18705 (define_insn "smaxdf3"
18706   [(set (match_operand:DF 0 "register_operand" "=x")
18707         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18708                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18709   "TARGET_SSE2 && TARGET_SSE_MATH"
18710   "maxsd\t{%2, %0|%0, %2}"
18711   [(set_attr "type" "sseadd")
18712    (set_attr "mode" "DF")])
18713
18714 ;; These versions of the min/max patterns implement exactly the operations
18715 ;;   min = (op1 < op2 ? op1 : op2)
18716 ;;   max = (!(op1 < op2) ? op1 : op2)
18717 ;; Their operands are not commutative, and thus they may be used in the
18718 ;; presence of -0.0 and NaN.
18719
18720 (define_insn "*ieee_sminsf3"
18721   [(set (match_operand:SF 0 "register_operand" "=x")
18722         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18723                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18724                    UNSPEC_IEEE_MIN))]
18725   "TARGET_SSE_MATH"
18726   "minss\t{%2, %0|%0, %2}"
18727   [(set_attr "type" "sseadd")
18728    (set_attr "mode" "SF")])
18729
18730 (define_insn "*ieee_smaxsf3"
18731   [(set (match_operand:SF 0 "register_operand" "=x")
18732         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18733                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18734                    UNSPEC_IEEE_MAX))]
18735   "TARGET_SSE_MATH"
18736   "maxss\t{%2, %0|%0, %2}"
18737   [(set_attr "type" "sseadd")
18738    (set_attr "mode" "SF")])
18739
18740 (define_insn "*ieee_smindf3"
18741   [(set (match_operand:DF 0 "register_operand" "=x")
18742         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18743                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18744                    UNSPEC_IEEE_MIN))]
18745   "TARGET_SSE2 && TARGET_SSE_MATH"
18746   "minsd\t{%2, %0|%0, %2}"
18747   [(set_attr "type" "sseadd")
18748    (set_attr "mode" "DF")])
18749
18750 (define_insn "*ieee_smaxdf3"
18751   [(set (match_operand:DF 0 "register_operand" "=x")
18752         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18753                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18754                    UNSPEC_IEEE_MAX))]
18755   "TARGET_SSE2 && TARGET_SSE_MATH"
18756   "maxsd\t{%2, %0|%0, %2}"
18757   [(set_attr "type" "sseadd")
18758    (set_attr "mode" "DF")])
18759
18760 ;; Make two stack loads independent:
18761 ;;   fld aa              fld aa
18762 ;;   fld %st(0)     ->   fld bb
18763 ;;   fmul bb             fmul %st(1), %st
18764 ;;
18765 ;; Actually we only match the last two instructions for simplicity.
18766 (define_peephole2
18767   [(set (match_operand 0 "fp_register_operand" "")
18768         (match_operand 1 "fp_register_operand" ""))
18769    (set (match_dup 0)
18770         (match_operator 2 "binary_fp_operator"
18771            [(match_dup 0)
18772             (match_operand 3 "memory_operand" "")]))]
18773   "REGNO (operands[0]) != REGNO (operands[1])"
18774   [(set (match_dup 0) (match_dup 3))
18775    (set (match_dup 0) (match_dup 4))]
18776
18777   ;; The % modifier is not operational anymore in peephole2's, so we have to
18778   ;; swap the operands manually in the case of addition and multiplication.
18779   "if (COMMUTATIVE_ARITH_P (operands[2]))
18780      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18781                                  operands[0], operands[1]);
18782    else
18783      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18784                                  operands[1], operands[0]);")
18785
18786 ;; Conditional addition patterns
18787 (define_expand "addqicc"
18788   [(match_operand:QI 0 "register_operand" "")
18789    (match_operand 1 "comparison_operator" "")
18790    (match_operand:QI 2 "register_operand" "")
18791    (match_operand:QI 3 "const_int_operand" "")]
18792   ""
18793   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18794
18795 (define_expand "addhicc"
18796   [(match_operand:HI 0 "register_operand" "")
18797    (match_operand 1 "comparison_operator" "")
18798    (match_operand:HI 2 "register_operand" "")
18799    (match_operand:HI 3 "const_int_operand" "")]
18800   ""
18801   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18802
18803 (define_expand "addsicc"
18804   [(match_operand:SI 0 "register_operand" "")
18805    (match_operand 1 "comparison_operator" "")
18806    (match_operand:SI 2 "register_operand" "")
18807    (match_operand:SI 3 "const_int_operand" "")]
18808   ""
18809   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18810
18811 (define_expand "adddicc"
18812   [(match_operand:DI 0 "register_operand" "")
18813    (match_operand 1 "comparison_operator" "")
18814    (match_operand:DI 2 "register_operand" "")
18815    (match_operand:DI 3 "const_int_operand" "")]
18816   "TARGET_64BIT"
18817   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18818
18819 \f
18820 ;; Misc patterns (?)
18821
18822 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18823 ;; Otherwise there will be nothing to keep
18824 ;; 
18825 ;; [(set (reg ebp) (reg esp))]
18826 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18827 ;;  (clobber (eflags)]
18828 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18829 ;;
18830 ;; in proper program order.
18831 (define_insn "pro_epilogue_adjust_stack_1"
18832   [(set (match_operand:SI 0 "register_operand" "=r,r")
18833         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18834                  (match_operand:SI 2 "immediate_operand" "i,i")))
18835    (clobber (reg:CC FLAGS_REG))
18836    (clobber (mem:BLK (scratch)))]
18837   "!TARGET_64BIT"
18838 {
18839   switch (get_attr_type (insn))
18840     {
18841     case TYPE_IMOV:
18842       return "mov{l}\t{%1, %0|%0, %1}";
18843
18844     case TYPE_ALU:
18845       if (GET_CODE (operands[2]) == CONST_INT
18846           && (INTVAL (operands[2]) == 128
18847               || (INTVAL (operands[2]) < 0
18848                   && INTVAL (operands[2]) != -128)))
18849         {
18850           operands[2] = GEN_INT (-INTVAL (operands[2]));
18851           return "sub{l}\t{%2, %0|%0, %2}";
18852         }
18853       return "add{l}\t{%2, %0|%0, %2}";
18854
18855     case TYPE_LEA:
18856       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18857       return "lea{l}\t{%a2, %0|%0, %a2}";
18858
18859     default:
18860       gcc_unreachable ();
18861     }
18862 }
18863   [(set (attr "type")
18864         (cond [(eq_attr "alternative" "0")
18865                  (const_string "alu")
18866                (match_operand:SI 2 "const0_operand" "")
18867                  (const_string "imov")
18868               ]
18869               (const_string "lea")))
18870    (set_attr "mode" "SI")])
18871
18872 (define_insn "pro_epilogue_adjust_stack_rex64"
18873   [(set (match_operand:DI 0 "register_operand" "=r,r")
18874         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18875                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18876    (clobber (reg:CC FLAGS_REG))
18877    (clobber (mem:BLK (scratch)))]
18878   "TARGET_64BIT"
18879 {
18880   switch (get_attr_type (insn))
18881     {
18882     case TYPE_IMOV:
18883       return "mov{q}\t{%1, %0|%0, %1}";
18884
18885     case TYPE_ALU:
18886       if (GET_CODE (operands[2]) == CONST_INT
18887           /* Avoid overflows.  */
18888           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18889           && (INTVAL (operands[2]) == 128
18890               || (INTVAL (operands[2]) < 0
18891                   && INTVAL (operands[2]) != -128)))
18892         {
18893           operands[2] = GEN_INT (-INTVAL (operands[2]));
18894           return "sub{q}\t{%2, %0|%0, %2}";
18895         }
18896       return "add{q}\t{%2, %0|%0, %2}";
18897
18898     case TYPE_LEA:
18899       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18900       return "lea{q}\t{%a2, %0|%0, %a2}";
18901
18902     default:
18903       gcc_unreachable ();
18904     }
18905 }
18906   [(set (attr "type")
18907         (cond [(eq_attr "alternative" "0")
18908                  (const_string "alu")
18909                (match_operand:DI 2 "const0_operand" "")
18910                  (const_string "imov")
18911               ]
18912               (const_string "lea")))
18913    (set_attr "mode" "DI")])
18914
18915 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18916   [(set (match_operand:DI 0 "register_operand" "=r,r")
18917         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18918                  (match_operand:DI 3 "immediate_operand" "i,i")))
18919    (use (match_operand:DI 2 "register_operand" "r,r"))
18920    (clobber (reg:CC FLAGS_REG))
18921    (clobber (mem:BLK (scratch)))]
18922   "TARGET_64BIT"
18923 {
18924   switch (get_attr_type (insn))
18925     {
18926     case TYPE_ALU:
18927       return "add{q}\t{%2, %0|%0, %2}";
18928
18929     case TYPE_LEA:
18930       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18931       return "lea{q}\t{%a2, %0|%0, %a2}";
18932
18933     default:
18934       gcc_unreachable ();
18935     }
18936 }
18937   [(set_attr "type" "alu,lea")
18938    (set_attr "mode" "DI")])
18939
18940 (define_expand "allocate_stack_worker"
18941   [(match_operand:SI 0 "register_operand" "")]
18942   "TARGET_STACK_PROBE"
18943 {
18944   if (reload_completed)
18945     {
18946       if (TARGET_64BIT)
18947         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18948       else
18949         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18950     }
18951   else
18952     {
18953       if (TARGET_64BIT)
18954         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18955       else
18956         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18957     }
18958   DONE;
18959 })
18960
18961 (define_insn "allocate_stack_worker_1"
18962   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18963     UNSPECV_STACK_PROBE)
18964    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18965    (clobber (match_scratch:SI 1 "=0"))
18966    (clobber (reg:CC FLAGS_REG))]
18967   "!TARGET_64BIT && TARGET_STACK_PROBE"
18968   "call\t__alloca"
18969   [(set_attr "type" "multi")
18970    (set_attr "length" "5")])
18971
18972 (define_expand "allocate_stack_worker_postreload"
18973   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18974                                     UNSPECV_STACK_PROBE)
18975               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18976               (clobber (match_dup 0))
18977               (clobber (reg:CC FLAGS_REG))])]
18978   ""
18979   "")
18980
18981 (define_insn "allocate_stack_worker_rex64"
18982   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18983     UNSPECV_STACK_PROBE)
18984    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18985    (clobber (match_scratch:DI 1 "=0"))
18986    (clobber (reg:CC FLAGS_REG))]
18987   "TARGET_64BIT && TARGET_STACK_PROBE"
18988   "call\t__alloca"
18989   [(set_attr "type" "multi")
18990    (set_attr "length" "5")])
18991
18992 (define_expand "allocate_stack_worker_rex64_postreload"
18993   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18994                                     UNSPECV_STACK_PROBE)
18995               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18996               (clobber (match_dup 0))
18997               (clobber (reg:CC FLAGS_REG))])]
18998   ""
18999   "")
19000
19001 (define_expand "allocate_stack"
19002   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19003                    (minus:SI (reg:SI SP_REG)
19004                              (match_operand:SI 1 "general_operand" "")))
19005               (clobber (reg:CC FLAGS_REG))])
19006    (parallel [(set (reg:SI SP_REG)
19007                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19008               (clobber (reg:CC FLAGS_REG))])]
19009   "TARGET_STACK_PROBE"
19010 {
19011 #ifdef CHECK_STACK_LIMIT
19012   if (GET_CODE (operands[1]) == CONST_INT
19013       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19014     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19015                            operands[1]));
19016   else 
19017 #endif
19018     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19019                                                             operands[1])));
19020
19021   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19022   DONE;
19023 })
19024
19025 (define_expand "builtin_setjmp_receiver"
19026   [(label_ref (match_operand 0 "" ""))]
19027   "!TARGET_64BIT && flag_pic"
19028 {
19029   if (TARGET_MACHO)
19030     {
19031       rtx xops[3];
19032       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19033       rtx label_rtx = gen_label_rtx ();
19034       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19035       xops[0] = xops[1] = picreg;
19036       xops[2] = gen_rtx_CONST (SImode,
19037                   gen_rtx_MINUS (SImode,
19038                     gen_rtx_LABEL_REF (SImode, label_rtx),
19039                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19040       ix86_expand_binary_operator (MINUS, SImode, xops);
19041     }
19042   else
19043     emit_insn (gen_set_got (pic_offset_table_rtx));
19044   DONE;
19045 })
19046 \f
19047 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19048
19049 (define_split
19050   [(set (match_operand 0 "register_operand" "")
19051         (match_operator 3 "promotable_binary_operator"
19052            [(match_operand 1 "register_operand" "")
19053             (match_operand 2 "aligned_operand" "")]))
19054    (clobber (reg:CC FLAGS_REG))]
19055   "! TARGET_PARTIAL_REG_STALL && reload_completed
19056    && ((GET_MODE (operands[0]) == HImode 
19057         && ((!optimize_size && !TARGET_FAST_PREFIX)
19058             /* ??? next two lines just !satisfies_constraint_K (...) */
19059             || GET_CODE (operands[2]) != CONST_INT
19060             || satisfies_constraint_K (operands[2])))
19061        || (GET_MODE (operands[0]) == QImode 
19062            && (TARGET_PROMOTE_QImode || optimize_size)))"
19063   [(parallel [(set (match_dup 0)
19064                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19065               (clobber (reg:CC FLAGS_REG))])]
19066   "operands[0] = gen_lowpart (SImode, operands[0]);
19067    operands[1] = gen_lowpart (SImode, operands[1]);
19068    if (GET_CODE (operands[3]) != ASHIFT)
19069      operands[2] = gen_lowpart (SImode, operands[2]);
19070    PUT_MODE (operands[3], SImode);")
19071
19072 ; Promote the QImode tests, as i386 has encoding of the AND
19073 ; instruction with 32-bit sign-extended immediate and thus the
19074 ; instruction size is unchanged, except in the %eax case for
19075 ; which it is increased by one byte, hence the ! optimize_size.
19076 (define_split
19077   [(set (match_operand 0 "flags_reg_operand" "")
19078         (match_operator 2 "compare_operator"
19079           [(and (match_operand 3 "aligned_operand" "")
19080                 (match_operand 4 "const_int_operand" ""))
19081            (const_int 0)]))
19082    (set (match_operand 1 "register_operand" "")
19083         (and (match_dup 3) (match_dup 4)))]
19084   "! TARGET_PARTIAL_REG_STALL && reload_completed
19085    /* Ensure that the operand will remain sign-extended immediate.  */
19086    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19087    && ! optimize_size
19088    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19089        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19090   [(parallel [(set (match_dup 0)
19091                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19092                                     (const_int 0)]))
19093               (set (match_dup 1)
19094                    (and:SI (match_dup 3) (match_dup 4)))])]
19095 {
19096   operands[4]
19097     = gen_int_mode (INTVAL (operands[4])
19098                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19099   operands[1] = gen_lowpart (SImode, operands[1]);
19100   operands[3] = gen_lowpart (SImode, operands[3]);
19101 })
19102
19103 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19104 ; the TEST instruction with 32-bit sign-extended immediate and thus
19105 ; the instruction size would at least double, which is not what we
19106 ; want even with ! optimize_size.
19107 (define_split
19108   [(set (match_operand 0 "flags_reg_operand" "")
19109         (match_operator 1 "compare_operator"
19110           [(and (match_operand:HI 2 "aligned_operand" "")
19111                 (match_operand:HI 3 "const_int_operand" ""))
19112            (const_int 0)]))]
19113   "! TARGET_PARTIAL_REG_STALL && reload_completed
19114    /* Ensure that the operand will remain sign-extended immediate.  */
19115    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19116    && ! TARGET_FAST_PREFIX
19117    && ! optimize_size"
19118   [(set (match_dup 0)
19119         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19120                          (const_int 0)]))]
19121 {
19122   operands[3]
19123     = gen_int_mode (INTVAL (operands[3])
19124                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19125   operands[2] = gen_lowpart (SImode, operands[2]);
19126 })
19127
19128 (define_split
19129   [(set (match_operand 0 "register_operand" "")
19130         (neg (match_operand 1 "register_operand" "")))
19131    (clobber (reg:CC FLAGS_REG))]
19132   "! TARGET_PARTIAL_REG_STALL && reload_completed
19133    && (GET_MODE (operands[0]) == HImode
19134        || (GET_MODE (operands[0]) == QImode 
19135            && (TARGET_PROMOTE_QImode || optimize_size)))"
19136   [(parallel [(set (match_dup 0)
19137                    (neg:SI (match_dup 1)))
19138               (clobber (reg:CC FLAGS_REG))])]
19139   "operands[0] = gen_lowpart (SImode, operands[0]);
19140    operands[1] = gen_lowpart (SImode, operands[1]);")
19141
19142 (define_split
19143   [(set (match_operand 0 "register_operand" "")
19144         (not (match_operand 1 "register_operand" "")))]
19145   "! TARGET_PARTIAL_REG_STALL && reload_completed
19146    && (GET_MODE (operands[0]) == HImode
19147        || (GET_MODE (operands[0]) == QImode 
19148            && (TARGET_PROMOTE_QImode || optimize_size)))"
19149   [(set (match_dup 0)
19150         (not:SI (match_dup 1)))]
19151   "operands[0] = gen_lowpart (SImode, operands[0]);
19152    operands[1] = gen_lowpart (SImode, operands[1]);")
19153
19154 (define_split 
19155   [(set (match_operand 0 "register_operand" "")
19156         (if_then_else (match_operator 1 "comparison_operator" 
19157                                 [(reg FLAGS_REG) (const_int 0)])
19158                       (match_operand 2 "register_operand" "")
19159                       (match_operand 3 "register_operand" "")))]
19160   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19161    && (GET_MODE (operands[0]) == HImode
19162        || (GET_MODE (operands[0]) == QImode 
19163            && (TARGET_PROMOTE_QImode || optimize_size)))"
19164   [(set (match_dup 0)
19165         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19166   "operands[0] = gen_lowpart (SImode, operands[0]);
19167    operands[2] = gen_lowpart (SImode, operands[2]);
19168    operands[3] = gen_lowpart (SImode, operands[3]);")
19169                         
19170 \f
19171 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19172 ;; transform a complex memory operation into two memory to register operations.
19173
19174 ;; Don't push memory operands
19175 (define_peephole2
19176   [(set (match_operand:SI 0 "push_operand" "")
19177         (match_operand:SI 1 "memory_operand" ""))
19178    (match_scratch:SI 2 "r")]
19179   "!optimize_size && !TARGET_PUSH_MEMORY
19180    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19181   [(set (match_dup 2) (match_dup 1))
19182    (set (match_dup 0) (match_dup 2))]
19183   "")
19184
19185 (define_peephole2
19186   [(set (match_operand:DI 0 "push_operand" "")
19187         (match_operand:DI 1 "memory_operand" ""))
19188    (match_scratch:DI 2 "r")]
19189   "!optimize_size && !TARGET_PUSH_MEMORY
19190    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19191   [(set (match_dup 2) (match_dup 1))
19192    (set (match_dup 0) (match_dup 2))]
19193   "")
19194
19195 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19196 ;; SImode pushes.
19197 (define_peephole2
19198   [(set (match_operand:SF 0 "push_operand" "")
19199         (match_operand:SF 1 "memory_operand" ""))
19200    (match_scratch:SF 2 "r")]
19201   "!optimize_size && !TARGET_PUSH_MEMORY
19202    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19203   [(set (match_dup 2) (match_dup 1))
19204    (set (match_dup 0) (match_dup 2))]
19205   "")
19206
19207 (define_peephole2
19208   [(set (match_operand:HI 0 "push_operand" "")
19209         (match_operand:HI 1 "memory_operand" ""))
19210    (match_scratch:HI 2 "r")]
19211   "!optimize_size && !TARGET_PUSH_MEMORY
19212    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19213   [(set (match_dup 2) (match_dup 1))
19214    (set (match_dup 0) (match_dup 2))]
19215   "")
19216
19217 (define_peephole2
19218   [(set (match_operand:QI 0 "push_operand" "")
19219         (match_operand:QI 1 "memory_operand" ""))
19220    (match_scratch:QI 2 "q")]
19221   "!optimize_size && !TARGET_PUSH_MEMORY
19222    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19223   [(set (match_dup 2) (match_dup 1))
19224    (set (match_dup 0) (match_dup 2))]
19225   "")
19226
19227 ;; Don't move an immediate directly to memory when the instruction
19228 ;; gets too big.
19229 (define_peephole2
19230   [(match_scratch:SI 1 "r")
19231    (set (match_operand:SI 0 "memory_operand" "")
19232         (const_int 0))]
19233   "! optimize_size
19234    && ! TARGET_USE_MOV0
19235    && TARGET_SPLIT_LONG_MOVES
19236    && get_attr_length (insn) >= ix86_cost->large_insn
19237    && peep2_regno_dead_p (0, FLAGS_REG)"
19238   [(parallel [(set (match_dup 1) (const_int 0))
19239               (clobber (reg:CC FLAGS_REG))])
19240    (set (match_dup 0) (match_dup 1))]
19241   "")
19242
19243 (define_peephole2
19244   [(match_scratch:HI 1 "r")
19245    (set (match_operand:HI 0 "memory_operand" "")
19246         (const_int 0))]
19247   "! optimize_size
19248    && ! TARGET_USE_MOV0
19249    && TARGET_SPLIT_LONG_MOVES
19250    && get_attr_length (insn) >= ix86_cost->large_insn
19251    && peep2_regno_dead_p (0, FLAGS_REG)"
19252   [(parallel [(set (match_dup 2) (const_int 0))
19253               (clobber (reg:CC FLAGS_REG))])
19254    (set (match_dup 0) (match_dup 1))]
19255   "operands[2] = gen_lowpart (SImode, operands[1]);")
19256
19257 (define_peephole2
19258   [(match_scratch:QI 1 "q")
19259    (set (match_operand:QI 0 "memory_operand" "")
19260         (const_int 0))]
19261   "! optimize_size
19262    && ! TARGET_USE_MOV0
19263    && TARGET_SPLIT_LONG_MOVES
19264    && get_attr_length (insn) >= ix86_cost->large_insn
19265    && peep2_regno_dead_p (0, FLAGS_REG)"
19266   [(parallel [(set (match_dup 2) (const_int 0))
19267               (clobber (reg:CC FLAGS_REG))])
19268    (set (match_dup 0) (match_dup 1))]
19269   "operands[2] = gen_lowpart (SImode, operands[1]);")
19270
19271 (define_peephole2
19272   [(match_scratch:SI 2 "r")
19273    (set (match_operand:SI 0 "memory_operand" "")
19274         (match_operand:SI 1 "immediate_operand" ""))]
19275   "! optimize_size
19276    && get_attr_length (insn) >= ix86_cost->large_insn
19277    && TARGET_SPLIT_LONG_MOVES"
19278   [(set (match_dup 2) (match_dup 1))
19279    (set (match_dup 0) (match_dup 2))]
19280   "")
19281
19282 (define_peephole2
19283   [(match_scratch:HI 2 "r")
19284    (set (match_operand:HI 0 "memory_operand" "")
19285         (match_operand:HI 1 "immediate_operand" ""))]
19286   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19287   && TARGET_SPLIT_LONG_MOVES"
19288   [(set (match_dup 2) (match_dup 1))
19289    (set (match_dup 0) (match_dup 2))]
19290   "")
19291
19292 (define_peephole2
19293   [(match_scratch:QI 2 "q")
19294    (set (match_operand:QI 0 "memory_operand" "")
19295         (match_operand:QI 1 "immediate_operand" ""))]
19296   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19297   && TARGET_SPLIT_LONG_MOVES"
19298   [(set (match_dup 2) (match_dup 1))
19299    (set (match_dup 0) (match_dup 2))]
19300   "")
19301
19302 ;; Don't compare memory with zero, load and use a test instead.
19303 (define_peephole2
19304   [(set (match_operand 0 "flags_reg_operand" "")
19305         (match_operator 1 "compare_operator"
19306           [(match_operand:SI 2 "memory_operand" "")
19307            (const_int 0)]))
19308    (match_scratch:SI 3 "r")]
19309   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19310   [(set (match_dup 3) (match_dup 2))
19311    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19312   "")
19313
19314 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19315 ;; Don't split NOTs with a displacement operand, because resulting XOR
19316 ;; will not be pairable anyway.
19317 ;;
19318 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19319 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19320 ;; so this split helps here as well.
19321 ;;
19322 ;; Note: Can't do this as a regular split because we can't get proper
19323 ;; lifetime information then.
19324
19325 (define_peephole2
19326   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19327         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19328   "!optimize_size
19329    && peep2_regno_dead_p (0, FLAGS_REG)
19330    && ((TARGET_PENTIUM 
19331         && (GET_CODE (operands[0]) != MEM
19332             || !memory_displacement_operand (operands[0], SImode)))
19333        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19334   [(parallel [(set (match_dup 0)
19335                    (xor:SI (match_dup 1) (const_int -1)))
19336               (clobber (reg:CC FLAGS_REG))])]
19337   "")
19338
19339 (define_peephole2
19340   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19341         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19342   "!optimize_size
19343    && peep2_regno_dead_p (0, FLAGS_REG)
19344    && ((TARGET_PENTIUM 
19345         && (GET_CODE (operands[0]) != MEM
19346             || !memory_displacement_operand (operands[0], HImode)))
19347        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19348   [(parallel [(set (match_dup 0)
19349                    (xor:HI (match_dup 1) (const_int -1)))
19350               (clobber (reg:CC FLAGS_REG))])]
19351   "")
19352
19353 (define_peephole2
19354   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19355         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19356   "!optimize_size
19357    && peep2_regno_dead_p (0, FLAGS_REG)
19358    && ((TARGET_PENTIUM 
19359         && (GET_CODE (operands[0]) != MEM
19360             || !memory_displacement_operand (operands[0], QImode)))
19361        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19362   [(parallel [(set (match_dup 0)
19363                    (xor:QI (match_dup 1) (const_int -1)))
19364               (clobber (reg:CC FLAGS_REG))])]
19365   "")
19366
19367 ;; Non pairable "test imm, reg" instructions can be translated to
19368 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19369 ;; byte opcode instead of two, have a short form for byte operands),
19370 ;; so do it for other CPUs as well.  Given that the value was dead,
19371 ;; this should not create any new dependencies.  Pass on the sub-word
19372 ;; versions if we're concerned about partial register stalls.
19373
19374 (define_peephole2
19375   [(set (match_operand 0 "flags_reg_operand" "")
19376         (match_operator 1 "compare_operator"
19377           [(and:SI (match_operand:SI 2 "register_operand" "")
19378                    (match_operand:SI 3 "immediate_operand" ""))
19379            (const_int 0)]))]
19380   "ix86_match_ccmode (insn, CCNOmode)
19381    && (true_regnum (operands[2]) != 0
19382        || satisfies_constraint_K (operands[3]))
19383    && peep2_reg_dead_p (1, operands[2])"
19384   [(parallel
19385      [(set (match_dup 0)
19386            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19387                             (const_int 0)]))
19388       (set (match_dup 2)
19389            (and:SI (match_dup 2) (match_dup 3)))])]
19390   "")
19391
19392 ;; We don't need to handle HImode case, because it will be promoted to SImode
19393 ;; on ! TARGET_PARTIAL_REG_STALL
19394
19395 (define_peephole2
19396   [(set (match_operand 0 "flags_reg_operand" "")
19397         (match_operator 1 "compare_operator"
19398           [(and:QI (match_operand:QI 2 "register_operand" "")
19399                    (match_operand:QI 3 "immediate_operand" ""))
19400            (const_int 0)]))]
19401   "! TARGET_PARTIAL_REG_STALL
19402    && ix86_match_ccmode (insn, CCNOmode)
19403    && true_regnum (operands[2]) != 0
19404    && peep2_reg_dead_p (1, operands[2])"
19405   [(parallel
19406      [(set (match_dup 0)
19407            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19408                             (const_int 0)]))
19409       (set (match_dup 2)
19410            (and:QI (match_dup 2) (match_dup 3)))])]
19411   "")
19412
19413 (define_peephole2
19414   [(set (match_operand 0 "flags_reg_operand" "")
19415         (match_operator 1 "compare_operator"
19416           [(and:SI
19417              (zero_extract:SI
19418                (match_operand 2 "ext_register_operand" "")
19419                (const_int 8)
19420                (const_int 8))
19421              (match_operand 3 "const_int_operand" ""))
19422            (const_int 0)]))]
19423   "! TARGET_PARTIAL_REG_STALL
19424    && ix86_match_ccmode (insn, CCNOmode)
19425    && true_regnum (operands[2]) != 0
19426    && peep2_reg_dead_p (1, operands[2])"
19427   [(parallel [(set (match_dup 0)
19428                    (match_op_dup 1
19429                      [(and:SI
19430                         (zero_extract:SI
19431                           (match_dup 2)
19432                           (const_int 8)
19433                           (const_int 8))
19434                         (match_dup 3))
19435                       (const_int 0)]))
19436               (set (zero_extract:SI (match_dup 2)
19437                                     (const_int 8)
19438                                     (const_int 8))
19439                    (and:SI 
19440                      (zero_extract:SI
19441                        (match_dup 2)
19442                        (const_int 8)
19443                        (const_int 8))
19444                      (match_dup 3)))])]
19445   "")
19446
19447 ;; Don't do logical operations with memory inputs.
19448 (define_peephole2
19449   [(match_scratch:SI 2 "r")
19450    (parallel [(set (match_operand:SI 0 "register_operand" "")
19451                    (match_operator:SI 3 "arith_or_logical_operator"
19452                      [(match_dup 0)
19453                       (match_operand:SI 1 "memory_operand" "")]))
19454               (clobber (reg:CC FLAGS_REG))])]
19455   "! optimize_size && ! TARGET_READ_MODIFY"
19456   [(set (match_dup 2) (match_dup 1))
19457    (parallel [(set (match_dup 0)
19458                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19459               (clobber (reg:CC FLAGS_REG))])]
19460   "")
19461
19462 (define_peephole2
19463   [(match_scratch:SI 2 "r")
19464    (parallel [(set (match_operand:SI 0 "register_operand" "")
19465                    (match_operator:SI 3 "arith_or_logical_operator"
19466                      [(match_operand:SI 1 "memory_operand" "")
19467                       (match_dup 0)]))
19468               (clobber (reg:CC FLAGS_REG))])]
19469   "! optimize_size && ! TARGET_READ_MODIFY"
19470   [(set (match_dup 2) (match_dup 1))
19471    (parallel [(set (match_dup 0)
19472                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19473               (clobber (reg:CC FLAGS_REG))])]
19474   "")
19475
19476 ; Don't do logical operations with memory outputs
19477 ;
19478 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19479 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19480 ; the same decoder scheduling characteristics as the original.
19481
19482 (define_peephole2
19483   [(match_scratch:SI 2 "r")
19484    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19485                    (match_operator:SI 3 "arith_or_logical_operator"
19486                      [(match_dup 0)
19487                       (match_operand:SI 1 "nonmemory_operand" "")]))
19488               (clobber (reg:CC FLAGS_REG))])]
19489   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19490   [(set (match_dup 2) (match_dup 0))
19491    (parallel [(set (match_dup 2)
19492                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19493               (clobber (reg:CC FLAGS_REG))])
19494    (set (match_dup 0) (match_dup 2))]
19495   "")
19496
19497 (define_peephole2
19498   [(match_scratch:SI 2 "r")
19499    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19500                    (match_operator:SI 3 "arith_or_logical_operator"
19501                      [(match_operand:SI 1 "nonmemory_operand" "")
19502                       (match_dup 0)]))
19503               (clobber (reg:CC FLAGS_REG))])]
19504   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19505   [(set (match_dup 2) (match_dup 0))
19506    (parallel [(set (match_dup 2)
19507                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19508               (clobber (reg:CC FLAGS_REG))])
19509    (set (match_dup 0) (match_dup 2))]
19510   "")
19511
19512 ;; Attempt to always use XOR for zeroing registers.
19513 (define_peephole2
19514   [(set (match_operand 0 "register_operand" "")
19515         (match_operand 1 "const0_operand" ""))]
19516   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19517    && (! TARGET_USE_MOV0 || optimize_size)
19518    && GENERAL_REG_P (operands[0])
19519    && peep2_regno_dead_p (0, FLAGS_REG)"
19520   [(parallel [(set (match_dup 0) (const_int 0))
19521               (clobber (reg:CC FLAGS_REG))])]
19522 {
19523   operands[0] = gen_lowpart (word_mode, operands[0]);
19524 })
19525
19526 (define_peephole2
19527   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19528         (const_int 0))]
19529   "(GET_MODE (operands[0]) == QImode
19530     || GET_MODE (operands[0]) == HImode)
19531    && (! TARGET_USE_MOV0 || optimize_size)
19532    && peep2_regno_dead_p (0, FLAGS_REG)"
19533   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19534               (clobber (reg:CC FLAGS_REG))])])
19535
19536 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19537 (define_peephole2
19538   [(set (match_operand 0 "register_operand" "")
19539         (const_int -1))]
19540   "(GET_MODE (operands[0]) == HImode
19541     || GET_MODE (operands[0]) == SImode 
19542     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19543    && (optimize_size || TARGET_PENTIUM)
19544    && peep2_regno_dead_p (0, FLAGS_REG)"
19545   [(parallel [(set (match_dup 0) (const_int -1))
19546               (clobber (reg:CC FLAGS_REG))])]
19547   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19548                               operands[0]);")
19549
19550 ;; Attempt to convert simple leas to adds. These can be created by
19551 ;; move expanders.
19552 (define_peephole2
19553   [(set (match_operand:SI 0 "register_operand" "")
19554         (plus:SI (match_dup 0)
19555                  (match_operand:SI 1 "nonmemory_operand" "")))]
19556   "peep2_regno_dead_p (0, FLAGS_REG)"
19557   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19558               (clobber (reg:CC FLAGS_REG))])]
19559   "")
19560
19561 (define_peephole2
19562   [(set (match_operand:SI 0 "register_operand" "")
19563         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19564                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19565   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19566   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19567               (clobber (reg:CC FLAGS_REG))])]
19568   "operands[2] = gen_lowpart (SImode, operands[2]);")
19569
19570 (define_peephole2
19571   [(set (match_operand:DI 0 "register_operand" "")
19572         (plus:DI (match_dup 0)
19573                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19574   "peep2_regno_dead_p (0, FLAGS_REG)"
19575   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19576               (clobber (reg:CC FLAGS_REG))])]
19577   "")
19578
19579 (define_peephole2
19580   [(set (match_operand:SI 0 "register_operand" "")
19581         (mult:SI (match_dup 0)
19582                  (match_operand:SI 1 "const_int_operand" "")))]
19583   "exact_log2 (INTVAL (operands[1])) >= 0
19584    && peep2_regno_dead_p (0, FLAGS_REG)"
19585   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19586               (clobber (reg:CC FLAGS_REG))])]
19587   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19588
19589 (define_peephole2
19590   [(set (match_operand:DI 0 "register_operand" "")
19591         (mult:DI (match_dup 0)
19592                  (match_operand:DI 1 "const_int_operand" "")))]
19593   "exact_log2 (INTVAL (operands[1])) >= 0
19594    && peep2_regno_dead_p (0, FLAGS_REG)"
19595   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19596               (clobber (reg:CC FLAGS_REG))])]
19597   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19598
19599 (define_peephole2
19600   [(set (match_operand:SI 0 "register_operand" "")
19601         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19602                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19603   "exact_log2 (INTVAL (operands[2])) >= 0
19604    && REGNO (operands[0]) == REGNO (operands[1])
19605    && peep2_regno_dead_p (0, FLAGS_REG)"
19606   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19607               (clobber (reg:CC FLAGS_REG))])]
19608   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19609
19610 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19611 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19612 ;; many CPUs it is also faster, since special hardware to avoid esp
19613 ;; dependencies is present.
19614
19615 ;; While some of these conversions may be done using splitters, we use peepholes
19616 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19617
19618 ;; Convert prologue esp subtractions to push.
19619 ;; We need register to push.  In order to keep verify_flow_info happy we have
19620 ;; two choices
19621 ;; - use scratch and clobber it in order to avoid dependencies
19622 ;; - use already live register
19623 ;; We can't use the second way right now, since there is no reliable way how to
19624 ;; verify that given register is live.  First choice will also most likely in
19625 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19626 ;; call clobbered registers are dead.  We may want to use base pointer as an
19627 ;; alternative when no register is available later.
19628
19629 (define_peephole2
19630   [(match_scratch:SI 0 "r")
19631    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19632               (clobber (reg:CC FLAGS_REG))
19633               (clobber (mem:BLK (scratch)))])]
19634   "optimize_size || !TARGET_SUB_ESP_4"
19635   [(clobber (match_dup 0))
19636    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19637               (clobber (mem:BLK (scratch)))])])
19638
19639 (define_peephole2
19640   [(match_scratch:SI 0 "r")
19641    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19642               (clobber (reg:CC FLAGS_REG))
19643               (clobber (mem:BLK (scratch)))])]
19644   "optimize_size || !TARGET_SUB_ESP_8"
19645   [(clobber (match_dup 0))
19646    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19647    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19648               (clobber (mem:BLK (scratch)))])])
19649
19650 ;; Convert esp subtractions to push.
19651 (define_peephole2
19652   [(match_scratch:SI 0 "r")
19653    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19654               (clobber (reg:CC FLAGS_REG))])]
19655   "optimize_size || !TARGET_SUB_ESP_4"
19656   [(clobber (match_dup 0))
19657    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19658
19659 (define_peephole2
19660   [(match_scratch:SI 0 "r")
19661    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19662               (clobber (reg:CC FLAGS_REG))])]
19663   "optimize_size || !TARGET_SUB_ESP_8"
19664   [(clobber (match_dup 0))
19665    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19666    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19667
19668 ;; Convert epilogue deallocator to pop.
19669 (define_peephole2
19670   [(match_scratch:SI 0 "r")
19671    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19672               (clobber (reg:CC FLAGS_REG))
19673               (clobber (mem:BLK (scratch)))])]
19674   "optimize_size || !TARGET_ADD_ESP_4"
19675   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19676               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19677               (clobber (mem:BLK (scratch)))])]
19678   "")
19679
19680 ;; Two pops case is tricky, since pop causes dependency on destination register.
19681 ;; We use two registers if available.
19682 (define_peephole2
19683   [(match_scratch:SI 0 "r")
19684    (match_scratch:SI 1 "r")
19685    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19686               (clobber (reg:CC FLAGS_REG))
19687               (clobber (mem:BLK (scratch)))])]
19688   "optimize_size || !TARGET_ADD_ESP_8"
19689   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19691               (clobber (mem:BLK (scratch)))])
19692    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19693               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19694   "")
19695
19696 (define_peephole2
19697   [(match_scratch:SI 0 "r")
19698    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19699               (clobber (reg:CC FLAGS_REG))
19700               (clobber (mem:BLK (scratch)))])]
19701   "optimize_size"
19702   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19703               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19704               (clobber (mem:BLK (scratch)))])
19705    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19706               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19707   "")
19708
19709 ;; Convert esp additions to pop.
19710 (define_peephole2
19711   [(match_scratch:SI 0 "r")
19712    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19713               (clobber (reg:CC FLAGS_REG))])]
19714   ""
19715   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19716               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19717   "")
19718
19719 ;; Two pops case is tricky, since pop causes dependency on destination register.
19720 ;; We use two registers if available.
19721 (define_peephole2
19722   [(match_scratch:SI 0 "r")
19723    (match_scratch:SI 1 "r")
19724    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19725               (clobber (reg:CC FLAGS_REG))])]
19726   ""
19727   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19728               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19729    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19730               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19731   "")
19732
19733 (define_peephole2
19734   [(match_scratch:SI 0 "r")
19735    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19736               (clobber (reg:CC FLAGS_REG))])]
19737   "optimize_size"
19738   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19739               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19740    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19741               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19742   "")
19743 \f
19744 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19745 ;; required and register dies.  Similarly for 128 to plus -128.
19746 (define_peephole2
19747   [(set (match_operand 0 "flags_reg_operand" "")
19748         (match_operator 1 "compare_operator"
19749           [(match_operand 2 "register_operand" "")
19750            (match_operand 3 "const_int_operand" "")]))]
19751   "(INTVAL (operands[3]) == -1
19752     || INTVAL (operands[3]) == 1
19753     || INTVAL (operands[3]) == 128)
19754    && ix86_match_ccmode (insn, CCGCmode)
19755    && peep2_reg_dead_p (1, operands[2])"
19756   [(parallel [(set (match_dup 0)
19757                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19758               (clobber (match_dup 2))])]
19759   "")
19760 \f
19761 (define_peephole2
19762   [(match_scratch:DI 0 "r")
19763    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19764               (clobber (reg:CC FLAGS_REG))
19765               (clobber (mem:BLK (scratch)))])]
19766   "optimize_size || !TARGET_SUB_ESP_4"
19767   [(clobber (match_dup 0))
19768    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19769               (clobber (mem:BLK (scratch)))])])
19770
19771 (define_peephole2
19772   [(match_scratch:DI 0 "r")
19773    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19774               (clobber (reg:CC FLAGS_REG))
19775               (clobber (mem:BLK (scratch)))])]
19776   "optimize_size || !TARGET_SUB_ESP_8"
19777   [(clobber (match_dup 0))
19778    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19779    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19780               (clobber (mem:BLK (scratch)))])])
19781
19782 ;; Convert esp subtractions to push.
19783 (define_peephole2
19784   [(match_scratch:DI 0 "r")
19785    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19786               (clobber (reg:CC FLAGS_REG))])]
19787   "optimize_size || !TARGET_SUB_ESP_4"
19788   [(clobber (match_dup 0))
19789    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19790
19791 (define_peephole2
19792   [(match_scratch:DI 0 "r")
19793    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19794               (clobber (reg:CC FLAGS_REG))])]
19795   "optimize_size || !TARGET_SUB_ESP_8"
19796   [(clobber (match_dup 0))
19797    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19798    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19799
19800 ;; Convert epilogue deallocator to pop.
19801 (define_peephole2
19802   [(match_scratch:DI 0 "r")
19803    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19804               (clobber (reg:CC FLAGS_REG))
19805               (clobber (mem:BLK (scratch)))])]
19806   "optimize_size || !TARGET_ADD_ESP_4"
19807   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19808               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19809               (clobber (mem:BLK (scratch)))])]
19810   "")
19811
19812 ;; Two pops case is tricky, since pop causes dependency on destination register.
19813 ;; We use two registers if available.
19814 (define_peephole2
19815   [(match_scratch:DI 0 "r")
19816    (match_scratch:DI 1 "r")
19817    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19818               (clobber (reg:CC FLAGS_REG))
19819               (clobber (mem:BLK (scratch)))])]
19820   "optimize_size || !TARGET_ADD_ESP_8"
19821   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19822               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19823               (clobber (mem:BLK (scratch)))])
19824    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19825               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19826   "")
19827
19828 (define_peephole2
19829   [(match_scratch:DI 0 "r")
19830    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19831               (clobber (reg:CC FLAGS_REG))
19832               (clobber (mem:BLK (scratch)))])]
19833   "optimize_size"
19834   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19835               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19836               (clobber (mem:BLK (scratch)))])
19837    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19838               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19839   "")
19840
19841 ;; Convert esp additions to pop.
19842 (define_peephole2
19843   [(match_scratch:DI 0 "r")
19844    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19845               (clobber (reg:CC FLAGS_REG))])]
19846   ""
19847   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19848               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19849   "")
19850
19851 ;; Two pops case is tricky, since pop causes dependency on destination register.
19852 ;; We use two registers if available.
19853 (define_peephole2
19854   [(match_scratch:DI 0 "r")
19855    (match_scratch:DI 1 "r")
19856    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19857               (clobber (reg:CC FLAGS_REG))])]
19858   ""
19859   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19860               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19861    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19862               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19863   "")
19864
19865 (define_peephole2
19866   [(match_scratch:DI 0 "r")
19867    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19868               (clobber (reg:CC FLAGS_REG))])]
19869   "optimize_size"
19870   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19871               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19872    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19873               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19874   "")
19875 \f
19876 ;; Convert imul by three, five and nine into lea
19877 (define_peephole2
19878   [(parallel
19879     [(set (match_operand:SI 0 "register_operand" "")
19880           (mult:SI (match_operand:SI 1 "register_operand" "")
19881                    (match_operand:SI 2 "const_int_operand" "")))
19882      (clobber (reg:CC FLAGS_REG))])]
19883   "INTVAL (operands[2]) == 3
19884    || INTVAL (operands[2]) == 5
19885    || INTVAL (operands[2]) == 9"
19886   [(set (match_dup 0)
19887         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19888                  (match_dup 1)))]
19889   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19890
19891 (define_peephole2
19892   [(parallel
19893     [(set (match_operand:SI 0 "register_operand" "")
19894           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19895                    (match_operand:SI 2 "const_int_operand" "")))
19896      (clobber (reg:CC FLAGS_REG))])]
19897   "!optimize_size 
19898    && (INTVAL (operands[2]) == 3
19899        || INTVAL (operands[2]) == 5
19900        || INTVAL (operands[2]) == 9)"
19901   [(set (match_dup 0) (match_dup 1))
19902    (set (match_dup 0)
19903         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19904                  (match_dup 0)))]
19905   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19906
19907 (define_peephole2
19908   [(parallel
19909     [(set (match_operand:DI 0 "register_operand" "")
19910           (mult:DI (match_operand:DI 1 "register_operand" "")
19911                    (match_operand:DI 2 "const_int_operand" "")))
19912      (clobber (reg:CC FLAGS_REG))])]
19913   "TARGET_64BIT
19914    && (INTVAL (operands[2]) == 3
19915        || INTVAL (operands[2]) == 5
19916        || INTVAL (operands[2]) == 9)"
19917   [(set (match_dup 0)
19918         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19919                  (match_dup 1)))]
19920   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19921
19922 (define_peephole2
19923   [(parallel
19924     [(set (match_operand:DI 0 "register_operand" "")
19925           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19926                    (match_operand:DI 2 "const_int_operand" "")))
19927      (clobber (reg:CC FLAGS_REG))])]
19928   "TARGET_64BIT
19929    && !optimize_size 
19930    && (INTVAL (operands[2]) == 3
19931        || INTVAL (operands[2]) == 5
19932        || INTVAL (operands[2]) == 9)"
19933   [(set (match_dup 0) (match_dup 1))
19934    (set (match_dup 0)
19935         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19936                  (match_dup 0)))]
19937   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19938
19939 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19940 ;; imul $32bit_imm, reg, reg is direct decoded.
19941 (define_peephole2
19942   [(match_scratch:DI 3 "r")
19943    (parallel [(set (match_operand:DI 0 "register_operand" "")
19944                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19945                             (match_operand:DI 2 "immediate_operand" "")))
19946               (clobber (reg:CC FLAGS_REG))])]
19947   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19948    && !satisfies_constraint_K (operands[2])"
19949   [(set (match_dup 3) (match_dup 1))
19950    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19951               (clobber (reg:CC FLAGS_REG))])]
19952 "")
19953
19954 (define_peephole2
19955   [(match_scratch:SI 3 "r")
19956    (parallel [(set (match_operand:SI 0 "register_operand" "")
19957                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19958                             (match_operand:SI 2 "immediate_operand" "")))
19959               (clobber (reg:CC FLAGS_REG))])]
19960   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19961    && !satisfies_constraint_K (operands[2])"
19962   [(set (match_dup 3) (match_dup 1))
19963    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19964               (clobber (reg:CC FLAGS_REG))])]
19965 "")
19966
19967 (define_peephole2
19968   [(match_scratch:SI 3 "r")
19969    (parallel [(set (match_operand:DI 0 "register_operand" "")
19970                    (zero_extend:DI
19971                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19972                               (match_operand:SI 2 "immediate_operand" ""))))
19973               (clobber (reg:CC FLAGS_REG))])]
19974   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19975    && !satisfies_constraint_K (operands[2])"
19976   [(set (match_dup 3) (match_dup 1))
19977    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19978               (clobber (reg:CC FLAGS_REG))])]
19979 "")
19980
19981 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19982 ;; Convert it into imul reg, reg
19983 ;; It would be better to force assembler to encode instruction using long
19984 ;; immediate, but there is apparently no way to do so.
19985 (define_peephole2
19986   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19987                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19988                             (match_operand:DI 2 "const_int_operand" "")))
19989               (clobber (reg:CC FLAGS_REG))])
19990    (match_scratch:DI 3 "r")]
19991   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19992    && satisfies_constraint_K (operands[2])"
19993   [(set (match_dup 3) (match_dup 2))
19994    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19995               (clobber (reg:CC FLAGS_REG))])]
19996 {
19997   if (!rtx_equal_p (operands[0], operands[1]))
19998     emit_move_insn (operands[0], operands[1]);
19999 })
20000
20001 (define_peephole2
20002   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20003                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20004                             (match_operand:SI 2 "const_int_operand" "")))
20005               (clobber (reg:CC FLAGS_REG))])
20006    (match_scratch:SI 3 "r")]
20007   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20008    && satisfies_constraint_K (operands[2])"
20009   [(set (match_dup 3) (match_dup 2))
20010    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20011               (clobber (reg:CC FLAGS_REG))])]
20012 {
20013   if (!rtx_equal_p (operands[0], operands[1]))
20014     emit_move_insn (operands[0], operands[1]);
20015 })
20016
20017 (define_peephole2
20018   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20019                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20020                             (match_operand:HI 2 "immediate_operand" "")))
20021               (clobber (reg:CC FLAGS_REG))])
20022    (match_scratch:HI 3 "r")]
20023   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20024   [(set (match_dup 3) (match_dup 2))
20025    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20026               (clobber (reg:CC FLAGS_REG))])]
20027 {
20028   if (!rtx_equal_p (operands[0], operands[1]))
20029     emit_move_insn (operands[0], operands[1]);
20030 })
20031
20032 ;; After splitting up read-modify operations, array accesses with memory
20033 ;; operands might end up in form:
20034 ;;  sall    $2, %eax
20035 ;;  movl    4(%esp), %edx
20036 ;;  addl    %edx, %eax
20037 ;; instead of pre-splitting:
20038 ;;  sall    $2, %eax
20039 ;;  addl    4(%esp), %eax
20040 ;; Turn it into:
20041 ;;  movl    4(%esp), %edx
20042 ;;  leal    (%edx,%eax,4), %eax
20043
20044 (define_peephole2
20045   [(parallel [(set (match_operand 0 "register_operand" "")
20046                    (ashift (match_operand 1 "register_operand" "")
20047                            (match_operand 2 "const_int_operand" "")))
20048                (clobber (reg:CC FLAGS_REG))])
20049    (set (match_operand 3 "register_operand")
20050         (match_operand 4 "x86_64_general_operand" ""))
20051    (parallel [(set (match_operand 5 "register_operand" "")
20052                    (plus (match_operand 6 "register_operand" "")
20053                          (match_operand 7 "register_operand" "")))
20054                    (clobber (reg:CC FLAGS_REG))])]
20055   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20056    /* Validate MODE for lea.  */
20057    && ((!TARGET_PARTIAL_REG_STALL
20058         && (GET_MODE (operands[0]) == QImode
20059             || GET_MODE (operands[0]) == HImode))
20060        || GET_MODE (operands[0]) == SImode 
20061        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20062    /* We reorder load and the shift.  */
20063    && !rtx_equal_p (operands[1], operands[3])
20064    && !reg_overlap_mentioned_p (operands[0], operands[4])
20065    /* Last PLUS must consist of operand 0 and 3.  */
20066    && !rtx_equal_p (operands[0], operands[3])
20067    && (rtx_equal_p (operands[3], operands[6])
20068        || rtx_equal_p (operands[3], operands[7]))
20069    && (rtx_equal_p (operands[0], operands[6])
20070        || rtx_equal_p (operands[0], operands[7]))
20071    /* The intermediate operand 0 must die or be same as output.  */
20072    && (rtx_equal_p (operands[0], operands[5])
20073        || peep2_reg_dead_p (3, operands[0]))"
20074   [(set (match_dup 3) (match_dup 4))
20075    (set (match_dup 0) (match_dup 1))]
20076 {
20077   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20078   int scale = 1 << INTVAL (operands[2]);
20079   rtx index = gen_lowpart (Pmode, operands[1]);
20080   rtx base = gen_lowpart (Pmode, operands[3]);
20081   rtx dest = gen_lowpart (mode, operands[5]);
20082
20083   operands[1] = gen_rtx_PLUS (Pmode, base,
20084                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20085   if (mode != Pmode)
20086     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20087   operands[0] = dest;
20088 })
20089 \f
20090 ;; Call-value patterns last so that the wildcard operand does not
20091 ;; disrupt insn-recog's switch tables.
20092
20093 (define_insn "*call_value_pop_0"
20094   [(set (match_operand 0 "" "")
20095         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20096               (match_operand:SI 2 "" "")))
20097    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20098                             (match_operand:SI 3 "immediate_operand" "")))]
20099   "!TARGET_64BIT"
20100 {
20101   if (SIBLING_CALL_P (insn))
20102     return "jmp\t%P1";
20103   else
20104     return "call\t%P1";
20105 }
20106   [(set_attr "type" "callv")])
20107
20108 (define_insn "*call_value_pop_1"
20109   [(set (match_operand 0 "" "")
20110         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20111               (match_operand:SI 2 "" "")))
20112    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20113                             (match_operand:SI 3 "immediate_operand" "i")))]
20114   "!TARGET_64BIT"
20115 {
20116   if (constant_call_address_operand (operands[1], Pmode))
20117     {
20118       if (SIBLING_CALL_P (insn))
20119         return "jmp\t%P1";
20120       else
20121         return "call\t%P1";
20122     }
20123   if (SIBLING_CALL_P (insn))
20124     return "jmp\t%A1";
20125   else
20126     return "call\t%A1";
20127 }
20128   [(set_attr "type" "callv")])
20129
20130 (define_insn "*call_value_0"
20131   [(set (match_operand 0 "" "")
20132         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20133               (match_operand:SI 2 "" "")))]
20134   "!TARGET_64BIT"
20135 {
20136   if (SIBLING_CALL_P (insn))
20137     return "jmp\t%P1";
20138   else
20139     return "call\t%P1";
20140 }
20141   [(set_attr "type" "callv")])
20142
20143 (define_insn "*call_value_0_rex64"
20144   [(set (match_operand 0 "" "")
20145         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20146               (match_operand:DI 2 "const_int_operand" "")))]
20147   "TARGET_64BIT"
20148 {
20149   if (SIBLING_CALL_P (insn))
20150     return "jmp\t%P1";
20151   else
20152     return "call\t%P1";
20153 }
20154   [(set_attr "type" "callv")])
20155
20156 (define_insn "*call_value_1"
20157   [(set (match_operand 0 "" "")
20158         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20159               (match_operand:SI 2 "" "")))]
20160   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20161 {
20162   if (constant_call_address_operand (operands[1], Pmode))
20163     return "call\t%P1";
20164   return "call\t%A1";
20165 }
20166   [(set_attr "type" "callv")])
20167
20168 (define_insn "*sibcall_value_1"
20169   [(set (match_operand 0 "" "")
20170         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20171               (match_operand:SI 2 "" "")))]
20172   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20173 {
20174   if (constant_call_address_operand (operands[1], Pmode))
20175     return "jmp\t%P1";
20176   return "jmp\t%A1";
20177 }
20178   [(set_attr "type" "callv")])
20179
20180 (define_insn "*call_value_1_rex64"
20181   [(set (match_operand 0 "" "")
20182         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20183               (match_operand:DI 2 "" "")))]
20184   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20185 {
20186   if (constant_call_address_operand (operands[1], Pmode))
20187     return "call\t%P1";
20188   return "call\t%A1";
20189 }
20190   [(set_attr "type" "callv")])
20191
20192 (define_insn "*sibcall_value_1_rex64"
20193   [(set (match_operand 0 "" "")
20194         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20195               (match_operand:DI 2 "" "")))]
20196   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20197   "jmp\t%P1"
20198   [(set_attr "type" "callv")])
20199
20200 (define_insn "*sibcall_value_1_rex64_v"
20201   [(set (match_operand 0 "" "")
20202         (call (mem:QI (reg:DI 40))
20203               (match_operand:DI 1 "" "")))]
20204   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20205   "jmp\t*%%r11"
20206   [(set_attr "type" "callv")])
20207 \f
20208 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20209 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20210 ;; caught for use by garbage collectors and the like.  Using an insn that
20211 ;; maps to SIGILL makes it more likely the program will rightfully die.
20212 ;; Keeping with tradition, "6" is in honor of #UD.
20213 (define_insn "trap"
20214   [(trap_if (const_int 1) (const_int 6))]
20215   ""
20216   { return ASM_SHORT "0x0b0f"; }
20217   [(set_attr "length" "2")])
20218
20219 (define_expand "sse_prologue_save"
20220   [(parallel [(set (match_operand:BLK 0 "" "")
20221                    (unspec:BLK [(reg:DI 21)
20222                                 (reg:DI 22)
20223                                 (reg:DI 23)
20224                                 (reg:DI 24)
20225                                 (reg:DI 25)
20226                                 (reg:DI 26)
20227                                 (reg:DI 27)
20228                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20229               (use (match_operand:DI 1 "register_operand" ""))
20230               (use (match_operand:DI 2 "immediate_operand" ""))
20231               (use (label_ref:DI (match_operand 3 "" "")))])]
20232   "TARGET_64BIT"
20233   "")
20234
20235 (define_insn "*sse_prologue_save_insn"
20236   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20237                           (match_operand:DI 4 "const_int_operand" "n")))
20238         (unspec:BLK [(reg:DI 21)
20239                      (reg:DI 22)
20240                      (reg:DI 23)
20241                      (reg:DI 24)
20242                      (reg:DI 25)
20243                      (reg:DI 26)
20244                      (reg:DI 27)
20245                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20246    (use (match_operand:DI 1 "register_operand" "r"))
20247    (use (match_operand:DI 2 "const_int_operand" "i"))
20248    (use (label_ref:DI (match_operand 3 "" "X")))]
20249   "TARGET_64BIT
20250    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20251    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20252   "*
20253 {
20254   int i;
20255   operands[0] = gen_rtx_MEM (Pmode,
20256                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20257   output_asm_insn (\"jmp\\t%A1\", operands);
20258   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20259     {
20260       operands[4] = adjust_address (operands[0], DImode, i*16);
20261       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20262       PUT_MODE (operands[4], TImode);
20263       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20264         output_asm_insn (\"rex\", operands);
20265       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20266     }
20267   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20268                              CODE_LABEL_NUMBER (operands[3]));
20269   RET;
20270 }
20271   "
20272   [(set_attr "type" "other")
20273    (set_attr "length_immediate" "0")
20274    (set_attr "length_address" "0")
20275    (set_attr "length" "135")
20276    (set_attr "memory" "store")
20277    (set_attr "modrm" "0")
20278    (set_attr "mode" "DI")])
20279
20280 (define_expand "prefetch"
20281   [(prefetch (match_operand 0 "address_operand" "")
20282              (match_operand:SI 1 "const_int_operand" "")
20283              (match_operand:SI 2 "const_int_operand" ""))]
20284   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20285 {
20286   int rw = INTVAL (operands[1]);
20287   int locality = INTVAL (operands[2]);
20288
20289   gcc_assert (rw == 0 || rw == 1);
20290   gcc_assert (locality >= 0 && locality <= 3);
20291   gcc_assert (GET_MODE (operands[0]) == Pmode
20292               || GET_MODE (operands[0]) == VOIDmode);
20293
20294   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20295      supported by SSE counterpart or the SSE prefetch is not available
20296      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20297      of locality.  */
20298   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20299     operands[2] = GEN_INT (3);
20300   else
20301     operands[1] = const0_rtx;
20302 })
20303
20304 (define_insn "*prefetch_sse"
20305   [(prefetch (match_operand:SI 0 "address_operand" "p")
20306              (const_int 0)
20307              (match_operand:SI 1 "const_int_operand" ""))]
20308   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20309 {
20310   static const char * const patterns[4] = {
20311    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20312   };
20313
20314   int locality = INTVAL (operands[1]);
20315   gcc_assert (locality >= 0 && locality <= 3);
20316
20317   return patterns[locality];  
20318 }
20319   [(set_attr "type" "sse")
20320    (set_attr "memory" "none")])
20321
20322 (define_insn "*prefetch_sse_rex"
20323   [(prefetch (match_operand:DI 0 "address_operand" "p")
20324              (const_int 0)
20325              (match_operand:SI 1 "const_int_operand" ""))]
20326   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20327 {
20328   static const char * const patterns[4] = {
20329    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20330   };
20331
20332   int locality = INTVAL (operands[1]);
20333   gcc_assert (locality >= 0 && locality <= 3);
20334
20335   return patterns[locality];  
20336 }
20337   [(set_attr "type" "sse")
20338    (set_attr "memory" "none")])
20339
20340 (define_insn "*prefetch_3dnow"
20341   [(prefetch (match_operand:SI 0 "address_operand" "p")
20342              (match_operand:SI 1 "const_int_operand" "n")
20343              (const_int 3))]
20344   "TARGET_3DNOW && !TARGET_64BIT"
20345 {
20346   if (INTVAL (operands[1]) == 0)
20347     return "prefetch\t%a0";
20348   else
20349     return "prefetchw\t%a0";
20350 }
20351   [(set_attr "type" "mmx")
20352    (set_attr "memory" "none")])
20353
20354 (define_insn "*prefetch_3dnow_rex"
20355   [(prefetch (match_operand:DI 0 "address_operand" "p")
20356              (match_operand:SI 1 "const_int_operand" "n")
20357              (const_int 3))]
20358   "TARGET_3DNOW && TARGET_64BIT"
20359 {
20360   if (INTVAL (operands[1]) == 0)
20361     return "prefetch\t%a0";
20362   else
20363     return "prefetchw\t%a0";
20364 }
20365   [(set_attr "type" "mmx")
20366    (set_attr "memory" "none")])
20367
20368 (define_expand "stack_protect_set"
20369   [(match_operand 0 "memory_operand" "")
20370    (match_operand 1 "memory_operand" "")]
20371   ""
20372 {
20373 #ifdef TARGET_THREAD_SSP_OFFSET
20374   if (TARGET_64BIT)
20375     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20376                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20377   else
20378     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20379                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20380 #else
20381   if (TARGET_64BIT)
20382     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20383   else
20384     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20385 #endif
20386   DONE;
20387 })
20388
20389 (define_insn "stack_protect_set_si"
20390   [(set (match_operand:SI 0 "memory_operand" "=m")
20391         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20392    (set (match_scratch:SI 2 "=&r") (const_int 0))
20393    (clobber (reg:CC FLAGS_REG))]
20394   ""
20395   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20396   [(set_attr "type" "multi")])
20397
20398 (define_insn "stack_protect_set_di"
20399   [(set (match_operand:DI 0 "memory_operand" "=m")
20400         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20401    (set (match_scratch:DI 2 "=&r") (const_int 0))
20402    (clobber (reg:CC FLAGS_REG))]
20403   "TARGET_64BIT"
20404   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20405   [(set_attr "type" "multi")])
20406
20407 (define_insn "stack_tls_protect_set_si"
20408   [(set (match_operand:SI 0 "memory_operand" "=m")
20409         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20410    (set (match_scratch:SI 2 "=&r") (const_int 0))
20411    (clobber (reg:CC FLAGS_REG))]
20412   ""
20413   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20414   [(set_attr "type" "multi")])
20415
20416 (define_insn "stack_tls_protect_set_di"
20417   [(set (match_operand:DI 0 "memory_operand" "=m")
20418         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20419    (set (match_scratch:DI 2 "=&r") (const_int 0))
20420    (clobber (reg:CC FLAGS_REG))]
20421   "TARGET_64BIT"
20422   {
20423      /* The kernel uses a different segment register for performance reasons; a
20424         system call would not have to trash the userspace segment register,
20425         which would be expensive */
20426      if (ix86_cmodel != CM_KERNEL)
20427         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20428      else
20429         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20430   }
20431   [(set_attr "type" "multi")])
20432
20433 (define_expand "stack_protect_test"
20434   [(match_operand 0 "memory_operand" "")
20435    (match_operand 1 "memory_operand" "")
20436    (match_operand 2 "" "")]
20437   ""
20438 {
20439   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20440   ix86_compare_op0 = operands[0];
20441   ix86_compare_op1 = operands[1];
20442   ix86_compare_emitted = flags;
20443
20444 #ifdef TARGET_THREAD_SSP_OFFSET
20445   if (TARGET_64BIT)
20446     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20447                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20448   else
20449     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20450                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20451 #else
20452   if (TARGET_64BIT)
20453     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20454   else
20455     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20456 #endif
20457   emit_jump_insn (gen_beq (operands[2]));
20458   DONE;
20459 })
20460
20461 (define_insn "stack_protect_test_si"
20462   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20463         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20464                      (match_operand:SI 2 "memory_operand" "m")]
20465                     UNSPEC_SP_TEST))
20466    (clobber (match_scratch:SI 3 "=&r"))]
20467   ""
20468   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20469   [(set_attr "type" "multi")])
20470
20471 (define_insn "stack_protect_test_di"
20472   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20473         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20474                      (match_operand:DI 2 "memory_operand" "m")]
20475                     UNSPEC_SP_TEST))
20476    (clobber (match_scratch:DI 3 "=&r"))]
20477   "TARGET_64BIT"
20478   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20479   [(set_attr "type" "multi")])
20480
20481 (define_insn "stack_tls_protect_test_si"
20482   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20483         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20484                      (match_operand:SI 2 "const_int_operand" "i")]
20485                     UNSPEC_SP_TLS_TEST))
20486    (clobber (match_scratch:SI 3 "=r"))]
20487   ""
20488   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20489   [(set_attr "type" "multi")])
20490
20491 (define_insn "stack_tls_protect_test_di"
20492   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20493         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20494                      (match_operand:DI 2 "const_int_operand" "i")]
20495                     UNSPEC_SP_TLS_TEST))
20496    (clobber (match_scratch:DI 3 "=r"))]
20497   "TARGET_64BIT"
20498   {
20499      /* The kernel uses a different segment register for performance reasons; a
20500         system call would not have to trash the userspace segment register,
20501         which would be expensive */
20502      if (ix86_cmodel != CM_KERNEL)
20503         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20504      else
20505         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20506   }
20507   [(set_attr "type" "multi")])
20508
20509 (include "sse.md")
20510 (include "mmx.md")
20511 (include "sync.md")