OSDN Git Service

2006-01-26 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
479
480 (include "predicates.md")
481
482 \f
483 ;; Compare instructions.
484
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
488
489 (define_expand "cmpti"
490   [(set (reg:CC FLAGS_REG)
491         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492                     (match_operand:TI 1 "x86_64_general_operand" "")))]
493   "TARGET_64BIT"
494 {
495   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496     operands[0] = force_reg (TImode, operands[0]);
497   ix86_compare_op0 = operands[0];
498   ix86_compare_op1 = operands[1];
499   DONE;
500 })
501
502 (define_expand "cmpdi"
503   [(set (reg:CC FLAGS_REG)
504         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505                     (match_operand:DI 1 "x86_64_general_operand" "")))]
506   ""
507 {
508   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509     operands[0] = force_reg (DImode, operands[0]);
510   ix86_compare_op0 = operands[0];
511   ix86_compare_op1 = operands[1];
512   DONE;
513 })
514
515 (define_expand "cmpsi"
516   [(set (reg:CC FLAGS_REG)
517         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518                     (match_operand:SI 1 "general_operand" "")))]
519   ""
520 {
521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522     operands[0] = force_reg (SImode, operands[0]);
523   ix86_compare_op0 = operands[0];
524   ix86_compare_op1 = operands[1];
525   DONE;
526 })
527
528 (define_expand "cmphi"
529   [(set (reg:CC FLAGS_REG)
530         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531                     (match_operand:HI 1 "general_operand" "")))]
532   ""
533 {
534   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535     operands[0] = force_reg (HImode, operands[0]);
536   ix86_compare_op0 = operands[0];
537   ix86_compare_op1 = operands[1];
538   DONE;
539 })
540
541 (define_expand "cmpqi"
542   [(set (reg:CC FLAGS_REG)
543         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544                     (match_operand:QI 1 "general_operand" "")))]
545   "TARGET_QIMODE_MATH"
546 {
547   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548     operands[0] = force_reg (QImode, operands[0]);
549   ix86_compare_op0 = operands[0];
550   ix86_compare_op1 = operands[1];
551   DONE;
552 })
553
554 (define_insn "cmpdi_ccno_1_rex64"
555   [(set (reg FLAGS_REG)
556         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557                  (match_operand:DI 1 "const0_operand" "n,n")))]
558   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
559   "@
560    test{q}\t{%0, %0|%0, %0}
561    cmp{q}\t{%1, %0|%0, %1}"
562   [(set_attr "type" "test,icmp")
563    (set_attr "length_immediate" "0,1")
564    (set_attr "mode" "DI")])
565
566 (define_insn "*cmpdi_minus_1_rex64"
567   [(set (reg FLAGS_REG)
568         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
570                  (const_int 0)))]
571   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572   "cmp{q}\t{%1, %0|%0, %1}"
573   [(set_attr "type" "icmp")
574    (set_attr "mode" "DI")])
575
576 (define_expand "cmpdi_1_rex64"
577   [(set (reg:CC FLAGS_REG)
578         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579                     (match_operand:DI 1 "general_operand" "")))]
580   "TARGET_64BIT"
581   "")
582
583 (define_insn "cmpdi_1_insn_rex64"
584   [(set (reg FLAGS_REG)
585         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
591
592
593 (define_insn "*cmpsi_ccno_1"
594   [(set (reg FLAGS_REG)
595         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596                  (match_operand:SI 1 "const0_operand" "n,n")))]
597   "ix86_match_ccmode (insn, CCNOmode)"
598   "@
599    test{l}\t{%0, %0|%0, %0}
600    cmp{l}\t{%1, %0|%0, %1}"
601   [(set_attr "type" "test,icmp")
602    (set_attr "length_immediate" "0,1")
603    (set_attr "mode" "SI")])
604
605 (define_insn "*cmpsi_minus_1"
606   [(set (reg FLAGS_REG)
607         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608                            (match_operand:SI 1 "general_operand" "ri,mr"))
609                  (const_int 0)))]
610   "ix86_match_ccmode (insn, CCGOCmode)"
611   "cmp{l}\t{%1, %0|%0, %1}"
612   [(set_attr "type" "icmp")
613    (set_attr "mode" "SI")])
614
615 (define_expand "cmpsi_1"
616   [(set (reg:CC FLAGS_REG)
617         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618                     (match_operand:SI 1 "general_operand" "ri,mr")))]
619   ""
620   "")
621
622 (define_insn "*cmpsi_1_insn"
623   [(set (reg FLAGS_REG)
624         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625                  (match_operand:SI 1 "general_operand" "ri,mr")))]
626   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627     && ix86_match_ccmode (insn, CCmode)"
628   "cmp{l}\t{%1, %0|%0, %1}"
629   [(set_attr "type" "icmp")
630    (set_attr "mode" "SI")])
631
632 (define_insn "*cmphi_ccno_1"
633   [(set (reg FLAGS_REG)
634         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635                  (match_operand:HI 1 "const0_operand" "n,n")))]
636   "ix86_match_ccmode (insn, CCNOmode)"
637   "@
638    test{w}\t{%0, %0|%0, %0}
639    cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "test,icmp")
641    (set_attr "length_immediate" "0,1")
642    (set_attr "mode" "HI")])
643
644 (define_insn "*cmphi_minus_1"
645   [(set (reg FLAGS_REG)
646         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647                            (match_operand:HI 1 "general_operand" "ri,mr"))
648                  (const_int 0)))]
649   "ix86_match_ccmode (insn, CCGOCmode)"
650   "cmp{w}\t{%1, %0|%0, %1}"
651   [(set_attr "type" "icmp")
652    (set_attr "mode" "HI")])
653
654 (define_insn "*cmphi_1"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657                  (match_operand:HI 1 "general_operand" "ri,mr")))]
658   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659    && ix86_match_ccmode (insn, CCmode)"
660   "cmp{w}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "HI")])
663
664 (define_insn "*cmpqi_ccno_1"
665   [(set (reg FLAGS_REG)
666         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667                  (match_operand:QI 1 "const0_operand" "n,n")))]
668   "ix86_match_ccmode (insn, CCNOmode)"
669   "@
670    test{b}\t{%0, %0|%0, %0}
671    cmp{b}\t{$0, %0|%0, 0}"
672   [(set_attr "type" "test,icmp")
673    (set_attr "length_immediate" "0,1")
674    (set_attr "mode" "QI")])
675
676 (define_insn "*cmpqi_1"
677   [(set (reg FLAGS_REG)
678         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679                  (match_operand:QI 1 "general_operand" "qi,mq")))]
680   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681     && ix86_match_ccmode (insn, CCmode)"
682   "cmp{b}\t{%1, %0|%0, %1}"
683   [(set_attr "type" "icmp")
684    (set_attr "mode" "QI")])
685
686 (define_insn "*cmpqi_minus_1"
687   [(set (reg FLAGS_REG)
688         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689                            (match_operand:QI 1 "general_operand" "qi,mq"))
690                  (const_int 0)))]
691   "ix86_match_ccmode (insn, CCGOCmode)"
692   "cmp{b}\t{%1, %0|%0, %1}"
693   [(set_attr "type" "icmp")
694    (set_attr "mode" "QI")])
695
696 (define_insn "*cmpqi_ext_1"
697   [(set (reg FLAGS_REG)
698         (compare
699           (match_operand:QI 0 "general_operand" "Qm")
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 1 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)))]
705   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%h1, %0|%0, %h1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_ext_1_rex64"
711   [(set (reg FLAGS_REG)
712         (compare
713           (match_operand:QI 0 "register_operand" "Q")
714           (subreg:QI
715             (zero_extract:SI
716               (match_operand 1 "ext_register_operand" "Q")
717               (const_int 8)
718               (const_int 8)) 0)))]
719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%h1, %0|%0, %h1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
723
724 (define_insn "*cmpqi_ext_2"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "const0_operand" "n")))]
733   "ix86_match_ccmode (insn, CCNOmode)"
734   "test{b}\t%h0, %h0"
735   [(set_attr "type" "test")
736    (set_attr "length_immediate" "0")
737    (set_attr "mode" "QI")])
738
739 (define_expand "cmpqi_ext_3"
740   [(set (reg:CC FLAGS_REG)
741         (compare:CC
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "general_operand" "")))]
748   ""
749   "")
750
751 (define_insn "cmpqi_ext_3_insn"
752   [(set (reg FLAGS_REG)
753         (compare
754           (subreg:QI
755             (zero_extract:SI
756               (match_operand 0 "ext_register_operand" "Q")
757               (const_int 8)
758               (const_int 8)) 0)
759           (match_operand:QI 1 "general_operand" "Qmn")))]
760   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761   "cmp{b}\t{%1, %h0|%h0, %1}"
762   [(set_attr "type" "icmp")
763    (set_attr "mode" "QI")])
764
765 (define_insn "cmpqi_ext_3_insn_rex64"
766   [(set (reg FLAGS_REG)
767         (compare
768           (subreg:QI
769             (zero_extract:SI
770               (match_operand 0 "ext_register_operand" "Q")
771               (const_int 8)
772               (const_int 8)) 0)
773           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775   "cmp{b}\t{%1, %h0|%h0, %1}"
776   [(set_attr "type" "icmp")
777    (set_attr "mode" "QI")])
778
779 (define_insn "*cmpqi_ext_4"
780   [(set (reg FLAGS_REG)
781         (compare
782           (subreg:QI
783             (zero_extract:SI
784               (match_operand 0 "ext_register_operand" "Q")
785               (const_int 8)
786               (const_int 8)) 0)
787           (subreg:QI
788             (zero_extract:SI
789               (match_operand 1 "ext_register_operand" "Q")
790               (const_int 8)
791               (const_int 8)) 0)))]
792   "ix86_match_ccmode (insn, CCmode)"
793   "cmp{b}\t{%h1, %h0|%h0, %h1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "QI")])
796
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares.  Which is what
800 ;; the old patterns did, but with many more of them.
801
802 (define_expand "cmpxf"
803   [(set (reg:CC FLAGS_REG)
804         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805                     (match_operand:XF 1 "nonmemory_operand" "")))]
806   "TARGET_80387"
807 {
808   ix86_compare_op0 = operands[0];
809   ix86_compare_op1 = operands[1];
810   DONE;
811 })
812
813 (define_expand "cmpdf"
814   [(set (reg:CC FLAGS_REG)
815         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
818 {
819   ix86_compare_op0 = operands[0];
820   ix86_compare_op1 = operands[1];
821   DONE;
822 })
823
824 (define_expand "cmpsf"
825   [(set (reg:CC FLAGS_REG)
826         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828   "TARGET_80387 || TARGET_SSE_MATH"
829 {
830   ix86_compare_op0 = operands[0];
831   ix86_compare_op1 = operands[1];
832   DONE;
833 })
834
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
837 ;;
838 ;; CCFPmode     compare with exceptions
839 ;; CCFPUmode    compare with no exceptions
840
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
843
844 (define_insn "*cmpfp_0"
845   [(set (match_operand:HI 0 "register_operand" "=a")
846         (unspec:HI
847           [(compare:CCFP
848              (match_operand 1 "register_operand" "f")
849              (match_operand 2 "const0_operand" "X"))]
850         UNSPEC_FNSTSW))]
851   "TARGET_80387
852    && FLOAT_MODE_P (GET_MODE (operands[1]))
853    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854   "* return output_fp_compare (insn, operands, 0, 0);"
855   [(set_attr "type" "multi")
856    (set_attr "unit" "i387")
857    (set (attr "mode")
858      (cond [(match_operand:SF 1 "" "")
859               (const_string "SF")
860             (match_operand:DF 1 "" "")
861               (const_string "DF")
862            ]
863            (const_string "XF")))])
864
865 (define_insn "*cmpfp_sf"
866   [(set (match_operand:HI 0 "register_operand" "=a")
867         (unspec:HI
868           [(compare:CCFP
869              (match_operand:SF 1 "register_operand" "f")
870              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871           UNSPEC_FNSTSW))]
872   "TARGET_80387"
873   "* return output_fp_compare (insn, operands, 0, 0);"
874   [(set_attr "type" "multi")
875    (set_attr "unit" "i387")
876    (set_attr "mode" "SF")])
877
878 (define_insn "*cmpfp_df"
879   [(set (match_operand:HI 0 "register_operand" "=a")
880         (unspec:HI
881           [(compare:CCFP
882              (match_operand:DF 1 "register_operand" "f")
883              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884           UNSPEC_FNSTSW))]
885   "TARGET_80387"
886   "* return output_fp_compare (insn, operands, 0, 0);"
887   [(set_attr "type" "multi")
888    (set_attr "unit" "i387")
889    (set_attr "mode" "DF")])
890
891 (define_insn "*cmpfp_xf"
892   [(set (match_operand:HI 0 "register_operand" "=a")
893         (unspec:HI
894           [(compare:CCFP
895              (match_operand:XF 1 "register_operand" "f")
896              (match_operand:XF 2 "register_operand" "f"))]
897           UNSPEC_FNSTSW))]
898   "TARGET_80387"
899   "* return output_fp_compare (insn, operands, 0, 0);"
900   [(set_attr "type" "multi")
901    (set_attr "unit" "i387")
902    (set_attr "mode" "XF")])
903
904 (define_insn "*cmpfp_u"
905   [(set (match_operand:HI 0 "register_operand" "=a")
906         (unspec:HI
907           [(compare:CCFPU
908              (match_operand 1 "register_operand" "f")
909              (match_operand 2 "register_operand" "f"))]
910           UNSPEC_FNSTSW))]
911   "TARGET_80387
912    && FLOAT_MODE_P (GET_MODE (operands[1]))
913    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914   "* return output_fp_compare (insn, operands, 0, 1);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set (attr "mode")
918      (cond [(match_operand:SF 1 "" "")
919               (const_string "SF")
920             (match_operand:DF 1 "" "")
921               (const_string "DF")
922            ]
923            (const_string "XF")))])
924
925 (define_insn "*cmpfp_<mode>"
926   [(set (match_operand:HI 0 "register_operand" "=a")
927         (unspec:HI
928           [(compare:CCFP
929              (match_operand 1 "register_operand" "f")
930              (match_operator 3 "float_operator"
931                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
932           UNSPEC_FNSTSW))]
933   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934    && FLOAT_MODE_P (GET_MODE (operands[1]))
935    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936   "* return output_fp_compare (insn, operands, 0, 0);"
937   [(set_attr "type" "multi")
938    (set_attr "unit" "i387")
939    (set_attr "fp_int_src" "true")
940    (set_attr "mode" "<MODE>")])
941
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
944
945 (define_insn "x86_fnstsw_1"
946   [(set (match_operand:HI 0 "register_operand" "=a")
947         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948   "TARGET_80387"
949   "fnstsw\t%0"
950   [(set_attr "length" "2")
951    (set_attr "mode" "SI")
952    (set_attr "unit" "i387")])
953
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
956
957 (define_insn "x86_sahf_1"
958   [(set (reg:CC FLAGS_REG)
959         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960   "!TARGET_64BIT"
961   "sahf"
962   [(set_attr "length" "1")
963    (set_attr "athlon_decode" "vector")
964    (set_attr "mode" "SI")])
965
966 ;; Pentium Pro can do steps 1 through 3 in one go.
967
968 (define_insn "*cmpfp_i_mixed"
969   [(set (reg:CCFP FLAGS_REG)
970         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
972   "TARGET_MIX_SSE_I387
973    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975   "* return output_fp_compare (insn, operands, 1, 0);"
976   [(set_attr "type" "fcmp,ssecomi")
977    (set (attr "mode")
978      (if_then_else (match_operand:SF 1 "" "")
979         (const_string "SF")
980         (const_string "DF")))
981    (set_attr "athlon_decode" "vector")])
982
983 (define_insn "*cmpfp_i_sse"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "x")
986                       (match_operand 1 "nonimmediate_operand" "xm")))]
987   "TARGET_SSE_MATH
988    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990   "* return output_fp_compare (insn, operands, 1, 0);"
991   [(set_attr "type" "ssecomi")
992    (set (attr "mode")
993      (if_then_else (match_operand:SF 1 "" "")
994         (const_string "SF")
995         (const_string "DF")))
996    (set_attr "athlon_decode" "vector")])
997
998 (define_insn "*cmpfp_i_i387"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "f")
1001                       (match_operand 1 "register_operand" "f")))]
1002   "TARGET_80387 && TARGET_CMOVE
1003    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004    && FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "fcmp")
1008    (set (attr "mode")
1009      (cond [(match_operand:SF 1 "" "")
1010               (const_string "SF")
1011             (match_operand:DF 1 "" "")
1012               (const_string "DF")
1013            ]
1014            (const_string "XF")))
1015    (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_mixed"
1018   [(set (reg:CCFPU FLAGS_REG)
1019         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021   "TARGET_MIX_SSE_I387
1022    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024   "* return output_fp_compare (insn, operands, 1, 1);"
1025   [(set_attr "type" "fcmp,ssecomi")
1026    (set (attr "mode")
1027      (if_then_else (match_operand:SF 1 "" "")
1028         (const_string "SF")
1029         (const_string "DF")))
1030    (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu_sse"
1033   [(set (reg:CCFPU FLAGS_REG)
1034         (compare:CCFPU (match_operand 0 "register_operand" "x")
1035                        (match_operand 1 "nonimmediate_operand" "xm")))]
1036   "TARGET_SSE_MATH
1037    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "ssecomi")
1041    (set (attr "mode")
1042      (if_then_else (match_operand:SF 1 "" "")
1043         (const_string "SF")
1044         (const_string "DF")))
1045    (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_iu_387"
1048   [(set (reg:CCFPU FLAGS_REG)
1049         (compare:CCFPU (match_operand 0 "register_operand" "f")
1050                        (match_operand 1 "register_operand" "f")))]
1051   "TARGET_80387 && TARGET_CMOVE
1052    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053    && FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "fcmp")
1057    (set (attr "mode")
1058      (cond [(match_operand:SF 1 "" "")
1059               (const_string "SF")
1060             (match_operand:DF 1 "" "")
1061               (const_string "DF")
1062            ]
1063            (const_string "XF")))
1064    (set_attr "athlon_decode" "vector")])
1065 \f
1066 ;; Move instructions.
1067
1068 ;; General case of fullword move.
1069
1070 (define_expand "movsi"
1071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072         (match_operand:SI 1 "general_operand" ""))]
1073   ""
1074   "ix86_expand_move (SImode, operands); DONE;")
1075
1076 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1077 ;; general_operand.
1078 ;;
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1084
1085 (define_insn "*pushsi2"
1086   [(set (match_operand:SI 0 "push_operand" "=<")
1087         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088   "!TARGET_64BIT"
1089   "push{l}\t%1"
1090   [(set_attr "type" "push")
1091    (set_attr "mode" "SI")])
1092
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095   [(set (match_operand:SI 0 "push_operand" "=X")
1096         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097   "TARGET_64BIT"
1098   "push{q}\t%q1"
1099   [(set_attr "type" "push")
1100    (set_attr "mode" "SI")])
1101
1102 (define_insn "*pushsi2_prologue"
1103   [(set (match_operand:SI 0 "push_operand" "=<")
1104         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105    (clobber (mem:BLK (scratch)))]
1106   "!TARGET_64BIT"
1107   "push{l}\t%1"
1108   [(set_attr "type" "push")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "*popsi1_epilogue"
1112   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113         (mem:SI (reg:SI SP_REG)))
1114    (set (reg:SI SP_REG)
1115         (plus:SI (reg:SI SP_REG) (const_int 4)))
1116    (clobber (mem:BLK (scratch)))]
1117   "!TARGET_64BIT"
1118   "pop{l}\t%0"
1119   [(set_attr "type" "pop")
1120    (set_attr "mode" "SI")])
1121
1122 (define_insn "popsi1"
1123   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124         (mem:SI (reg:SI SP_REG)))
1125    (set (reg:SI SP_REG)
1126         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127   "!TARGET_64BIT"
1128   "pop{l}\t%0"
1129   [(set_attr "type" "pop")
1130    (set_attr "mode" "SI")])
1131
1132 (define_insn "*movsi_xor"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (match_operand:SI 1 "const0_operand" "i"))
1135    (clobber (reg:CC FLAGS_REG))]
1136   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137   "xor{l}\t{%0, %0|%0, %0}"
1138   [(set_attr "type" "alu1")
1139    (set_attr "mode" "SI")
1140    (set_attr "length_immediate" "0")])
1141  
1142 (define_insn "*movsi_or"
1143   [(set (match_operand:SI 0 "register_operand" "=r")
1144         (match_operand:SI 1 "immediate_operand" "i"))
1145    (clobber (reg:CC FLAGS_REG))]
1146   "reload_completed
1147    && operands[1] == constm1_rtx
1148    && (TARGET_PENTIUM || optimize_size)"
1149 {
1150   operands[1] = constm1_rtx;
1151   return "or{l}\t{%1, %0|%0, %1}";
1152 }
1153   [(set_attr "type" "alu1")
1154    (set_attr "mode" "SI")
1155    (set_attr "length_immediate" "1")])
1156
1157 (define_insn "*movsi_1"
1158   [(set (match_operand:SI 0 "nonimmediate_operand"
1159                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160         (match_operand:SI 1 "general_operand"
1161                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1162   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1163 {
1164   switch (get_attr_type (insn))
1165     {
1166     case TYPE_SSELOG1:
1167       if (get_attr_mode (insn) == MODE_TI)
1168         return "pxor\t%0, %0";
1169       return "xorps\t%0, %0";
1170
1171     case TYPE_SSEMOV:
1172       switch (get_attr_mode (insn))
1173         {
1174         case MODE_TI:
1175           return "movdqa\t{%1, %0|%0, %1}";
1176         case MODE_V4SF:
1177           return "movaps\t{%1, %0|%0, %1}";
1178         case MODE_SI:
1179           return "movd\t{%1, %0|%0, %1}";
1180         case MODE_SF:
1181           return "movss\t{%1, %0|%0, %1}";
1182         default:
1183           gcc_unreachable ();
1184         }
1185
1186     case TYPE_MMXADD:
1187       return "pxor\t%0, %0";
1188
1189     case TYPE_MMXMOV:
1190       if (get_attr_mode (insn) == MODE_DI)
1191         return "movq\t{%1, %0|%0, %1}";
1192       return "movd\t{%1, %0|%0, %1}";
1193
1194     case TYPE_LEA:
1195       return "lea{l}\t{%1, %0|%0, %1}";
1196
1197     default:
1198       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199       return "mov{l}\t{%1, %0|%0, %1}";
1200     }
1201 }
1202   [(set (attr "type")
1203      (cond [(eq_attr "alternative" "2")
1204               (const_string "mmxadd")
1205             (eq_attr "alternative" "3,4,5")
1206               (const_string "mmxmov")
1207             (eq_attr "alternative" "6")
1208               (const_string "sselog1")
1209             (eq_attr "alternative" "7,8,9,10,11")
1210               (const_string "ssemov")
1211             (match_operand:DI 1 "pic_32bit_operand" "")
1212               (const_string "lea")
1213            ]
1214            (const_string "imov")))
1215    (set (attr "mode")
1216      (cond [(eq_attr "alternative" "2,3")
1217               (const_string "DI")
1218             (eq_attr "alternative" "6,7")
1219               (if_then_else
1220                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221                 (const_string "V4SF")
1222                 (const_string "TI"))
1223             (and (eq_attr "alternative" "8,9,10,11")
1224                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225               (const_string "SF")
1226            ]
1227            (const_string "SI")))])
1228
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1236   "@
1237    movabs{l}\t{%1, %P0|%P0, %1}
1238    mov{l}\t{%1, %a0|%a0, %1}"
1239   [(set_attr "type" "imov")
1240    (set_attr "modrm" "0,*")
1241    (set_attr "length_address" "8,0")
1242    (set_attr "length_immediate" "0,*")
1243    (set_attr "memory" "store")
1244    (set_attr "mode" "SI")])
1245
1246 (define_insn "*movabssi_2_rex64"
1247   [(set (match_operand:SI 0 "register_operand" "=a,r")
1248         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1250   "@
1251    movabs{l}\t{%P1, %0|%0, %P1}
1252    mov{l}\t{%a1, %0|%0, %a1}"
1253   [(set_attr "type" "imov")
1254    (set_attr "modrm" "0,*")
1255    (set_attr "length_address" "8,0")
1256    (set_attr "length_immediate" "0")
1257    (set_attr "memory" "load")
1258    (set_attr "mode" "SI")])
1259
1260 (define_insn "*swapsi"
1261   [(set (match_operand:SI 0 "register_operand" "+r")
1262         (match_operand:SI 1 "register_operand" "+r"))
1263    (set (match_dup 1)
1264         (match_dup 0))]
1265   ""
1266   "xchg{l}\t%1, %0"
1267   [(set_attr "type" "imov")
1268    (set_attr "mode" "SI")
1269    (set_attr "pent_pair" "np")
1270    (set_attr "athlon_decode" "vector")])
1271
1272 (define_expand "movhi"
1273   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274         (match_operand:HI 1 "general_operand" ""))]
1275   ""
1276   "ix86_expand_move (HImode, operands); DONE;")
1277
1278 (define_insn "*pushhi2"
1279   [(set (match_operand:HI 0 "push_operand" "=X")
1280         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281   "!TARGET_64BIT"
1282   "push{l}\t%k1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "SI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "DI")])
1294
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1312 }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1388
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1400
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1440
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444   "!TARGET_64BIT"
1445   "push{l}\t%k1"
1446   [(set_attr "type" "push")
1447    (set_attr "mode" "SI")])
1448
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451   [(set (match_operand:QI 0 "push_operand" "=X")
1452         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453   "TARGET_64BIT"
1454   "push{q}\t%q1"
1455   [(set_attr "type" "push")
1456    (set_attr "mode" "DI")])
1457
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; instruction).
1464 ;;
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there.  Then we use movzx.
1468 (define_insn "*movqi_1"
1469   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1471   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1472 {
1473   switch (get_attr_type (insn))
1474     {
1475     case TYPE_IMOVX:
1476       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478     default:
1479       if (get_attr_mode (insn) == MODE_SI)
1480         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481       else
1482         return "mov{b}\t{%1, %0|%0, %1}";
1483     }
1484 }
1485   [(set (attr "type")
1486      (cond [(and (eq_attr "alternative" "5")
1487                  (not (match_operand:QI 1 "aligned_operand" "")))
1488               (const_string "imovx")
1489             (ne (symbol_ref "optimize_size") (const_int 0))
1490               (const_string "imov")
1491             (and (eq_attr "alternative" "3")
1492                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1493                           (const_int 0))
1494                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1495                           (const_int 0))))
1496               (const_string "imov")
1497             (eq_attr "alternative" "3,5")
1498               (const_string "imovx")
1499             (and (ne (symbol_ref "TARGET_MOVX")
1500                      (const_int 0))
1501                  (eq_attr "alternative" "2"))
1502               (const_string "imovx")
1503            ]
1504            (const_string "imov")))
1505    (set (attr "mode")
1506       (cond [(eq_attr "alternative" "3,4,5")
1507                (const_string "SI")
1508              (eq_attr "alternative" "6")
1509                (const_string "QI")
1510              (eq_attr "type" "imovx")
1511                (const_string "SI")
1512              (and (eq_attr "type" "imov")
1513                   (and (eq_attr "alternative" "0,1")
1514                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515                                 (const_int 0))
1516                             (and (eq (symbol_ref "optimize_size")
1517                                      (const_int 0))
1518                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                      (const_int 0))))))
1520                (const_string "SI")
1521              ;; Avoid partial register stalls when not using QImode arithmetic
1522              (and (eq_attr "type" "imov")
1523                   (and (eq_attr "alternative" "0,1")
1524                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525                                 (const_int 0))
1526                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1527                                 (const_int 0)))))
1528                (const_string "SI")
1529            ]
1530            (const_string "QI")))])
1531
1532 (define_expand "reload_outqi"
1533   [(parallel [(match_operand:QI 0 "" "=m")
1534               (match_operand:QI 1 "register_operand" "r")
1535               (match_operand:QI 2 "register_operand" "=&q")])]
1536   ""
1537 {
1538   rtx op0, op1, op2;
1539   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1540
1541   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542   if (! q_regs_operand (op1, QImode))
1543     {
1544       emit_insn (gen_movqi (op2, op1));
1545       op1 = op2;
1546     }
1547   emit_insn (gen_movqi (op0, op1));
1548   DONE;
1549 })
1550
1551 (define_insn "*swapqi_1"
1552   [(set (match_operand:QI 0 "register_operand" "+r")
1553         (match_operand:QI 1 "register_operand" "+r"))
1554    (set (match_dup 1)
1555         (match_dup 0))]
1556   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1557   "xchg{l}\t%k1, %k0"
1558   [(set_attr "type" "imov")
1559    (set_attr "mode" "SI")
1560    (set_attr "pent_pair" "np")
1561    (set_attr "athlon_decode" "vector")])
1562
1563 (define_insn "*swapqi_2"
1564   [(set (match_operand:QI 0 "register_operand" "+q")
1565         (match_operand:QI 1 "register_operand" "+q"))
1566    (set (match_dup 1)
1567         (match_dup 0))]
1568   "TARGET_PARTIAL_REG_STALL"
1569   "xchg{b}\t%1, %0"
1570   [(set_attr "type" "imov")
1571    (set_attr "mode" "QI")
1572    (set_attr "pent_pair" "np")
1573    (set_attr "athlon_decode" "vector")])
1574
1575 (define_expand "movstrictqi"
1576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577         (match_operand:QI 1 "general_operand" ""))]
1578   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1579 {
1580   /* Don't generate memory->memory moves, go through a register.  */
1581   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582     operands[1] = force_reg (QImode, operands[1]);
1583 })
1584
1585 (define_insn "*movstrictqi_1"
1586   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587         (match_operand:QI 1 "general_operand" "*qn,m"))]
1588   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590   "mov{b}\t{%1, %0|%0, %1}"
1591   [(set_attr "type" "imov")
1592    (set_attr "mode" "QI")])
1593
1594 (define_insn "*movstrictqi_xor"
1595   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596         (match_operand:QI 1 "const0_operand" "i"))
1597    (clobber (reg:CC FLAGS_REG))]
1598   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599   "xor{b}\t{%0, %0|%0, %0}"
1600   [(set_attr "type" "alu1")
1601    (set_attr "mode" "QI")
1602    (set_attr "length_immediate" "0")])
1603
1604 (define_insn "*movsi_extv_1"
1605   [(set (match_operand:SI 0 "register_operand" "=R")
1606         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   ""
1610   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611   [(set_attr "type" "imovx")
1612    (set_attr "mode" "SI")])
1613
1614 (define_insn "*movhi_extv_1"
1615   [(set (match_operand:HI 0 "register_operand" "=R")
1616         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   ""
1620   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621   [(set_attr "type" "imovx")
1622    (set_attr "mode" "SI")])
1623
1624 (define_insn "*movqi_extv_1"
1625   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   "!TARGET_64BIT"
1630 {
1631   switch (get_attr_type (insn))
1632     {
1633     case TYPE_IMOVX:
1634       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635     default:
1636       return "mov{b}\t{%h1, %0|%0, %h1}";
1637     }
1638 }
1639   [(set (attr "type")
1640      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642                              (ne (symbol_ref "TARGET_MOVX")
1643                                  (const_int 0))))
1644         (const_string "imovx")
1645         (const_string "imov")))
1646    (set (attr "mode")
1647      (if_then_else (eq_attr "type" "imovx")
1648         (const_string "SI")
1649         (const_string "QI")))])
1650
1651 (define_insn "*movqi_extv_1_rex64"
1652   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1653         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654                          (const_int 8)
1655                          (const_int 8)))]
1656   "TARGET_64BIT"
1657 {
1658   switch (get_attr_type (insn))
1659     {
1660     case TYPE_IMOVX:
1661       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662     default:
1663       return "mov{b}\t{%h1, %0|%0, %h1}";
1664     }
1665 }
1666   [(set (attr "type")
1667      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669                              (ne (symbol_ref "TARGET_MOVX")
1670                                  (const_int 0))))
1671         (const_string "imovx")
1672         (const_string "imov")))
1673    (set (attr "mode")
1674      (if_then_else (eq_attr "type" "imovx")
1675         (const_string "SI")
1676         (const_string "QI")))])
1677
1678 ;; Stores and loads of ax to arbitrary constant address.
1679 ;; We fake an second form of instruction to force reload to load address
1680 ;; into register when rax is not available
1681 (define_insn "*movabsqi_1_rex64"
1682   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1685   "@
1686    movabs{b}\t{%1, %P0|%P0, %1}
1687    mov{b}\t{%1, %a0|%a0, %1}"
1688   [(set_attr "type" "imov")
1689    (set_attr "modrm" "0,*")
1690    (set_attr "length_address" "8,0")
1691    (set_attr "length_immediate" "0,*")
1692    (set_attr "memory" "store")
1693    (set_attr "mode" "QI")])
1694
1695 (define_insn "*movabsqi_2_rex64"
1696   [(set (match_operand:QI 0 "register_operand" "=a,r")
1697         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1699   "@
1700    movabs{b}\t{%P1, %0|%0, %P1}
1701    mov{b}\t{%a1, %0|%0, %a1}"
1702   [(set_attr "type" "imov")
1703    (set_attr "modrm" "0,*")
1704    (set_attr "length_address" "8,0")
1705    (set_attr "length_immediate" "0")
1706    (set_attr "memory" "load")
1707    (set_attr "mode" "QI")])
1708
1709 (define_insn "*movdi_extzv_1"
1710   [(set (match_operand:DI 0 "register_operand" "=R")
1711         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1712                          (const_int 8)
1713                          (const_int 8)))]
1714   "TARGET_64BIT"
1715   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716   [(set_attr "type" "imovx")
1717    (set_attr "mode" "DI")])
1718
1719 (define_insn "*movsi_extzv_1"
1720   [(set (match_operand:SI 0 "register_operand" "=R")
1721         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1722                          (const_int 8)
1723                          (const_int 8)))]
1724   ""
1725   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726   [(set_attr "type" "imovx")
1727    (set_attr "mode" "SI")])
1728
1729 (define_insn "*movqi_extzv_2"
1730   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1732                                     (const_int 8)
1733                                     (const_int 8)) 0))]
1734   "!TARGET_64BIT"
1735 {
1736   switch (get_attr_type (insn))
1737     {
1738     case TYPE_IMOVX:
1739       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1740     default:
1741       return "mov{b}\t{%h1, %0|%0, %h1}";
1742     }
1743 }
1744   [(set (attr "type")
1745      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747                              (ne (symbol_ref "TARGET_MOVX")
1748                                  (const_int 0))))
1749         (const_string "imovx")
1750         (const_string "imov")))
1751    (set (attr "mode")
1752      (if_then_else (eq_attr "type" "imovx")
1753         (const_string "SI")
1754         (const_string "QI")))])
1755
1756 (define_insn "*movqi_extzv_2_rex64"
1757   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1758         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759                                     (const_int 8)
1760                                     (const_int 8)) 0))]
1761   "TARGET_64BIT"
1762 {
1763   switch (get_attr_type (insn))
1764     {
1765     case TYPE_IMOVX:
1766       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767     default:
1768       return "mov{b}\t{%h1, %0|%0, %h1}";
1769     }
1770 }
1771   [(set (attr "type")
1772      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773                         (ne (symbol_ref "TARGET_MOVX")
1774                             (const_int 0)))
1775         (const_string "imovx")
1776         (const_string "imov")))
1777    (set (attr "mode")
1778      (if_then_else (eq_attr "type" "imovx")
1779         (const_string "SI")
1780         (const_string "QI")))])
1781
1782 (define_insn "movsi_insv_1"
1783   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784                          (const_int 8)
1785                          (const_int 8))
1786         (match_operand:SI 1 "general_operand" "Qmn"))]
1787   "!TARGET_64BIT"
1788   "mov{b}\t{%b1, %h0|%h0, %b1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1791
1792 (define_insn "movdi_insv_1_rex64"
1793   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794                          (const_int 8)
1795                          (const_int 8))
1796         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1797   "TARGET_64BIT"
1798   "mov{b}\t{%b1, %h0|%h0, %b1}"
1799   [(set_attr "type" "imov")
1800    (set_attr "mode" "QI")])
1801
1802 (define_insn "*movqi_insv_2"
1803   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804                          (const_int 8)
1805                          (const_int 8))
1806         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807                      (const_int 8)))]
1808   ""
1809   "mov{b}\t{%h1, %h0|%h0, %h1}"
1810   [(set_attr "type" "imov")
1811    (set_attr "mode" "QI")])
1812
1813 (define_expand "movdi"
1814   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815         (match_operand:DI 1 "general_operand" ""))]
1816   ""
1817   "ix86_expand_move (DImode, operands); DONE;")
1818
1819 (define_insn "*pushdi"
1820   [(set (match_operand:DI 0 "push_operand" "=<")
1821         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1822   "!TARGET_64BIT"
1823   "#")
1824
1825 (define_insn "*pushdi2_rex64"
1826   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1828   "TARGET_64BIT"
1829   "@
1830    push{q}\t%1
1831    #"
1832   [(set_attr "type" "push,multi")
1833    (set_attr "mode" "DI")])
1834
1835 ;; Convert impossible pushes of immediate to existing instructions.
1836 ;; First try to get scratch register and go through it.  In case this
1837 ;; fails, push sign extended lower part first and then overwrite
1838 ;; upper part by 32bit move.
1839 (define_peephole2
1840   [(match_scratch:DI 2 "r")
1841    (set (match_operand:DI 0 "push_operand" "")
1842         (match_operand:DI 1 "immediate_operand" ""))]
1843   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844    && !x86_64_immediate_operand (operands[1], DImode)"
1845   [(set (match_dup 2) (match_dup 1))
1846    (set (match_dup 0) (match_dup 2))]
1847   "")
1848
1849 ;; We need to define this as both peepholer and splitter for case
1850 ;; peephole2 pass is not run.
1851 ;; "&& 1" is needed to keep it from matching the previous pattern.
1852 (define_peephole2
1853   [(set (match_operand:DI 0 "push_operand" "")
1854         (match_operand:DI 1 "immediate_operand" ""))]
1855   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857   [(set (match_dup 0) (match_dup 1))
1858    (set (match_dup 2) (match_dup 3))]
1859   "split_di (operands + 1, 1, operands + 2, operands + 3);
1860    operands[1] = gen_lowpart (DImode, operands[2]);
1861    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862                                                     GEN_INT (4)));
1863   ")
1864
1865 (define_split
1866   [(set (match_operand:DI 0 "push_operand" "")
1867         (match_operand:DI 1 "immediate_operand" ""))]
1868   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869                     ? flow2_completed : reload_completed)
1870    && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 0) (match_dup 1))
1873    (set (match_dup 2) (match_dup 3))]
1874   "split_di (operands + 1, 1, operands + 2, operands + 3);
1875    operands[1] = gen_lowpart (DImode, operands[2]);
1876    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877                                                     GEN_INT (4)));
1878   ")
1879
1880 (define_insn "*pushdi2_prologue_rex64"
1881   [(set (match_operand:DI 0 "push_operand" "=<")
1882         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883    (clobber (mem:BLK (scratch)))]
1884   "TARGET_64BIT"
1885   "push{q}\t%1"
1886   [(set_attr "type" "push")
1887    (set_attr "mode" "DI")])
1888
1889 (define_insn "*popdi1_epilogue_rex64"
1890   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891         (mem:DI (reg:DI SP_REG)))
1892    (set (reg:DI SP_REG)
1893         (plus:DI (reg:DI SP_REG) (const_int 8)))
1894    (clobber (mem:BLK (scratch)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1899
1900 (define_insn "popdi1"
1901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902         (mem:DI (reg:DI SP_REG)))
1903    (set (reg:DI SP_REG)
1904         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905   "TARGET_64BIT"
1906   "pop{q}\t%0"
1907   [(set_attr "type" "pop")
1908    (set_attr "mode" "DI")])
1909
1910 (define_insn "*movdi_xor_rex64"
1911   [(set (match_operand:DI 0 "register_operand" "=r")
1912         (match_operand:DI 1 "const0_operand" "i"))
1913    (clobber (reg:CC FLAGS_REG))]
1914   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915    && reload_completed"
1916   "xor{l}\t{%k0, %k0|%k0, %k0}"
1917   [(set_attr "type" "alu1")
1918    (set_attr "mode" "SI")
1919    (set_attr "length_immediate" "0")])
1920
1921 (define_insn "*movdi_or_rex64"
1922   [(set (match_operand:DI 0 "register_operand" "=r")
1923         (match_operand:DI 1 "const_int_operand" "i"))
1924    (clobber (reg:CC FLAGS_REG))]
1925   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926    && reload_completed
1927    && operands[1] == constm1_rtx"
1928 {
1929   operands[1] = constm1_rtx;
1930   return "or{q}\t{%1, %0|%0, %1}";
1931 }
1932   [(set_attr "type" "alu1")
1933    (set_attr "mode" "DI")
1934    (set_attr "length_immediate" "1")])
1935
1936 (define_insn "*movdi_2"
1937   [(set (match_operand:DI 0 "nonimmediate_operand"
1938                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939         (match_operand:DI 1 "general_operand"
1940                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942   "@
1943    #
1944    #
1945    pxor\t%0, %0
1946    movq\t{%1, %0|%0, %1}
1947    movq\t{%1, %0|%0, %1}
1948    pxor\t%0, %0
1949    movq\t{%1, %0|%0, %1}
1950    movdqa\t{%1, %0|%0, %1}
1951    movq\t{%1, %0|%0, %1}
1952    xorps\t%0, %0
1953    movlps\t{%1, %0|%0, %1}
1954    movaps\t{%1, %0|%0, %1}
1955    movlps\t{%1, %0|%0, %1}"
1956   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958
1959 (define_split
1960   [(set (match_operand:DI 0 "push_operand" "")
1961         (match_operand:DI 1 "general_operand" ""))]
1962   "!TARGET_64BIT && reload_completed
1963    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1966
1967 ;; %%% This multiword shite has got to go.
1968 (define_split
1969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974   [(const_int 0)]
1975   "ix86_split_long_move (operands); DONE;")
1976
1977 (define_insn "*movdi_1_rex64"
1978   [(set (match_operand:DI 0 "nonimmediate_operand"
1979                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980         (match_operand:DI 1 "general_operand"
1981                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 {
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSECVT:
1987       if (which_alternative == 13)
1988         return "movq2dq\t{%1, %0|%0, %1}";
1989       else
1990         return "movdq2q\t{%1, %0|%0, %1}";
1991     case TYPE_SSEMOV:
1992       if (get_attr_mode (insn) == MODE_TI)
1993           return "movdqa\t{%1, %0|%0, %1}";
1994       /* FALLTHRU */
1995     case TYPE_MMXMOV:
1996       /* Moves from and into integer register is done using movd opcode with
1997          REX prefix.  */
1998       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999           return "movd\t{%1, %0|%0, %1}";
2000       return "movq\t{%1, %0|%0, %1}";
2001     case TYPE_SSELOG1:
2002     case TYPE_MMXADD:
2003       return "pxor\t%0, %0";
2004     case TYPE_MULTI:
2005       return "#";
2006     case TYPE_LEA:
2007       return "lea{q}\t{%a1, %0|%0, %a1}";
2008     default:
2009       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010       if (get_attr_mode (insn) == MODE_SI)
2011         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012       else if (which_alternative == 2)
2013         return "movabs{q}\t{%1, %0|%0, %1}";
2014       else
2015         return "mov{q}\t{%1, %0|%0, %1}";
2016     }
2017 }
2018   [(set (attr "type")
2019      (cond [(eq_attr "alternative" "5")
2020               (const_string "mmxadd")
2021             (eq_attr "alternative" "6,7,8")
2022               (const_string "mmxmov")
2023             (eq_attr "alternative" "9")
2024               (const_string "sselog1")
2025             (eq_attr "alternative" "10,11,12")
2026               (const_string "ssemov")
2027             (eq_attr "alternative" "13,14")
2028               (const_string "ssecvt")
2029             (eq_attr "alternative" "4")
2030               (const_string "multi")
2031             (match_operand:DI 1 "pic_32bit_operand" "")
2032               (const_string "lea")
2033            ]
2034            (const_string "imov")))
2035    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2038
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046   "@
2047    movabs{q}\t{%1, %P0|%P0, %1}
2048    mov{q}\t{%1, %a0|%a0, %1}"
2049   [(set_attr "type" "imov")
2050    (set_attr "modrm" "0,*")
2051    (set_attr "length_address" "8,0")
2052    (set_attr "length_immediate" "0,*")
2053    (set_attr "memory" "store")
2054    (set_attr "mode" "DI")])
2055
2056 (define_insn "*movabsdi_2_rex64"
2057   [(set (match_operand:DI 0 "register_operand" "=a,r")
2058         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060   "@
2061    movabs{q}\t{%P1, %0|%0, %P1}
2062    mov{q}\t{%a1, %0|%0, %a1}"
2063   [(set_attr "type" "imov")
2064    (set_attr "modrm" "0,*")
2065    (set_attr "length_address" "8,0")
2066    (set_attr "length_immediate" "0")
2067    (set_attr "memory" "load")
2068    (set_attr "mode" "DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))]
2081   "")
2082
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 (define_peephole2
2087   [(set (match_operand:DI 0 "memory_operand" "")
2088         (match_operand:DI 1 "immediate_operand" ""))]
2089   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091   [(set (match_dup 2) (match_dup 3))
2092    (set (match_dup 4) (match_dup 5))]
2093   "split_di (operands, 2, operands + 2, operands + 4);")
2094
2095 (define_split
2096   [(set (match_operand:DI 0 "memory_operand" "")
2097         (match_operand:DI 1 "immediate_operand" ""))]
2098   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099                     ? flow2_completed : reload_completed)
2100    && !symbolic_operand (operands[1], DImode)
2101    && !x86_64_immediate_operand (operands[1], DImode)"
2102   [(set (match_dup 2) (match_dup 3))
2103    (set (match_dup 4) (match_dup 5))]
2104   "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106 (define_insn "*swapdi_rex64"
2107   [(set (match_operand:DI 0 "register_operand" "+r")
2108         (match_operand:DI 1 "register_operand" "+r"))
2109    (set (match_dup 1)
2110         (match_dup 0))]
2111   "TARGET_64BIT"
2112   "xchg{q}\t%1, %0"
2113   [(set_attr "type" "imov")
2114    (set_attr "mode" "DI")
2115    (set_attr "pent_pair" "np")
2116    (set_attr "athlon_decode" "vector")])
2117
2118 (define_expand "movti"
2119   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120         (match_operand:TI 1 "nonimmediate_operand" ""))]
2121   "TARGET_SSE || TARGET_64BIT"
2122 {
2123   if (TARGET_64BIT)
2124     ix86_expand_move (TImode, operands);
2125   else
2126     ix86_expand_vector_move (TImode, operands);
2127   DONE;
2128 })
2129
2130 (define_insn "*movti_internal"
2131   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133   "TARGET_SSE && !TARGET_64BIT
2134    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2135 {
2136   switch (which_alternative)
2137     {
2138     case 0:
2139       if (get_attr_mode (insn) == MODE_V4SF)
2140         return "xorps\t%0, %0";
2141       else
2142         return "pxor\t%0, %0";
2143     case 1:
2144     case 2:
2145       if (get_attr_mode (insn) == MODE_V4SF)
2146         return "movaps\t{%1, %0|%0, %1}";
2147       else
2148         return "movdqa\t{%1, %0|%0, %1}";
2149     default:
2150       gcc_unreachable ();
2151     }
2152 }
2153   [(set_attr "type" "sselog1,ssemov,ssemov")
2154    (set (attr "mode")
2155         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156                     (ne (symbol_ref "optimize_size") (const_int 0)))
2157                  (const_string "V4SF")
2158                (and (eq_attr "alternative" "2")
2159                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2160                         (const_int 0)))
2161                  (const_string "V4SF")]
2162               (const_string "TI")))])
2163
2164 (define_insn "*movti_rex64"
2165   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2167   "TARGET_64BIT
2168    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2169 {
2170   switch (which_alternative)
2171     {
2172     case 0:
2173     case 1:
2174       return "#";
2175     case 2:
2176       if (get_attr_mode (insn) == MODE_V4SF)
2177         return "xorps\t%0, %0";
2178       else
2179         return "pxor\t%0, %0";
2180     case 3:
2181     case 4:
2182       if (get_attr_mode (insn) == MODE_V4SF)
2183         return "movaps\t{%1, %0|%0, %1}";
2184       else
2185         return "movdqa\t{%1, %0|%0, %1}";
2186     default:
2187       gcc_unreachable ();
2188     }
2189 }
2190   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2191    (set (attr "mode")
2192         (cond [(eq_attr "alternative" "2,3")
2193                  (if_then_else
2194                    (ne (symbol_ref "optimize_size")
2195                        (const_int 0))
2196                    (const_string "V4SF")
2197                    (const_string "TI"))
2198                (eq_attr "alternative" "4")
2199                  (if_then_else
2200                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201                             (const_int 0))
2202                         (ne (symbol_ref "optimize_size")
2203                             (const_int 0)))
2204                    (const_string "V4SF")
2205                    (const_string "TI"))]
2206                (const_string "DI")))])
2207
2208 (define_split
2209   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210         (match_operand:TI 1 "general_operand" ""))]
2211   "reload_completed && !SSE_REG_P (operands[0])
2212    && !SSE_REG_P (operands[1])"
2213   [(const_int 0)]
2214   "ix86_split_long_move (operands); DONE;")
2215
2216 (define_expand "movsf"
2217   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218         (match_operand:SF 1 "general_operand" ""))]
2219   ""
2220   "ix86_expand_move (SFmode, operands); DONE;")
2221
2222 (define_insn "*pushsf"
2223   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2225   "!TARGET_64BIT"
2226 {
2227   /* Anything else should be already split before reg-stack.  */
2228   gcc_assert (which_alternative == 1);
2229   return "push{l}\t%1";
2230 }
2231   [(set_attr "type" "multi,push,multi")
2232    (set_attr "unit" "i387,*,*")
2233    (set_attr "mode" "SF,SI,SF")])
2234
2235 (define_insn "*pushsf_rex64"
2236   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2238   "TARGET_64BIT"
2239 {
2240   /* Anything else should be already split before reg-stack.  */
2241   gcc_assert (which_alternative == 1);
2242   return "push{q}\t%q1";
2243 }
2244   [(set_attr "type" "multi,push,multi")
2245    (set_attr "unit" "i387,*,*")
2246    (set_attr "mode" "SF,DI,SF")])
2247
2248 (define_split
2249   [(set (match_operand:SF 0 "push_operand" "")
2250         (match_operand:SF 1 "memory_operand" ""))]
2251   "reload_completed
2252    && GET_CODE (operands[1]) == MEM
2253    && constant_pool_reference_p (operands[1])"
2254   [(set (match_dup 0)
2255         (match_dup 1))]
2256   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2257
2258
2259 ;; %%% Kill this when call knows how to work this out.
2260 (define_split
2261   [(set (match_operand:SF 0 "push_operand" "")
2262         (match_operand:SF 1 "any_fp_register_operand" ""))]
2263   "!TARGET_64BIT"
2264   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266
2267 (define_split
2268   [(set (match_operand:SF 0 "push_operand" "")
2269         (match_operand:SF 1 "any_fp_register_operand" ""))]
2270   "TARGET_64BIT"
2271   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2273
2274 (define_insn "*movsf_1"
2275   [(set (match_operand:SF 0 "nonimmediate_operand"
2276           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2277         (match_operand:SF 1 "general_operand"
2278           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2279   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280    && (reload_in_progress || reload_completed
2281        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282        || GET_CODE (operands[1]) != CONST_DOUBLE
2283        || memory_operand (operands[0], SFmode))" 
2284 {
2285   switch (which_alternative)
2286     {
2287     case 0:
2288       return output_387_reg_move (insn, operands);
2289
2290     case 1:
2291       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292         return "fstp%z0\t%y0";
2293       else
2294         return "fst%z0\t%y0";
2295
2296     case 2:
2297       return standard_80387_constant_opcode (operands[1]);
2298
2299     case 3:
2300     case 4:
2301       return "mov{l}\t{%1, %0|%0, %1}";
2302     case 5:
2303       if (get_attr_mode (insn) == MODE_TI)
2304         return "pxor\t%0, %0";
2305       else
2306         return "xorps\t%0, %0";
2307     case 6:
2308       if (get_attr_mode (insn) == MODE_V4SF)
2309         return "movaps\t{%1, %0|%0, %1}";
2310       else
2311         return "movss\t{%1, %0|%0, %1}";
2312     case 7:
2313     case 8:
2314       return "movss\t{%1, %0|%0, %1}";
2315
2316     case 9:
2317     case 10:
2318       return "movd\t{%1, %0|%0, %1}";
2319
2320     case 11:
2321       return "movq\t{%1, %0|%0, %1}";
2322
2323     default:
2324       gcc_unreachable ();
2325     }
2326 }
2327   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2328    (set (attr "mode")
2329         (cond [(eq_attr "alternative" "3,4,9,10")
2330                  (const_string "SI")
2331                (eq_attr "alternative" "5")
2332                  (if_then_else
2333                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2334                                  (const_int 0))
2335                              (ne (symbol_ref "TARGET_SSE2")
2336                                  (const_int 0)))
2337                         (eq (symbol_ref "optimize_size")
2338                             (const_int 0)))
2339                    (const_string "TI")
2340                    (const_string "V4SF"))
2341                /* For architectures resolving dependencies on
2342                   whole SSE registers use APS move to break dependency
2343                   chains, otherwise use short move to avoid extra work. 
2344
2345                   Do the same for architectures resolving dependencies on
2346                   the parts.  While in DF mode it is better to always handle
2347                   just register parts, the SF mode is different due to lack
2348                   of instructions to load just part of the register.  It is
2349                   better to maintain the whole registers in single format
2350                   to avoid problems on using packed logical operations.  */
2351                (eq_attr "alternative" "6")
2352                  (if_then_else
2353                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2354                             (const_int 0))
2355                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2356                             (const_int 0)))
2357                    (const_string "V4SF")
2358                    (const_string "SF"))
2359                (eq_attr "alternative" "11")
2360                  (const_string "DI")]
2361                (const_string "SF")))])
2362
2363 (define_insn "*swapsf"
2364   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365         (match_operand:SF 1 "fp_register_operand" "+f"))
2366    (set (match_dup 1)
2367         (match_dup 0))]
2368   "reload_completed || TARGET_80387"
2369 {
2370   if (STACK_TOP_P (operands[0]))
2371     return "fxch\t%1";
2372   else
2373     return "fxch\t%0";
2374 }
2375   [(set_attr "type" "fxch")
2376    (set_attr "mode" "SF")])
2377
2378 (define_expand "movdf"
2379   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380         (match_operand:DF 1 "general_operand" ""))]
2381   ""
2382   "ix86_expand_move (DFmode, operands); DONE;")
2383
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter.  Allow this
2387 ;; pattern for optimize_size too.
2388
2389 (define_insn "*pushdf_nointeger"
2390   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2393 {
2394   /* This insn should be already split before reg-stack.  */
2395   gcc_unreachable ();
2396 }
2397   [(set_attr "type" "multi")
2398    (set_attr "unit" "i387,*,*,*")
2399    (set_attr "mode" "DF,SI,SI,DF")])
2400
2401 (define_insn "*pushdf_integer"
2402   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2405 {
2406   /* This insn should be already split before reg-stack.  */
2407   gcc_unreachable ();
2408 }
2409   [(set_attr "type" "multi")
2410    (set_attr "unit" "i387,*,*")
2411    (set_attr "mode" "DF,SI,DF")])
2412
2413 ;; %%% Kill this when call knows how to work this out.
2414 (define_split
2415   [(set (match_operand:DF 0 "push_operand" "")
2416         (match_operand:DF 1 "any_fp_register_operand" ""))]
2417   "!TARGET_64BIT && reload_completed"
2418   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2420   "")
2421
2422 (define_split
2423   [(set (match_operand:DF 0 "push_operand" "")
2424         (match_operand:DF 1 "any_fp_register_operand" ""))]
2425   "TARGET_64BIT && reload_completed"
2426   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2428   "")
2429
2430 (define_split
2431   [(set (match_operand:DF 0 "push_operand" "")
2432         (match_operand:DF 1 "general_operand" ""))]
2433   "reload_completed"
2434   [(const_int 0)]
2435   "ix86_split_long_move (operands); DONE;")
2436
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2440
2441 (define_insn "*movdf_nointeger"
2442   [(set (match_operand:DF 0 "nonimmediate_operand"
2443                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2444         (match_operand:DF 1 "general_operand"
2445                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2446   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448    && (reload_in_progress || reload_completed
2449        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450        || GET_CODE (operands[1]) != CONST_DOUBLE
2451        || memory_operand (operands[0], DFmode))" 
2452 {
2453   switch (which_alternative)
2454     {
2455     case 0:
2456       return output_387_reg_move (insn, operands);
2457
2458     case 1:
2459       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460         return "fstp%z0\t%y0";
2461       else
2462         return "fst%z0\t%y0";
2463
2464     case 2:
2465       return standard_80387_constant_opcode (operands[1]);
2466
2467     case 3:
2468     case 4:
2469       return "#";
2470     case 5:
2471       switch (get_attr_mode (insn))
2472         {
2473         case MODE_V4SF:
2474           return "xorps\t%0, %0";
2475         case MODE_V2DF:
2476           return "xorpd\t%0, %0";
2477         case MODE_TI:
2478           return "pxor\t%0, %0";
2479         default:
2480           gcc_unreachable ();
2481         }
2482     case 6:
2483     case 7:
2484     case 8:
2485       switch (get_attr_mode (insn))
2486         {
2487         case MODE_V4SF:
2488           return "movaps\t{%1, %0|%0, %1}";
2489         case MODE_V2DF:
2490           return "movapd\t{%1, %0|%0, %1}";
2491         case MODE_TI:
2492           return "movdqa\t{%1, %0|%0, %1}";
2493         case MODE_DI:
2494           return "movq\t{%1, %0|%0, %1}";
2495         case MODE_DF:
2496           return "movsd\t{%1, %0|%0, %1}";
2497         case MODE_V1DF:
2498           return "movlpd\t{%1, %0|%0, %1}";
2499         case MODE_V2SF:
2500           return "movlps\t{%1, %0|%0, %1}";
2501         default:
2502           gcc_unreachable ();
2503         }
2504
2505     default:
2506       gcc_unreachable ();
2507     }
2508 }
2509   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2510    (set (attr "mode")
2511         (cond [(eq_attr "alternative" "0,1,2")
2512                  (const_string "DF")
2513                (eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2515
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (const_string "V4SF")
2520                        ]
2521                    (const_string "V2SF"))
2522
2523                /* xorps is one byte shorter.  */
2524                (eq_attr "alternative" "5")
2525                  (cond [(ne (symbol_ref "optimize_size")
2526                             (const_int 0))
2527                           (const_string "V4SF")
2528                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2529                             (const_int 0))
2530                           (const_string "TI")
2531                        ]
2532                        (const_string "V2DF"))
2533
2534                /* For architectures resolving dependencies on
2535                   whole SSE registers use APD move to break dependency
2536                   chains, otherwise use short move to avoid extra work.
2537
2538                   movaps encodes one byte shorter.  */
2539                (eq_attr "alternative" "6")
2540                  (cond
2541                    [(ne (symbol_ref "optimize_size")
2542                         (const_int 0))
2543                       (const_string "V4SF")
2544                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2545                         (const_int 0))
2546                       (const_string "V2DF")
2547                    ]
2548                    (const_string "DF"))
2549                /* For architectures resolving dependencies on register
2550                   parts we may avoid extra work to zero out upper part
2551                   of register.  */
2552                (eq_attr "alternative" "7")
2553                  (if_then_else
2554                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2555                        (const_int 0))
2556                    (const_string "V1DF")
2557                    (const_string "DF"))
2558               ]
2559               (const_string "DF")))])
2560
2561 (define_insn "*movdf_integer"
2562   [(set (match_operand:DF 0 "nonimmediate_operand"
2563                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564         (match_operand:DF 1 "general_operand"
2565                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2566   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568    && (reload_in_progress || reload_completed
2569        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570        || GET_CODE (operands[1]) != CONST_DOUBLE
2571        || memory_operand (operands[0], DFmode))" 
2572 {
2573   switch (which_alternative)
2574     {
2575     case 0:
2576       return output_387_reg_move (insn, operands);
2577
2578     case 1:
2579       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580         return "fstp%z0\t%y0";
2581       else
2582         return "fst%z0\t%y0";
2583
2584     case 2:
2585       return standard_80387_constant_opcode (operands[1]);
2586
2587     case 3:
2588     case 4:
2589       return "#";
2590
2591     case 5:
2592       switch (get_attr_mode (insn))
2593         {
2594         case MODE_V4SF:
2595           return "xorps\t%0, %0";
2596         case MODE_V2DF:
2597           return "xorpd\t%0, %0";
2598         case MODE_TI:
2599           return "pxor\t%0, %0";
2600         default:
2601           gcc_unreachable ();
2602         }
2603     case 6:
2604     case 7:
2605     case 8:
2606       switch (get_attr_mode (insn))
2607         {
2608         case MODE_V4SF:
2609           return "movaps\t{%1, %0|%0, %1}";
2610         case MODE_V2DF:
2611           return "movapd\t{%1, %0|%0, %1}";
2612         case MODE_TI:
2613           return "movdqa\t{%1, %0|%0, %1}";
2614         case MODE_DI:
2615           return "movq\t{%1, %0|%0, %1}";
2616         case MODE_DF:
2617           return "movsd\t{%1, %0|%0, %1}";
2618         case MODE_V1DF:
2619           return "movlpd\t{%1, %0|%0, %1}";
2620         case MODE_V2SF:
2621           return "movlps\t{%1, %0|%0, %1}";
2622         default:
2623           gcc_unreachable ();
2624         }
2625
2626     default:
2627       gcc_unreachable();
2628     }
2629 }
2630   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2631    (set (attr "mode")
2632         (cond [(eq_attr "alternative" "0,1,2")
2633                  (const_string "DF")
2634                (eq_attr "alternative" "3,4")
2635                  (const_string "SI")
2636
2637                /* For SSE1, we have many fewer alternatives.  */
2638                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639                  (cond [(eq_attr "alternative" "5,6")
2640                           (const_string "V4SF")
2641                        ]
2642                    (const_string "V2SF"))
2643
2644                /* xorps is one byte shorter.  */
2645                (eq_attr "alternative" "5")
2646                  (cond [(ne (symbol_ref "optimize_size")
2647                             (const_int 0))
2648                           (const_string "V4SF")
2649                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650                             (const_int 0))
2651                           (const_string "TI")
2652                        ]
2653                        (const_string "V2DF"))
2654
2655                /* For architectures resolving dependencies on
2656                   whole SSE registers use APD move to break dependency
2657                   chains, otherwise use short move to avoid extra work.
2658
2659                   movaps encodes one byte shorter.  */
2660                (eq_attr "alternative" "6")
2661                  (cond
2662                    [(ne (symbol_ref "optimize_size")
2663                         (const_int 0))
2664                       (const_string "V4SF")
2665                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2666                         (const_int 0))
2667                       (const_string "V2DF")
2668                    ]
2669                    (const_string "DF"))
2670                /* For architectures resolving dependencies on register
2671                   parts we may avoid extra work to zero out upper part
2672                   of register.  */
2673                (eq_attr "alternative" "7")
2674                  (if_then_else
2675                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676                        (const_int 0))
2677                    (const_string "V1DF")
2678                    (const_string "DF"))
2679               ]
2680               (const_string "DF")))])
2681
2682 (define_split
2683   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684         (match_operand:DF 1 "general_operand" ""))]
2685   "reload_completed
2686    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687    && ! (ANY_FP_REG_P (operands[0]) || 
2688          (GET_CODE (operands[0]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690    && ! (ANY_FP_REG_P (operands[1]) || 
2691          (GET_CODE (operands[1]) == SUBREG
2692           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693   [(const_int 0)]
2694   "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*swapdf"
2697   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698         (match_operand:DF 1 "fp_register_operand" "+f"))
2699    (set (match_dup 1)
2700         (match_dup 0))]
2701   "reload_completed || TARGET_80387"
2702 {
2703   if (STACK_TOP_P (operands[0]))
2704     return "fxch\t%1";
2705   else
2706     return "fxch\t%0";
2707 }
2708   [(set_attr "type" "fxch")
2709    (set_attr "mode" "DF")])
2710
2711 (define_expand "movxf"
2712   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713         (match_operand:XF 1 "general_operand" ""))]
2714   ""
2715   "ix86_expand_move (XFmode, operands); DONE;")
2716
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;;  handled elsewhere).
2723
2724 (define_insn "*pushxf_nointeger"
2725   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727   "optimize_size"
2728 {
2729   /* This insn should be already split before reg-stack.  */
2730   gcc_unreachable ();
2731 }
2732   [(set_attr "type" "multi")
2733    (set_attr "unit" "i387,*,*")
2734    (set_attr "mode" "XF,SI,SI")])
2735
2736 (define_insn "*pushxf_integer"
2737   [(set (match_operand:XF 0 "push_operand" "=<,<")
2738         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2739   "!optimize_size"
2740 {
2741   /* This insn should be already split before reg-stack.  */
2742   gcc_unreachable ();
2743 }
2744   [(set_attr "type" "multi")
2745    (set_attr "unit" "i387,*")
2746    (set_attr "mode" "XF,SI")])
2747
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2757
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2783 {
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2788
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3: case 4:
2801       return "#";
2802     default:
2803       gcc_unreachable ();
2804     }
2805 }
2806   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807    (set_attr "mode" "XF,XF,XF,SI,SI")])
2808
2809 (define_insn "*movxf_integer"
2810   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2812   "!optimize_size
2813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814    && (reload_in_progress || reload_completed
2815        || GET_CODE (operands[1]) != CONST_DOUBLE
2816        || memory_operand (operands[0], XFmode))" 
2817 {
2818   switch (which_alternative)
2819     {
2820     case 0:
2821       return output_387_reg_move (insn, operands);
2822
2823     case 1:
2824       /* There is no non-popping store to memory for XFmode.  So if
2825          we need one, follow the store with a load.  */
2826       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827         return "fstp%z0\t%y0\;fld%z0\t%y0";
2828       else
2829         return "fstp%z0\t%y0";
2830
2831     case 2:
2832       return standard_80387_constant_opcode (operands[1]);
2833
2834     case 3: case 4:
2835       return "#";
2836
2837     default:
2838       gcc_unreachable ();
2839     }
2840 }
2841   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842    (set_attr "mode" "XF,XF,XF,SI,SI")])
2843
2844 (define_split
2845   [(set (match_operand 0 "nonimmediate_operand" "")
2846         (match_operand 1 "general_operand" ""))]
2847   "reload_completed
2848    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849    && GET_MODE (operands[0]) == XFmode
2850    && ! (ANY_FP_REG_P (operands[0]) || 
2851          (GET_CODE (operands[0]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853    && ! (ANY_FP_REG_P (operands[1]) || 
2854          (GET_CODE (operands[1]) == SUBREG
2855           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2856   [(const_int 0)]
2857   "ix86_split_long_move (operands); DONE;")
2858
2859 (define_split
2860   [(set (match_operand 0 "register_operand" "")
2861         (match_operand 1 "memory_operand" ""))]
2862   "reload_completed
2863    && GET_CODE (operands[1]) == MEM
2864    && (GET_MODE (operands[0]) == XFmode
2865        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866    && constant_pool_reference_p (operands[1])"
2867   [(set (match_dup 0) (match_dup 1))]
2868 {
2869   rtx c = avoid_constant_pool_reference (operands[1]);
2870   rtx r = operands[0];
2871
2872   if (GET_CODE (r) == SUBREG)
2873     r = SUBREG_REG (r);
2874
2875   if (SSE_REG_P (r))
2876     {
2877       if (!standard_sse_constant_p (c))
2878         FAIL;
2879     }
2880   else if (FP_REG_P (r))
2881     {
2882       if (!standard_80387_constant_p (c))
2883         FAIL;
2884     }
2885   else if (MMX_REG_P (r))
2886     FAIL;
2887
2888   operands[1] = c;
2889 })
2890
2891 (define_insn "swapxf"
2892   [(set (match_operand:XF 0 "register_operand" "+f")
2893         (match_operand:XF 1 "register_operand" "+f"))
2894    (set (match_dup 1)
2895         (match_dup 0))]
2896   "TARGET_80387"
2897 {
2898   if (STACK_TOP_P (operands[0]))
2899     return "fxch\t%1";
2900   else
2901     return "fxch\t%0";
2902 }
2903   [(set_attr "type" "fxch")
2904    (set_attr "mode" "XF")])
2905
2906 (define_expand "movtf"
2907   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908         (match_operand:TF 1 "nonimmediate_operand" ""))]
2909   "TARGET_64BIT"
2910 {
2911   ix86_expand_move (TFmode, operands);
2912   DONE;
2913 })
2914
2915 (define_insn "*movtf_internal"
2916   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2918   "TARGET_64BIT
2919    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2920 {
2921   switch (which_alternative)
2922     {
2923     case 0:
2924     case 1:
2925       return "#";
2926     case 2:
2927       if (get_attr_mode (insn) == MODE_V4SF)
2928         return "xorps\t%0, %0";
2929       else
2930         return "pxor\t%0, %0";
2931     case 3:
2932     case 4:
2933       if (get_attr_mode (insn) == MODE_V4SF)
2934         return "movaps\t{%1, %0|%0, %1}";
2935       else
2936         return "movdqa\t{%1, %0|%0, %1}";
2937     default:
2938       gcc_unreachable ();
2939     }
2940 }
2941   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2942    (set (attr "mode")
2943         (cond [(eq_attr "alternative" "2,3")
2944                  (if_then_else
2945                    (ne (symbol_ref "optimize_size")
2946                        (const_int 0))
2947                    (const_string "V4SF")
2948                    (const_string "TI"))
2949                (eq_attr "alternative" "4")
2950                  (if_then_else
2951                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2952                             (const_int 0))
2953                         (ne (symbol_ref "optimize_size")
2954                             (const_int 0)))
2955                    (const_string "V4SF")
2956                    (const_string "TI"))]
2957                (const_string "DI")))])
2958
2959 (define_split
2960   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961         (match_operand:TF 1 "general_operand" ""))]
2962   "reload_completed && !SSE_REG_P (operands[0])
2963    && !SSE_REG_P (operands[1])"
2964   [(const_int 0)]
2965   "ix86_split_long_move (operands); DONE;")
2966 \f
2967 ;; Zero extension instructions
2968
2969 (define_expand "zero_extendhisi2"
2970   [(set (match_operand:SI 0 "register_operand" "")
2971      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2972   ""
2973 {
2974   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2975     {
2976       operands[1] = force_reg (HImode, operands[1]);
2977       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2978       DONE;
2979     }
2980 })
2981
2982 (define_insn "zero_extendhisi2_and"
2983   [(set (match_operand:SI 0 "register_operand" "=r")
2984      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985    (clobber (reg:CC FLAGS_REG))]
2986   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987   "#"
2988   [(set_attr "type" "alu1")
2989    (set_attr "mode" "SI")])
2990
2991 (define_split
2992   [(set (match_operand:SI 0 "register_operand" "")
2993         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994    (clobber (reg:CC FLAGS_REG))]
2995   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997               (clobber (reg:CC FLAGS_REG))])]
2998   "")
2999
3000 (define_insn "*zero_extendhisi2_movzwl"
3001   [(set (match_operand:SI 0 "register_operand" "=r")
3002      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004   "movz{wl|x}\t{%1, %0|%0, %1}"
3005   [(set_attr "type" "imovx")
3006    (set_attr "mode" "SI")])
3007
3008 (define_expand "zero_extendqihi2"
3009   [(parallel
3010     [(set (match_operand:HI 0 "register_operand" "")
3011        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012      (clobber (reg:CC FLAGS_REG))])]
3013   ""
3014   "")
3015
3016 (define_insn "*zero_extendqihi2_and"
3017   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019    (clobber (reg:CC FLAGS_REG))]
3020   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3021   "#"
3022   [(set_attr "type" "alu1")
3023    (set_attr "mode" "HI")])
3024
3025 (define_insn "*zero_extendqihi2_movzbw_and"
3026   [(set (match_operand:HI 0 "register_operand" "=r,r")
3027      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028    (clobber (reg:CC FLAGS_REG))]
3029   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3030   "#"
3031   [(set_attr "type" "imovx,alu1")
3032    (set_attr "mode" "HI")])
3033
3034 ; zero extend to SImode here to avoid partial register stalls
3035 (define_insn "*zero_extendqihi2_movzbl"
3036   [(set (match_operand:HI 0 "register_operand" "=r")
3037      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3040   [(set_attr "type" "imovx")
3041    (set_attr "mode" "SI")])
3042
3043 ;; For the movzbw case strip only the clobber
3044 (define_split
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed 
3049    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && ANY_QI_REG_P (operands[0])
3062    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064   [(set (match_dup 0) (const_int 0))
3065    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066   "operands[2] = gen_lowpart (QImode, operands[0]);")
3067
3068 ;; Rest is handled by single and.
3069 (define_split
3070   [(set (match_operand:HI 0 "register_operand" "")
3071         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "reload_completed
3074    && true_regnum (operands[0]) == true_regnum (operands[1])"
3075   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076               (clobber (reg:CC FLAGS_REG))])]
3077   "")
3078
3079 (define_expand "zero_extendqisi2"
3080   [(parallel
3081     [(set (match_operand:SI 0 "register_operand" "")
3082        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083      (clobber (reg:CC FLAGS_REG))])]
3084   ""
3085   "")
3086
3087 (define_insn "*zero_extendqisi2_and"
3088   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092   "#"
3093   [(set_attr "type" "alu1")
3094    (set_attr "mode" "SI")])
3095
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097   [(set (match_operand:SI 0 "register_operand" "=r,r")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101   "#"
3102   [(set_attr "type" "imovx,alu1")
3103    (set_attr "mode" "SI")])
3104
3105 (define_insn "*zero_extendqisi2_movzbw"
3106   [(set (match_operand:SI 0 "register_operand" "=r")
3107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109   "movz{bl|x}\t{%1, %0|%0, %1}"
3110   [(set_attr "type" "imovx")
3111    (set_attr "mode" "SI")])
3112
3113 ;; For the movzbl case strip only the clobber
3114 (define_split
3115   [(set (match_operand:SI 0 "register_operand" "")
3116         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117    (clobber (reg:CC FLAGS_REG))]
3118   "reload_completed 
3119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121   [(set (match_dup 0)
3122         (zero_extend:SI (match_dup 1)))])
3123
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127   [(set (match_operand:SI 0 "register_operand" "")
3128         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129    (clobber (reg:CC FLAGS_REG))]
3130   "reload_completed
3131    && ANY_QI_REG_P (operands[0])
3132    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135   [(set (match_dup 0) (const_int 0))
3136    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137   "operands[2] = gen_lowpart (QImode, operands[0]);")
3138
3139 ;; Rest is handled by single and.
3140 (define_split
3141   [(set (match_operand:SI 0 "register_operand" "")
3142         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143    (clobber (reg:CC FLAGS_REG))]
3144   "reload_completed
3145    && true_regnum (operands[0]) == true_regnum (operands[1])"
3146   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147               (clobber (reg:CC FLAGS_REG))])]
3148   "")
3149
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152   [(set (match_operand:DI 0 "register_operand" "=r")
3153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154   ""
3155   "if (!TARGET_64BIT)
3156      {
3157        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158        DONE;
3159      }
3160   ")
3161
3162 (define_insn "zero_extendsidi2_32"
3163   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165    (clobber (reg:CC FLAGS_REG))]
3166   "!TARGET_64BIT"
3167   "@
3168    #
3169    #
3170    #
3171    movd\t{%1, %0|%0, %1}
3172    movd\t{%1, %0|%0, %1}"
3173   [(set_attr "mode" "SI,SI,SI,DI,TI")
3174    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175
3176 (define_insn "zero_extendsidi2_rex64"
3177   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179   "TARGET_64BIT"
3180   "@
3181    mov\t{%k1, %k0|%k0, %k1}
3182    #
3183    movd\t{%1, %0|%0, %1}
3184    movd\t{%1, %0|%0, %1}"
3185   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186    (set_attr "mode" "SI,DI,SI,SI")])
3187
3188 (define_split
3189   [(set (match_operand:DI 0 "memory_operand" "")
3190      (zero_extend:DI (match_dup 0)))]
3191   "TARGET_64BIT"
3192   [(set (match_dup 4) (const_int 0))]
3193   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_split 
3196   [(set (match_operand:DI 0 "register_operand" "")
3197         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198    (clobber (reg:CC FLAGS_REG))]
3199   "!TARGET_64BIT && reload_completed
3200    && true_regnum (operands[0]) == true_regnum (operands[1])"
3201   [(set (match_dup 4) (const_int 0))]
3202   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203
3204 (define_split 
3205   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "!TARGET_64BIT && reload_completed
3209    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210   [(set (match_dup 3) (match_dup 1))
3211    (set (match_dup 4) (const_int 0))]
3212   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213
3214 (define_insn "zero_extendhidi2"
3215   [(set (match_operand:DI 0 "register_operand" "=r")
3216      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217   "TARGET_64BIT"
3218   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219   [(set_attr "type" "imovx")
3220    (set_attr "mode" "DI")])
3221
3222 (define_insn "zero_extendqidi2"
3223   [(set (match_operand:DI 0 "register_operand" "=r")
3224      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225   "TARGET_64BIT"
3226   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")])
3229 \f
3230 ;; Sign extension instructions
3231
3232 (define_expand "extendsidi2"
3233   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235               (clobber (reg:CC FLAGS_REG))
3236               (clobber (match_scratch:SI 2 ""))])]
3237   ""
3238 {
3239   if (TARGET_64BIT)
3240     {
3241       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242       DONE;
3243     }
3244 })
3245
3246 (define_insn "*extendsidi2_1"
3247   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249    (clobber (reg:CC FLAGS_REG))
3250    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251   "!TARGET_64BIT"
3252   "#")
3253
3254 (define_insn "extendsidi2_rex64"
3255   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257   "TARGET_64BIT"
3258   "@
3259    {cltq|cdqe}
3260    movs{lq|x}\t{%1,%0|%0, %1}"
3261   [(set_attr "type" "imovx")
3262    (set_attr "mode" "DI")
3263    (set_attr "prefix_0f" "0")
3264    (set_attr "modrm" "0,1")])
3265
3266 (define_insn "extendhidi2"
3267   [(set (match_operand:DI 0 "register_operand" "=r")
3268         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269   "TARGET_64BIT"
3270   "movs{wq|x}\t{%1,%0|%0, %1}"
3271   [(set_attr "type" "imovx")
3272    (set_attr "mode" "DI")])
3273
3274 (define_insn "extendqidi2"
3275   [(set (match_operand:DI 0 "register_operand" "=r")
3276         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277   "TARGET_64BIT"
3278   "movs{bq|x}\t{%1,%0|%0, %1}"
3279    [(set_attr "type" "imovx")
3280     (set_attr "mode" "DI")])
3281
3282 ;; Extend to memory case when source register does die.
3283 (define_split 
3284   [(set (match_operand:DI 0 "memory_operand" "")
3285         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286    (clobber (reg:CC FLAGS_REG))
3287    (clobber (match_operand:SI 2 "register_operand" ""))]
3288   "(reload_completed
3289     && dead_or_set_p (insn, operands[1])
3290     && !reg_mentioned_p (operands[1], operands[0]))"
3291   [(set (match_dup 3) (match_dup 1))
3292    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293               (clobber (reg:CC FLAGS_REG))])
3294    (set (match_dup 4) (match_dup 1))]
3295   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296
3297 ;; Extend to memory case when source register does not die.
3298 (define_split 
3299   [(set (match_operand:DI 0 "memory_operand" "")
3300         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301    (clobber (reg:CC FLAGS_REG))
3302    (clobber (match_operand:SI 2 "register_operand" ""))]
3303   "reload_completed"
3304   [(const_int 0)]
3305 {
3306   split_di (&operands[0], 1, &operands[3], &operands[4]);
3307
3308   emit_move_insn (operands[3], operands[1]);
3309
3310   /* Generate a cltd if possible and doing so it profitable.  */
3311   if (true_regnum (operands[1]) == 0
3312       && true_regnum (operands[2]) == 1
3313       && (optimize_size || TARGET_USE_CLTD))
3314     {
3315       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316     }
3317   else
3318     {
3319       emit_move_insn (operands[2], operands[1]);
3320       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321     }
3322   emit_move_insn (operands[4], operands[2]);
3323   DONE;
3324 })
3325
3326 ;; Extend to register case.  Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3328 (define_split 
3329   [(set (match_operand:DI 0 "register_operand" "")
3330         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331    (clobber (reg:CC FLAGS_REG))
3332    (clobber (match_scratch:SI 2 ""))]
3333   "reload_completed"
3334   [(const_int 0)]
3335 {
3336   split_di (&operands[0], 1, &operands[3], &operands[4]);
3337
3338   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339     emit_move_insn (operands[3], operands[1]);
3340
3341   /* Generate a cltd if possible and doing so it profitable.  */
3342   if (true_regnum (operands[3]) == 0
3343       && (optimize_size || TARGET_USE_CLTD))
3344     {
3345       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346       DONE;
3347     }
3348
3349   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350     emit_move_insn (operands[4], operands[1]);
3351
3352   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353   DONE;
3354 })
3355
3356 (define_insn "extendhisi2"
3357   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359   ""
3360 {
3361   switch (get_attr_prefix_0f (insn))
3362     {
3363     case 0:
3364       return "{cwtl|cwde}";
3365     default:
3366       return "movs{wl|x}\t{%1,%0|%0, %1}";
3367     }
3368 }
3369   [(set_attr "type" "imovx")
3370    (set_attr "mode" "SI")
3371    (set (attr "prefix_0f")
3372      ;; movsx is short decodable while cwtl is vector decoded.
3373      (if_then_else (and (eq_attr "cpu" "!k6")
3374                         (eq_attr "alternative" "0"))
3375         (const_string "0")
3376         (const_string "1")))
3377    (set (attr "modrm")
3378      (if_then_else (eq_attr "prefix_0f" "0")
3379         (const_string "0")
3380         (const_string "1")))])
3381
3382 (define_insn "*extendhisi2_zext"
3383   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384         (zero_extend:DI
3385           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386   "TARGET_64BIT"
3387 {
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cwtl|cwde}";
3392     default:
3393       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394     }
3395 }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "SI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3408
3409 (define_insn "extendqihi2"
3410   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412   ""
3413 {
3414   switch (get_attr_prefix_0f (insn))
3415     {
3416     case 0:
3417       return "{cbtw|cbw}";
3418     default:
3419       return "movs{bw|x}\t{%1,%0|%0, %1}";
3420     }
3421 }
3422   [(set_attr "type" "imovx")
3423    (set_attr "mode" "HI")
3424    (set (attr "prefix_0f")
3425      ;; movsx is short decodable while cwtl is vector decoded.
3426      (if_then_else (and (eq_attr "cpu" "!k6")
3427                         (eq_attr "alternative" "0"))
3428         (const_string "0")
3429         (const_string "1")))
3430    (set (attr "modrm")
3431      (if_then_else (eq_attr "prefix_0f" "0")
3432         (const_string "0")
3433         (const_string "1")))])
3434
3435 (define_insn "extendqisi2"
3436   [(set (match_operand:SI 0 "register_operand" "=r")
3437         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438   ""
3439   "movs{bl|x}\t{%1,%0|%0, %1}"
3440    [(set_attr "type" "imovx")
3441     (set_attr "mode" "SI")])
3442
3443 (define_insn "*extendqisi2_zext"
3444   [(set (match_operand:DI 0 "register_operand" "=r")
3445         (zero_extend:DI
3446           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447   "TARGET_64BIT"
3448   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449    [(set_attr "type" "imovx")
3450     (set_attr "mode" "SI")])
3451 \f
3452 ;; Conversions between float and double.
3453
3454 ;; These are all no-ops in the model used for the 80387.  So just
3455 ;; emit moves.
3456
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3458 (define_insn "*dummy_extendsfdf2"
3459   [(set (match_operand:DF 0 "push_operand" "=<")
3460         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461   "0"
3462   "#")
3463
3464 (define_split
3465   [(set (match_operand:DF 0 "push_operand" "")
3466         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467   "!TARGET_64BIT"
3468   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470
3471 (define_split
3472   [(set (match_operand:DF 0 "push_operand" "")
3473         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "TARGET_64BIT"
3475   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478 (define_insn "*dummy_extendsfxf2"
3479   [(set (match_operand:XF 0 "push_operand" "=<")
3480         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481   "0"
3482   "#")
3483
3484 (define_split
3485   [(set (match_operand:XF 0 "push_operand" "")
3486         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487   ""
3488   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491
3492 (define_split
3493   [(set (match_operand:XF 0 "push_operand" "")
3494         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495   "TARGET_64BIT"
3496   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499
3500 (define_split
3501   [(set (match_operand:XF 0 "push_operand" "")
3502         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503   ""
3504   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
3508 (define_split
3509   [(set (match_operand:XF 0 "push_operand" "")
3510         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511   "TARGET_64BIT"
3512   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515
3516 (define_expand "extendsfdf2"
3517   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520 {
3521   /* ??? Needed for compress_float_constant since all fp constants
3522      are LEGITIMATE_CONSTANT_P.  */
3523   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524     {
3525       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3526           && standard_80387_constant_p (operands[1]) > 0)
3527         {
3528           operands[1] = simplify_const_unary_operation
3529             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3530           emit_move_insn_1 (operands[0], operands[1]);
3531           DONE;
3532         }
3533       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3534     }
3535   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3536     operands[1] = force_reg (SFmode, operands[1]);
3537 })
3538
3539 (define_insn "*extendsfdf2_mixed"
3540   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3541         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3542   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3543    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3544 {
3545   switch (which_alternative)
3546     {
3547     case 0:
3548       return output_387_reg_move (insn, operands);
3549
3550     case 1:
3551       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3552         return "fstp%z0\t%y0";
3553       else
3554         return "fst%z0\t%y0";
3555
3556     case 2:
3557       return "cvtss2sd\t{%1, %0|%0, %1}";
3558
3559     default:
3560       gcc_unreachable ();
3561     }
3562 }
3563   [(set_attr "type" "fmov,fmov,ssecvt")
3564    (set_attr "mode" "SF,XF,DF")])
3565
3566 (define_insn "*extendsfdf2_sse"
3567   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3568         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3569   "TARGET_SSE2 && TARGET_SSE_MATH
3570    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3571   "cvtss2sd\t{%1, %0|%0, %1}"
3572   [(set_attr "type" "ssecvt")
3573    (set_attr "mode" "DF")])
3574
3575 (define_insn "*extendsfdf2_i387"
3576   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3577         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3578   "TARGET_80387
3579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3580 {
3581   switch (which_alternative)
3582     {
3583     case 0:
3584       return output_387_reg_move (insn, operands);
3585
3586     case 1:
3587       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3588         return "fstp%z0\t%y0";
3589       else
3590         return "fst%z0\t%y0";
3591
3592     default:
3593       gcc_unreachable ();
3594     }
3595 }
3596   [(set_attr "type" "fmov")
3597    (set_attr "mode" "SF,XF")])
3598
3599 (define_expand "extendsfxf2"
3600   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3601         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3602   "TARGET_80387"
3603 {
3604   /* ??? Needed for compress_float_constant since all fp constants
3605      are LEGITIMATE_CONSTANT_P.  */
3606   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3607     {
3608       if (standard_80387_constant_p (operands[1]) > 0)
3609         {
3610           operands[1] = simplify_const_unary_operation
3611             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3612           emit_move_insn_1 (operands[0], operands[1]);
3613           DONE;
3614         }
3615       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3616     }
3617   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3618     operands[1] = force_reg (SFmode, operands[1]);
3619 })
3620
3621 (define_insn "*extendsfxf2_i387"
3622   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3623         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3624   "TARGET_80387
3625    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3626 {
3627   switch (which_alternative)
3628     {
3629     case 0:
3630       return output_387_reg_move (insn, operands);
3631
3632     case 1:
3633       /* There is no non-popping store to memory for XFmode.  So if
3634          we need one, follow the store with a load.  */
3635       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636         return "fstp%z0\t%y0";
3637       else
3638         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3639
3640     default:
3641       gcc_unreachable ();
3642     }
3643 }
3644   [(set_attr "type" "fmov")
3645    (set_attr "mode" "SF,XF")])
3646
3647 (define_expand "extenddfxf2"
3648   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3649         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3650   "TARGET_80387"
3651 {
3652   /* ??? Needed for compress_float_constant since all fp constants
3653      are LEGITIMATE_CONSTANT_P.  */
3654   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3655     {
3656       if (standard_80387_constant_p (operands[1]) > 0)
3657         {
3658           operands[1] = simplify_const_unary_operation
3659             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3660           emit_move_insn_1 (operands[0], operands[1]);
3661           DONE;
3662         }
3663       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3664     }
3665   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3666     operands[1] = force_reg (DFmode, operands[1]);
3667 })
3668
3669 (define_insn "*extenddfxf2_i387"
3670   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3671         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3672   "TARGET_80387
3673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3674 {
3675   switch (which_alternative)
3676     {
3677     case 0:
3678       return output_387_reg_move (insn, operands);
3679
3680     case 1:
3681       /* There is no non-popping store to memory for XFmode.  So if
3682          we need one, follow the store with a load.  */
3683       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3685       else
3686         return "fstp%z0\t%y0";
3687
3688     default:
3689       gcc_unreachable ();
3690     }
3691 }
3692   [(set_attr "type" "fmov")
3693    (set_attr "mode" "DF,XF")])
3694
3695 ;; %%% This seems bad bad news.
3696 ;; This cannot output into an f-reg because there is no way to be sure
3697 ;; of truncating in that case.  Otherwise this is just like a simple move
3698 ;; insn.  So we pretend we can output to a reg in order to get better
3699 ;; register preferencing, but we really use a stack slot.
3700
3701 ;; Conversion from DFmode to SFmode.
3702
3703 (define_expand "truncdfsf2"
3704   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3705         (float_truncate:SF
3706           (match_operand:DF 1 "nonimmediate_operand" "")))]
3707   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3708 {
3709   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3710     operands[1] = force_reg (DFmode, operands[1]);
3711
3712   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3713     ;
3714   else if (flag_unsafe_math_optimizations)
3715     ;
3716   else
3717     {
3718       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3719       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3720       DONE;
3721     }
3722 })
3723
3724 (define_expand "truncdfsf2_with_temp"
3725   [(parallel [(set (match_operand:SF 0 "" "")
3726                    (float_truncate:SF (match_operand:DF 1 "" "")))
3727               (clobber (match_operand:SF 2 "" ""))])]
3728   "")
3729
3730 (define_insn "*truncdfsf_fast_mixed"
3731   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3732         (float_truncate:SF
3733           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3734   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3735 {
3736   switch (which_alternative)
3737     {
3738     case 0:
3739       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3740         return "fstp%z0\t%y0";
3741       else
3742         return "fst%z0\t%y0";
3743     case 1:
3744       return output_387_reg_move (insn, operands);
3745     case 2:
3746       return "cvtsd2ss\t{%1, %0|%0, %1}";
3747     default:
3748       gcc_unreachable ();
3749     }
3750 }
3751   [(set_attr "type" "fmov,fmov,ssecvt")
3752    (set_attr "mode" "SF")])
3753
3754 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3755 ;; because nothing we do here is unsafe.
3756 (define_insn "*truncdfsf_fast_sse"
3757   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3758         (float_truncate:SF
3759           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3760   "TARGET_SSE2 && TARGET_SSE_MATH"
3761   "cvtsd2ss\t{%1, %0|%0, %1}"
3762   [(set_attr "type" "ssecvt")
3763    (set_attr "mode" "SF")])
3764
3765 (define_insn "*truncdfsf_fast_i387"
3766   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3767         (float_truncate:SF
3768           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3769   "TARGET_80387 && flag_unsafe_math_optimizations"
3770   "* return output_387_reg_move (insn, operands);"
3771   [(set_attr "type" "fmov")
3772    (set_attr "mode" "SF")])
3773
3774 (define_insn "*truncdfsf_mixed"
3775   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3776         (float_truncate:SF
3777           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3778    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3779   "TARGET_MIX_SSE_I387"
3780 {
3781   switch (which_alternative)
3782     {
3783     case 0:
3784       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3785         return "fstp%z0\t%y0";
3786       else
3787         return "fst%z0\t%y0";
3788     case 1:
3789       return "#";
3790     case 2:
3791       return "cvtsd2ss\t{%1, %0|%0, %1}";
3792     default:
3793       gcc_unreachable ();
3794     }
3795 }
3796   [(set_attr "type" "fmov,multi,ssecvt")
3797    (set_attr "unit" "*,i387,*")
3798    (set_attr "mode" "SF")])
3799
3800 (define_insn "*truncdfsf_i387"
3801   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3802         (float_truncate:SF
3803           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3804    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3805   "TARGET_80387"
3806 {
3807   switch (which_alternative)
3808     {
3809     case 0:
3810       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811         return "fstp%z0\t%y0";
3812       else
3813         return "fst%z0\t%y0";
3814     case 1:
3815       return "#";
3816     default:
3817       gcc_unreachable ();
3818     }
3819 }
3820   [(set_attr "type" "fmov,multi")
3821    (set_attr "unit" "*,i387")
3822    (set_attr "mode" "SF")])
3823
3824 (define_insn "*truncdfsf2_i387_1"
3825   [(set (match_operand:SF 0 "memory_operand" "=m")
3826         (float_truncate:SF
3827           (match_operand:DF 1 "register_operand" "f")))]
3828   "TARGET_80387
3829    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3830    && !TARGET_MIX_SSE_I387"
3831 {
3832   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3833     return "fstp%z0\t%y0";
3834   else
3835     return "fst%z0\t%y0";
3836 }
3837   [(set_attr "type" "fmov")
3838    (set_attr "mode" "SF")])
3839
3840 (define_split
3841   [(set (match_operand:SF 0 "register_operand" "")
3842         (float_truncate:SF
3843          (match_operand:DF 1 "fp_register_operand" "")))
3844    (clobber (match_operand 2 "" ""))]
3845   "reload_completed"
3846   [(set (match_dup 2) (match_dup 1))
3847    (set (match_dup 0) (match_dup 2))]
3848 {
3849   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3850 })
3851
3852 ;; Conversion from XFmode to SFmode.
3853
3854 (define_expand "truncxfsf2"
3855   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3856                    (float_truncate:SF
3857                     (match_operand:XF 1 "register_operand" "")))
3858               (clobber (match_dup 2))])]
3859   "TARGET_80387"
3860 {
3861   if (flag_unsafe_math_optimizations)
3862     {
3863       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3864       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3865       if (reg != operands[0])
3866         emit_move_insn (operands[0], reg);
3867       DONE;
3868     }
3869   else
3870     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3871 })
3872
3873 (define_insn "*truncxfsf2_mixed"
3874   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3875         (float_truncate:SF
3876          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3877    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3878   "TARGET_MIX_SSE_I387"
3879 {
3880   gcc_assert (!which_alternative);
3881   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3882     return "fstp%z0\t%y0";
3883   else
3884     return "fst%z0\t%y0";
3885 }
3886   [(set_attr "type" "fmov,multi,multi,multi")
3887    (set_attr "unit" "*,i387,i387,i387")
3888    (set_attr "mode" "SF")])
3889
3890 (define_insn "truncxfsf2_i387_noop"
3891   [(set (match_operand:SF 0 "register_operand" "=f")
3892         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3893   "TARGET_80387 && flag_unsafe_math_optimizations"
3894 {
3895   return output_387_reg_move (insn, operands);
3896 }
3897   [(set_attr "type" "fmov")
3898    (set_attr "mode" "SF")])
3899
3900 (define_insn "*truncxfsf2_i387"
3901   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3902         (float_truncate:SF
3903          (match_operand:XF 1 "register_operand" "f,f,f")))
3904    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3905   "TARGET_80387"
3906 {
3907   gcc_assert (!which_alternative);
3908   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3909     return "fstp%z0\t%y0";
3910    else
3911      return "fst%z0\t%y0";
3912 }
3913   [(set_attr "type" "fmov,multi,multi")
3914    (set_attr "unit" "*,i387,i387")
3915    (set_attr "mode" "SF")])
3916
3917 (define_insn "*truncxfsf2_i387_1"
3918   [(set (match_operand:SF 0 "memory_operand" "=m")
3919         (float_truncate:SF
3920          (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387"
3922 {
3923   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3924     return "fstp%z0\t%y0";
3925   else
3926     return "fst%z0\t%y0";
3927 }
3928   [(set_attr "type" "fmov")
3929    (set_attr "mode" "SF")])
3930
3931 (define_split
3932   [(set (match_operand:SF 0 "register_operand" "")
3933         (float_truncate:SF
3934          (match_operand:XF 1 "register_operand" "")))
3935    (clobber (match_operand:SF 2 "memory_operand" ""))]
3936   "TARGET_80387 && reload_completed"
3937   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3938    (set (match_dup 0) (match_dup 2))]
3939   "")
3940
3941 (define_split
3942   [(set (match_operand:SF 0 "memory_operand" "")
3943         (float_truncate:SF
3944          (match_operand:XF 1 "register_operand" "")))
3945    (clobber (match_operand:SF 2 "memory_operand" ""))]
3946   "TARGET_80387"
3947   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3948   "")
3949
3950 ;; Conversion from XFmode to DFmode.
3951
3952 (define_expand "truncxfdf2"
3953   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3954                    (float_truncate:DF
3955                     (match_operand:XF 1 "register_operand" "")))
3956               (clobber (match_dup 2))])]
3957   "TARGET_80387"
3958 {
3959   if (flag_unsafe_math_optimizations)
3960     {
3961       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3962       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3963       if (reg != operands[0])
3964         emit_move_insn (operands[0], reg);
3965       DONE;
3966     }
3967   else
3968     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3969 })
3970
3971 (define_insn "*truncxfdf2_mixed"
3972   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3973         (float_truncate:DF
3974          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3975    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3976   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3977 {
3978   gcc_assert (!which_alternative);
3979   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3980     return "fstp%z0\t%y0";
3981   else
3982     return "fst%z0\t%y0";
3983 }
3984   [(set_attr "type" "fmov,multi,multi,multi")
3985    (set_attr "unit" "*,i387,i387,i387")
3986    (set_attr "mode" "DF")])
3987
3988 (define_insn "truncxfdf2_i387_noop"
3989   [(set (match_operand:DF 0 "register_operand" "=f")
3990         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3991   "TARGET_80387 && flag_unsafe_math_optimizations"
3992 {
3993   return output_387_reg_move (insn, operands);
3994 }
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "DF")])
3997
3998 (define_insn "*truncxfdf2_i387"
3999   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4000         (float_truncate:DF
4001          (match_operand:XF 1 "register_operand" "f,f,f")))
4002    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4003   "TARGET_80387"
4004 {
4005   gcc_assert (!which_alternative);
4006   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4007     return "fstp%z0\t%y0";
4008   else
4009     return "fst%z0\t%y0";
4010 }
4011   [(set_attr "type" "fmov,multi,multi")
4012    (set_attr "unit" "*,i387,i387")
4013    (set_attr "mode" "DF")])
4014
4015 (define_insn "*truncxfdf2_i387_1"
4016   [(set (match_operand:DF 0 "memory_operand" "=m")
4017         (float_truncate:DF
4018           (match_operand:XF 1 "register_operand" "f")))]
4019   "TARGET_80387"
4020 {
4021   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022     return "fstp%z0\t%y0";
4023   else
4024     return "fst%z0\t%y0";
4025 }
4026   [(set_attr "type" "fmov")
4027    (set_attr "mode" "DF")])
4028
4029 (define_split
4030   [(set (match_operand:DF 0 "register_operand" "")
4031         (float_truncate:DF
4032          (match_operand:XF 1 "register_operand" "")))
4033    (clobber (match_operand:DF 2 "memory_operand" ""))]
4034   "TARGET_80387 && reload_completed"
4035   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4036    (set (match_dup 0) (match_dup 2))]
4037   "")
4038
4039 (define_split
4040   [(set (match_operand:DF 0 "memory_operand" "")
4041         (float_truncate:DF
4042          (match_operand:XF 1 "register_operand" "")))
4043    (clobber (match_operand:DF 2 "memory_operand" ""))]
4044   "TARGET_80387"
4045   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4046   "")
4047 \f
4048 ;; Signed conversion to DImode.
4049
4050 (define_expand "fix_truncxfdi2"
4051   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4052                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4053               (clobber (reg:CC FLAGS_REG))])]
4054   "TARGET_80387"
4055 {
4056   if (TARGET_FISTTP)
4057    {
4058      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4059      DONE;
4060    }
4061 })
4062
4063 (define_expand "fix_trunc<mode>di2"
4064   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4065                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4066               (clobber (reg:CC FLAGS_REG))])]
4067   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4068 {
4069   if (TARGET_FISTTP
4070       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4071    {
4072      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4073      DONE;
4074    }
4075   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4076    {
4077      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4078      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4079      if (out != operands[0])
4080         emit_move_insn (operands[0], out);
4081      DONE;
4082    }
4083 })
4084
4085 ;; Signed conversion to SImode.
4086
4087 (define_expand "fix_truncxfsi2"
4088   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4089                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4090               (clobber (reg:CC FLAGS_REG))])]
4091   "TARGET_80387"
4092 {
4093   if (TARGET_FISTTP)
4094    {
4095      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4096      DONE;
4097    }
4098 })
4099
4100 (define_expand "fix_trunc<mode>si2"
4101   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4102                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4103               (clobber (reg:CC FLAGS_REG))])]
4104   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4105 {
4106   if (TARGET_FISTTP
4107       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4108    {
4109      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4110      DONE;
4111    }
4112   if (SSE_FLOAT_MODE_P (<MODE>mode))
4113    {
4114      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4115      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4116      if (out != operands[0])
4117         emit_move_insn (operands[0], out);
4118      DONE;
4119    }
4120 })
4121
4122 ;; Signed conversion to HImode.
4123
4124 (define_expand "fix_trunc<mode>hi2"
4125   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4126                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4127               (clobber (reg:CC FLAGS_REG))])]
4128   "TARGET_80387
4129    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4130 {
4131   if (TARGET_FISTTP)
4132    {
4133      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4134      DONE;
4135    }
4136 })
4137
4138 ;; When SSE is available, it is always faster to use it!
4139 (define_insn "fix_truncsfdi_sse"
4140   [(set (match_operand:DI 0 "register_operand" "=r,r")
4141         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4142   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4143   "cvttss2si{q}\t{%1, %0|%0, %1}"
4144   [(set_attr "type" "sseicvt")
4145    (set_attr "mode" "SF")
4146    (set_attr "athlon_decode" "double,vector")])
4147
4148 (define_insn "fix_truncdfdi_sse"
4149   [(set (match_operand:DI 0 "register_operand" "=r,r")
4150         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4151   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4152   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4153   [(set_attr "type" "sseicvt")
4154    (set_attr "mode" "DF")
4155    (set_attr "athlon_decode" "double,vector")])
4156
4157 (define_insn "fix_truncsfsi_sse"
4158   [(set (match_operand:SI 0 "register_operand" "=r,r")
4159         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4160   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4161   "cvttss2si\t{%1, %0|%0, %1}"
4162   [(set_attr "type" "sseicvt")
4163    (set_attr "mode" "DF")
4164    (set_attr "athlon_decode" "double,vector")])
4165
4166 (define_insn "fix_truncdfsi_sse"
4167   [(set (match_operand:SI 0 "register_operand" "=r,r")
4168         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4169   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4170   "cvttsd2si\t{%1, %0|%0, %1}"
4171   [(set_attr "type" "sseicvt")
4172    (set_attr "mode" "DF")
4173    (set_attr "athlon_decode" "double,vector")])
4174
4175 ;; Avoid vector decoded forms of the instruction.
4176 (define_peephole2
4177   [(match_scratch:DF 2 "Y")
4178    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4179         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4180   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4181   [(set (match_dup 2) (match_dup 1))
4182    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4183   "")
4184
4185 (define_peephole2
4186   [(match_scratch:SF 2 "x")
4187    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4188         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4189   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4190   [(set (match_dup 2) (match_dup 1))
4191    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4192   "")
4193
4194 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4195   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4196         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4197   "TARGET_FISTTP
4198    && FLOAT_MODE_P (GET_MODE (operands[1]))
4199    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200          && (TARGET_64BIT || <MODE>mode != DImode))
4201         && TARGET_SSE_MATH)
4202    && !(reload_completed || reload_in_progress)"
4203   "#"
4204   "&& 1"
4205   [(const_int 0)]
4206 {
4207   if (memory_operand (operands[0], VOIDmode))
4208     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4209   else
4210     {
4211       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4212       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4213                                                             operands[1],
4214                                                             operands[2]));
4215     }
4216   DONE;
4217 }
4218   [(set_attr "type" "fisttp")
4219    (set_attr "mode" "<MODE>")])
4220
4221 (define_insn "fix_trunc<mode>_i387_fisttp"
4222   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4223         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4224    (clobber (match_scratch:XF 2 "=&1f"))]
4225   "TARGET_FISTTP
4226    && FLOAT_MODE_P (GET_MODE (operands[1]))
4227    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4228          && (TARGET_64BIT || <MODE>mode != DImode))
4229         && TARGET_SSE_MATH)"
4230   "* return output_fix_trunc (insn, operands, 1);"
4231   [(set_attr "type" "fisttp")
4232    (set_attr "mode" "<MODE>")])
4233
4234 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4235   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4236         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4237    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4238    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4239   "TARGET_FISTTP
4240    && FLOAT_MODE_P (GET_MODE (operands[1]))
4241    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4242         && (TARGET_64BIT || <MODE>mode != DImode))
4243         && TARGET_SSE_MATH)"
4244   "#"
4245   [(set_attr "type" "fisttp")
4246    (set_attr "mode" "<MODE>")])
4247
4248 (define_split
4249   [(set (match_operand:X87MODEI 0 "register_operand" "")
4250         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4251    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4252    (clobber (match_scratch 3 ""))]
4253   "reload_completed"
4254   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4255               (clobber (match_dup 3))])
4256    (set (match_dup 0) (match_dup 2))]
4257   "")
4258
4259 (define_split
4260   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4261         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4262    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4263    (clobber (match_scratch 3 ""))]
4264   "reload_completed"
4265   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4266               (clobber (match_dup 3))])]
4267   "")
4268
4269 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4270 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4271 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4272 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4273 ;; function in i386.c.
4274 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4275   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4276         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4277    (clobber (reg:CC FLAGS_REG))]
4278   "TARGET_80387 && !TARGET_FISTTP
4279    && FLOAT_MODE_P (GET_MODE (operands[1]))
4280    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4281          && (TARGET_64BIT || <MODE>mode != DImode))
4282    && !(reload_completed || reload_in_progress)"
4283   "#"
4284   "&& 1"
4285   [(const_int 0)]
4286 {
4287   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4288
4289   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4290   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4291   if (memory_operand (operands[0], VOIDmode))
4292     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4293                                          operands[2], operands[3]));
4294   else
4295     {
4296       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4297       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4298                                                      operands[2], operands[3],
4299                                                      operands[4]));
4300     }
4301   DONE;
4302 }
4303   [(set_attr "type" "fistp")
4304    (set_attr "i387_cw" "trunc")
4305    (set_attr "mode" "<MODE>")])
4306
4307 (define_insn "fix_truncdi_i387"
4308   [(set (match_operand:DI 0 "memory_operand" "=m")
4309         (fix:DI (match_operand 1 "register_operand" "f")))
4310    (use (match_operand:HI 2 "memory_operand" "m"))
4311    (use (match_operand:HI 3 "memory_operand" "m"))
4312    (clobber (match_scratch:XF 4 "=&1f"))]
4313   "TARGET_80387 && !TARGET_FISTTP
4314    && FLOAT_MODE_P (GET_MODE (operands[1]))
4315    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4316   "* return output_fix_trunc (insn, operands, 0);"
4317   [(set_attr "type" "fistp")
4318    (set_attr "i387_cw" "trunc")
4319    (set_attr "mode" "DI")])
4320
4321 (define_insn "fix_truncdi_i387_with_temp"
4322   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4323         (fix:DI (match_operand 1 "register_operand" "f,f")))
4324    (use (match_operand:HI 2 "memory_operand" "m,m"))
4325    (use (match_operand:HI 3 "memory_operand" "m,m"))
4326    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4327    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4328   "TARGET_80387 && !TARGET_FISTTP
4329    && FLOAT_MODE_P (GET_MODE (operands[1]))
4330    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4331   "#"
4332   [(set_attr "type" "fistp")
4333    (set_attr "i387_cw" "trunc")
4334    (set_attr "mode" "DI")])
4335
4336 (define_split 
4337   [(set (match_operand:DI 0 "register_operand" "")
4338         (fix:DI (match_operand 1 "register_operand" "")))
4339    (use (match_operand:HI 2 "memory_operand" ""))
4340    (use (match_operand:HI 3 "memory_operand" ""))
4341    (clobber (match_operand:DI 4 "memory_operand" ""))
4342    (clobber (match_scratch 5 ""))]
4343   "reload_completed"
4344   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4345               (use (match_dup 2))
4346               (use (match_dup 3))
4347               (clobber (match_dup 5))])
4348    (set (match_dup 0) (match_dup 4))]
4349   "")
4350
4351 (define_split 
4352   [(set (match_operand:DI 0 "memory_operand" "")
4353         (fix:DI (match_operand 1 "register_operand" "")))
4354    (use (match_operand:HI 2 "memory_operand" ""))
4355    (use (match_operand:HI 3 "memory_operand" ""))
4356    (clobber (match_operand:DI 4 "memory_operand" ""))
4357    (clobber (match_scratch 5 ""))]
4358   "reload_completed"
4359   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4360               (use (match_dup 2))
4361               (use (match_dup 3))
4362               (clobber (match_dup 5))])]
4363   "")
4364
4365 (define_insn "fix_trunc<mode>_i387"
4366   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4367         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4368    (use (match_operand:HI 2 "memory_operand" "m"))
4369    (use (match_operand:HI 3 "memory_operand" "m"))]
4370   "TARGET_80387 && !TARGET_FISTTP
4371    && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "* return output_fix_trunc (insn, operands, 0);"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "<MODE>")])
4377
4378 (define_insn "fix_trunc<mode>_i387_with_temp"
4379   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4380         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4381    (use (match_operand:HI 2 "memory_operand" "m,m"))
4382    (use (match_operand:HI 3 "memory_operand" "m,m"))
4383    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4384   "TARGET_80387 && !TARGET_FISTTP
4385    && FLOAT_MODE_P (GET_MODE (operands[1]))
4386    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387   "#"
4388   [(set_attr "type" "fistp")
4389    (set_attr "i387_cw" "trunc")
4390    (set_attr "mode" "<MODE>")])
4391
4392 (define_split 
4393   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4394         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4398   "reload_completed"
4399   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4400               (use (match_dup 2))
4401               (use (match_dup 3))])
4402    (set (match_dup 0) (match_dup 4))]
4403   "")
4404
4405 (define_split 
4406   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4407         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4408    (use (match_operand:HI 2 "memory_operand" ""))
4409    (use (match_operand:HI 3 "memory_operand" ""))
4410    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4411   "reload_completed"
4412   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4413               (use (match_dup 2))
4414               (use (match_dup 3))])]
4415   "")
4416
4417 (define_insn "x86_fnstcw_1"
4418   [(set (match_operand:HI 0 "memory_operand" "=m")
4419         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4420   "TARGET_80387"
4421   "fnstcw\t%0"
4422   [(set_attr "length" "2")
4423    (set_attr "mode" "HI")
4424    (set_attr "unit" "i387")])
4425
4426 (define_insn "x86_fldcw_1"
4427   [(set (reg:HI FPSR_REG)
4428         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4429   "TARGET_80387"
4430   "fldcw\t%0"
4431   [(set_attr "length" "2")
4432    (set_attr "mode" "HI")
4433    (set_attr "unit" "i387")
4434    (set_attr "athlon_decode" "vector")])
4435 \f
4436 ;; Conversion between fixed point and floating point.
4437
4438 ;; Even though we only accept memory inputs, the backend _really_
4439 ;; wants to be able to do this between registers.
4440
4441 (define_expand "floathisf2"
4442   [(set (match_operand:SF 0 "register_operand" "")
4443         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4444   "TARGET_80387 || TARGET_SSE_MATH"
4445 {
4446   if (TARGET_SSE_MATH)
4447     {
4448       emit_insn (gen_floatsisf2 (operands[0],
4449                                  convert_to_mode (SImode, operands[1], 0)));
4450       DONE;
4451     }
4452 })
4453
4454 (define_insn "*floathisf2_i387"
4455   [(set (match_operand:SF 0 "register_operand" "=f,f")
4456         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4457   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4458   "@
4459    fild%z1\t%1
4460    #"
4461   [(set_attr "type" "fmov,multi")
4462    (set_attr "mode" "SF")
4463    (set_attr "unit" "*,i387")
4464    (set_attr "fp_int_src" "true")])
4465
4466 (define_expand "floatsisf2"
4467   [(set (match_operand:SF 0 "register_operand" "")
4468         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4469   "TARGET_80387 || TARGET_SSE_MATH"
4470   "")
4471
4472 (define_insn "*floatsisf2_mixed"
4473   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4474         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4475   "TARGET_MIX_SSE_I387"
4476   "@
4477    fild%z1\t%1
4478    #
4479    cvtsi2ss\t{%1, %0|%0, %1}
4480    cvtsi2ss\t{%1, %0|%0, %1}"
4481   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4482    (set_attr "mode" "SF")
4483    (set_attr "unit" "*,i387,*,*")
4484    (set_attr "athlon_decode" "*,*,vector,double")
4485    (set_attr "fp_int_src" "true")])
4486
4487 (define_insn "*floatsisf2_sse"
4488   [(set (match_operand:SF 0 "register_operand" "=x,x")
4489         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4490   "TARGET_SSE_MATH"
4491   "cvtsi2ss\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "sseicvt")
4493    (set_attr "mode" "SF")
4494    (set_attr "athlon_decode" "vector,double")
4495    (set_attr "fp_int_src" "true")])
4496
4497 (define_insn "*floatsisf2_i387"
4498   [(set (match_operand:SF 0 "register_operand" "=f,f")
4499         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4500   "TARGET_80387"
4501   "@
4502    fild%z1\t%1
4503    #"
4504   [(set_attr "type" "fmov,multi")
4505    (set_attr "mode" "SF")
4506    (set_attr "unit" "*,i387")
4507    (set_attr "fp_int_src" "true")])
4508
4509 (define_expand "floatdisf2"
4510   [(set (match_operand:SF 0 "register_operand" "")
4511         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4512   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4513   "")
4514
4515 (define_insn "*floatdisf2_mixed"
4516   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4517         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4518   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4519   "@
4520    fild%z1\t%1
4521    #
4522    cvtsi2ss{q}\t{%1, %0|%0, %1}
4523    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4524   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4525    (set_attr "mode" "SF")
4526    (set_attr "unit" "*,i387,*,*")
4527    (set_attr "athlon_decode" "*,*,vector,double")
4528    (set_attr "fp_int_src" "true")])
4529
4530 (define_insn "*floatdisf2_sse"
4531   [(set (match_operand:SF 0 "register_operand" "=x,x")
4532         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4533   "TARGET_64BIT && TARGET_SSE_MATH"
4534   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4535   [(set_attr "type" "sseicvt")
4536    (set_attr "mode" "SF")
4537    (set_attr "athlon_decode" "vector,double")
4538    (set_attr "fp_int_src" "true")])
4539
4540 (define_insn "*floatdisf2_i387"
4541   [(set (match_operand:SF 0 "register_operand" "=f,f")
4542         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4543   "TARGET_80387"
4544   "@
4545    fild%z1\t%1
4546    #"
4547   [(set_attr "type" "fmov,multi")
4548    (set_attr "mode" "SF")
4549    (set_attr "unit" "*,i387")
4550    (set_attr "fp_int_src" "true")])
4551
4552 (define_expand "floathidf2"
4553   [(set (match_operand:DF 0 "register_operand" "")
4554         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4555   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4556 {
4557   if (TARGET_SSE2 && TARGET_SSE_MATH)
4558     {
4559       emit_insn (gen_floatsidf2 (operands[0],
4560                                  convert_to_mode (SImode, operands[1], 0)));
4561       DONE;
4562     }
4563 })
4564
4565 (define_insn "*floathidf2_i387"
4566   [(set (match_operand:DF 0 "register_operand" "=f,f")
4567         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4568   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4569   "@
4570    fild%z1\t%1
4571    #"
4572   [(set_attr "type" "fmov,multi")
4573    (set_attr "mode" "DF")
4574    (set_attr "unit" "*,i387")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_expand "floatsidf2"
4578   [(set (match_operand:DF 0 "register_operand" "")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4581   "")
4582
4583 (define_insn "*floatsidf2_mixed"
4584   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587   "@
4588    fild%z1\t%1
4589    #
4590    cvtsi2sd\t{%1, %0|%0, %1}
4591    cvtsi2sd\t{%1, %0|%0, %1}"
4592   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593    (set_attr "mode" "DF")
4594    (set_attr "unit" "*,i387,*,*")
4595    (set_attr "athlon_decode" "*,*,double,direct")
4596    (set_attr "fp_int_src" "true")])
4597
4598 (define_insn "*floatsidf2_sse"
4599   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4600         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4601   "TARGET_SSE2 && TARGET_SSE_MATH"
4602   "cvtsi2sd\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "athlon_decode" "double,direct")
4606    (set_attr "fp_int_src" "true")])
4607
4608 (define_insn "*floatsidf2_i387"
4609   [(set (match_operand:DF 0 "register_operand" "=f,f")
4610         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4611   "TARGET_80387"
4612   "@
4613    fild%z1\t%1
4614    #"
4615   [(set_attr "type" "fmov,multi")
4616    (set_attr "mode" "DF")
4617    (set_attr "unit" "*,i387")
4618    (set_attr "fp_int_src" "true")])
4619
4620 (define_expand "floatdidf2"
4621   [(set (match_operand:DF 0 "register_operand" "")
4622         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4623   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4624   "")
4625
4626 (define_insn "*floatdidf2_mixed"
4627   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4628         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4629   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4630   "@
4631    fild%z1\t%1
4632    #
4633    cvtsi2sd{q}\t{%1, %0|%0, %1}
4634    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4635   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4636    (set_attr "mode" "DF")
4637    (set_attr "unit" "*,i387,*,*")
4638    (set_attr "athlon_decode" "*,*,double,direct")
4639    (set_attr "fp_int_src" "true")])
4640
4641 (define_insn "*floatdidf2_sse"
4642   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4643         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4644   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4645   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4646   [(set_attr "type" "sseicvt")
4647    (set_attr "mode" "DF")
4648    (set_attr "athlon_decode" "double,direct")
4649    (set_attr "fp_int_src" "true")])
4650
4651 (define_insn "*floatdidf2_i387"
4652   [(set (match_operand:DF 0 "register_operand" "=f,f")
4653         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4654   "TARGET_80387"
4655   "@
4656    fild%z1\t%1
4657    #"
4658   [(set_attr "type" "fmov,multi")
4659    (set_attr "mode" "DF")
4660    (set_attr "unit" "*,i387")
4661    (set_attr "fp_int_src" "true")])
4662
4663 (define_insn "floathixf2"
4664   [(set (match_operand:XF 0 "register_operand" "=f,f")
4665         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4666   "TARGET_80387"
4667   "@
4668    fild%z1\t%1
4669    #"
4670   [(set_attr "type" "fmov,multi")
4671    (set_attr "mode" "XF")
4672    (set_attr "unit" "*,i387")
4673    (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "floatsixf2"
4676   [(set (match_operand:XF 0 "register_operand" "=f,f")
4677         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4678   "TARGET_80387"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "XF")
4684    (set_attr "unit" "*,i387")
4685    (set_attr "fp_int_src" "true")])
4686
4687 (define_insn "floatdixf2"
4688   [(set (match_operand:XF 0 "register_operand" "=f,f")
4689         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4690   "TARGET_80387"
4691   "@
4692    fild%z1\t%1
4693    #"
4694   [(set_attr "type" "fmov,multi")
4695    (set_attr "mode" "XF")
4696    (set_attr "unit" "*,i387")
4697    (set_attr "fp_int_src" "true")])
4698
4699 ;; %%% Kill these when reload knows how to do it.
4700 (define_split
4701   [(set (match_operand 0 "fp_register_operand" "")
4702         (float (match_operand 1 "register_operand" "")))]
4703   "reload_completed
4704    && TARGET_80387
4705    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4706   [(const_int 0)]
4707 {
4708   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4709   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4710   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4711   ix86_free_from_memory (GET_MODE (operands[1]));
4712   DONE;
4713 })
4714
4715 (define_expand "floatunssisf2"
4716   [(use (match_operand:SF 0 "register_operand" ""))
4717    (use (match_operand:SI 1 "register_operand" ""))]
4718   "!TARGET_64BIT && TARGET_SSE_MATH"
4719   "x86_emit_floatuns (operands); DONE;")
4720
4721 (define_expand "floatunsdisf2"
4722   [(use (match_operand:SF 0 "register_operand" ""))
4723    (use (match_operand:DI 1 "register_operand" ""))]
4724   "TARGET_64BIT && TARGET_SSE_MATH"
4725   "x86_emit_floatuns (operands); DONE;")
4726
4727 (define_expand "floatunsdidf2"
4728   [(use (match_operand:DF 0 "register_operand" ""))
4729    (use (match_operand:DI 1 "register_operand" ""))]
4730   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731   "x86_emit_floatuns (operands); DONE;")
4732 \f
4733 ;; SSE extract/set expanders
4734
4735 \f
4736 ;; Add instructions
4737
4738 ;; %%% splits for addditi3
4739
4740 (define_expand "addti3"
4741   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4742         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4743                  (match_operand:TI 2 "x86_64_general_operand" "")))
4744    (clobber (reg:CC FLAGS_REG))]
4745   "TARGET_64BIT"
4746   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4747
4748 (define_insn "*addti3_1"
4749   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4750         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4751                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4752    (clobber (reg:CC FLAGS_REG))]
4753   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4754   "#")
4755
4756 (define_split
4757   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759                  (match_operand:TI 2 "general_operand" "")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "TARGET_64BIT && reload_completed"
4762   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4763                                           UNSPEC_ADD_CARRY))
4764               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4765    (parallel [(set (match_dup 3)
4766                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4767                                      (match_dup 4))
4768                             (match_dup 5)))
4769               (clobber (reg:CC FLAGS_REG))])]
4770   "split_ti (operands+0, 1, operands+0, operands+3);
4771    split_ti (operands+1, 1, operands+1, operands+4);
4772    split_ti (operands+2, 1, operands+2, operands+5);")
4773
4774 ;; %%% splits for addsidi3
4775 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4776 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4777 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4778
4779 (define_expand "adddi3"
4780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4781         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4782                  (match_operand:DI 2 "x86_64_general_operand" "")))
4783    (clobber (reg:CC FLAGS_REG))]
4784   ""
4785   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4786
4787 (define_insn "*adddi3_1"
4788   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4789         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4790                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4791    (clobber (reg:CC FLAGS_REG))]
4792   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4793   "#")
4794
4795 (define_split
4796   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798                  (match_operand:DI 2 "general_operand" "")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   "!TARGET_64BIT && reload_completed"
4801   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4802                                           UNSPEC_ADD_CARRY))
4803               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4804    (parallel [(set (match_dup 3)
4805                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4806                                      (match_dup 4))
4807                             (match_dup 5)))
4808               (clobber (reg:CC FLAGS_REG))])]
4809   "split_di (operands+0, 1, operands+0, operands+3);
4810    split_di (operands+1, 1, operands+1, operands+4);
4811    split_di (operands+2, 1, operands+2, operands+5);")
4812
4813 (define_insn "adddi3_carry_rex64"
4814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4815           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4816                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4817                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4818    (clobber (reg:CC FLAGS_REG))]
4819   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4820   "adc{q}\t{%2, %0|%0, %2}"
4821   [(set_attr "type" "alu")
4822    (set_attr "pent_pair" "pu")
4823    (set_attr "mode" "DI")])
4824
4825 (define_insn "*adddi3_cc_rex64"
4826   [(set (reg:CC FLAGS_REG)
4827         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4828                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4829                    UNSPEC_ADD_CARRY))
4830    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831         (plus:DI (match_dup 1) (match_dup 2)))]
4832   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4833   "add{q}\t{%2, %0|%0, %2}"
4834   [(set_attr "type" "alu")
4835    (set_attr "mode" "DI")])
4836
4837 (define_insn "addqi3_carry"
4838   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4839           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4840                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4841                    (match_operand:QI 2 "general_operand" "qi,qm")))
4842    (clobber (reg:CC FLAGS_REG))]
4843   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4844   "adc{b}\t{%2, %0|%0, %2}"
4845   [(set_attr "type" "alu")
4846    (set_attr "pent_pair" "pu")
4847    (set_attr "mode" "QI")])
4848
4849 (define_insn "addhi3_carry"
4850   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4851           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4852                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4853                    (match_operand:HI 2 "general_operand" "ri,rm")))
4854    (clobber (reg:CC FLAGS_REG))]
4855   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4856   "adc{w}\t{%2, %0|%0, %2}"
4857   [(set_attr "type" "alu")
4858    (set_attr "pent_pair" "pu")
4859    (set_attr "mode" "HI")])
4860
4861 (define_insn "addsi3_carry"
4862   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4863           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4864                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4865                    (match_operand:SI 2 "general_operand" "ri,rm")))
4866    (clobber (reg:CC FLAGS_REG))]
4867   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4868   "adc{l}\t{%2, %0|%0, %2}"
4869   [(set_attr "type" "alu")
4870    (set_attr "pent_pair" "pu")
4871    (set_attr "mode" "SI")])
4872
4873 (define_insn "*addsi3_carry_zext"
4874   [(set (match_operand:DI 0 "register_operand" "=r")
4875           (zero_extend:DI 
4876             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4877                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4878                      (match_operand:SI 2 "general_operand" "rim"))))
4879    (clobber (reg:CC FLAGS_REG))]
4880   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4881   "adc{l}\t{%2, %k0|%k0, %2}"
4882   [(set_attr "type" "alu")
4883    (set_attr "pent_pair" "pu")
4884    (set_attr "mode" "SI")])
4885
4886 (define_insn "*addsi3_cc"
4887   [(set (reg:CC FLAGS_REG)
4888         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4889                     (match_operand:SI 2 "general_operand" "ri,rm")]
4890                    UNSPEC_ADD_CARRY))
4891    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4892         (plus:SI (match_dup 1) (match_dup 2)))]
4893   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4894   "add{l}\t{%2, %0|%0, %2}"
4895   [(set_attr "type" "alu")
4896    (set_attr "mode" "SI")])
4897
4898 (define_insn "addqi3_cc"
4899   [(set (reg:CC FLAGS_REG)
4900         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4901                     (match_operand:QI 2 "general_operand" "qi,qm")]
4902                    UNSPEC_ADD_CARRY))
4903    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4904         (plus:QI (match_dup 1) (match_dup 2)))]
4905   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4906   "add{b}\t{%2, %0|%0, %2}"
4907   [(set_attr "type" "alu")
4908    (set_attr "mode" "QI")])
4909
4910 (define_expand "addsi3"
4911   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4912                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4913                             (match_operand:SI 2 "general_operand" "")))
4914               (clobber (reg:CC FLAGS_REG))])]
4915   ""
4916   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4917
4918 (define_insn "*lea_1"
4919   [(set (match_operand:SI 0 "register_operand" "=r")
4920         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4921   "!TARGET_64BIT"
4922   "lea{l}\t{%a1, %0|%0, %a1}"
4923   [(set_attr "type" "lea")
4924    (set_attr "mode" "SI")])
4925
4926 (define_insn "*lea_1_rex64"
4927   [(set (match_operand:SI 0 "register_operand" "=r")
4928         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4929   "TARGET_64BIT"
4930   "lea{l}\t{%a1, %0|%0, %a1}"
4931   [(set_attr "type" "lea")
4932    (set_attr "mode" "SI")])
4933
4934 (define_insn "*lea_1_zext"
4935   [(set (match_operand:DI 0 "register_operand" "=r")
4936         (zero_extend:DI
4937          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4938   "TARGET_64BIT"
4939   "lea{l}\t{%a1, %k0|%k0, %a1}"
4940   [(set_attr "type" "lea")
4941    (set_attr "mode" "SI")])
4942
4943 (define_insn "*lea_2_rex64"
4944   [(set (match_operand:DI 0 "register_operand" "=r")
4945         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4946   "TARGET_64BIT"
4947   "lea{q}\t{%a1, %0|%0, %a1}"
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "DI")])
4950
4951 ;; The lea patterns for non-Pmodes needs to be matched by several
4952 ;; insns converted to real lea by splitters.
4953
4954 (define_insn_and_split "*lea_general_1"
4955   [(set (match_operand 0 "register_operand" "=r")
4956         (plus (plus (match_operand 1 "index_register_operand" "l")
4957                     (match_operand 2 "register_operand" "r"))
4958               (match_operand 3 "immediate_operand" "i")))]
4959   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4960     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4961    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4962    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4963    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4964    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4965        || GET_MODE (operands[3]) == VOIDmode)"
4966   "#"
4967   "&& reload_completed"
4968   [(const_int 0)]
4969 {
4970   rtx pat;
4971   operands[0] = gen_lowpart (SImode, operands[0]);
4972   operands[1] = gen_lowpart (Pmode, operands[1]);
4973   operands[2] = gen_lowpart (Pmode, operands[2]);
4974   operands[3] = gen_lowpart (Pmode, operands[3]);
4975   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4976                       operands[3]);
4977   if (Pmode != SImode)
4978     pat = gen_rtx_SUBREG (SImode, pat, 0);
4979   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4980   DONE;
4981 }
4982   [(set_attr "type" "lea")
4983    (set_attr "mode" "SI")])
4984
4985 (define_insn_and_split "*lea_general_1_zext"
4986   [(set (match_operand:DI 0 "register_operand" "=r")
4987         (zero_extend:DI
4988           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4989                             (match_operand:SI 2 "register_operand" "r"))
4990                    (match_operand:SI 3 "immediate_operand" "i"))))]
4991   "TARGET_64BIT"
4992   "#"
4993   "&& reload_completed"
4994   [(set (match_dup 0)
4995         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4996                                                      (match_dup 2))
4997                                             (match_dup 3)) 0)))]
4998 {
4999   operands[1] = gen_lowpart (Pmode, operands[1]);
5000   operands[2] = gen_lowpart (Pmode, operands[2]);
5001   operands[3] = gen_lowpart (Pmode, operands[3]);
5002 }
5003   [(set_attr "type" "lea")
5004    (set_attr "mode" "SI")])
5005
5006 (define_insn_and_split "*lea_general_2"
5007   [(set (match_operand 0 "register_operand" "=r")
5008         (plus (mult (match_operand 1 "index_register_operand" "l")
5009                     (match_operand 2 "const248_operand" "i"))
5010               (match_operand 3 "nonmemory_operand" "ri")))]
5011   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5012     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5013    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5014    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5015    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5016        || GET_MODE (operands[3]) == VOIDmode)"
5017   "#"
5018   "&& reload_completed"
5019   [(const_int 0)]
5020 {
5021   rtx pat;
5022   operands[0] = gen_lowpart (SImode, operands[0]);
5023   operands[1] = gen_lowpart (Pmode, operands[1]);
5024   operands[3] = gen_lowpart (Pmode, operands[3]);
5025   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5026                       operands[3]);
5027   if (Pmode != SImode)
5028     pat = gen_rtx_SUBREG (SImode, pat, 0);
5029   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5030   DONE;
5031 }
5032   [(set_attr "type" "lea")
5033    (set_attr "mode" "SI")])
5034
5035 (define_insn_and_split "*lea_general_2_zext"
5036   [(set (match_operand:DI 0 "register_operand" "=r")
5037         (zero_extend:DI
5038           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5039                             (match_operand:SI 2 "const248_operand" "n"))
5040                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5041   "TARGET_64BIT"
5042   "#"
5043   "&& reload_completed"
5044   [(set (match_dup 0)
5045         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5046                                                      (match_dup 2))
5047                                             (match_dup 3)) 0)))]
5048 {
5049   operands[1] = gen_lowpart (Pmode, operands[1]);
5050   operands[3] = gen_lowpart (Pmode, operands[3]);
5051 }
5052   [(set_attr "type" "lea")
5053    (set_attr "mode" "SI")])
5054
5055 (define_insn_and_split "*lea_general_3"
5056   [(set (match_operand 0 "register_operand" "=r")
5057         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5058                           (match_operand 2 "const248_operand" "i"))
5059                     (match_operand 3 "register_operand" "r"))
5060               (match_operand 4 "immediate_operand" "i")))]
5061   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5062     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5063    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5064    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5065    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5066   "#"
5067   "&& reload_completed"
5068   [(const_int 0)]
5069 {
5070   rtx pat;
5071   operands[0] = gen_lowpart (SImode, operands[0]);
5072   operands[1] = gen_lowpart (Pmode, operands[1]);
5073   operands[3] = gen_lowpart (Pmode, operands[3]);
5074   operands[4] = gen_lowpart (Pmode, operands[4]);
5075   pat = gen_rtx_PLUS (Pmode,
5076                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5077                                                          operands[2]),
5078                                     operands[3]),
5079                       operands[4]);
5080   if (Pmode != SImode)
5081     pat = gen_rtx_SUBREG (SImode, pat, 0);
5082   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5083   DONE;
5084 }
5085   [(set_attr "type" "lea")
5086    (set_attr "mode" "SI")])
5087
5088 (define_insn_and_split "*lea_general_3_zext"
5089   [(set (match_operand:DI 0 "register_operand" "=r")
5090         (zero_extend:DI
5091           (plus:SI (plus:SI (mult:SI
5092                               (match_operand:SI 1 "index_register_operand" "l")
5093                               (match_operand:SI 2 "const248_operand" "n"))
5094                             (match_operand:SI 3 "register_operand" "r"))
5095                    (match_operand:SI 4 "immediate_operand" "i"))))]
5096   "TARGET_64BIT"
5097   "#"
5098   "&& reload_completed"
5099   [(set (match_dup 0)
5100         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5101                                                               (match_dup 2))
5102                                                      (match_dup 3))
5103                                             (match_dup 4)) 0)))]
5104 {
5105   operands[1] = gen_lowpart (Pmode, operands[1]);
5106   operands[3] = gen_lowpart (Pmode, operands[3]);
5107   operands[4] = gen_lowpart (Pmode, operands[4]);
5108 }
5109   [(set_attr "type" "lea")
5110    (set_attr "mode" "SI")])
5111
5112 (define_insn "*adddi_1_rex64"
5113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5114         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5115                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5116    (clobber (reg:CC FLAGS_REG))]
5117   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5118 {
5119   switch (get_attr_type (insn))
5120     {
5121     case TYPE_LEA:
5122       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5123       return "lea{q}\t{%a2, %0|%0, %a2}";
5124
5125     case TYPE_INCDEC:
5126       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5127       if (operands[2] == const1_rtx)
5128         return "inc{q}\t%0";
5129       else
5130         {
5131           gcc_assert (operands[2] == constm1_rtx);
5132           return "dec{q}\t%0";
5133         }
5134
5135     default:
5136       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5137
5138       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5139          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5140       if (GET_CODE (operands[2]) == CONST_INT
5141           /* Avoid overflows.  */
5142           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5143           && (INTVAL (operands[2]) == 128
5144               || (INTVAL (operands[2]) < 0
5145                   && INTVAL (operands[2]) != -128)))
5146         {
5147           operands[2] = GEN_INT (-INTVAL (operands[2]));
5148           return "sub{q}\t{%2, %0|%0, %2}";
5149         }
5150       return "add{q}\t{%2, %0|%0, %2}";
5151     }
5152 }
5153   [(set (attr "type")
5154      (cond [(eq_attr "alternative" "2")
5155               (const_string "lea")
5156             ; Current assemblers are broken and do not allow @GOTOFF in
5157             ; ought but a memory context.
5158             (match_operand:DI 2 "pic_symbolic_operand" "")
5159               (const_string "lea")
5160             (match_operand:DI 2 "incdec_operand" "")
5161               (const_string "incdec")
5162            ]
5163            (const_string "alu")))
5164    (set_attr "mode" "DI")])
5165
5166 ;; Convert lea to the lea pattern to avoid flags dependency.
5167 (define_split
5168   [(set (match_operand:DI 0 "register_operand" "")
5169         (plus:DI (match_operand:DI 1 "register_operand" "")
5170                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5171    (clobber (reg:CC FLAGS_REG))]
5172   "TARGET_64BIT && reload_completed
5173    && true_regnum (operands[0]) != true_regnum (operands[1])"
5174   [(set (match_dup 0)
5175         (plus:DI (match_dup 1)
5176                  (match_dup 2)))]
5177   "")
5178
5179 (define_insn "*adddi_2_rex64"
5180   [(set (reg FLAGS_REG)
5181         (compare
5182           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5183                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5184           (const_int 0)))                       
5185    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5186         (plus:DI (match_dup 1) (match_dup 2)))]
5187   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5188    && ix86_binary_operator_ok (PLUS, DImode, operands)
5189    /* Current assemblers are broken and do not allow @GOTOFF in
5190       ought but a memory context.  */
5191    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5192 {
5193   switch (get_attr_type (insn))
5194     {
5195     case TYPE_INCDEC:
5196       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5197       if (operands[2] == const1_rtx)
5198         return "inc{q}\t%0";
5199       else
5200         {
5201           gcc_assert (operands[2] == constm1_rtx);
5202           return "dec{q}\t%0";
5203         }
5204
5205     default:
5206       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5207       /* ???? We ought to handle there the 32bit case too
5208          - do we need new constraint?  */
5209       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5210          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5211       if (GET_CODE (operands[2]) == CONST_INT
5212           /* Avoid overflows.  */
5213           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5214           && (INTVAL (operands[2]) == 128
5215               || (INTVAL (operands[2]) < 0
5216                   && INTVAL (operands[2]) != -128)))
5217         {
5218           operands[2] = GEN_INT (-INTVAL (operands[2]));
5219           return "sub{q}\t{%2, %0|%0, %2}";
5220         }
5221       return "add{q}\t{%2, %0|%0, %2}";
5222     }
5223 }
5224   [(set (attr "type")
5225      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5226         (const_string "incdec")
5227         (const_string "alu")))
5228    (set_attr "mode" "DI")])
5229
5230 (define_insn "*adddi_3_rex64"
5231   [(set (reg FLAGS_REG)
5232         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5233                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5234    (clobber (match_scratch:DI 0 "=r"))]
5235   "TARGET_64BIT
5236    && ix86_match_ccmode (insn, CCZmode)
5237    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5238    /* Current assemblers are broken and do not allow @GOTOFF in
5239       ought but a memory context.  */
5240    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5241 {
5242   switch (get_attr_type (insn))
5243     {
5244     case TYPE_INCDEC:
5245       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5246       if (operands[2] == const1_rtx)
5247         return "inc{q}\t%0";
5248       else
5249         {
5250           gcc_assert (operands[2] == constm1_rtx);
5251           return "dec{q}\t%0";
5252         }
5253
5254     default:
5255       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5256       /* ???? We ought to handle there the 32bit case too
5257          - do we need new constraint?  */
5258       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5259          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5260       if (GET_CODE (operands[2]) == CONST_INT
5261           /* Avoid overflows.  */
5262           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5263           && (INTVAL (operands[2]) == 128
5264               || (INTVAL (operands[2]) < 0
5265                   && INTVAL (operands[2]) != -128)))
5266         {
5267           operands[2] = GEN_INT (-INTVAL (operands[2]));
5268           return "sub{q}\t{%2, %0|%0, %2}";
5269         }
5270       return "add{q}\t{%2, %0|%0, %2}";
5271     }
5272 }
5273   [(set (attr "type")
5274      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5275         (const_string "incdec")
5276         (const_string "alu")))
5277    (set_attr "mode" "DI")])
5278
5279 ; For comparisons against 1, -1 and 128, we may generate better code
5280 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5281 ; is matched then.  We can't accept general immediate, because for
5282 ; case of overflows,  the result is messed up.
5283 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5284 ; when negated.
5285 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5286 ; only for comparisons not depending on it.
5287 (define_insn "*adddi_4_rex64"
5288   [(set (reg FLAGS_REG)
5289         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5290                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5291    (clobber (match_scratch:DI 0 "=rm"))]
5292   "TARGET_64BIT
5293    &&  ix86_match_ccmode (insn, CCGCmode)"
5294 {
5295   switch (get_attr_type (insn))
5296     {
5297     case TYPE_INCDEC:
5298       if (operands[2] == constm1_rtx)
5299         return "inc{q}\t%0";
5300       else
5301         {
5302           gcc_assert (operands[2] == const1_rtx);
5303           return "dec{q}\t%0";
5304         }
5305
5306     default:
5307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5310       if ((INTVAL (operands[2]) == -128
5311            || (INTVAL (operands[2]) > 0
5312                && INTVAL (operands[2]) != 128))
5313           /* Avoid overflows.  */
5314           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5315         return "sub{q}\t{%2, %0|%0, %2}";
5316       operands[2] = GEN_INT (-INTVAL (operands[2]));
5317       return "add{q}\t{%2, %0|%0, %2}";
5318     }
5319 }
5320   [(set (attr "type")
5321      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5322         (const_string "incdec")
5323         (const_string "alu")))
5324    (set_attr "mode" "DI")])
5325
5326 (define_insn "*adddi_5_rex64"
5327   [(set (reg FLAGS_REG)
5328         (compare
5329           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5330                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5331           (const_int 0)))                       
5332    (clobber (match_scratch:DI 0 "=r"))]
5333   "TARGET_64BIT
5334    && ix86_match_ccmode (insn, CCGOCmode)
5335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5336    /* Current assemblers are broken and do not allow @GOTOFF in
5337       ought but a memory context.  */
5338    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5339 {
5340   switch (get_attr_type (insn))
5341     {
5342     case TYPE_INCDEC:
5343       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5344       if (operands[2] == const1_rtx)
5345         return "inc{q}\t%0";
5346       else
5347         {
5348           gcc_assert (operands[2] == constm1_rtx);
5349           return "dec{q}\t%0";
5350         }
5351
5352     default:
5353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5355          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5356       if (GET_CODE (operands[2]) == CONST_INT
5357           /* Avoid overflows.  */
5358           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5359           && (INTVAL (operands[2]) == 128
5360               || (INTVAL (operands[2]) < 0
5361                   && INTVAL (operands[2]) != -128)))
5362         {
5363           operands[2] = GEN_INT (-INTVAL (operands[2]));
5364           return "sub{q}\t{%2, %0|%0, %2}";
5365         }
5366       return "add{q}\t{%2, %0|%0, %2}";
5367     }
5368 }
5369   [(set (attr "type")
5370      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5371         (const_string "incdec")
5372         (const_string "alu")))
5373    (set_attr "mode" "DI")])
5374
5375
5376 (define_insn "*addsi_1"
5377   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5378         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5379                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5380    (clobber (reg:CC FLAGS_REG))]
5381   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5382 {
5383   switch (get_attr_type (insn))
5384     {
5385     case TYPE_LEA:
5386       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5387       return "lea{l}\t{%a2, %0|%0, %a2}";
5388
5389     case TYPE_INCDEC:
5390       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5391       if (operands[2] == const1_rtx)
5392         return "inc{l}\t%0";
5393       else
5394         {
5395           gcc_assert (operands[2] == constm1_rtx);
5396           return "dec{l}\t%0";
5397         }
5398
5399     default:
5400       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401
5402       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5403          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5404       if (GET_CODE (operands[2]) == CONST_INT
5405           && (INTVAL (operands[2]) == 128
5406               || (INTVAL (operands[2]) < 0
5407                   && INTVAL (operands[2]) != -128)))
5408         {
5409           operands[2] = GEN_INT (-INTVAL (operands[2]));
5410           return "sub{l}\t{%2, %0|%0, %2}";
5411         }
5412       return "add{l}\t{%2, %0|%0, %2}";
5413     }
5414 }
5415   [(set (attr "type")
5416      (cond [(eq_attr "alternative" "2")
5417               (const_string "lea")
5418             ; Current assemblers are broken and do not allow @GOTOFF in
5419             ; ought but a memory context.
5420             (match_operand:SI 2 "pic_symbolic_operand" "")
5421               (const_string "lea")
5422             (match_operand:SI 2 "incdec_operand" "")
5423               (const_string "incdec")
5424            ]
5425            (const_string "alu")))
5426    (set_attr "mode" "SI")])
5427
5428 ;; Convert lea to the lea pattern to avoid flags dependency.
5429 (define_split
5430   [(set (match_operand 0 "register_operand" "")
5431         (plus (match_operand 1 "register_operand" "")
5432               (match_operand 2 "nonmemory_operand" "")))
5433    (clobber (reg:CC FLAGS_REG))]
5434   "reload_completed
5435    && true_regnum (operands[0]) != true_regnum (operands[1])"
5436   [(const_int 0)]
5437 {
5438   rtx pat;
5439   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5440      may confuse gen_lowpart.  */
5441   if (GET_MODE (operands[0]) != Pmode)
5442     {
5443       operands[1] = gen_lowpart (Pmode, operands[1]);
5444       operands[2] = gen_lowpart (Pmode, operands[2]);
5445     }
5446   operands[0] = gen_lowpart (SImode, operands[0]);
5447   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5448   if (Pmode != SImode)
5449     pat = gen_rtx_SUBREG (SImode, pat, 0);
5450   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5451   DONE;
5452 })
5453
5454 ;; It may seem that nonimmediate operand is proper one for operand 1.
5455 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5456 ;; we take care in ix86_binary_operator_ok to not allow two memory
5457 ;; operands so proper swapping will be done in reload.  This allow
5458 ;; patterns constructed from addsi_1 to match.
5459 (define_insn "addsi_1_zext"
5460   [(set (match_operand:DI 0 "register_operand" "=r,r")
5461         (zero_extend:DI
5462           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5463                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5464    (clobber (reg:CC FLAGS_REG))]
5465   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5466 {
5467   switch (get_attr_type (insn))
5468     {
5469     case TYPE_LEA:
5470       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5471       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5472
5473     case TYPE_INCDEC:
5474       if (operands[2] == const1_rtx)
5475         return "inc{l}\t%k0";
5476       else
5477         {
5478           gcc_assert (operands[2] == constm1_rtx);
5479           return "dec{l}\t%k0";
5480         }
5481
5482     default:
5483       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5484          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5485       if (GET_CODE (operands[2]) == CONST_INT
5486           && (INTVAL (operands[2]) == 128
5487               || (INTVAL (operands[2]) < 0
5488                   && INTVAL (operands[2]) != -128)))
5489         {
5490           operands[2] = GEN_INT (-INTVAL (operands[2]));
5491           return "sub{l}\t{%2, %k0|%k0, %2}";
5492         }
5493       return "add{l}\t{%2, %k0|%k0, %2}";
5494     }
5495 }
5496   [(set (attr "type")
5497      (cond [(eq_attr "alternative" "1")
5498               (const_string "lea")
5499             ; Current assemblers are broken and do not allow @GOTOFF in
5500             ; ought but a memory context.
5501             (match_operand:SI 2 "pic_symbolic_operand" "")
5502               (const_string "lea")
5503             (match_operand:SI 2 "incdec_operand" "")
5504               (const_string "incdec")
5505            ]
5506            (const_string "alu")))
5507    (set_attr "mode" "SI")])
5508
5509 ;; Convert lea to the lea pattern to avoid flags dependency.
5510 (define_split
5511   [(set (match_operand:DI 0 "register_operand" "")
5512         (zero_extend:DI
5513           (plus:SI (match_operand:SI 1 "register_operand" "")
5514                    (match_operand:SI 2 "nonmemory_operand" ""))))
5515    (clobber (reg:CC FLAGS_REG))]
5516   "TARGET_64BIT && reload_completed
5517    && true_regnum (operands[0]) != true_regnum (operands[1])"
5518   [(set (match_dup 0)
5519         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5520 {
5521   operands[1] = gen_lowpart (Pmode, operands[1]);
5522   operands[2] = gen_lowpart (Pmode, operands[2]);
5523 })
5524
5525 (define_insn "*addsi_2"
5526   [(set (reg FLAGS_REG)
5527         (compare
5528           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5529                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5530           (const_int 0)))                       
5531    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5532         (plus:SI (match_dup 1) (match_dup 2)))]
5533   "ix86_match_ccmode (insn, CCGOCmode)
5534    && ix86_binary_operator_ok (PLUS, SImode, operands)
5535    /* Current assemblers are broken and do not allow @GOTOFF in
5536       ought but a memory context.  */
5537    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5538 {
5539   switch (get_attr_type (insn))
5540     {
5541     case TYPE_INCDEC:
5542       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543       if (operands[2] == const1_rtx)
5544         return "inc{l}\t%0";
5545       else
5546         {
5547           gcc_assert (operands[2] == constm1_rtx);
5548           return "dec{l}\t%0";
5549         }
5550
5551     default:
5552       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5553       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5554          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5555       if (GET_CODE (operands[2]) == CONST_INT
5556           && (INTVAL (operands[2]) == 128
5557               || (INTVAL (operands[2]) < 0
5558                   && INTVAL (operands[2]) != -128)))
5559         {
5560           operands[2] = GEN_INT (-INTVAL (operands[2]));
5561           return "sub{l}\t{%2, %0|%0, %2}";
5562         }
5563       return "add{l}\t{%2, %0|%0, %2}";
5564     }
5565 }
5566   [(set (attr "type")
5567      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5568         (const_string "incdec")
5569         (const_string "alu")))
5570    (set_attr "mode" "SI")])
5571
5572 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5573 (define_insn "*addsi_2_zext"
5574   [(set (reg FLAGS_REG)
5575         (compare
5576           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5577                    (match_operand:SI 2 "general_operand" "rmni"))
5578           (const_int 0)))                       
5579    (set (match_operand:DI 0 "register_operand" "=r")
5580         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5581   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5582    && ix86_binary_operator_ok (PLUS, SImode, operands)
5583    /* Current assemblers are broken and do not allow @GOTOFF in
5584       ought but a memory context.  */
5585    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586 {
5587   switch (get_attr_type (insn))
5588     {
5589     case TYPE_INCDEC:
5590       if (operands[2] == const1_rtx)
5591         return "inc{l}\t%k0";
5592       else
5593         {
5594           gcc_assert (operands[2] == constm1_rtx);
5595           return "dec{l}\t%k0";
5596         }
5597
5598     default:
5599       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5600          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5601       if (GET_CODE (operands[2]) == CONST_INT
5602           && (INTVAL (operands[2]) == 128
5603               || (INTVAL (operands[2]) < 0
5604                   && INTVAL (operands[2]) != -128)))
5605         {
5606           operands[2] = GEN_INT (-INTVAL (operands[2]));
5607           return "sub{l}\t{%2, %k0|%k0, %2}";
5608         }
5609       return "add{l}\t{%2, %k0|%k0, %2}";
5610     }
5611 }
5612   [(set (attr "type")
5613      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5614         (const_string "incdec")
5615         (const_string "alu")))
5616    (set_attr "mode" "SI")])
5617
5618 (define_insn "*addsi_3"
5619   [(set (reg FLAGS_REG)
5620         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5621                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5622    (clobber (match_scratch:SI 0 "=r"))]
5623   "ix86_match_ccmode (insn, CCZmode)
5624    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5625    /* Current assemblers are broken and do not allow @GOTOFF in
5626       ought but a memory context.  */
5627    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5628 {
5629   switch (get_attr_type (insn))
5630     {
5631     case TYPE_INCDEC:
5632       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633       if (operands[2] == const1_rtx)
5634         return "inc{l}\t%0";
5635       else
5636         {
5637           gcc_assert (operands[2] == constm1_rtx);
5638           return "dec{l}\t%0";
5639         }
5640
5641     default:
5642       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5644          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5645       if (GET_CODE (operands[2]) == CONST_INT
5646           && (INTVAL (operands[2]) == 128
5647               || (INTVAL (operands[2]) < 0
5648                   && INTVAL (operands[2]) != -128)))
5649         {
5650           operands[2] = GEN_INT (-INTVAL (operands[2]));
5651           return "sub{l}\t{%2, %0|%0, %2}";
5652         }
5653       return "add{l}\t{%2, %0|%0, %2}";
5654     }
5655 }
5656   [(set (attr "type")
5657      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5658         (const_string "incdec")
5659         (const_string "alu")))
5660    (set_attr "mode" "SI")])
5661
5662 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5663 (define_insn "*addsi_3_zext"
5664   [(set (reg FLAGS_REG)
5665         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5666                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5667    (set (match_operand:DI 0 "register_operand" "=r")
5668         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5669   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5670    && ix86_binary_operator_ok (PLUS, SImode, operands)
5671    /* Current assemblers are broken and do not allow @GOTOFF in
5672       ought but a memory context.  */
5673    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5674 {
5675   switch (get_attr_type (insn))
5676     {
5677     case TYPE_INCDEC:
5678       if (operands[2] == const1_rtx)
5679         return "inc{l}\t%k0";
5680       else
5681         {
5682           gcc_assert (operands[2] == constm1_rtx);
5683           return "dec{l}\t%k0";
5684         }
5685
5686     default:
5687       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5688          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5689       if (GET_CODE (operands[2]) == CONST_INT
5690           && (INTVAL (operands[2]) == 128
5691               || (INTVAL (operands[2]) < 0
5692                   && INTVAL (operands[2]) != -128)))
5693         {
5694           operands[2] = GEN_INT (-INTVAL (operands[2]));
5695           return "sub{l}\t{%2, %k0|%k0, %2}";
5696         }
5697       return "add{l}\t{%2, %k0|%k0, %2}";
5698     }
5699 }
5700   [(set (attr "type")
5701      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5702         (const_string "incdec")
5703         (const_string "alu")))
5704    (set_attr "mode" "SI")])
5705
5706 ; For comparisons against 1, -1 and 128, we may generate better code
5707 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5708 ; is matched then.  We can't accept general immediate, because for
5709 ; case of overflows,  the result is messed up.
5710 ; This pattern also don't hold of 0x80000000, since the value overflows
5711 ; when negated.
5712 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5713 ; only for comparisons not depending on it.
5714 (define_insn "*addsi_4"
5715   [(set (reg FLAGS_REG)
5716         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5717                  (match_operand:SI 2 "const_int_operand" "n")))
5718    (clobber (match_scratch:SI 0 "=rm"))]
5719   "ix86_match_ccmode (insn, CCGCmode)
5720    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5721 {
5722   switch (get_attr_type (insn))
5723     {
5724     case TYPE_INCDEC:
5725       if (operands[2] == constm1_rtx)
5726         return "inc{l}\t%0";
5727       else
5728         {
5729           gcc_assert (operands[2] == const1_rtx);
5730           return "dec{l}\t%0";
5731         }
5732
5733     default:
5734       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5735       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5736          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5737       if ((INTVAL (operands[2]) == -128
5738            || (INTVAL (operands[2]) > 0
5739                && INTVAL (operands[2]) != 128)))
5740         return "sub{l}\t{%2, %0|%0, %2}";
5741       operands[2] = GEN_INT (-INTVAL (operands[2]));
5742       return "add{l}\t{%2, %0|%0, %2}";
5743     }
5744 }
5745   [(set (attr "type")
5746      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5747         (const_string "incdec")
5748         (const_string "alu")))
5749    (set_attr "mode" "SI")])
5750
5751 (define_insn "*addsi_5"
5752   [(set (reg FLAGS_REG)
5753         (compare
5754           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5755                    (match_operand:SI 2 "general_operand" "rmni"))
5756           (const_int 0)))                       
5757    (clobber (match_scratch:SI 0 "=r"))]
5758   "ix86_match_ccmode (insn, CCGOCmode)
5759    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5760    /* Current assemblers are broken and do not allow @GOTOFF in
5761       ought but a memory context.  */
5762    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5763 {
5764   switch (get_attr_type (insn))
5765     {
5766     case TYPE_INCDEC:
5767       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5768       if (operands[2] == const1_rtx)
5769         return "inc{l}\t%0";
5770       else
5771         {
5772           gcc_assert (operands[2] == constm1_rtx);
5773           return "dec{l}\t%0";
5774         }
5775
5776     default:
5777       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5780       if (GET_CODE (operands[2]) == CONST_INT
5781           && (INTVAL (operands[2]) == 128
5782               || (INTVAL (operands[2]) < 0
5783                   && INTVAL (operands[2]) != -128)))
5784         {
5785           operands[2] = GEN_INT (-INTVAL (operands[2]));
5786           return "sub{l}\t{%2, %0|%0, %2}";
5787         }
5788       return "add{l}\t{%2, %0|%0, %2}";
5789     }
5790 }
5791   [(set (attr "type")
5792      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5793         (const_string "incdec")
5794         (const_string "alu")))
5795    (set_attr "mode" "SI")])
5796
5797 (define_expand "addhi3"
5798   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5799                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5800                             (match_operand:HI 2 "general_operand" "")))
5801               (clobber (reg:CC FLAGS_REG))])]
5802   "TARGET_HIMODE_MATH"
5803   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5804
5805 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5806 ;; type optimizations enabled by define-splits.  This is not important
5807 ;; for PII, and in fact harmful because of partial register stalls.
5808
5809 (define_insn "*addhi_1_lea"
5810   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5811         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5812                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5813    (clobber (reg:CC FLAGS_REG))]
5814   "!TARGET_PARTIAL_REG_STALL
5815    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5816 {
5817   switch (get_attr_type (insn))
5818     {
5819     case TYPE_LEA:
5820       return "#";
5821     case TYPE_INCDEC:
5822       if (operands[2] == const1_rtx)
5823         return "inc{w}\t%0";
5824       else
5825         {
5826           gcc_assert (operands[2] == constm1_rtx);
5827           return "dec{w}\t%0";
5828         }
5829
5830     default:
5831       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5833       if (GET_CODE (operands[2]) == CONST_INT
5834           && (INTVAL (operands[2]) == 128
5835               || (INTVAL (operands[2]) < 0
5836                   && INTVAL (operands[2]) != -128)))
5837         {
5838           operands[2] = GEN_INT (-INTVAL (operands[2]));
5839           return "sub{w}\t{%2, %0|%0, %2}";
5840         }
5841       return "add{w}\t{%2, %0|%0, %2}";
5842     }
5843 }
5844   [(set (attr "type")
5845      (if_then_else (eq_attr "alternative" "2")
5846         (const_string "lea")
5847         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5848            (const_string "incdec")
5849            (const_string "alu"))))
5850    (set_attr "mode" "HI,HI,SI")])
5851
5852 (define_insn "*addhi_1"
5853   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5854         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5855                  (match_operand:HI 2 "general_operand" "ri,rm")))
5856    (clobber (reg:CC FLAGS_REG))]
5857   "TARGET_PARTIAL_REG_STALL
5858    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5859 {
5860   switch (get_attr_type (insn))
5861     {
5862     case TYPE_INCDEC:
5863       if (operands[2] == const1_rtx)
5864         return "inc{w}\t%0";
5865       else
5866         {
5867           gcc_assert (operands[2] == constm1_rtx);
5868           return "dec{w}\t%0";
5869         }
5870
5871     default:
5872       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5874       if (GET_CODE (operands[2]) == CONST_INT
5875           && (INTVAL (operands[2]) == 128
5876               || (INTVAL (operands[2]) < 0
5877                   && INTVAL (operands[2]) != -128)))
5878         {
5879           operands[2] = GEN_INT (-INTVAL (operands[2]));
5880           return "sub{w}\t{%2, %0|%0, %2}";
5881         }
5882       return "add{w}\t{%2, %0|%0, %2}";
5883     }
5884 }
5885   [(set (attr "type")
5886      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5887         (const_string "incdec")
5888         (const_string "alu")))
5889    (set_attr "mode" "HI")])
5890
5891 (define_insn "*addhi_2"
5892   [(set (reg FLAGS_REG)
5893         (compare
5894           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5895                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5896           (const_int 0)))                       
5897    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5898         (plus:HI (match_dup 1) (match_dup 2)))]
5899   "ix86_match_ccmode (insn, CCGOCmode)
5900    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5901 {
5902   switch (get_attr_type (insn))
5903     {
5904     case TYPE_INCDEC:
5905       if (operands[2] == const1_rtx)
5906         return "inc{w}\t%0";
5907       else
5908         {
5909           gcc_assert (operands[2] == constm1_rtx);
5910           return "dec{w}\t%0";
5911         }
5912
5913     default:
5914       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5916       if (GET_CODE (operands[2]) == CONST_INT
5917           && (INTVAL (operands[2]) == 128
5918               || (INTVAL (operands[2]) < 0
5919                   && INTVAL (operands[2]) != -128)))
5920         {
5921           operands[2] = GEN_INT (-INTVAL (operands[2]));
5922           return "sub{w}\t{%2, %0|%0, %2}";
5923         }
5924       return "add{w}\t{%2, %0|%0, %2}";
5925     }
5926 }
5927   [(set (attr "type")
5928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929         (const_string "incdec")
5930         (const_string "alu")))
5931    (set_attr "mode" "HI")])
5932
5933 (define_insn "*addhi_3"
5934   [(set (reg FLAGS_REG)
5935         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5936                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5937    (clobber (match_scratch:HI 0 "=r"))]
5938   "ix86_match_ccmode (insn, CCZmode)
5939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5940 {
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{w}\t%0";
5946       else
5947         {
5948           gcc_assert (operands[2] == constm1_rtx);
5949           return "dec{w}\t%0";
5950         }
5951
5952     default:
5953       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5954          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5955       if (GET_CODE (operands[2]) == CONST_INT
5956           && (INTVAL (operands[2]) == 128
5957               || (INTVAL (operands[2]) < 0
5958                   && INTVAL (operands[2]) != -128)))
5959         {
5960           operands[2] = GEN_INT (-INTVAL (operands[2]));
5961           return "sub{w}\t{%2, %0|%0, %2}";
5962         }
5963       return "add{w}\t{%2, %0|%0, %2}";
5964     }
5965 }
5966   [(set (attr "type")
5967      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5968         (const_string "incdec")
5969         (const_string "alu")))
5970    (set_attr "mode" "HI")])
5971
5972 ; See comments above addsi_4 for details.
5973 (define_insn "*addhi_4"
5974   [(set (reg FLAGS_REG)
5975         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5976                  (match_operand:HI 2 "const_int_operand" "n")))
5977    (clobber (match_scratch:HI 0 "=rm"))]
5978   "ix86_match_ccmode (insn, CCGCmode)
5979    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5980 {
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_INCDEC:
5984       if (operands[2] == constm1_rtx)
5985         return "inc{w}\t%0";
5986       else
5987         {
5988           gcc_assert (operands[2] == const1_rtx);
5989           return "dec{w}\t%0";
5990         }
5991
5992     default:
5993       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5996       if ((INTVAL (operands[2]) == -128
5997            || (INTVAL (operands[2]) > 0
5998                && INTVAL (operands[2]) != 128)))
5999         return "sub{w}\t{%2, %0|%0, %2}";
6000       operands[2] = GEN_INT (-INTVAL (operands[2]));
6001       return "add{w}\t{%2, %0|%0, %2}";
6002     }
6003 }
6004   [(set (attr "type")
6005      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6006         (const_string "incdec")
6007         (const_string "alu")))
6008    (set_attr "mode" "SI")])
6009
6010
6011 (define_insn "*addhi_5"
6012   [(set (reg FLAGS_REG)
6013         (compare
6014           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6015                    (match_operand:HI 2 "general_operand" "rmni"))
6016           (const_int 0)))                       
6017    (clobber (match_scratch:HI 0 "=r"))]
6018   "ix86_match_ccmode (insn, CCGOCmode)
6019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6020 {
6021   switch (get_attr_type (insn))
6022     {
6023     case TYPE_INCDEC:
6024       if (operands[2] == const1_rtx)
6025         return "inc{w}\t%0";
6026       else
6027         {
6028           gcc_assert (operands[2] == constm1_rtx);
6029           return "dec{w}\t%0";
6030         }
6031
6032     default:
6033       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6034          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6035       if (GET_CODE (operands[2]) == CONST_INT
6036           && (INTVAL (operands[2]) == 128
6037               || (INTVAL (operands[2]) < 0
6038                   && INTVAL (operands[2]) != -128)))
6039         {
6040           operands[2] = GEN_INT (-INTVAL (operands[2]));
6041           return "sub{w}\t{%2, %0|%0, %2}";
6042         }
6043       return "add{w}\t{%2, %0|%0, %2}";
6044     }
6045 }
6046   [(set (attr "type")
6047      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6048         (const_string "incdec")
6049         (const_string "alu")))
6050    (set_attr "mode" "HI")])
6051
6052 (define_expand "addqi3"
6053   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6054                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6055                             (match_operand:QI 2 "general_operand" "")))
6056               (clobber (reg:CC FLAGS_REG))])]
6057   "TARGET_QIMODE_MATH"
6058   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6059
6060 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6061 (define_insn "*addqi_1_lea"
6062   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6063         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6064                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6065    (clobber (reg:CC FLAGS_REG))]
6066   "!TARGET_PARTIAL_REG_STALL
6067    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6068 {
6069   int widen = (which_alternative == 2);
6070   switch (get_attr_type (insn))
6071     {
6072     case TYPE_LEA:
6073       return "#";
6074     case TYPE_INCDEC:
6075       if (operands[2] == const1_rtx)
6076         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6077       else
6078         {
6079           gcc_assert (operands[2] == constm1_rtx);
6080           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6081         }
6082
6083     default:
6084       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6086       if (GET_CODE (operands[2]) == CONST_INT
6087           && (INTVAL (operands[2]) == 128
6088               || (INTVAL (operands[2]) < 0
6089                   && INTVAL (operands[2]) != -128)))
6090         {
6091           operands[2] = GEN_INT (-INTVAL (operands[2]));
6092           if (widen)
6093             return "sub{l}\t{%2, %k0|%k0, %2}";
6094           else
6095             return "sub{b}\t{%2, %0|%0, %2}";
6096         }
6097       if (widen)
6098         return "add{l}\t{%k2, %k0|%k0, %k2}";
6099       else
6100         return "add{b}\t{%2, %0|%0, %2}";
6101     }
6102 }
6103   [(set (attr "type")
6104      (if_then_else (eq_attr "alternative" "3")
6105         (const_string "lea")
6106         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6107            (const_string "incdec")
6108            (const_string "alu"))))
6109    (set_attr "mode" "QI,QI,SI,SI")])
6110
6111 (define_insn "*addqi_1"
6112   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6113         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6114                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6115    (clobber (reg:CC FLAGS_REG))]
6116   "TARGET_PARTIAL_REG_STALL
6117    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6118 {
6119   int widen = (which_alternative == 2);
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == const1_rtx)
6124         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6125       else
6126         {
6127           gcc_assert (operands[2] == constm1_rtx);
6128           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6129         }
6130
6131     default:
6132       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6133          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6134       if (GET_CODE (operands[2]) == CONST_INT
6135           && (INTVAL (operands[2]) == 128
6136               || (INTVAL (operands[2]) < 0
6137                   && INTVAL (operands[2]) != -128)))
6138         {
6139           operands[2] = GEN_INT (-INTVAL (operands[2]));
6140           if (widen)
6141             return "sub{l}\t{%2, %k0|%k0, %2}";
6142           else
6143             return "sub{b}\t{%2, %0|%0, %2}";
6144         }
6145       if (widen)
6146         return "add{l}\t{%k2, %k0|%k0, %k2}";
6147       else
6148         return "add{b}\t{%2, %0|%0, %2}";
6149     }
6150 }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "QI,QI,SI")])
6156
6157 (define_insn "*addqi_1_slp"
6158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6159         (plus:QI (match_dup 0)
6160                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6161    (clobber (reg:CC FLAGS_REG))]
6162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6164 {
6165   switch (get_attr_type (insn))
6166     {
6167     case TYPE_INCDEC:
6168       if (operands[1] == const1_rtx)
6169         return "inc{b}\t%0";
6170       else
6171         {
6172           gcc_assert (operands[1] == constm1_rtx);
6173           return "dec{b}\t%0";
6174         }
6175
6176     default:
6177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6178       if (GET_CODE (operands[1]) == CONST_INT
6179           && INTVAL (operands[1]) < 0)
6180         {
6181           operands[1] = GEN_INT (-INTVAL (operands[1]));
6182           return "sub{b}\t{%1, %0|%0, %1}";
6183         }
6184       return "add{b}\t{%1, %0|%0, %1}";
6185     }
6186 }
6187   [(set (attr "type")
6188      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6189         (const_string "incdec")
6190         (const_string "alu1")))
6191    (set (attr "memory")
6192      (if_then_else (match_operand 1 "memory_operand" "")
6193         (const_string "load")
6194         (const_string "none")))
6195    (set_attr "mode" "QI")])
6196
6197 (define_insn "*addqi_2"
6198   [(set (reg FLAGS_REG)
6199         (compare
6200           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6201                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6202           (const_int 0)))
6203    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6204         (plus:QI (match_dup 1) (match_dup 2)))]
6205   "ix86_match_ccmode (insn, CCGOCmode)
6206    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6207 {
6208   switch (get_attr_type (insn))
6209     {
6210     case TYPE_INCDEC:
6211       if (operands[2] == const1_rtx)
6212         return "inc{b}\t%0";
6213       else
6214         {
6215           gcc_assert (operands[2] == constm1_rtx
6216                       || (GET_CODE (operands[2]) == CONST_INT
6217                           && INTVAL (operands[2]) == 255));
6218           return "dec{b}\t%0";
6219         }
6220
6221     default:
6222       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6223       if (GET_CODE (operands[2]) == CONST_INT
6224           && INTVAL (operands[2]) < 0)
6225         {
6226           operands[2] = GEN_INT (-INTVAL (operands[2]));
6227           return "sub{b}\t{%2, %0|%0, %2}";
6228         }
6229       return "add{b}\t{%2, %0|%0, %2}";
6230     }
6231 }
6232   [(set (attr "type")
6233      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6234         (const_string "incdec")
6235         (const_string "alu")))
6236    (set_attr "mode" "QI")])
6237
6238 (define_insn "*addqi_3"
6239   [(set (reg FLAGS_REG)
6240         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6241                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6242    (clobber (match_scratch:QI 0 "=q"))]
6243   "ix86_match_ccmode (insn, CCZmode)
6244    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6245 {
6246   switch (get_attr_type (insn))
6247     {
6248     case TYPE_INCDEC:
6249       if (operands[2] == const1_rtx)
6250         return "inc{b}\t%0";
6251       else
6252         {
6253           gcc_assert (operands[2] == constm1_rtx
6254                       || (GET_CODE (operands[2]) == CONST_INT
6255                           && INTVAL (operands[2]) == 255));
6256           return "dec{b}\t%0";
6257         }
6258
6259     default:
6260       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6261       if (GET_CODE (operands[2]) == CONST_INT
6262           && INTVAL (operands[2]) < 0)
6263         {
6264           operands[2] = GEN_INT (-INTVAL (operands[2]));
6265           return "sub{b}\t{%2, %0|%0, %2}";
6266         }
6267       return "add{b}\t{%2, %0|%0, %2}";
6268     }
6269 }
6270   [(set (attr "type")
6271      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6272         (const_string "incdec")
6273         (const_string "alu")))
6274    (set_attr "mode" "QI")])
6275
6276 ; See comments above addsi_4 for details.
6277 (define_insn "*addqi_4"
6278   [(set (reg FLAGS_REG)
6279         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6280                  (match_operand:QI 2 "const_int_operand" "n")))
6281    (clobber (match_scratch:QI 0 "=qm"))]
6282   "ix86_match_ccmode (insn, CCGCmode)
6283    && (INTVAL (operands[2]) & 0xff) != 0x80"
6284 {
6285   switch (get_attr_type (insn))
6286     {
6287     case TYPE_INCDEC:
6288       if (operands[2] == constm1_rtx
6289           || (GET_CODE (operands[2]) == CONST_INT
6290               && INTVAL (operands[2]) == 255))
6291         return "inc{b}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == const1_rtx);
6295           return "dec{b}\t%0";
6296         }
6297
6298     default:
6299       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6300       if (INTVAL (operands[2]) < 0)
6301         {
6302           operands[2] = GEN_INT (-INTVAL (operands[2]));
6303           return "add{b}\t{%2, %0|%0, %2}";
6304         }
6305       return "sub{b}\t{%2, %0|%0, %2}";
6306     }
6307 }
6308   [(set (attr "type")
6309      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6310         (const_string "incdec")
6311         (const_string "alu")))
6312    (set_attr "mode" "QI")])
6313
6314
6315 (define_insn "*addqi_5"
6316   [(set (reg FLAGS_REG)
6317         (compare
6318           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6319                    (match_operand:QI 2 "general_operand" "qmni"))
6320           (const_int 0)))
6321    (clobber (match_scratch:QI 0 "=q"))]
6322   "ix86_match_ccmode (insn, CCGOCmode)
6323    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6324 {
6325   switch (get_attr_type (insn))
6326     {
6327     case TYPE_INCDEC:
6328       if (operands[2] == const1_rtx)
6329         return "inc{b}\t%0";
6330       else
6331         {
6332           gcc_assert (operands[2] == constm1_rtx
6333                       || (GET_CODE (operands[2]) == CONST_INT
6334                           && INTVAL (operands[2]) == 255));
6335           return "dec{b}\t%0";
6336         }
6337
6338     default:
6339       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6340       if (GET_CODE (operands[2]) == CONST_INT
6341           && INTVAL (operands[2]) < 0)
6342         {
6343           operands[2] = GEN_INT (-INTVAL (operands[2]));
6344           return "sub{b}\t{%2, %0|%0, %2}";
6345         }
6346       return "add{b}\t{%2, %0|%0, %2}";
6347     }
6348 }
6349   [(set (attr "type")
6350      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6351         (const_string "incdec")
6352         (const_string "alu")))
6353    (set_attr "mode" "QI")])
6354
6355
6356 (define_insn "addqi_ext_1"
6357   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6358                          (const_int 8)
6359                          (const_int 8))
6360         (plus:SI
6361           (zero_extract:SI
6362             (match_operand 1 "ext_register_operand" "0")
6363             (const_int 8)
6364             (const_int 8))
6365           (match_operand:QI 2 "general_operand" "Qmn")))
6366    (clobber (reg:CC FLAGS_REG))]
6367   "!TARGET_64BIT"
6368 {
6369   switch (get_attr_type (insn))
6370     {
6371     case TYPE_INCDEC:
6372       if (operands[2] == const1_rtx)
6373         return "inc{b}\t%h0";
6374       else
6375         {
6376           gcc_assert (operands[2] == constm1_rtx
6377                       || (GET_CODE (operands[2]) == CONST_INT
6378                           && INTVAL (operands[2]) == 255));
6379           return "dec{b}\t%h0";
6380         }
6381
6382     default:
6383       return "add{b}\t{%2, %h0|%h0, %2}";
6384     }
6385 }
6386   [(set (attr "type")
6387      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6388         (const_string "incdec")
6389         (const_string "alu")))
6390    (set_attr "mode" "QI")])
6391
6392 (define_insn "*addqi_ext_1_rex64"
6393   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6394                          (const_int 8)
6395                          (const_int 8))
6396         (plus:SI
6397           (zero_extract:SI
6398             (match_operand 1 "ext_register_operand" "0")
6399             (const_int 8)
6400             (const_int 8))
6401           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6402    (clobber (reg:CC FLAGS_REG))]
6403   "TARGET_64BIT"
6404 {
6405   switch (get_attr_type (insn))
6406     {
6407     case TYPE_INCDEC:
6408       if (operands[2] == const1_rtx)
6409         return "inc{b}\t%h0";
6410       else
6411         {
6412           gcc_assert (operands[2] == constm1_rtx
6413                       || (GET_CODE (operands[2]) == CONST_INT
6414                           && INTVAL (operands[2]) == 255));
6415           return "dec{b}\t%h0";
6416         }
6417
6418     default:
6419       return "add{b}\t{%2, %h0|%h0, %2}";
6420     }
6421 }
6422   [(set (attr "type")
6423      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424         (const_string "incdec")
6425         (const_string "alu")))
6426    (set_attr "mode" "QI")])
6427
6428 (define_insn "*addqi_ext_2"
6429   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6430                          (const_int 8)
6431                          (const_int 8))
6432         (plus:SI
6433           (zero_extract:SI
6434             (match_operand 1 "ext_register_operand" "%0")
6435             (const_int 8)
6436             (const_int 8))
6437           (zero_extract:SI
6438             (match_operand 2 "ext_register_operand" "Q")
6439             (const_int 8)
6440             (const_int 8))))
6441    (clobber (reg:CC FLAGS_REG))]
6442   ""
6443   "add{b}\t{%h2, %h0|%h0, %h2}"
6444   [(set_attr "type" "alu")
6445    (set_attr "mode" "QI")])
6446
6447 ;; The patterns that match these are at the end of this file.
6448
6449 (define_expand "addxf3"
6450   [(set (match_operand:XF 0 "register_operand" "")
6451         (plus:XF (match_operand:XF 1 "register_operand" "")
6452                  (match_operand:XF 2 "register_operand" "")))]
6453   "TARGET_80387"
6454   "")
6455
6456 (define_expand "adddf3"
6457   [(set (match_operand:DF 0 "register_operand" "")
6458         (plus:DF (match_operand:DF 1 "register_operand" "")
6459                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6460   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6461   "")
6462
6463 (define_expand "addsf3"
6464   [(set (match_operand:SF 0 "register_operand" "")
6465         (plus:SF (match_operand:SF 1 "register_operand" "")
6466                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6467   "TARGET_80387 || TARGET_SSE_MATH"
6468   "")
6469 \f
6470 ;; Subtract instructions
6471
6472 ;; %%% splits for subditi3
6473
6474 (define_expand "subti3"
6475   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6476                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6477                              (match_operand:TI 2 "x86_64_general_operand" "")))
6478               (clobber (reg:CC FLAGS_REG))])]
6479   "TARGET_64BIT"
6480   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6481
6482 (define_insn "*subti3_1"
6483   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6484         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6485                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6486    (clobber (reg:CC FLAGS_REG))]
6487   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6488   "#")
6489
6490 (define_split
6491   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493                   (match_operand:TI 2 "general_operand" "")))
6494    (clobber (reg:CC FLAGS_REG))]
6495   "TARGET_64BIT && reload_completed"
6496   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6497               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6498    (parallel [(set (match_dup 3)
6499                    (minus:DI (match_dup 4)
6500                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6501                                       (match_dup 5))))
6502               (clobber (reg:CC FLAGS_REG))])]
6503   "split_ti (operands+0, 1, operands+0, operands+3);
6504    split_ti (operands+1, 1, operands+1, operands+4);
6505    split_ti (operands+2, 1, operands+2, operands+5);")
6506
6507 ;; %%% splits for subsidi3
6508
6509 (define_expand "subdi3"
6510   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6511                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6512                              (match_operand:DI 2 "x86_64_general_operand" "")))
6513               (clobber (reg:CC FLAGS_REG))])]
6514   ""
6515   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6516
6517 (define_insn "*subdi3_1"
6518   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6519         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6520                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6521    (clobber (reg:CC FLAGS_REG))]
6522   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6523   "#")
6524
6525 (define_split
6526   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528                   (match_operand:DI 2 "general_operand" "")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "!TARGET_64BIT && reload_completed"
6531   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6532               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6533    (parallel [(set (match_dup 3)
6534                    (minus:SI (match_dup 4)
6535                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6536                                       (match_dup 5))))
6537               (clobber (reg:CC FLAGS_REG))])]
6538   "split_di (operands+0, 1, operands+0, operands+3);
6539    split_di (operands+1, 1, operands+1, operands+4);
6540    split_di (operands+2, 1, operands+2, operands+5);")
6541
6542 (define_insn "subdi3_carry_rex64"
6543   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6544           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6545             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6546                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6547    (clobber (reg:CC FLAGS_REG))]
6548   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6549   "sbb{q}\t{%2, %0|%0, %2}"
6550   [(set_attr "type" "alu")
6551    (set_attr "pent_pair" "pu")
6552    (set_attr "mode" "DI")])
6553
6554 (define_insn "*subdi_1_rex64"
6555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6556         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6557                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6558    (clobber (reg:CC FLAGS_REG))]
6559   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6560   "sub{q}\t{%2, %0|%0, %2}"
6561   [(set_attr "type" "alu")
6562    (set_attr "mode" "DI")])
6563
6564 (define_insn "*subdi_2_rex64"
6565   [(set (reg FLAGS_REG)
6566         (compare
6567           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6568                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6569           (const_int 0)))
6570    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6571         (minus:DI (match_dup 1) (match_dup 2)))]
6572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6573    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6574   "sub{q}\t{%2, %0|%0, %2}"
6575   [(set_attr "type" "alu")
6576    (set_attr "mode" "DI")])
6577
6578 (define_insn "*subdi_3_rex63"
6579   [(set (reg FLAGS_REG)
6580         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6581                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6582    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6583         (minus:DI (match_dup 1) (match_dup 2)))]
6584   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6585    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6586   "sub{q}\t{%2, %0|%0, %2}"
6587   [(set_attr "type" "alu")
6588    (set_attr "mode" "DI")])
6589
6590 (define_insn "subqi3_carry"
6591   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6592           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6593             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6594                (match_operand:QI 2 "general_operand" "qi,qm"))))
6595    (clobber (reg:CC FLAGS_REG))]
6596   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6597   "sbb{b}\t{%2, %0|%0, %2}"
6598   [(set_attr "type" "alu")
6599    (set_attr "pent_pair" "pu")
6600    (set_attr "mode" "QI")])
6601
6602 (define_insn "subhi3_carry"
6603   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6604           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6605             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6606                (match_operand:HI 2 "general_operand" "ri,rm"))))
6607    (clobber (reg:CC FLAGS_REG))]
6608   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6609   "sbb{w}\t{%2, %0|%0, %2}"
6610   [(set_attr "type" "alu")
6611    (set_attr "pent_pair" "pu")
6612    (set_attr "mode" "HI")])
6613
6614 (define_insn "subsi3_carry"
6615   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6616           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6617             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6618                (match_operand:SI 2 "general_operand" "ri,rm"))))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sbb{l}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "pent_pair" "pu")
6624    (set_attr "mode" "SI")])
6625
6626 (define_insn "subsi3_carry_zext"
6627   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6628           (zero_extend:DI
6629             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6630               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6631                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6632    (clobber (reg:CC FLAGS_REG))]
6633   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6634   "sbb{l}\t{%2, %k0|%k0, %2}"
6635   [(set_attr "type" "alu")
6636    (set_attr "pent_pair" "pu")
6637    (set_attr "mode" "SI")])
6638
6639 (define_expand "subsi3"
6640   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6641                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6642                              (match_operand:SI 2 "general_operand" "")))
6643               (clobber (reg:CC FLAGS_REG))])]
6644   ""
6645   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6646
6647 (define_insn "*subsi_1"
6648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6649         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6650                   (match_operand:SI 2 "general_operand" "ri,rm")))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6653   "sub{l}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "mode" "SI")])
6656
6657 (define_insn "*subsi_1_zext"
6658   [(set (match_operand:DI 0 "register_operand" "=r")
6659         (zero_extend:DI
6660           (minus:SI (match_operand:SI 1 "register_operand" "0")
6661                     (match_operand:SI 2 "general_operand" "rim"))))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6664   "sub{l}\t{%2, %k0|%k0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "SI")])
6667
6668 (define_insn "*subsi_2"
6669   [(set (reg FLAGS_REG)
6670         (compare
6671           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6672                     (match_operand:SI 2 "general_operand" "ri,rm"))
6673           (const_int 0)))
6674    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675         (minus:SI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCGOCmode)
6677    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678   "sub{l}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "SI")])
6681
6682 (define_insn "*subsi_2_zext"
6683   [(set (reg FLAGS_REG)
6684         (compare
6685           (minus:SI (match_operand:SI 1 "register_operand" "0")
6686                     (match_operand:SI 2 "general_operand" "rim"))
6687           (const_int 0)))
6688    (set (match_operand:DI 0 "register_operand" "=r")
6689         (zero_extend:DI
6690           (minus:SI (match_dup 1)
6691                     (match_dup 2))))]
6692   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6693    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sub{l}\t{%2, %k0|%k0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "SI")])
6697
6698 (define_insn "*subsi_3"
6699   [(set (reg FLAGS_REG)
6700         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6701                  (match_operand:SI 2 "general_operand" "ri,rm")))
6702    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6703         (minus:SI (match_dup 1) (match_dup 2)))]
6704   "ix86_match_ccmode (insn, CCmode)
6705    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6706   "sub{l}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "SI")])
6709
6710 (define_insn "*subsi_3_zext"
6711   [(set (reg FLAGS_REG)
6712         (compare (match_operand:SI 1 "register_operand" "0")
6713                  (match_operand:SI 2 "general_operand" "rim")))
6714    (set (match_operand:DI 0 "register_operand" "=r")
6715         (zero_extend:DI
6716           (minus:SI (match_dup 1)
6717                     (match_dup 2))))]
6718   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6719    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sub{q}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "DI")])
6723
6724 (define_expand "subhi3"
6725   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6726                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6727                              (match_operand:HI 2 "general_operand" "")))
6728               (clobber (reg:CC FLAGS_REG))])]
6729   "TARGET_HIMODE_MATH"
6730   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6731
6732 (define_insn "*subhi_1"
6733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6734         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6735                   (match_operand:HI 2 "general_operand" "ri,rm")))
6736    (clobber (reg:CC FLAGS_REG))]
6737   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6738   "sub{w}\t{%2, %0|%0, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "HI")])
6741
6742 (define_insn "*subhi_2"
6743   [(set (reg FLAGS_REG)
6744         (compare
6745           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6746                     (match_operand:HI 2 "general_operand" "ri,rm"))
6747           (const_int 0)))
6748    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6749         (minus:HI (match_dup 1) (match_dup 2)))]
6750   "ix86_match_ccmode (insn, CCGOCmode)
6751    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6752   "sub{w}\t{%2, %0|%0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "HI")])
6755
6756 (define_insn "*subhi_3"
6757   [(set (reg FLAGS_REG)
6758         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6759                  (match_operand:HI 2 "general_operand" "ri,rm")))
6760    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6761         (minus:HI (match_dup 1) (match_dup 2)))]
6762   "ix86_match_ccmode (insn, CCmode)
6763    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6764   "sub{w}\t{%2, %0|%0, %2}"
6765   [(set_attr "type" "alu")
6766    (set_attr "mode" "HI")])
6767
6768 (define_expand "subqi3"
6769   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6770                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6771                              (match_operand:QI 2 "general_operand" "")))
6772               (clobber (reg:CC FLAGS_REG))])]
6773   "TARGET_QIMODE_MATH"
6774   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6775
6776 (define_insn "*subqi_1"
6777   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6778         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6779                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6780    (clobber (reg:CC FLAGS_REG))]
6781   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6782   "sub{b}\t{%2, %0|%0, %2}"
6783   [(set_attr "type" "alu")
6784    (set_attr "mode" "QI")])
6785
6786 (define_insn "*subqi_1_slp"
6787   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6788         (minus:QI (match_dup 0)
6789                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6792    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6793   "sub{b}\t{%1, %0|%0, %1}"
6794   [(set_attr "type" "alu1")
6795    (set_attr "mode" "QI")])
6796
6797 (define_insn "*subqi_2"
6798   [(set (reg FLAGS_REG)
6799         (compare
6800           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6801                     (match_operand:QI 2 "general_operand" "qi,qm"))
6802           (const_int 0)))
6803    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6804         (minus:HI (match_dup 1) (match_dup 2)))]
6805   "ix86_match_ccmode (insn, CCGOCmode)
6806    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6807   "sub{b}\t{%2, %0|%0, %2}"
6808   [(set_attr "type" "alu")
6809    (set_attr "mode" "QI")])
6810
6811 (define_insn "*subqi_3"
6812   [(set (reg FLAGS_REG)
6813         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6814                  (match_operand:QI 2 "general_operand" "qi,qm")))
6815    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6816         (minus:HI (match_dup 1) (match_dup 2)))]
6817   "ix86_match_ccmode (insn, CCmode)
6818    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6819   "sub{b}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "QI")])
6822
6823 ;; The patterns that match these are at the end of this file.
6824
6825 (define_expand "subxf3"
6826   [(set (match_operand:XF 0 "register_operand" "")
6827         (minus:XF (match_operand:XF 1 "register_operand" "")
6828                   (match_operand:XF 2 "register_operand" "")))]
6829   "TARGET_80387"
6830   "")
6831
6832 (define_expand "subdf3"
6833   [(set (match_operand:DF 0 "register_operand" "")
6834         (minus:DF (match_operand:DF 1 "register_operand" "")
6835                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6836   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6837   "")
6838
6839 (define_expand "subsf3"
6840   [(set (match_operand:SF 0 "register_operand" "")
6841         (minus:SF (match_operand:SF 1 "register_operand" "")
6842                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6843   "TARGET_80387 || TARGET_SSE_MATH"
6844   "")
6845 \f
6846 ;; Multiply instructions
6847
6848 (define_expand "muldi3"
6849   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6850                    (mult:DI (match_operand:DI 1 "register_operand" "")
6851                             (match_operand:DI 2 "x86_64_general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   "TARGET_64BIT"
6854   "")
6855
6856 (define_insn "*muldi3_1_rex64"
6857   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6858         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "TARGET_64BIT
6862    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6863   "@
6864    imul{q}\t{%2, %1, %0|%0, %1, %2}
6865    imul{q}\t{%2, %1, %0|%0, %1, %2}
6866    imul{q}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "imul")
6868    (set_attr "prefix_0f" "0,0,1")
6869    (set (attr "athlon_decode")
6870         (cond [(eq_attr "cpu" "athlon")
6871                   (const_string "vector")
6872                (eq_attr "alternative" "1")
6873                   (const_string "vector")
6874                (and (eq_attr "alternative" "2")
6875                     (match_operand 1 "memory_operand" ""))
6876                   (const_string "vector")]
6877               (const_string "direct")))
6878    (set_attr "mode" "DI")])
6879
6880 (define_expand "mulsi3"
6881   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6882                    (mult:SI (match_operand:SI 1 "register_operand" "")
6883                             (match_operand:SI 2 "general_operand" "")))
6884               (clobber (reg:CC FLAGS_REG))])]
6885   ""
6886   "")
6887
6888 (define_insn "*mulsi3_1"
6889   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6890         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6892    (clobber (reg:CC FLAGS_REG))]
6893   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6894   "@
6895    imul{l}\t{%2, %1, %0|%0, %1, %2}
6896    imul{l}\t{%2, %1, %0|%0, %1, %2}
6897    imul{l}\t{%2, %0|%0, %2}"
6898   [(set_attr "type" "imul")
6899    (set_attr "prefix_0f" "0,0,1")
6900    (set (attr "athlon_decode")
6901         (cond [(eq_attr "cpu" "athlon")
6902                   (const_string "vector")
6903                (eq_attr "alternative" "1")
6904                   (const_string "vector")
6905                (and (eq_attr "alternative" "2")
6906                     (match_operand 1 "memory_operand" ""))
6907                   (const_string "vector")]
6908               (const_string "direct")))
6909    (set_attr "mode" "SI")])
6910
6911 (define_insn "*mulsi3_1_zext"
6912   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6913         (zero_extend:DI
6914           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6915                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6919   "@
6920    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6921    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922    imul{l}\t{%2, %k0|%k0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1")
6929                   (const_string "vector")
6930                (and (eq_attr "alternative" "2")
6931                     (match_operand 1 "memory_operand" ""))
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "SI")])
6935
6936 (define_expand "mulhi3"
6937   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6938                    (mult:HI (match_operand:HI 1 "register_operand" "")
6939                             (match_operand:HI 2 "general_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   "TARGET_HIMODE_MATH"
6942   "")
6943
6944 (define_insn "*mulhi3_1"
6945   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6946         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6947                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6950   "@
6951    imul{w}\t{%2, %1, %0|%0, %1, %2}
6952    imul{w}\t{%2, %1, %0|%0, %1, %2}
6953    imul{w}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "imul")
6955    (set_attr "prefix_0f" "0,0,1")
6956    (set (attr "athlon_decode")
6957         (cond [(eq_attr "cpu" "athlon")
6958                   (const_string "vector")
6959                (eq_attr "alternative" "1,2")
6960                   (const_string "vector")]
6961               (const_string "direct")))
6962    (set_attr "mode" "HI")])
6963
6964 (define_expand "mulqi3"
6965   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6966                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6967                             (match_operand:QI 2 "register_operand" "")))
6968               (clobber (reg:CC FLAGS_REG))])]
6969   "TARGET_QIMODE_MATH"
6970   "")
6971
6972 (define_insn "*mulqi3_1"
6973   [(set (match_operand:QI 0 "register_operand" "=a")
6974         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6975                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6976    (clobber (reg:CC FLAGS_REG))]
6977   "TARGET_QIMODE_MATH
6978    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6979   "mul{b}\t%2"
6980   [(set_attr "type" "imul")
6981    (set_attr "length_immediate" "0")
6982    (set (attr "athlon_decode")
6983      (if_then_else (eq_attr "cpu" "athlon")
6984         (const_string "vector")
6985         (const_string "direct")))
6986    (set_attr "mode" "QI")])
6987
6988 (define_expand "umulqihi3"
6989   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6990                    (mult:HI (zero_extend:HI
6991                               (match_operand:QI 1 "nonimmediate_operand" ""))
6992                             (zero_extend:HI
6993                               (match_operand:QI 2 "register_operand" ""))))
6994               (clobber (reg:CC FLAGS_REG))])]
6995   "TARGET_QIMODE_MATH"
6996   "")
6997
6998 (define_insn "*umulqihi3_1"
6999   [(set (match_operand:HI 0 "register_operand" "=a")
7000         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7001                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "TARGET_QIMODE_MATH
7004    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7005   "mul{b}\t%2"
7006   [(set_attr "type" "imul")
7007    (set_attr "length_immediate" "0")
7008    (set (attr "athlon_decode")
7009      (if_then_else (eq_attr "cpu" "athlon")
7010         (const_string "vector")
7011         (const_string "direct")))
7012    (set_attr "mode" "QI")])
7013
7014 (define_expand "mulqihi3"
7015   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7017                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7018               (clobber (reg:CC FLAGS_REG))])]
7019   "TARGET_QIMODE_MATH"
7020   "")
7021
7022 (define_insn "*mulqihi3_insn"
7023   [(set (match_operand:HI 0 "register_operand" "=a")
7024         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7025                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7026    (clobber (reg:CC FLAGS_REG))]
7027   "TARGET_QIMODE_MATH
7028    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7029   "imul{b}\t%2"
7030   [(set_attr "type" "imul")
7031    (set_attr "length_immediate" "0")
7032    (set (attr "athlon_decode")
7033      (if_then_else (eq_attr "cpu" "athlon")
7034         (const_string "vector")
7035         (const_string "direct")))
7036    (set_attr "mode" "QI")])
7037
7038 (define_expand "umulditi3"
7039   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7040                    (mult:TI (zero_extend:TI
7041                               (match_operand:DI 1 "nonimmediate_operand" ""))
7042                             (zero_extend:TI
7043                               (match_operand:DI 2 "register_operand" ""))))
7044               (clobber (reg:CC FLAGS_REG))])]
7045   "TARGET_64BIT"
7046   "")
7047
7048 (define_insn "*umulditi3_insn"
7049   [(set (match_operand:TI 0 "register_operand" "=A")
7050         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7051                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7052    (clobber (reg:CC FLAGS_REG))]
7053   "TARGET_64BIT
7054    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7055   "mul{q}\t%2"
7056   [(set_attr "type" "imul")
7057    (set_attr "length_immediate" "0")
7058    (set (attr "athlon_decode")
7059      (if_then_else (eq_attr "cpu" "athlon")
7060         (const_string "vector")
7061         (const_string "double")))
7062    (set_attr "mode" "DI")])
7063
7064 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7065 (define_expand "umulsidi3"
7066   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7067                    (mult:DI (zero_extend:DI
7068                               (match_operand:SI 1 "nonimmediate_operand" ""))
7069                             (zero_extend:DI
7070                               (match_operand:SI 2 "register_operand" ""))))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   "!TARGET_64BIT"
7073   "")
7074
7075 (define_insn "*umulsidi3_insn"
7076   [(set (match_operand:DI 0 "register_operand" "=A")
7077         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7078                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "!TARGET_64BIT
7081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082   "mul{l}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "double")))
7089    (set_attr "mode" "SI")])
7090
7091 (define_expand "mulditi3"
7092   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7093                    (mult:TI (sign_extend:TI
7094                               (match_operand:DI 1 "nonimmediate_operand" ""))
7095                             (sign_extend:TI
7096                               (match_operand:DI 2 "register_operand" ""))))
7097               (clobber (reg:CC FLAGS_REG))])]
7098   "TARGET_64BIT"
7099   "")
7100
7101 (define_insn "*mulditi3_insn"
7102   [(set (match_operand:TI 0 "register_operand" "=A")
7103         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7104                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7105    (clobber (reg:CC FLAGS_REG))]
7106   "TARGET_64BIT
7107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7108   "imul{q}\t%2"
7109   [(set_attr "type" "imul")
7110    (set_attr "length_immediate" "0")
7111    (set (attr "athlon_decode")
7112      (if_then_else (eq_attr "cpu" "athlon")
7113         (const_string "vector")
7114         (const_string "double")))
7115    (set_attr "mode" "DI")])
7116
7117 (define_expand "mulsidi3"
7118   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7119                    (mult:DI (sign_extend:DI
7120                               (match_operand:SI 1 "nonimmediate_operand" ""))
7121                             (sign_extend:DI
7122                               (match_operand:SI 2 "register_operand" ""))))
7123               (clobber (reg:CC FLAGS_REG))])]
7124   "!TARGET_64BIT"
7125   "")
7126
7127 (define_insn "*mulsidi3_insn"
7128   [(set (match_operand:DI 0 "register_operand" "=A")
7129         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7130                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7131    (clobber (reg:CC FLAGS_REG))]
7132   "!TARGET_64BIT
7133    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7134   "imul{l}\t%2"
7135   [(set_attr "type" "imul")
7136    (set_attr "length_immediate" "0")
7137    (set (attr "athlon_decode")
7138      (if_then_else (eq_attr "cpu" "athlon")
7139         (const_string "vector")
7140         (const_string "double")))
7141    (set_attr "mode" "SI")])
7142
7143 (define_expand "umuldi3_highpart"
7144   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7145                    (truncate:DI
7146                      (lshiftrt:TI
7147                        (mult:TI (zero_extend:TI
7148                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7149                                 (zero_extend:TI
7150                                   (match_operand:DI 2 "register_operand" "")))
7151                        (const_int 64))))
7152               (clobber (match_scratch:DI 3 ""))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_64BIT"
7155   "")
7156
7157 (define_insn "*umuldi3_highpart_rex64"
7158   [(set (match_operand:DI 0 "register_operand" "=d")
7159         (truncate:DI
7160           (lshiftrt:TI
7161             (mult:TI (zero_extend:TI
7162                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7163                      (zero_extend:TI
7164                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7165             (const_int 64))))
7166    (clobber (match_scratch:DI 3 "=1"))
7167    (clobber (reg:CC FLAGS_REG))]
7168   "TARGET_64BIT
7169    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7170   "mul{q}\t%2"
7171   [(set_attr "type" "imul")
7172    (set_attr "length_immediate" "0")
7173    (set (attr "athlon_decode")
7174      (if_then_else (eq_attr "cpu" "athlon")
7175         (const_string "vector")
7176         (const_string "double")))
7177    (set_attr "mode" "DI")])
7178
7179 (define_expand "umulsi3_highpart"
7180   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7181                    (truncate:SI
7182                      (lshiftrt:DI
7183                        (mult:DI (zero_extend:DI
7184                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7185                                 (zero_extend:DI
7186                                   (match_operand:SI 2 "register_operand" "")))
7187                        (const_int 32))))
7188               (clobber (match_scratch:SI 3 ""))
7189               (clobber (reg:CC FLAGS_REG))])]
7190   ""
7191   "")
7192
7193 (define_insn "*umulsi3_highpart_insn"
7194   [(set (match_operand:SI 0 "register_operand" "=d")
7195         (truncate:SI
7196           (lshiftrt:DI
7197             (mult:DI (zero_extend:DI
7198                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7199                      (zero_extend:DI
7200                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7201             (const_int 32))))
7202    (clobber (match_scratch:SI 3 "=1"))
7203    (clobber (reg:CC FLAGS_REG))]
7204   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7205   "mul{l}\t%2"
7206   [(set_attr "type" "imul")
7207    (set_attr "length_immediate" "0")
7208    (set (attr "athlon_decode")
7209      (if_then_else (eq_attr "cpu" "athlon")
7210         (const_string "vector")
7211         (const_string "double")))
7212    (set_attr "mode" "SI")])
7213
7214 (define_insn "*umulsi3_highpart_zext"
7215   [(set (match_operand:DI 0 "register_operand" "=d")
7216         (zero_extend:DI (truncate:SI
7217           (lshiftrt:DI
7218             (mult:DI (zero_extend:DI
7219                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7220                      (zero_extend:DI
7221                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7222             (const_int 32)))))
7223    (clobber (match_scratch:SI 3 "=1"))
7224    (clobber (reg:CC FLAGS_REG))]
7225   "TARGET_64BIT
7226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227   "mul{l}\t%2"
7228   [(set_attr "type" "imul")
7229    (set_attr "length_immediate" "0")
7230    (set (attr "athlon_decode")
7231      (if_then_else (eq_attr "cpu" "athlon")
7232         (const_string "vector")
7233         (const_string "double")))
7234    (set_attr "mode" "SI")])
7235
7236 (define_expand "smuldi3_highpart"
7237   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7238                    (truncate:DI
7239                      (lshiftrt:TI
7240                        (mult:TI (sign_extend:TI
7241                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7242                                 (sign_extend:TI
7243                                   (match_operand:DI 2 "register_operand" "")))
7244                        (const_int 64))))
7245               (clobber (match_scratch:DI 3 ""))
7246               (clobber (reg:CC FLAGS_REG))])]
7247   "TARGET_64BIT"
7248   "")
7249
7250 (define_insn "*smuldi3_highpart_rex64"
7251   [(set (match_operand:DI 0 "register_operand" "=d")
7252         (truncate:DI
7253           (lshiftrt:TI
7254             (mult:TI (sign_extend:TI
7255                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7256                      (sign_extend:TI
7257                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7258             (const_int 64))))
7259    (clobber (match_scratch:DI 3 "=1"))
7260    (clobber (reg:CC FLAGS_REG))]
7261   "TARGET_64BIT
7262    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7263   "imul{q}\t%2"
7264   [(set_attr "type" "imul")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "double")))
7269    (set_attr "mode" "DI")])
7270
7271 (define_expand "smulsi3_highpart"
7272   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7273                    (truncate:SI
7274                      (lshiftrt:DI
7275                        (mult:DI (sign_extend:DI
7276                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7277                                 (sign_extend:DI
7278                                   (match_operand:SI 2 "register_operand" "")))
7279                        (const_int 32))))
7280               (clobber (match_scratch:SI 3 ""))
7281               (clobber (reg:CC FLAGS_REG))])]
7282   ""
7283   "")
7284
7285 (define_insn "*smulsi3_highpart_insn"
7286   [(set (match_operand:SI 0 "register_operand" "=d")
7287         (truncate:SI
7288           (lshiftrt:DI
7289             (mult:DI (sign_extend:DI
7290                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7291                      (sign_extend:DI
7292                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7293             (const_int 32))))
7294    (clobber (match_scratch:SI 3 "=1"))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7297   "imul{l}\t%2"
7298   [(set_attr "type" "imul")
7299    (set (attr "athlon_decode")
7300      (if_then_else (eq_attr "cpu" "athlon")
7301         (const_string "vector")
7302         (const_string "double")))
7303    (set_attr "mode" "SI")])
7304
7305 (define_insn "*smulsi3_highpart_zext"
7306   [(set (match_operand:DI 0 "register_operand" "=d")
7307         (zero_extend:DI (truncate:SI
7308           (lshiftrt:DI
7309             (mult:DI (sign_extend:DI
7310                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7311                      (sign_extend:DI
7312                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7313             (const_int 32)))))
7314    (clobber (match_scratch:SI 3 "=1"))
7315    (clobber (reg:CC FLAGS_REG))]
7316   "TARGET_64BIT
7317    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7318   "imul{l}\t%2"
7319   [(set_attr "type" "imul")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "mode" "SI")])
7325
7326 ;; The patterns that match these are at the end of this file.
7327
7328 (define_expand "mulxf3"
7329   [(set (match_operand:XF 0 "register_operand" "")
7330         (mult:XF (match_operand:XF 1 "register_operand" "")
7331                  (match_operand:XF 2 "register_operand" "")))]
7332   "TARGET_80387"
7333   "")
7334
7335 (define_expand "muldf3"
7336   [(set (match_operand:DF 0 "register_operand" "")
7337         (mult:DF (match_operand:DF 1 "register_operand" "")
7338                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7339   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7340   "")
7341
7342 (define_expand "mulsf3"
7343   [(set (match_operand:SF 0 "register_operand" "")
7344         (mult:SF (match_operand:SF 1 "register_operand" "")
7345                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7346   "TARGET_80387 || TARGET_SSE_MATH"
7347   "")
7348 \f
7349 ;; Divide instructions
7350
7351 (define_insn "divqi3"
7352   [(set (match_operand:QI 0 "register_operand" "=a")
7353         (div:QI (match_operand:HI 1 "register_operand" "0")
7354                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7355    (clobber (reg:CC FLAGS_REG))]
7356   "TARGET_QIMODE_MATH"
7357   "idiv{b}\t%2"
7358   [(set_attr "type" "idiv")
7359    (set_attr "mode" "QI")])
7360
7361 (define_insn "udivqi3"
7362   [(set (match_operand:QI 0 "register_operand" "=a")
7363         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7364                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7365    (clobber (reg:CC FLAGS_REG))]
7366   "TARGET_QIMODE_MATH"
7367   "div{b}\t%2"
7368   [(set_attr "type" "idiv")
7369    (set_attr "mode" "QI")])
7370
7371 ;; The patterns that match these are at the end of this file.
7372
7373 (define_expand "divxf3"
7374   [(set (match_operand:XF 0 "register_operand" "")
7375         (div:XF (match_operand:XF 1 "register_operand" "")
7376                 (match_operand:XF 2 "register_operand" "")))]
7377   "TARGET_80387"
7378   "")
7379
7380 (define_expand "divdf3"
7381   [(set (match_operand:DF 0 "register_operand" "")
7382         (div:DF (match_operand:DF 1 "register_operand" "")
7383                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7384    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7385    "")
7386  
7387 (define_expand "divsf3"
7388   [(set (match_operand:SF 0 "register_operand" "")
7389         (div:SF (match_operand:SF 1 "register_operand" "")
7390                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7391   "TARGET_80387 || TARGET_SSE_MATH"
7392   "")
7393 \f
7394 ;; Remainder instructions.
7395
7396 (define_expand "divmoddi4"
7397   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7398                    (div:DI (match_operand:DI 1 "register_operand" "")
7399                            (match_operand:DI 2 "nonimmediate_operand" "")))
7400               (set (match_operand:DI 3 "register_operand" "")
7401                    (mod:DI (match_dup 1) (match_dup 2)))
7402               (clobber (reg:CC FLAGS_REG))])]
7403   "TARGET_64BIT"
7404   "")
7405
7406 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7407 ;; Penalize eax case slightly because it results in worse scheduling
7408 ;; of code.
7409 (define_insn "*divmoddi4_nocltd_rex64"
7410   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7411         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7412                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7413    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7414         (mod:DI (match_dup 2) (match_dup 3)))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7417   "#"
7418   [(set_attr "type" "multi")])
7419
7420 (define_insn "*divmoddi4_cltd_rex64"
7421   [(set (match_operand:DI 0 "register_operand" "=a")
7422         (div:DI (match_operand:DI 2 "register_operand" "a")
7423                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7424    (set (match_operand:DI 1 "register_operand" "=&d")
7425         (mod:DI (match_dup 2) (match_dup 3)))
7426    (clobber (reg:CC FLAGS_REG))]
7427   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7428   "#"
7429   [(set_attr "type" "multi")])
7430
7431 (define_insn "*divmoddi_noext_rex64"
7432   [(set (match_operand:DI 0 "register_operand" "=a")
7433         (div:DI (match_operand:DI 1 "register_operand" "0")
7434                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7435    (set (match_operand:DI 3 "register_operand" "=d")
7436         (mod:DI (match_dup 1) (match_dup 2)))
7437    (use (match_operand:DI 4 "register_operand" "3"))
7438    (clobber (reg:CC FLAGS_REG))]
7439   "TARGET_64BIT"
7440   "idiv{q}\t%2"
7441   [(set_attr "type" "idiv")
7442    (set_attr "mode" "DI")])
7443
7444 (define_split
7445   [(set (match_operand:DI 0 "register_operand" "")
7446         (div:DI (match_operand:DI 1 "register_operand" "")
7447                 (match_operand:DI 2 "nonimmediate_operand" "")))
7448    (set (match_operand:DI 3 "register_operand" "")
7449         (mod:DI (match_dup 1) (match_dup 2)))
7450    (clobber (reg:CC FLAGS_REG))]
7451   "TARGET_64BIT && reload_completed"
7452   [(parallel [(set (match_dup 3)
7453                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7454               (clobber (reg:CC FLAGS_REG))])
7455    (parallel [(set (match_dup 0)
7456                    (div:DI (reg:DI 0) (match_dup 2)))
7457               (set (match_dup 3)
7458                    (mod:DI (reg:DI 0) (match_dup 2)))
7459               (use (match_dup 3))
7460               (clobber (reg:CC FLAGS_REG))])]
7461 {
7462   /* Avoid use of cltd in favor of a mov+shift.  */
7463   if (!TARGET_USE_CLTD && !optimize_size)
7464     {
7465       if (true_regnum (operands[1]))
7466         emit_move_insn (operands[0], operands[1]);
7467       else
7468         emit_move_insn (operands[3], operands[1]);
7469       operands[4] = operands[3];
7470     }
7471   else
7472     {
7473       gcc_assert (!true_regnum (operands[1]));
7474       operands[4] = operands[1];
7475     }
7476 })
7477
7478
7479 (define_expand "divmodsi4"
7480   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7481                    (div:SI (match_operand:SI 1 "register_operand" "")
7482                            (match_operand:SI 2 "nonimmediate_operand" "")))
7483               (set (match_operand:SI 3 "register_operand" "")
7484                    (mod:SI (match_dup 1) (match_dup 2)))
7485               (clobber (reg:CC FLAGS_REG))])]
7486   ""
7487   "")
7488
7489 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7490 ;; Penalize eax case slightly because it results in worse scheduling
7491 ;; of code.
7492 (define_insn "*divmodsi4_nocltd"
7493   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7494         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7495                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7496    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7497         (mod:SI (match_dup 2) (match_dup 3)))
7498    (clobber (reg:CC FLAGS_REG))]
7499   "!optimize_size && !TARGET_USE_CLTD"
7500   "#"
7501   [(set_attr "type" "multi")])
7502
7503 (define_insn "*divmodsi4_cltd"
7504   [(set (match_operand:SI 0 "register_operand" "=a")
7505         (div:SI (match_operand:SI 2 "register_operand" "a")
7506                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7507    (set (match_operand:SI 1 "register_operand" "=&d")
7508         (mod:SI (match_dup 2) (match_dup 3)))
7509    (clobber (reg:CC FLAGS_REG))]
7510   "optimize_size || TARGET_USE_CLTD"
7511   "#"
7512   [(set_attr "type" "multi")])
7513
7514 (define_insn "*divmodsi_noext"
7515   [(set (match_operand:SI 0 "register_operand" "=a")
7516         (div:SI (match_operand:SI 1 "register_operand" "0")
7517                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7518    (set (match_operand:SI 3 "register_operand" "=d")
7519         (mod:SI (match_dup 1) (match_dup 2)))
7520    (use (match_operand:SI 4 "register_operand" "3"))
7521    (clobber (reg:CC FLAGS_REG))]
7522   ""
7523   "idiv{l}\t%2"
7524   [(set_attr "type" "idiv")
7525    (set_attr "mode" "SI")])
7526
7527 (define_split
7528   [(set (match_operand:SI 0 "register_operand" "")
7529         (div:SI (match_operand:SI 1 "register_operand" "")
7530                 (match_operand:SI 2 "nonimmediate_operand" "")))
7531    (set (match_operand:SI 3 "register_operand" "")
7532         (mod:SI (match_dup 1) (match_dup 2)))
7533    (clobber (reg:CC FLAGS_REG))]
7534   "reload_completed"
7535   [(parallel [(set (match_dup 3)
7536                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7537               (clobber (reg:CC FLAGS_REG))])
7538    (parallel [(set (match_dup 0)
7539                    (div:SI (reg:SI 0) (match_dup 2)))
7540               (set (match_dup 3)
7541                    (mod:SI (reg:SI 0) (match_dup 2)))
7542               (use (match_dup 3))
7543               (clobber (reg:CC FLAGS_REG))])]
7544 {
7545   /* Avoid use of cltd in favor of a mov+shift.  */
7546   if (!TARGET_USE_CLTD && !optimize_size)
7547     {
7548       if (true_regnum (operands[1]))
7549         emit_move_insn (operands[0], operands[1]);
7550       else
7551         emit_move_insn (operands[3], operands[1]);
7552       operands[4] = operands[3];
7553     }
7554   else
7555     {
7556       gcc_assert (!true_regnum (operands[1]));
7557       operands[4] = operands[1];
7558     }
7559 })
7560 ;; %%% Split me.
7561 (define_insn "divmodhi4"
7562   [(set (match_operand:HI 0 "register_operand" "=a")
7563         (div:HI (match_operand:HI 1 "register_operand" "0")
7564                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7565    (set (match_operand:HI 3 "register_operand" "=&d")
7566         (mod:HI (match_dup 1) (match_dup 2)))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "TARGET_HIMODE_MATH"
7569   "cwtd\;idiv{w}\t%2"
7570   [(set_attr "type" "multi")
7571    (set_attr "length_immediate" "0")
7572    (set_attr "mode" "SI")])
7573
7574 (define_insn "udivmoddi4"
7575   [(set (match_operand:DI 0 "register_operand" "=a")
7576         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7577                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7578    (set (match_operand:DI 3 "register_operand" "=&d")
7579         (umod:DI (match_dup 1) (match_dup 2)))
7580    (clobber (reg:CC FLAGS_REG))]
7581   "TARGET_64BIT"
7582   "xor{q}\t%3, %3\;div{q}\t%2"
7583   [(set_attr "type" "multi")
7584    (set_attr "length_immediate" "0")
7585    (set_attr "mode" "DI")])
7586
7587 (define_insn "*udivmoddi4_noext"
7588   [(set (match_operand:DI 0 "register_operand" "=a")
7589         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7590                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7591    (set (match_operand:DI 3 "register_operand" "=d")
7592         (umod:DI (match_dup 1) (match_dup 2)))
7593    (use (match_dup 3))
7594    (clobber (reg:CC FLAGS_REG))]
7595   "TARGET_64BIT"
7596   "div{q}\t%2"
7597   [(set_attr "type" "idiv")
7598    (set_attr "mode" "DI")])
7599
7600 (define_split
7601   [(set (match_operand:DI 0 "register_operand" "")
7602         (udiv:DI (match_operand:DI 1 "register_operand" "")
7603                  (match_operand:DI 2 "nonimmediate_operand" "")))
7604    (set (match_operand:DI 3 "register_operand" "")
7605         (umod:DI (match_dup 1) (match_dup 2)))
7606    (clobber (reg:CC FLAGS_REG))]
7607   "TARGET_64BIT && reload_completed"
7608   [(set (match_dup 3) (const_int 0))
7609    (parallel [(set (match_dup 0)
7610                    (udiv:DI (match_dup 1) (match_dup 2)))
7611               (set (match_dup 3)
7612                    (umod:DI (match_dup 1) (match_dup 2)))
7613               (use (match_dup 3))
7614               (clobber (reg:CC FLAGS_REG))])]
7615   "")
7616
7617 (define_insn "udivmodsi4"
7618   [(set (match_operand:SI 0 "register_operand" "=a")
7619         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7620                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7621    (set (match_operand:SI 3 "register_operand" "=&d")
7622         (umod:SI (match_dup 1) (match_dup 2)))
7623    (clobber (reg:CC FLAGS_REG))]
7624   ""
7625   "xor{l}\t%3, %3\;div{l}\t%2"
7626   [(set_attr "type" "multi")
7627    (set_attr "length_immediate" "0")
7628    (set_attr "mode" "SI")])
7629
7630 (define_insn "*udivmodsi4_noext"
7631   [(set (match_operand:SI 0 "register_operand" "=a")
7632         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7633                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7634    (set (match_operand:SI 3 "register_operand" "=d")
7635         (umod:SI (match_dup 1) (match_dup 2)))
7636    (use (match_dup 3))
7637    (clobber (reg:CC FLAGS_REG))]
7638   ""
7639   "div{l}\t%2"
7640   [(set_attr "type" "idiv")
7641    (set_attr "mode" "SI")])
7642
7643 (define_split
7644   [(set (match_operand:SI 0 "register_operand" "")
7645         (udiv:SI (match_operand:SI 1 "register_operand" "")
7646                  (match_operand:SI 2 "nonimmediate_operand" "")))
7647    (set (match_operand:SI 3 "register_operand" "")
7648         (umod:SI (match_dup 1) (match_dup 2)))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "reload_completed"
7651   [(set (match_dup 3) (const_int 0))
7652    (parallel [(set (match_dup 0)
7653                    (udiv:SI (match_dup 1) (match_dup 2)))
7654               (set (match_dup 3)
7655                    (umod:SI (match_dup 1) (match_dup 2)))
7656               (use (match_dup 3))
7657               (clobber (reg:CC FLAGS_REG))])]
7658   "")
7659
7660 (define_expand "udivmodhi4"
7661   [(set (match_dup 4) (const_int 0))
7662    (parallel [(set (match_operand:HI 0 "register_operand" "")
7663                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7664                             (match_operand:HI 2 "nonimmediate_operand" "")))
7665               (set (match_operand:HI 3 "register_operand" "")
7666                    (umod:HI (match_dup 1) (match_dup 2)))
7667               (use (match_dup 4))
7668               (clobber (reg:CC FLAGS_REG))])]
7669   "TARGET_HIMODE_MATH"
7670   "operands[4] = gen_reg_rtx (HImode);")
7671
7672 (define_insn "*udivmodhi_noext"
7673   [(set (match_operand:HI 0 "register_operand" "=a")
7674         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7675                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7676    (set (match_operand:HI 3 "register_operand" "=d")
7677         (umod:HI (match_dup 1) (match_dup 2)))
7678    (use (match_operand:HI 4 "register_operand" "3"))
7679    (clobber (reg:CC FLAGS_REG))]
7680   ""
7681   "div{w}\t%2"
7682   [(set_attr "type" "idiv")
7683    (set_attr "mode" "HI")])
7684
7685 ;; We cannot use div/idiv for double division, because it causes
7686 ;; "division by zero" on the overflow and that's not what we expect
7687 ;; from truncate.  Because true (non truncating) double division is
7688 ;; never generated, we can't create this insn anyway.
7689 ;
7690 ;(define_insn ""
7691 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7692 ;       (truncate:SI
7693 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7694 ;                  (zero_extend:DI
7695 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7696 ;   (set (match_operand:SI 3 "register_operand" "=d")
7697 ;       (truncate:SI
7698 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7699 ;   (clobber (reg:CC FLAGS_REG))]
7700 ;  ""
7701 ;  "div{l}\t{%2, %0|%0, %2}"
7702 ;  [(set_attr "type" "idiv")])
7703 \f
7704 ;;- Logical AND instructions
7705
7706 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7707 ;; Note that this excludes ah.
7708
7709 (define_insn "*testdi_1_rex64"
7710   [(set (reg FLAGS_REG)
7711         (compare
7712           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7713                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7714           (const_int 0)))]
7715   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7716    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7717   "@
7718    test{l}\t{%k1, %k0|%k0, %k1}
7719    test{l}\t{%k1, %k0|%k0, %k1}
7720    test{q}\t{%1, %0|%0, %1}
7721    test{q}\t{%1, %0|%0, %1}
7722    test{q}\t{%1, %0|%0, %1}"
7723   [(set_attr "type" "test")
7724    (set_attr "modrm" "0,1,0,1,1")
7725    (set_attr "mode" "SI,SI,DI,DI,DI")
7726    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7727
7728 (define_insn "testsi_1"
7729   [(set (reg FLAGS_REG)
7730         (compare
7731           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7732                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7733           (const_int 0)))]
7734   "ix86_match_ccmode (insn, CCNOmode)
7735    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7736   "test{l}\t{%1, %0|%0, %1}"
7737   [(set_attr "type" "test")
7738    (set_attr "modrm" "0,1,1")
7739    (set_attr "mode" "SI")
7740    (set_attr "pent_pair" "uv,np,uv")])
7741
7742 (define_expand "testsi_ccno_1"
7743   [(set (reg:CCNO FLAGS_REG)
7744         (compare:CCNO
7745           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7746                   (match_operand:SI 1 "nonmemory_operand" ""))
7747           (const_int 0)))]
7748   ""
7749   "")
7750
7751 (define_insn "*testhi_1"
7752   [(set (reg FLAGS_REG)
7753         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7754                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7755                  (const_int 0)))]
7756   "ix86_match_ccmode (insn, CCNOmode)
7757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7758   "test{w}\t{%1, %0|%0, %1}"
7759   [(set_attr "type" "test")
7760    (set_attr "modrm" "0,1,1")
7761    (set_attr "mode" "HI")
7762    (set_attr "pent_pair" "uv,np,uv")])
7763
7764 (define_expand "testqi_ccz_1"
7765   [(set (reg:CCZ FLAGS_REG)
7766         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7767                              (match_operand:QI 1 "nonmemory_operand" ""))
7768                  (const_int 0)))]
7769   ""
7770   "")
7771
7772 (define_insn "*testqi_1_maybe_si"
7773   [(set (reg FLAGS_REG)
7774         (compare
7775           (and:QI
7776             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7777             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7778           (const_int 0)))]
7779    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7780     && ix86_match_ccmode (insn,
7781                          GET_CODE (operands[1]) == CONST_INT
7782                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7783 {
7784   if (which_alternative == 3)
7785     {
7786       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7787         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7788       return "test{l}\t{%1, %k0|%k0, %1}";
7789     }
7790   return "test{b}\t{%1, %0|%0, %1}";
7791 }
7792   [(set_attr "type" "test")
7793    (set_attr "modrm" "0,1,1,1")
7794    (set_attr "mode" "QI,QI,QI,SI")
7795    (set_attr "pent_pair" "uv,np,uv,np")])
7796
7797 (define_insn "*testqi_1"
7798   [(set (reg FLAGS_REG)
7799         (compare
7800           (and:QI
7801             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7802             (match_operand:QI 1 "general_operand" "n,n,qn"))
7803           (const_int 0)))]
7804   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7805    && ix86_match_ccmode (insn, CCNOmode)"
7806   "test{b}\t{%1, %0|%0, %1}"
7807   [(set_attr "type" "test")
7808    (set_attr "modrm" "0,1,1")
7809    (set_attr "mode" "QI")
7810    (set_attr "pent_pair" "uv,np,uv")])
7811
7812 (define_expand "testqi_ext_ccno_0"
7813   [(set (reg:CCNO FLAGS_REG)
7814         (compare:CCNO
7815           (and:SI
7816             (zero_extract:SI
7817               (match_operand 0 "ext_register_operand" "")
7818               (const_int 8)
7819               (const_int 8))
7820             (match_operand 1 "const_int_operand" ""))
7821           (const_int 0)))]
7822   ""
7823   "")
7824
7825 (define_insn "*testqi_ext_0"
7826   [(set (reg FLAGS_REG)
7827         (compare
7828           (and:SI
7829             (zero_extract:SI
7830               (match_operand 0 "ext_register_operand" "Q")
7831               (const_int 8)
7832               (const_int 8))
7833             (match_operand 1 "const_int_operand" "n"))
7834           (const_int 0)))]
7835   "ix86_match_ccmode (insn, CCNOmode)"
7836   "test{b}\t{%1, %h0|%h0, %1}"
7837   [(set_attr "type" "test")
7838    (set_attr "mode" "QI")
7839    (set_attr "length_immediate" "1")
7840    (set_attr "pent_pair" "np")])
7841
7842 (define_insn "*testqi_ext_1"
7843   [(set (reg FLAGS_REG)
7844         (compare
7845           (and:SI
7846             (zero_extract:SI
7847               (match_operand 0 "ext_register_operand" "Q")
7848               (const_int 8)
7849               (const_int 8))
7850             (zero_extend:SI
7851               (match_operand:QI 1 "general_operand" "Qm")))
7852           (const_int 0)))]
7853   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7855   "test{b}\t{%1, %h0|%h0, %1}"
7856   [(set_attr "type" "test")
7857    (set_attr "mode" "QI")])
7858
7859 (define_insn "*testqi_ext_1_rex64"
7860   [(set (reg FLAGS_REG)
7861         (compare
7862           (and:SI
7863             (zero_extract:SI
7864               (match_operand 0 "ext_register_operand" "Q")
7865               (const_int 8)
7866               (const_int 8))
7867             (zero_extend:SI
7868               (match_operand:QI 1 "register_operand" "Q")))
7869           (const_int 0)))]
7870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7871   "test{b}\t{%1, %h0|%h0, %1}"
7872   [(set_attr "type" "test")
7873    (set_attr "mode" "QI")])
7874
7875 (define_insn "*testqi_ext_2"
7876   [(set (reg FLAGS_REG)
7877         (compare
7878           (and:SI
7879             (zero_extract:SI
7880               (match_operand 0 "ext_register_operand" "Q")
7881               (const_int 8)
7882               (const_int 8))
7883             (zero_extract:SI
7884               (match_operand 1 "ext_register_operand" "Q")
7885               (const_int 8)
7886               (const_int 8)))
7887           (const_int 0)))]
7888   "ix86_match_ccmode (insn, CCNOmode)"
7889   "test{b}\t{%h1, %h0|%h0, %h1}"
7890   [(set_attr "type" "test")
7891    (set_attr "mode" "QI")])
7892
7893 ;; Combine likes to form bit extractions for some tests.  Humor it.
7894 (define_insn "*testqi_ext_3"
7895   [(set (reg FLAGS_REG)
7896         (compare (zero_extract:SI
7897                    (match_operand 0 "nonimmediate_operand" "rm")
7898                    (match_operand:SI 1 "const_int_operand" "")
7899                    (match_operand:SI 2 "const_int_operand" ""))
7900                  (const_int 0)))]
7901   "ix86_match_ccmode (insn, CCNOmode)
7902    && INTVAL (operands[1]) > 0
7903    && INTVAL (operands[2]) >= 0
7904    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7905    && (GET_MODE (operands[0]) == SImode
7906        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7907        || GET_MODE (operands[0]) == HImode
7908        || GET_MODE (operands[0]) == QImode)"
7909   "#")
7910
7911 (define_insn "*testqi_ext_3_rex64"
7912   [(set (reg FLAGS_REG)
7913         (compare (zero_extract:DI
7914                    (match_operand 0 "nonimmediate_operand" "rm")
7915                    (match_operand:DI 1 "const_int_operand" "")
7916                    (match_operand:DI 2 "const_int_operand" ""))
7917                  (const_int 0)))]
7918   "TARGET_64BIT
7919    && ix86_match_ccmode (insn, CCNOmode)
7920    && INTVAL (operands[1]) > 0
7921    && INTVAL (operands[2]) >= 0
7922    /* Ensure that resulting mask is zero or sign extended operand.  */
7923    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7924        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7925            && INTVAL (operands[1]) > 32))
7926    && (GET_MODE (operands[0]) == SImode
7927        || GET_MODE (operands[0]) == DImode
7928        || GET_MODE (operands[0]) == HImode
7929        || GET_MODE (operands[0]) == QImode)"
7930   "#")
7931
7932 (define_split
7933   [(set (match_operand 0 "flags_reg_operand" "")
7934         (match_operator 1 "compare_operator"
7935           [(zero_extract
7936              (match_operand 2 "nonimmediate_operand" "")
7937              (match_operand 3 "const_int_operand" "")
7938              (match_operand 4 "const_int_operand" ""))
7939            (const_int 0)]))]
7940   "ix86_match_ccmode (insn, CCNOmode)"
7941   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7942 {
7943   rtx val = operands[2];
7944   HOST_WIDE_INT len = INTVAL (operands[3]);
7945   HOST_WIDE_INT pos = INTVAL (operands[4]);
7946   HOST_WIDE_INT mask;
7947   enum machine_mode mode, submode;
7948
7949   mode = GET_MODE (val);
7950   if (GET_CODE (val) == MEM)
7951     {
7952       /* ??? Combine likes to put non-volatile mem extractions in QImode
7953          no matter the size of the test.  So find a mode that works.  */
7954       if (! MEM_VOLATILE_P (val))
7955         {
7956           mode = smallest_mode_for_size (pos + len, MODE_INT);
7957           val = adjust_address (val, mode, 0);
7958         }
7959     }
7960   else if (GET_CODE (val) == SUBREG
7961            && (submode = GET_MODE (SUBREG_REG (val)),
7962                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7963            && pos + len <= GET_MODE_BITSIZE (submode))
7964     {
7965       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7966       mode = submode;
7967       val = SUBREG_REG (val);
7968     }
7969   else if (mode == HImode && pos + len <= 8)
7970     {
7971       /* Small HImode tests can be converted to QImode.  */
7972       mode = QImode;
7973       val = gen_lowpart (QImode, val);
7974     }
7975
7976   if (len == HOST_BITS_PER_WIDE_INT)
7977     mask = -1;
7978   else
7979     mask = ((HOST_WIDE_INT)1 << len) - 1;
7980   mask <<= pos;
7981
7982   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7983 })
7984
7985 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7986 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7987 ;; this is relatively important trick.
7988 ;; Do the conversion only post-reload to avoid limiting of the register class
7989 ;; to QI regs.
7990 (define_split
7991   [(set (match_operand 0 "flags_reg_operand" "")
7992         (match_operator 1 "compare_operator"
7993           [(and (match_operand 2 "register_operand" "")
7994                 (match_operand 3 "const_int_operand" ""))
7995            (const_int 0)]))]
7996    "reload_completed
7997     && QI_REG_P (operands[2])
7998     && GET_MODE (operands[2]) != QImode
7999     && ((ix86_match_ccmode (insn, CCZmode)
8000          && !(INTVAL (operands[3]) & ~(255 << 8)))
8001         || (ix86_match_ccmode (insn, CCNOmode)
8002             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8003   [(set (match_dup 0)
8004         (match_op_dup 1
8005           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8006                    (match_dup 3))
8007            (const_int 0)]))]
8008   "operands[2] = gen_lowpart (SImode, operands[2]);
8009    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8010
8011 (define_split
8012   [(set (match_operand 0 "flags_reg_operand" "")
8013         (match_operator 1 "compare_operator"
8014           [(and (match_operand 2 "nonimmediate_operand" "")
8015                 (match_operand 3 "const_int_operand" ""))
8016            (const_int 0)]))]
8017    "reload_completed
8018     && GET_MODE (operands[2]) != QImode
8019     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8020     && ((ix86_match_ccmode (insn, CCZmode)
8021          && !(INTVAL (operands[3]) & ~255))
8022         || (ix86_match_ccmode (insn, CCNOmode)
8023             && !(INTVAL (operands[3]) & ~127)))"
8024   [(set (match_dup 0)
8025         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8026                          (const_int 0)]))]
8027   "operands[2] = gen_lowpart (QImode, operands[2]);
8028    operands[3] = gen_lowpart (QImode, operands[3]);")
8029
8030
8031 ;; %%% This used to optimize known byte-wide and operations to memory,
8032 ;; and sometimes to QImode registers.  If this is considered useful,
8033 ;; it should be done with splitters.
8034
8035 (define_expand "anddi3"
8036   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8037         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8038                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "TARGET_64BIT"
8041   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8042
8043 (define_insn "*anddi_1_rex64"
8044   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8045         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8046                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8049 {
8050   switch (get_attr_type (insn))
8051     {
8052     case TYPE_IMOVX:
8053       {
8054         enum machine_mode mode;
8055
8056         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8057         if (INTVAL (operands[2]) == 0xff)
8058           mode = QImode;
8059         else
8060           {
8061             gcc_assert (INTVAL (operands[2]) == 0xffff);
8062             mode = HImode;
8063           }
8064         
8065         operands[1] = gen_lowpart (mode, operands[1]);
8066         if (mode == QImode)
8067           return "movz{bq|x}\t{%1,%0|%0, %1}";
8068         else
8069           return "movz{wq|x}\t{%1,%0|%0, %1}";
8070       }
8071
8072     default:
8073       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8074       if (get_attr_mode (insn) == MODE_SI)
8075         return "and{l}\t{%k2, %k0|%k0, %k2}";
8076       else
8077         return "and{q}\t{%2, %0|%0, %2}";
8078     }
8079 }
8080   [(set_attr "type" "alu,alu,alu,imovx")
8081    (set_attr "length_immediate" "*,*,*,0")
8082    (set_attr "mode" "SI,DI,DI,DI")])
8083
8084 (define_insn "*anddi_2"
8085   [(set (reg FLAGS_REG)
8086         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8087                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8088                  (const_int 0)))
8089    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8090         (and:DI (match_dup 1) (match_dup 2)))]
8091   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092    && ix86_binary_operator_ok (AND, DImode, operands)"
8093   "@
8094    and{l}\t{%k2, %k0|%k0, %k2}
8095    and{q}\t{%2, %0|%0, %2}
8096    and{q}\t{%2, %0|%0, %2}"
8097   [(set_attr "type" "alu")
8098    (set_attr "mode" "SI,DI,DI")])
8099
8100 (define_expand "andsi3"
8101   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8102         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8103                 (match_operand:SI 2 "general_operand" "")))
8104    (clobber (reg:CC FLAGS_REG))]
8105   ""
8106   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8107
8108 (define_insn "*andsi_1"
8109   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8110         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8111                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8112    (clobber (reg:CC FLAGS_REG))]
8113   "ix86_binary_operator_ok (AND, SImode, operands)"
8114 {
8115   switch (get_attr_type (insn))
8116     {
8117     case TYPE_IMOVX:
8118       {
8119         enum machine_mode mode;
8120
8121         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8122         if (INTVAL (operands[2]) == 0xff)
8123           mode = QImode;
8124         else
8125           {
8126             gcc_assert (INTVAL (operands[2]) == 0xffff);
8127             mode = HImode;
8128           }
8129         
8130         operands[1] = gen_lowpart (mode, operands[1]);
8131         if (mode == QImode)
8132           return "movz{bl|x}\t{%1,%0|%0, %1}";
8133         else
8134           return "movz{wl|x}\t{%1,%0|%0, %1}";
8135       }
8136
8137     default:
8138       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8139       return "and{l}\t{%2, %0|%0, %2}";
8140     }
8141 }
8142   [(set_attr "type" "alu,alu,imovx")
8143    (set_attr "length_immediate" "*,*,0")
8144    (set_attr "mode" "SI")])
8145
8146 (define_split
8147   [(set (match_operand 0 "register_operand" "")
8148         (and (match_dup 0)
8149              (const_int -65536)))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8152   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8153   "operands[1] = gen_lowpart (HImode, operands[0]);")
8154
8155 (define_split
8156   [(set (match_operand 0 "ext_register_operand" "")
8157         (and (match_dup 0)
8158              (const_int -256)))
8159    (clobber (reg:CC FLAGS_REG))]
8160   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8161   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8162   "operands[1] = gen_lowpart (QImode, operands[0]);")
8163
8164 (define_split
8165   [(set (match_operand 0 "ext_register_operand" "")
8166         (and (match_dup 0)
8167              (const_int -65281)))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8170   [(parallel [(set (zero_extract:SI (match_dup 0)
8171                                     (const_int 8)
8172                                     (const_int 8))
8173                    (xor:SI 
8174                      (zero_extract:SI (match_dup 0)
8175                                       (const_int 8)
8176                                       (const_int 8))
8177                      (zero_extract:SI (match_dup 0)
8178                                       (const_int 8)
8179                                       (const_int 8))))
8180               (clobber (reg:CC FLAGS_REG))])]
8181   "operands[0] = gen_lowpart (SImode, operands[0]);")
8182
8183 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8184 (define_insn "*andsi_1_zext"
8185   [(set (match_operand:DI 0 "register_operand" "=r")
8186         (zero_extend:DI
8187           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8188                   (match_operand:SI 2 "general_operand" "rim"))))
8189    (clobber (reg:CC FLAGS_REG))]
8190   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8191   "and{l}\t{%2, %k0|%k0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "SI")])
8194
8195 (define_insn "*andsi_2"
8196   [(set (reg FLAGS_REG)
8197         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8198                          (match_operand:SI 2 "general_operand" "rim,ri"))
8199                  (const_int 0)))
8200    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8201         (and:SI (match_dup 1) (match_dup 2)))]
8202   "ix86_match_ccmode (insn, CCNOmode)
8203    && ix86_binary_operator_ok (AND, SImode, operands)"
8204   "and{l}\t{%2, %0|%0, %2}"
8205   [(set_attr "type" "alu")
8206    (set_attr "mode" "SI")])
8207
8208 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8209 (define_insn "*andsi_2_zext"
8210   [(set (reg FLAGS_REG)
8211         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8212                          (match_operand:SI 2 "general_operand" "rim"))
8213                  (const_int 0)))
8214    (set (match_operand:DI 0 "register_operand" "=r")
8215         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8216   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8217    && ix86_binary_operator_ok (AND, SImode, operands)"
8218   "and{l}\t{%2, %k0|%k0, %2}"
8219   [(set_attr "type" "alu")
8220    (set_attr "mode" "SI")])
8221
8222 (define_expand "andhi3"
8223   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8224         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8225                 (match_operand:HI 2 "general_operand" "")))
8226    (clobber (reg:CC FLAGS_REG))]
8227   "TARGET_HIMODE_MATH"
8228   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8229
8230 (define_insn "*andhi_1"
8231   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8232         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8233                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "ix86_binary_operator_ok (AND, HImode, operands)"
8236 {
8237   switch (get_attr_type (insn))
8238     {
8239     case TYPE_IMOVX:
8240       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8241       gcc_assert (INTVAL (operands[2]) == 0xff);
8242       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8243
8244     default:
8245       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8246
8247       return "and{w}\t{%2, %0|%0, %2}";
8248     }
8249 }
8250   [(set_attr "type" "alu,alu,imovx")
8251    (set_attr "length_immediate" "*,*,0")
8252    (set_attr "mode" "HI,HI,SI")])
8253
8254 (define_insn "*andhi_2"
8255   [(set (reg FLAGS_REG)
8256         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8257                          (match_operand:HI 2 "general_operand" "rim,ri"))
8258                  (const_int 0)))
8259    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8260         (and:HI (match_dup 1) (match_dup 2)))]
8261   "ix86_match_ccmode (insn, CCNOmode)
8262    && ix86_binary_operator_ok (AND, HImode, operands)"
8263   "and{w}\t{%2, %0|%0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "mode" "HI")])
8266
8267 (define_expand "andqi3"
8268   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8269         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8270                 (match_operand:QI 2 "general_operand" "")))
8271    (clobber (reg:CC FLAGS_REG))]
8272   "TARGET_QIMODE_MATH"
8273   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8274
8275 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8276 (define_insn "*andqi_1"
8277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8278         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8279                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "ix86_binary_operator_ok (AND, QImode, operands)"
8282   "@
8283    and{b}\t{%2, %0|%0, %2}
8284    and{b}\t{%2, %0|%0, %2}
8285    and{l}\t{%k2, %k0|%k0, %k2}"
8286   [(set_attr "type" "alu")
8287    (set_attr "mode" "QI,QI,SI")])
8288
8289 (define_insn "*andqi_1_slp"
8290   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8291         (and:QI (match_dup 0)
8292                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8293    (clobber (reg:CC FLAGS_REG))]
8294   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8295    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8296   "and{b}\t{%1, %0|%0, %1}"
8297   [(set_attr "type" "alu1")
8298    (set_attr "mode" "QI")])
8299
8300 (define_insn "*andqi_2_maybe_si"
8301   [(set (reg FLAGS_REG)
8302         (compare (and:QI
8303                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8304                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8305                  (const_int 0)))
8306    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8307         (and:QI (match_dup 1) (match_dup 2)))]
8308   "ix86_binary_operator_ok (AND, QImode, operands)
8309    && ix86_match_ccmode (insn,
8310                          GET_CODE (operands[2]) == CONST_INT
8311                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8312 {
8313   if (which_alternative == 2)
8314     {
8315       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8316         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8317       return "and{l}\t{%2, %k0|%k0, %2}";
8318     }
8319   return "and{b}\t{%2, %0|%0, %2}";
8320 }
8321   [(set_attr "type" "alu")
8322    (set_attr "mode" "QI,QI,SI")])
8323
8324 (define_insn "*andqi_2"
8325   [(set (reg FLAGS_REG)
8326         (compare (and:QI
8327                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8328                    (match_operand:QI 2 "general_operand" "qim,qi"))
8329                  (const_int 0)))
8330    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8331         (and:QI (match_dup 1) (match_dup 2)))]
8332   "ix86_match_ccmode (insn, CCNOmode)
8333    && ix86_binary_operator_ok (AND, QImode, operands)"
8334   "and{b}\t{%2, %0|%0, %2}"
8335   [(set_attr "type" "alu")
8336    (set_attr "mode" "QI")])
8337
8338 (define_insn "*andqi_2_slp"
8339   [(set (reg FLAGS_REG)
8340         (compare (and:QI
8341                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8342                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8343                  (const_int 0)))
8344    (set (strict_low_part (match_dup 0))
8345         (and:QI (match_dup 0) (match_dup 1)))]
8346   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8347    && ix86_match_ccmode (insn, CCNOmode)
8348    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8349   "and{b}\t{%1, %0|%0, %1}"
8350   [(set_attr "type" "alu1")
8351    (set_attr "mode" "QI")])
8352
8353 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8354 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8355 ;; for a QImode operand, which of course failed.
8356
8357 (define_insn "andqi_ext_0"
8358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359                          (const_int 8)
8360                          (const_int 8))
8361         (and:SI 
8362           (zero_extract:SI
8363             (match_operand 1 "ext_register_operand" "0")
8364             (const_int 8)
8365             (const_int 8))
8366           (match_operand 2 "const_int_operand" "n")))
8367    (clobber (reg:CC FLAGS_REG))]
8368   ""
8369   "and{b}\t{%2, %h0|%h0, %2}"
8370   [(set_attr "type" "alu")
8371    (set_attr "length_immediate" "1")
8372    (set_attr "mode" "QI")])
8373
8374 ;; Generated by peephole translating test to and.  This shows up
8375 ;; often in fp comparisons.
8376
8377 (define_insn "*andqi_ext_0_cc"
8378   [(set (reg FLAGS_REG)
8379         (compare
8380           (and:SI
8381             (zero_extract:SI
8382               (match_operand 1 "ext_register_operand" "0")
8383               (const_int 8)
8384               (const_int 8))
8385             (match_operand 2 "const_int_operand" "n"))
8386           (const_int 0)))
8387    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388                          (const_int 8)
8389                          (const_int 8))
8390         (and:SI 
8391           (zero_extract:SI
8392             (match_dup 1)
8393             (const_int 8)
8394             (const_int 8))
8395           (match_dup 2)))]
8396   "ix86_match_ccmode (insn, CCNOmode)"
8397   "and{b}\t{%2, %h0|%h0, %2}"
8398   [(set_attr "type" "alu")
8399    (set_attr "length_immediate" "1")
8400    (set_attr "mode" "QI")])
8401
8402 (define_insn "*andqi_ext_1"
8403   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404                          (const_int 8)
8405                          (const_int 8))
8406         (and:SI 
8407           (zero_extract:SI
8408             (match_operand 1 "ext_register_operand" "0")
8409             (const_int 8)
8410             (const_int 8))
8411           (zero_extend:SI
8412             (match_operand:QI 2 "general_operand" "Qm"))))
8413    (clobber (reg:CC FLAGS_REG))]
8414   "!TARGET_64BIT"
8415   "and{b}\t{%2, %h0|%h0, %2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "QI")])
8419
8420 (define_insn "*andqi_ext_1_rex64"
8421   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422                          (const_int 8)
8423                          (const_int 8))
8424         (and:SI 
8425           (zero_extract:SI
8426             (match_operand 1 "ext_register_operand" "0")
8427             (const_int 8)
8428             (const_int 8))
8429           (zero_extend:SI
8430             (match_operand 2 "ext_register_operand" "Q"))))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "TARGET_64BIT"
8433   "and{b}\t{%2, %h0|%h0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "length_immediate" "0")
8436    (set_attr "mode" "QI")])
8437
8438 (define_insn "*andqi_ext_2"
8439   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8440                          (const_int 8)
8441                          (const_int 8))
8442         (and:SI
8443           (zero_extract:SI
8444             (match_operand 1 "ext_register_operand" "%0")
8445             (const_int 8)
8446             (const_int 8))
8447           (zero_extract:SI
8448             (match_operand 2 "ext_register_operand" "Q")
8449             (const_int 8)
8450             (const_int 8))))
8451    (clobber (reg:CC FLAGS_REG))]
8452   ""
8453   "and{b}\t{%h2, %h0|%h0, %h2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "0")
8456    (set_attr "mode" "QI")])
8457
8458 ;; Convert wide AND instructions with immediate operand to shorter QImode
8459 ;; equivalents when possible.
8460 ;; Don't do the splitting with memory operands, since it introduces risk
8461 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8462 ;; for size, but that can (should?) be handled by generic code instead.
8463 (define_split
8464   [(set (match_operand 0 "register_operand" "")
8465         (and (match_operand 1 "register_operand" "")
8466              (match_operand 2 "const_int_operand" "")))
8467    (clobber (reg:CC FLAGS_REG))]
8468    "reload_completed
8469     && QI_REG_P (operands[0])
8470     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8471     && !(~INTVAL (operands[2]) & ~(255 << 8))
8472     && GET_MODE (operands[0]) != QImode"
8473   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8474                    (and:SI (zero_extract:SI (match_dup 1)
8475                                             (const_int 8) (const_int 8))
8476                            (match_dup 2)))
8477               (clobber (reg:CC FLAGS_REG))])]
8478   "operands[0] = gen_lowpart (SImode, operands[0]);
8479    operands[1] = gen_lowpart (SImode, operands[1]);
8480    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8481
8482 ;; Since AND can be encoded with sign extended immediate, this is only
8483 ;; profitable when 7th bit is not set.
8484 (define_split
8485   [(set (match_operand 0 "register_operand" "")
8486         (and (match_operand 1 "general_operand" "")
8487              (match_operand 2 "const_int_operand" "")))
8488    (clobber (reg:CC FLAGS_REG))]
8489    "reload_completed
8490     && ANY_QI_REG_P (operands[0])
8491     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8492     && !(~INTVAL (operands[2]) & ~255)
8493     && !(INTVAL (operands[2]) & 128)
8494     && GET_MODE (operands[0]) != QImode"
8495   [(parallel [(set (strict_low_part (match_dup 0))
8496                    (and:QI (match_dup 1)
8497                            (match_dup 2)))
8498               (clobber (reg:CC FLAGS_REG))])]
8499   "operands[0] = gen_lowpart (QImode, operands[0]);
8500    operands[1] = gen_lowpart (QImode, operands[1]);
8501    operands[2] = gen_lowpart (QImode, operands[2]);")
8502 \f
8503 ;; Logical inclusive OR instructions
8504
8505 ;; %%% This used to optimize known byte-wide and operations to memory.
8506 ;; If this is considered useful, it should be done with splitters.
8507
8508 (define_expand "iordi3"
8509   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8510         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8511                 (match_operand:DI 2 "x86_64_general_operand" "")))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "TARGET_64BIT"
8514   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8515
8516 (define_insn "*iordi_1_rex64"
8517   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8518         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8519                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT
8522    && ix86_binary_operator_ok (IOR, DImode, operands)"
8523   "or{q}\t{%2, %0|%0, %2}"
8524   [(set_attr "type" "alu")
8525    (set_attr "mode" "DI")])
8526
8527 (define_insn "*iordi_2_rex64"
8528   [(set (reg FLAGS_REG)
8529         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8530                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8531                  (const_int 0)))
8532    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8533         (ior:DI (match_dup 1) (match_dup 2)))]
8534   "TARGET_64BIT
8535    && ix86_match_ccmode (insn, CCNOmode)
8536    && ix86_binary_operator_ok (IOR, DImode, operands)"
8537   "or{q}\t{%2, %0|%0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "DI")])
8540
8541 (define_insn "*iordi_3_rex64"
8542   [(set (reg FLAGS_REG)
8543         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8544                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8545                  (const_int 0)))
8546    (clobber (match_scratch:DI 0 "=r"))]
8547   "TARGET_64BIT
8548    && ix86_match_ccmode (insn, CCNOmode)
8549    && ix86_binary_operator_ok (IOR, DImode, operands)"
8550   "or{q}\t{%2, %0|%0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "DI")])
8553
8554
8555 (define_expand "iorsi3"
8556   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8557         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8558                 (match_operand:SI 2 "general_operand" "")))
8559    (clobber (reg:CC FLAGS_REG))]
8560   ""
8561   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8562
8563 (define_insn "*iorsi_1"
8564   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8565         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8566                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   "ix86_binary_operator_ok (IOR, SImode, operands)"
8569   "or{l}\t{%2, %0|%0, %2}"
8570   [(set_attr "type" "alu")
8571    (set_attr "mode" "SI")])
8572
8573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8574 (define_insn "*iorsi_1_zext"
8575   [(set (match_operand:DI 0 "register_operand" "=rm")
8576         (zero_extend:DI
8577           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8578                   (match_operand:SI 2 "general_operand" "rim"))))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8581   "or{l}\t{%2, %k0|%k0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "mode" "SI")])
8584
8585 (define_insn "*iorsi_1_zext_imm"
8586   [(set (match_operand:DI 0 "register_operand" "=rm")
8587         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8588                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8589    (clobber (reg:CC FLAGS_REG))]
8590   "TARGET_64BIT"
8591   "or{l}\t{%2, %k0|%k0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8594
8595 (define_insn "*iorsi_2"
8596   [(set (reg FLAGS_REG)
8597         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8598                          (match_operand:SI 2 "general_operand" "rim,ri"))
8599                  (const_int 0)))
8600    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8601         (ior:SI (match_dup 1) (match_dup 2)))]
8602   "ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, SImode, operands)"
8604   "or{l}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "SI")])
8607
8608 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8609 ;; ??? Special case for immediate operand is missing - it is tricky.
8610 (define_insn "*iorsi_2_zext"
8611   [(set (reg FLAGS_REG)
8612         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8613                          (match_operand:SI 2 "general_operand" "rim"))
8614                  (const_int 0)))
8615    (set (match_operand:DI 0 "register_operand" "=r")
8616         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8617   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8618    && ix86_binary_operator_ok (IOR, SImode, operands)"
8619   "or{l}\t{%2, %k0|%k0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "SI")])
8622
8623 (define_insn "*iorsi_2_zext_imm"
8624   [(set (reg FLAGS_REG)
8625         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8626                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8627                  (const_int 0)))
8628    (set (match_operand:DI 0 "register_operand" "=r")
8629         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8630   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8631    && ix86_binary_operator_ok (IOR, SImode, operands)"
8632   "or{l}\t{%2, %k0|%k0, %2}"
8633   [(set_attr "type" "alu")
8634    (set_attr "mode" "SI")])
8635
8636 (define_insn "*iorsi_3"
8637   [(set (reg FLAGS_REG)
8638         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8639                          (match_operand:SI 2 "general_operand" "rim"))
8640                  (const_int 0)))
8641    (clobber (match_scratch:SI 0 "=r"))]
8642   "ix86_match_ccmode (insn, CCNOmode)
8643    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8644   "or{l}\t{%2, %0|%0, %2}"
8645   [(set_attr "type" "alu")
8646    (set_attr "mode" "SI")])
8647
8648 (define_expand "iorhi3"
8649   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8650         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8651                 (match_operand:HI 2 "general_operand" "")))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "TARGET_HIMODE_MATH"
8654   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8655
8656 (define_insn "*iorhi_1"
8657   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8658         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8659                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8660    (clobber (reg:CC FLAGS_REG))]
8661   "ix86_binary_operator_ok (IOR, HImode, operands)"
8662   "or{w}\t{%2, %0|%0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "mode" "HI")])
8665
8666 (define_insn "*iorhi_2"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8669                          (match_operand:HI 2 "general_operand" "rim,ri"))
8670                  (const_int 0)))
8671    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8672         (ior:HI (match_dup 1) (match_dup 2)))]
8673   "ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (IOR, HImode, operands)"
8675   "or{w}\t{%2, %0|%0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "HI")])
8678
8679 (define_insn "*iorhi_3"
8680   [(set (reg FLAGS_REG)
8681         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8682                          (match_operand:HI 2 "general_operand" "rim"))
8683                  (const_int 0)))
8684    (clobber (match_scratch:HI 0 "=r"))]
8685   "ix86_match_ccmode (insn, CCNOmode)
8686    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8687   "or{w}\t{%2, %0|%0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "mode" "HI")])
8690
8691 (define_expand "iorqi3"
8692   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8693         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8694                 (match_operand:QI 2 "general_operand" "")))
8695    (clobber (reg:CC FLAGS_REG))]
8696   "TARGET_QIMODE_MATH"
8697   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8698
8699 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8700 (define_insn "*iorqi_1"
8701   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8702         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8703                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "ix86_binary_operator_ok (IOR, QImode, operands)"
8706   "@
8707    or{b}\t{%2, %0|%0, %2}
8708    or{b}\t{%2, %0|%0, %2}
8709    or{l}\t{%k2, %k0|%k0, %k2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "QI,QI,SI")])
8712
8713 (define_insn "*iorqi_1_slp"
8714   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8715         (ior:QI (match_dup 0)
8716                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8719    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8720   "or{b}\t{%1, %0|%0, %1}"
8721   [(set_attr "type" "alu1")
8722    (set_attr "mode" "QI")])
8723
8724 (define_insn "*iorqi_2"
8725   [(set (reg FLAGS_REG)
8726         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8727                          (match_operand:QI 2 "general_operand" "qim,qi"))
8728                  (const_int 0)))
8729    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8730         (ior:QI (match_dup 1) (match_dup 2)))]
8731   "ix86_match_ccmode (insn, CCNOmode)
8732    && ix86_binary_operator_ok (IOR, QImode, operands)"
8733   "or{b}\t{%2, %0|%0, %2}"
8734   [(set_attr "type" "alu")
8735    (set_attr "mode" "QI")])
8736
8737 (define_insn "*iorqi_2_slp"
8738   [(set (reg FLAGS_REG)
8739         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8740                          (match_operand:QI 1 "general_operand" "qim,qi"))
8741                  (const_int 0)))
8742    (set (strict_low_part (match_dup 0))
8743         (ior:QI (match_dup 0) (match_dup 1)))]
8744   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8745    && ix86_match_ccmode (insn, CCNOmode)
8746    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8747   "or{b}\t{%1, %0|%0, %1}"
8748   [(set_attr "type" "alu1")
8749    (set_attr "mode" "QI")])
8750
8751 (define_insn "*iorqi_3"
8752   [(set (reg FLAGS_REG)
8753         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8754                          (match_operand:QI 2 "general_operand" "qim"))
8755                  (const_int 0)))
8756    (clobber (match_scratch:QI 0 "=q"))]
8757   "ix86_match_ccmode (insn, CCNOmode)
8758    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8759   "or{b}\t{%2, %0|%0, %2}"
8760   [(set_attr "type" "alu")
8761    (set_attr "mode" "QI")])
8762
8763 (define_insn "iorqi_ext_0"
8764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765                          (const_int 8)
8766                          (const_int 8))
8767         (ior:SI 
8768           (zero_extract:SI
8769             (match_operand 1 "ext_register_operand" "0")
8770             (const_int 8)
8771             (const_int 8))
8772           (match_operand 2 "const_int_operand" "n")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775   "or{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "length_immediate" "1")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_ext_1"
8781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782                          (const_int 8)
8783                          (const_int 8))
8784         (ior:SI 
8785           (zero_extract:SI
8786             (match_operand 1 "ext_register_operand" "0")
8787             (const_int 8)
8788             (const_int 8))
8789           (zero_extend:SI
8790             (match_operand:QI 2 "general_operand" "Qm"))))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "!TARGET_64BIT
8793    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8794   "or{b}\t{%2, %h0|%h0, %2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "length_immediate" "0")
8797    (set_attr "mode" "QI")])
8798
8799 (define_insn "*iorqi_ext_1_rex64"
8800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8801                          (const_int 8)
8802                          (const_int 8))
8803         (ior:SI 
8804           (zero_extract:SI
8805             (match_operand 1 "ext_register_operand" "0")
8806             (const_int 8)
8807             (const_int 8))
8808           (zero_extend:SI
8809             (match_operand 2 "ext_register_operand" "Q"))))
8810    (clobber (reg:CC FLAGS_REG))]
8811   "TARGET_64BIT
8812    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8813   "or{b}\t{%2, %h0|%h0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "length_immediate" "0")
8816    (set_attr "mode" "QI")])
8817
8818 (define_insn "*iorqi_ext_2"
8819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820                          (const_int 8)
8821                          (const_int 8))
8822         (ior:SI 
8823           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8824                            (const_int 8)
8825                            (const_int 8))
8826           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8827                            (const_int 8)
8828                            (const_int 8))))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831   "ior{b}\t{%h2, %h0|%h0, %h2}"
8832   [(set_attr "type" "alu")
8833    (set_attr "length_immediate" "0")
8834    (set_attr "mode" "QI")])
8835
8836 (define_split
8837   [(set (match_operand 0 "register_operand" "")
8838         (ior (match_operand 1 "register_operand" "")
8839              (match_operand 2 "const_int_operand" "")))
8840    (clobber (reg:CC FLAGS_REG))]
8841    "reload_completed
8842     && QI_REG_P (operands[0])
8843     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844     && !(INTVAL (operands[2]) & ~(255 << 8))
8845     && GET_MODE (operands[0]) != QImode"
8846   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847                    (ior:SI (zero_extract:SI (match_dup 1)
8848                                             (const_int 8) (const_int 8))
8849                            (match_dup 2)))
8850               (clobber (reg:CC FLAGS_REG))])]
8851   "operands[0] = gen_lowpart (SImode, operands[0]);
8852    operands[1] = gen_lowpart (SImode, operands[1]);
8853    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8854
8855 ;; Since OR can be encoded with sign extended immediate, this is only
8856 ;; profitable when 7th bit is set.
8857 (define_split
8858   [(set (match_operand 0 "register_operand" "")
8859         (ior (match_operand 1 "general_operand" "")
8860              (match_operand 2 "const_int_operand" "")))
8861    (clobber (reg:CC FLAGS_REG))]
8862    "reload_completed
8863     && ANY_QI_REG_P (operands[0])
8864     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865     && !(INTVAL (operands[2]) & ~255)
8866     && (INTVAL (operands[2]) & 128)
8867     && GET_MODE (operands[0]) != QImode"
8868   [(parallel [(set (strict_low_part (match_dup 0))
8869                    (ior:QI (match_dup 1)
8870                            (match_dup 2)))
8871               (clobber (reg:CC FLAGS_REG))])]
8872   "operands[0] = gen_lowpart (QImode, operands[0]);
8873    operands[1] = gen_lowpart (QImode, operands[1]);
8874    operands[2] = gen_lowpart (QImode, operands[2]);")
8875 \f
8876 ;; Logical XOR instructions
8877
8878 ;; %%% This used to optimize known byte-wide and operations to memory.
8879 ;; If this is considered useful, it should be done with splitters.
8880
8881 (define_expand "xordi3"
8882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884                 (match_operand:DI 2 "x86_64_general_operand" "")))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT"
8887   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8888
8889 (define_insn "*xordi_1_rex64"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT
8895    && ix86_binary_operator_ok (XOR, DImode, operands)"
8896   "@
8897    xor{q}\t{%2, %0|%0, %2}
8898    xor{q}\t{%2, %0|%0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "mode" "DI,DI")])
8901
8902 (define_insn "*xordi_2_rex64"
8903   [(set (reg FLAGS_REG)
8904         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8905                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8906                  (const_int 0)))
8907    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8908         (xor:DI (match_dup 1) (match_dup 2)))]
8909   "TARGET_64BIT
8910    && ix86_match_ccmode (insn, CCNOmode)
8911    && ix86_binary_operator_ok (XOR, DImode, operands)"
8912   "@
8913    xor{q}\t{%2, %0|%0, %2}
8914    xor{q}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "DI,DI")])
8917
8918 (define_insn "*xordi_3_rex64"
8919   [(set (reg FLAGS_REG)
8920         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8921                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8922                  (const_int 0)))
8923    (clobber (match_scratch:DI 0 "=r"))]
8924   "TARGET_64BIT
8925    && ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_binary_operator_ok (XOR, DImode, operands)"
8927   "xor{q}\t{%2, %0|%0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "DI")])
8930
8931 (define_expand "xorsi3"
8932   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8933         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8934                 (match_operand:SI 2 "general_operand" "")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   ""
8937   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8938
8939 (define_insn "*xorsi_1"
8940   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8941         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8942                 (match_operand:SI 2 "general_operand" "ri,rm")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "ix86_binary_operator_ok (XOR, SImode, operands)"
8945   "xor{l}\t{%2, %0|%0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "SI")])
8948
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 ;; Add speccase for immediates
8951 (define_insn "*xorsi_1_zext"
8952   [(set (match_operand:DI 0 "register_operand" "=r")
8953         (zero_extend:DI
8954           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8955                   (match_operand:SI 2 "general_operand" "rim"))))
8956    (clobber (reg:CC FLAGS_REG))]
8957   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8958   "xor{l}\t{%2, %k0|%k0, %2}"
8959   [(set_attr "type" "alu")
8960    (set_attr "mode" "SI")])
8961
8962 (define_insn "*xorsi_1_zext_imm"
8963   [(set (match_operand:DI 0 "register_operand" "=r")
8964         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8965                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8966    (clobber (reg:CC FLAGS_REG))]
8967   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8968   "xor{l}\t{%2, %k0|%k0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "SI")])
8971
8972 (define_insn "*xorsi_2"
8973   [(set (reg FLAGS_REG)
8974         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8975                          (match_operand:SI 2 "general_operand" "rim,ri"))
8976                  (const_int 0)))
8977    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8978         (xor:SI (match_dup 1) (match_dup 2)))]
8979   "ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, SImode, operands)"
8981   "xor{l}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "SI")])
8984
8985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8986 ;; ??? Special case for immediate operand is missing - it is tricky.
8987 (define_insn "*xorsi_2_zext"
8988   [(set (reg FLAGS_REG)
8989         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990                          (match_operand:SI 2 "general_operand" "rim"))
8991                  (const_int 0)))
8992    (set (match_operand:DI 0 "register_operand" "=r")
8993         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8994   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8995    && ix86_binary_operator_ok (XOR, SImode, operands)"
8996   "xor{l}\t{%2, %k0|%k0, %2}"
8997   [(set_attr "type" "alu")
8998    (set_attr "mode" "SI")])
8999
9000 (define_insn "*xorsi_2_zext_imm"
9001   [(set (reg FLAGS_REG)
9002         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9004                  (const_int 0)))
9005    (set (match_operand:DI 0 "register_operand" "=r")
9006         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9007   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9008    && ix86_binary_operator_ok (XOR, SImode, operands)"
9009   "xor{l}\t{%2, %k0|%k0, %2}"
9010   [(set_attr "type" "alu")
9011    (set_attr "mode" "SI")])
9012
9013 (define_insn "*xorsi_3"
9014   [(set (reg FLAGS_REG)
9015         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9016                          (match_operand:SI 2 "general_operand" "rim"))
9017                  (const_int 0)))
9018    (clobber (match_scratch:SI 0 "=r"))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9021   "xor{l}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "SI")])
9024
9025 (define_expand "xorhi3"
9026   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9027         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9028                 (match_operand:HI 2 "general_operand" "")))
9029    (clobber (reg:CC FLAGS_REG))]
9030   "TARGET_HIMODE_MATH"
9031   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9032
9033 (define_insn "*xorhi_1"
9034   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9035         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9036                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "ix86_binary_operator_ok (XOR, HImode, operands)"
9039   "xor{w}\t{%2, %0|%0, %2}"
9040   [(set_attr "type" "alu")
9041    (set_attr "mode" "HI")])
9042
9043 (define_insn "*xorhi_2"
9044   [(set (reg FLAGS_REG)
9045         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9046                          (match_operand:HI 2 "general_operand" "rim,ri"))
9047                  (const_int 0)))
9048    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9049         (xor:HI (match_dup 1) (match_dup 2)))]
9050   "ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, HImode, operands)"
9052   "xor{w}\t{%2, %0|%0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "HI")])
9055
9056 (define_insn "*xorhi_3"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9059                          (match_operand:HI 2 "general_operand" "rim"))
9060                  (const_int 0)))
9061    (clobber (match_scratch:HI 0 "=r"))]
9062   "ix86_match_ccmode (insn, CCNOmode)
9063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9064   "xor{w}\t{%2, %0|%0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "HI")])
9067
9068 (define_expand "xorqi3"
9069   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9070         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9071                 (match_operand:QI 2 "general_operand" "")))
9072    (clobber (reg:CC FLAGS_REG))]
9073   "TARGET_QIMODE_MATH"
9074   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9075
9076 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9077 (define_insn "*xorqi_1"
9078   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9079         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9080                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "ix86_binary_operator_ok (XOR, QImode, operands)"
9083   "@
9084    xor{b}\t{%2, %0|%0, %2}
9085    xor{b}\t{%2, %0|%0, %2}
9086    xor{l}\t{%k2, %k0|%k0, %k2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "QI,QI,SI")])
9089
9090 (define_insn "*xorqi_1_slp"
9091   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9092         (xor:QI (match_dup 0)
9093                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9096    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9097   "xor{b}\t{%1, %0|%0, %1}"
9098   [(set_attr "type" "alu1")
9099    (set_attr "mode" "QI")])
9100
9101 (define_insn "xorqi_ext_0"
9102   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9103                          (const_int 8)
9104                          (const_int 8))
9105         (xor:SI 
9106           (zero_extract:SI
9107             (match_operand 1 "ext_register_operand" "0")
9108             (const_int 8)
9109             (const_int 8))
9110           (match_operand 2 "const_int_operand" "n")))
9111    (clobber (reg:CC FLAGS_REG))]
9112   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113   "xor{b}\t{%2, %h0|%h0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "length_immediate" "1")
9116    (set_attr "mode" "QI")])
9117
9118 (define_insn "*xorqi_ext_1"
9119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120                          (const_int 8)
9121                          (const_int 8))
9122         (xor:SI 
9123           (zero_extract:SI
9124             (match_operand 1 "ext_register_operand" "0")
9125             (const_int 8)
9126             (const_int 8))
9127           (zero_extend:SI
9128             (match_operand:QI 2 "general_operand" "Qm"))))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "!TARGET_64BIT
9131    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9132   "xor{b}\t{%2, %h0|%h0, %2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "length_immediate" "0")
9135    (set_attr "mode" "QI")])
9136
9137 (define_insn "*xorqi_ext_1_rex64"
9138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9139                          (const_int 8)
9140                          (const_int 8))
9141         (xor:SI 
9142           (zero_extract:SI
9143             (match_operand 1 "ext_register_operand" "0")
9144             (const_int 8)
9145             (const_int 8))
9146           (zero_extend:SI
9147             (match_operand 2 "ext_register_operand" "Q"))))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "TARGET_64BIT
9150    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151   "xor{b}\t{%2, %h0|%h0, %2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "length_immediate" "0")
9154    (set_attr "mode" "QI")])
9155
9156 (define_insn "*xorqi_ext_2"
9157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158                          (const_int 8)
9159                          (const_int 8))
9160         (xor:SI 
9161           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9162                            (const_int 8)
9163                            (const_int 8))
9164           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9165                            (const_int 8)
9166                            (const_int 8))))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169   "xor{b}\t{%h2, %h0|%h0, %h2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "0")
9172    (set_attr "mode" "QI")])
9173
9174 (define_insn "*xorqi_cc_1"
9175   [(set (reg FLAGS_REG)
9176         (compare
9177           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9178                   (match_operand:QI 2 "general_operand" "qim,qi"))
9179           (const_int 0)))
9180    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9181         (xor:QI (match_dup 1) (match_dup 2)))]
9182   "ix86_match_ccmode (insn, CCNOmode)
9183    && ix86_binary_operator_ok (XOR, QImode, operands)"
9184   "xor{b}\t{%2, %0|%0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "mode" "QI")])
9187
9188 (define_insn "*xorqi_2_slp"
9189   [(set (reg FLAGS_REG)
9190         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9191                          (match_operand:QI 1 "general_operand" "qim,qi"))
9192                  (const_int 0)))
9193    (set (strict_low_part (match_dup 0))
9194         (xor:QI (match_dup 0) (match_dup 1)))]
9195   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196    && ix86_match_ccmode (insn, CCNOmode)
9197    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9198   "xor{b}\t{%1, %0|%0, %1}"
9199   [(set_attr "type" "alu1")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_cc_2"
9203   [(set (reg FLAGS_REG)
9204         (compare
9205           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9206                   (match_operand:QI 2 "general_operand" "qim"))
9207           (const_int 0)))
9208    (clobber (match_scratch:QI 0 "=q"))]
9209   "ix86_match_ccmode (insn, CCNOmode)
9210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9211   "xor{b}\t{%2, %0|%0, %2}"
9212   [(set_attr "type" "alu")
9213    (set_attr "mode" "QI")])
9214
9215 (define_insn "*xorqi_cc_ext_1"
9216   [(set (reg FLAGS_REG)
9217         (compare
9218           (xor:SI
9219             (zero_extract:SI
9220               (match_operand 1 "ext_register_operand" "0")
9221               (const_int 8)
9222               (const_int 8))
9223             (match_operand:QI 2 "general_operand" "qmn"))
9224           (const_int 0)))
9225    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9226                          (const_int 8)
9227                          (const_int 8))
9228         (xor:SI 
9229           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9230           (match_dup 2)))]
9231   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9232   "xor{b}\t{%2, %h0|%h0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "mode" "QI")])
9235
9236 (define_insn "*xorqi_cc_ext_1_rex64"
9237   [(set (reg FLAGS_REG)
9238         (compare
9239           (xor:SI
9240             (zero_extract:SI
9241               (match_operand 1 "ext_register_operand" "0")
9242               (const_int 8)
9243               (const_int 8))
9244             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9245           (const_int 0)))
9246    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9247                          (const_int 8)
9248                          (const_int 8))
9249         (xor:SI 
9250           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9251           (match_dup 2)))]
9252   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9253   "xor{b}\t{%2, %h0|%h0, %2}"
9254   [(set_attr "type" "alu")
9255    (set_attr "mode" "QI")])
9256
9257 (define_expand "xorqi_cc_ext_1"
9258   [(parallel [
9259      (set (reg:CCNO FLAGS_REG)
9260           (compare:CCNO
9261             (xor:SI
9262               (zero_extract:SI
9263                 (match_operand 1 "ext_register_operand" "")
9264                 (const_int 8)
9265                 (const_int 8))
9266               (match_operand:QI 2 "general_operand" ""))
9267             (const_int 0)))
9268      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9269                            (const_int 8)
9270                            (const_int 8))
9271           (xor:SI 
9272             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9273             (match_dup 2)))])]
9274   ""
9275   "")
9276
9277 (define_split
9278   [(set (match_operand 0 "register_operand" "")
9279         (xor (match_operand 1 "register_operand" "")
9280              (match_operand 2 "const_int_operand" "")))
9281    (clobber (reg:CC FLAGS_REG))]
9282    "reload_completed
9283     && QI_REG_P (operands[0])
9284     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9285     && !(INTVAL (operands[2]) & ~(255 << 8))
9286     && GET_MODE (operands[0]) != QImode"
9287   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9288                    (xor:SI (zero_extract:SI (match_dup 1)
9289                                             (const_int 8) (const_int 8))
9290                            (match_dup 2)))
9291               (clobber (reg:CC FLAGS_REG))])]
9292   "operands[0] = gen_lowpart (SImode, operands[0]);
9293    operands[1] = gen_lowpart (SImode, operands[1]);
9294    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9295
9296 ;; Since XOR can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is set.
9298 (define_split
9299   [(set (match_operand 0 "register_operand" "")
9300         (xor (match_operand 1 "general_operand" "")
9301              (match_operand 2 "const_int_operand" "")))
9302    (clobber (reg:CC FLAGS_REG))]
9303    "reload_completed
9304     && ANY_QI_REG_P (operands[0])
9305     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9306     && !(INTVAL (operands[2]) & ~255)
9307     && (INTVAL (operands[2]) & 128)
9308     && GET_MODE (operands[0]) != QImode"
9309   [(parallel [(set (strict_low_part (match_dup 0))
9310                    (xor:QI (match_dup 1)
9311                            (match_dup 2)))
9312               (clobber (reg:CC FLAGS_REG))])]
9313   "operands[0] = gen_lowpart (QImode, operands[0]);
9314    operands[1] = gen_lowpart (QImode, operands[1]);
9315    operands[2] = gen_lowpart (QImode, operands[2]);")
9316 \f
9317 ;; Negation instructions
9318
9319 (define_expand "negti2"
9320   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9321                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9322               (clobber (reg:CC FLAGS_REG))])]
9323   "TARGET_64BIT"
9324   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9325
9326 (define_insn "*negti2_1"
9327   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9328         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "TARGET_64BIT
9331    && ix86_unary_operator_ok (NEG, TImode, operands)"
9332   "#")
9333
9334 (define_split
9335   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9336         (neg:TI (match_operand:TI 1 "general_operand" "")))
9337    (clobber (reg:CC FLAGS_REG))]
9338   "TARGET_64BIT && reload_completed"
9339   [(parallel
9340     [(set (reg:CCZ FLAGS_REG)
9341           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9342      (set (match_dup 0) (neg:DI (match_dup 2)))])
9343    (parallel
9344     [(set (match_dup 1)
9345           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9346                             (match_dup 3))
9347                    (const_int 0)))
9348      (clobber (reg:CC FLAGS_REG))])
9349    (parallel
9350     [(set (match_dup 1)
9351           (neg:DI (match_dup 1)))
9352      (clobber (reg:CC FLAGS_REG))])]
9353   "split_ti (operands+1, 1, operands+2, operands+3);
9354    split_ti (operands+0, 1, operands+0, operands+1);")
9355
9356 (define_expand "negdi2"
9357   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9359               (clobber (reg:CC FLAGS_REG))])]
9360   ""
9361   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9362
9363 (define_insn "*negdi2_1"
9364   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9365         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "!TARGET_64BIT
9368    && ix86_unary_operator_ok (NEG, DImode, operands)"
9369   "#")
9370
9371 (define_split
9372   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9373         (neg:DI (match_operand:DI 1 "general_operand" "")))
9374    (clobber (reg:CC FLAGS_REG))]
9375   "!TARGET_64BIT && reload_completed"
9376   [(parallel
9377     [(set (reg:CCZ FLAGS_REG)
9378           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9379      (set (match_dup 0) (neg:SI (match_dup 2)))])
9380    (parallel
9381     [(set (match_dup 1)
9382           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9383                             (match_dup 3))
9384                    (const_int 0)))
9385      (clobber (reg:CC FLAGS_REG))])
9386    (parallel
9387     [(set (match_dup 1)
9388           (neg:SI (match_dup 1)))
9389      (clobber (reg:CC FLAGS_REG))])]
9390   "split_di (operands+1, 1, operands+2, operands+3);
9391    split_di (operands+0, 1, operands+0, operands+1);")
9392
9393 (define_insn "*negdi2_1_rex64"
9394   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9395         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9398   "neg{q}\t%0"
9399   [(set_attr "type" "negnot")
9400    (set_attr "mode" "DI")])
9401
9402 ;; The problem with neg is that it does not perform (compare x 0),
9403 ;; it really performs (compare 0 x), which leaves us with the zero
9404 ;; flag being the only useful item.
9405
9406 (define_insn "*negdi2_cmpz_rex64"
9407   [(set (reg:CCZ FLAGS_REG)
9408         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9409                      (const_int 0)))
9410    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411         (neg:DI (match_dup 1)))]
9412   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9413   "neg{q}\t%0"
9414   [(set_attr "type" "negnot")
9415    (set_attr "mode" "DI")])
9416
9417
9418 (define_expand "negsi2"
9419   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9420                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9421               (clobber (reg:CC FLAGS_REG))])]
9422   ""
9423   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9424
9425 (define_insn "*negsi2_1"
9426   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9427         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9428    (clobber (reg:CC FLAGS_REG))]
9429   "ix86_unary_operator_ok (NEG, SImode, operands)"
9430   "neg{l}\t%0"
9431   [(set_attr "type" "negnot")
9432    (set_attr "mode" "SI")])
9433
9434 ;; Combine is quite creative about this pattern.
9435 (define_insn "*negsi2_1_zext"
9436   [(set (match_operand:DI 0 "register_operand" "=r")
9437         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9438                                         (const_int 32)))
9439                      (const_int 32)))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9442   "neg{l}\t%k0"
9443   [(set_attr "type" "negnot")
9444    (set_attr "mode" "SI")])
9445
9446 ;; The problem with neg is that it does not perform (compare x 0),
9447 ;; it really performs (compare 0 x), which leaves us with the zero
9448 ;; flag being the only useful item.
9449
9450 (define_insn "*negsi2_cmpz"
9451   [(set (reg:CCZ FLAGS_REG)
9452         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9453                      (const_int 0)))
9454    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455         (neg:SI (match_dup 1)))]
9456   "ix86_unary_operator_ok (NEG, SImode, operands)"
9457   "neg{l}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "SI")])
9460
9461 (define_insn "*negsi2_cmpz_zext"
9462   [(set (reg:CCZ FLAGS_REG)
9463         (compare:CCZ (lshiftrt:DI
9464                        (neg:DI (ashift:DI
9465                                  (match_operand:DI 1 "register_operand" "0")
9466                                  (const_int 32)))
9467                        (const_int 32))
9468                      (const_int 0)))
9469    (set (match_operand:DI 0 "register_operand" "=r")
9470         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9471                                         (const_int 32)))
9472                      (const_int 32)))]
9473   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9474   "neg{l}\t%k0"
9475   [(set_attr "type" "negnot")
9476    (set_attr "mode" "SI")])
9477
9478 (define_expand "neghi2"
9479   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9480                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9481               (clobber (reg:CC FLAGS_REG))])]
9482   "TARGET_HIMODE_MATH"
9483   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9484
9485 (define_insn "*neghi2_1"
9486   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9487         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "ix86_unary_operator_ok (NEG, HImode, operands)"
9490   "neg{w}\t%0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "HI")])
9493
9494 (define_insn "*neghi2_cmpz"
9495   [(set (reg:CCZ FLAGS_REG)
9496         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9497                      (const_int 0)))
9498    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9499         (neg:HI (match_dup 1)))]
9500   "ix86_unary_operator_ok (NEG, HImode, operands)"
9501   "neg{w}\t%0"
9502   [(set_attr "type" "negnot")
9503    (set_attr "mode" "HI")])
9504
9505 (define_expand "negqi2"
9506   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9507                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9508               (clobber (reg:CC FLAGS_REG))])]
9509   "TARGET_QIMODE_MATH"
9510   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9511
9512 (define_insn "*negqi2_1"
9513   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9514         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9515    (clobber (reg:CC FLAGS_REG))]
9516   "ix86_unary_operator_ok (NEG, QImode, operands)"
9517   "neg{b}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "QI")])
9520
9521 (define_insn "*negqi2_cmpz"
9522   [(set (reg:CCZ FLAGS_REG)
9523         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9524                      (const_int 0)))
9525    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9526         (neg:QI (match_dup 1)))]
9527   "ix86_unary_operator_ok (NEG, QImode, operands)"
9528   "neg{b}\t%0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "QI")])
9531
9532 ;; Changing of sign for FP values is doable using integer unit too.
9533
9534 (define_expand "negsf2"
9535   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9536         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9537   "TARGET_80387 || TARGET_SSE_MATH"
9538   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9539
9540 (define_expand "abssf2"
9541   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9542         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9543   "TARGET_80387 || TARGET_SSE_MATH"
9544   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9545
9546 (define_insn "*absnegsf2_mixed"
9547   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9548         (match_operator:SF 3 "absneg_operator"
9549           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9550    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9553    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9554   "#")
9555
9556 (define_insn "*absnegsf2_sse"
9557   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9558         (match_operator:SF 3 "absneg_operator"
9559           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9560    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9561    (clobber (reg:CC FLAGS_REG))]
9562   "TARGET_SSE_MATH
9563    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9564   "#")
9565
9566 (define_insn "*absnegsf2_i387"
9567   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9568         (match_operator:SF 3 "absneg_operator"
9569           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9570    (use (match_operand 2 "" ""))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "TARGET_80387 && !TARGET_SSE_MATH
9573    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9574   "#")
9575
9576 (define_expand "copysignsf3"
9577   [(match_operand:SF 0 "register_operand" "")
9578    (match_operand:SF 1 "nonmemory_operand" "")
9579    (match_operand:SF 2 "register_operand" "")]
9580   "TARGET_SSE_MATH"
9581 {
9582   ix86_expand_copysign (operands);
9583   DONE;
9584 })
9585
9586 (define_insn_and_split "copysignsf3_const"
9587   [(set (match_operand:SF 0 "register_operand"          "=x")
9588         (unspec:SF
9589           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9590            (match_operand:SF 2 "register_operand"       "0")
9591            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9592           UNSPEC_COPYSIGN))]
9593   "TARGET_SSE_MATH"
9594   "#"
9595   "&& reload_completed"
9596   [(const_int 0)]
9597 {
9598   ix86_split_copysign_const (operands);
9599   DONE;
9600 })
9601
9602 (define_insn "copysignsf3_var"
9603   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9604         (unspec:SF
9605           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9606            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9607            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9608            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9609           UNSPEC_COPYSIGN))
9610    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9611   "TARGET_SSE_MATH"
9612   "#")
9613
9614 (define_split
9615   [(set (match_operand:SF 0 "register_operand" "")
9616         (unspec:SF
9617           [(match_operand:SF 2 "register_operand" "")
9618            (match_operand:SF 3 "register_operand" "")
9619            (match_operand:V4SF 4 "" "")
9620            (match_operand:V4SF 5 "" "")]
9621           UNSPEC_COPYSIGN))
9622    (clobber (match_scratch:V4SF 1 ""))]
9623   "TARGET_SSE_MATH && reload_completed"
9624   [(const_int 0)]
9625 {
9626   ix86_split_copysign_var (operands);
9627   DONE;
9628 })
9629
9630 (define_expand "negdf2"
9631   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9635
9636 (define_expand "absdf2"
9637   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641
9642 (define_insn "*absnegdf2_mixed"
9643   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9644         (match_operator:DF 3 "absneg_operator"
9645           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9646    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9650   "#")
9651
9652 (define_insn "*absnegdf2_sse"
9653   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9654         (match_operator:DF 3 "absneg_operator"
9655           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9656    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "TARGET_SSE2 && TARGET_SSE_MATH
9659    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9660   "#")
9661
9662 (define_insn "*absnegdf2_i387"
9663   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9664         (match_operator:DF 3 "absneg_operator"
9665           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666    (use (match_operand 2 "" ""))
9667    (clobber (reg:CC FLAGS_REG))]
9668   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9670   "#")
9671
9672 (define_expand "copysigndf3"
9673   [(match_operand:DF 0 "register_operand" "")
9674    (match_operand:DF 1 "nonmemory_operand" "")
9675    (match_operand:DF 2 "register_operand" "")]
9676   "TARGET_SSE2 && TARGET_SSE_MATH"
9677 {
9678   ix86_expand_copysign (operands);
9679   DONE;
9680 })
9681
9682 (define_insn_and_split "copysigndf3_const"
9683   [(set (match_operand:DF 0 "register_operand"          "=x")
9684         (unspec:DF
9685           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9686            (match_operand:DF 2 "register_operand"       "0")
9687            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9688           UNSPEC_COPYSIGN))]
9689   "TARGET_SSE2 && TARGET_SSE_MATH"
9690   "#"
9691   "&& reload_completed"
9692   [(const_int 0)]
9693 {
9694   ix86_split_copysign_const (operands);
9695   DONE;
9696 })
9697
9698 (define_insn "copysigndf3_var"
9699   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9700         (unspec:DF
9701           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9702            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9703            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9704            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9705           UNSPEC_COPYSIGN))
9706    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9707   "TARGET_SSE2 && TARGET_SSE_MATH"
9708   "#")
9709
9710 (define_split
9711   [(set (match_operand:DF 0 "register_operand" "")
9712         (unspec:DF
9713           [(match_operand:DF 2 "register_operand" "")
9714            (match_operand:DF 3 "register_operand" "")
9715            (match_operand:V2DF 4 "" "")
9716            (match_operand:V2DF 5 "" "")]
9717           UNSPEC_COPYSIGN))
9718    (clobber (match_scratch:V2DF 1 ""))]
9719   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9720   [(const_int 0)]
9721 {
9722   ix86_split_copysign_var (operands);
9723   DONE;
9724 })
9725
9726 (define_expand "negxf2"
9727   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9728         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9729   "TARGET_80387"
9730   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9731
9732 (define_expand "absxf2"
9733   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9734         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9735   "TARGET_80387"
9736   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9737
9738 (define_insn "*absnegxf2_i387"
9739   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9740         (match_operator:XF 3 "absneg_operator"
9741           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9742    (use (match_operand 2 "" ""))
9743    (clobber (reg:CC FLAGS_REG))]
9744   "TARGET_80387
9745    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9746   "#")
9747
9748 ;; Splitters for fp abs and neg.
9749
9750 (define_split
9751   [(set (match_operand 0 "fp_register_operand" "")
9752         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9753    (use (match_operand 2 "" ""))
9754    (clobber (reg:CC FLAGS_REG))]
9755   "reload_completed"
9756   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9757
9758 (define_split
9759   [(set (match_operand 0 "register_operand" "")
9760         (match_operator 3 "absneg_operator"
9761           [(match_operand 1 "register_operand" "")]))
9762    (use (match_operand 2 "nonimmediate_operand" ""))
9763    (clobber (reg:CC FLAGS_REG))]
9764   "reload_completed && SSE_REG_P (operands[0])"
9765   [(set (match_dup 0) (match_dup 3))]
9766 {
9767   enum machine_mode mode = GET_MODE (operands[0]);
9768   enum machine_mode vmode = GET_MODE (operands[2]);
9769   rtx tmp;
9770   
9771   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9772   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9773   if (operands_match_p (operands[0], operands[2]))
9774     {
9775       tmp = operands[1];
9776       operands[1] = operands[2];
9777       operands[2] = tmp;
9778     }
9779   if (GET_CODE (operands[3]) == ABS)
9780     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9781   else
9782     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9783   operands[3] = tmp;
9784 })
9785
9786 (define_split
9787   [(set (match_operand:SF 0 "register_operand" "")
9788         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9789    (use (match_operand:V4SF 2 "" ""))
9790    (clobber (reg:CC FLAGS_REG))]
9791   "reload_completed"
9792   [(parallel [(set (match_dup 0) (match_dup 1))
9793               (clobber (reg:CC FLAGS_REG))])]
9794
9795   rtx tmp;
9796   operands[0] = gen_lowpart (SImode, operands[0]);
9797   if (GET_CODE (operands[1]) == ABS)
9798     {
9799       tmp = gen_int_mode (0x7fffffff, SImode);
9800       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9801     }
9802   else
9803     {
9804       tmp = gen_int_mode (0x80000000, SImode);
9805       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9806     }
9807   operands[1] = tmp;
9808 })
9809
9810 (define_split
9811   [(set (match_operand:DF 0 "register_operand" "")
9812         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9813    (use (match_operand 2 "" ""))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "reload_completed"
9816   [(parallel [(set (match_dup 0) (match_dup 1))
9817               (clobber (reg:CC FLAGS_REG))])]
9818 {
9819   rtx tmp;
9820   if (TARGET_64BIT)
9821     {
9822       tmp = gen_lowpart (DImode, operands[0]);
9823       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9824       operands[0] = tmp;
9825
9826       if (GET_CODE (operands[1]) == ABS)
9827         tmp = const0_rtx;
9828       else
9829         tmp = gen_rtx_NOT (DImode, tmp);
9830     }
9831   else
9832     {
9833       operands[0] = gen_highpart (SImode, operands[0]);
9834       if (GET_CODE (operands[1]) == ABS)
9835         {
9836           tmp = gen_int_mode (0x7fffffff, SImode);
9837           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9838         }
9839       else
9840         {
9841           tmp = gen_int_mode (0x80000000, SImode);
9842           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9843         }
9844     }
9845   operands[1] = tmp;
9846 })
9847
9848 (define_split
9849   [(set (match_operand:XF 0 "register_operand" "")
9850         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9851    (use (match_operand 2 "" ""))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "reload_completed"
9854   [(parallel [(set (match_dup 0) (match_dup 1))
9855               (clobber (reg:CC FLAGS_REG))])]
9856 {
9857   rtx tmp;
9858   operands[0] = gen_rtx_REG (SImode,
9859                              true_regnum (operands[0])
9860                              + (TARGET_64BIT ? 1 : 2));
9861   if (GET_CODE (operands[1]) == ABS)
9862     {
9863       tmp = GEN_INT (0x7fff);
9864       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9865     }
9866   else
9867     {
9868       tmp = GEN_INT (0x8000);
9869       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9870     }
9871   operands[1] = tmp;
9872 })
9873
9874 (define_split
9875   [(set (match_operand 0 "memory_operand" "")
9876         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9877    (use (match_operand 2 "" ""))
9878    (clobber (reg:CC FLAGS_REG))]
9879   "reload_completed"
9880   [(parallel [(set (match_dup 0) (match_dup 1))
9881               (clobber (reg:CC FLAGS_REG))])]
9882 {
9883   enum machine_mode mode = GET_MODE (operands[0]);
9884   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9885   rtx tmp;
9886
9887   operands[0] = adjust_address (operands[0], QImode, size - 1);
9888   if (GET_CODE (operands[1]) == ABS)
9889     {
9890       tmp = gen_int_mode (0x7f, QImode);
9891       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9892     }
9893   else
9894     {
9895       tmp = gen_int_mode (0x80, QImode);
9896       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9897     }
9898   operands[1] = tmp;
9899 })
9900
9901 ;; Conditionalize these after reload. If they match before reload, we 
9902 ;; lose the clobber and ability to use integer instructions.
9903
9904 (define_insn "*negsf2_1"
9905   [(set (match_operand:SF 0 "register_operand" "=f")
9906         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9907   "TARGET_80387 && reload_completed"
9908   "fchs"
9909   [(set_attr "type" "fsgn")
9910    (set_attr "mode" "SF")])
9911
9912 (define_insn "*negdf2_1"
9913   [(set (match_operand:DF 0 "register_operand" "=f")
9914         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9915   "TARGET_80387 && reload_completed"
9916   "fchs"
9917   [(set_attr "type" "fsgn")
9918    (set_attr "mode" "DF")])
9919
9920 (define_insn "*negxf2_1"
9921   [(set (match_operand:XF 0 "register_operand" "=f")
9922         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9923   "TARGET_80387 && reload_completed"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "XF")])
9927
9928 (define_insn "*abssf2_1"
9929   [(set (match_operand:SF 0 "register_operand" "=f")
9930         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9931   "TARGET_80387 && reload_completed"
9932   "fabs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "SF")])
9935
9936 (define_insn "*absdf2_1"
9937   [(set (match_operand:DF 0 "register_operand" "=f")
9938         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9939   "TARGET_80387 && reload_completed"
9940   "fabs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "DF")])
9943
9944 (define_insn "*absxf2_1"
9945   [(set (match_operand:XF 0 "register_operand" "=f")
9946         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9947   "TARGET_80387 && reload_completed"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "DF")])
9951
9952 (define_insn "*negextendsfdf2"
9953   [(set (match_operand:DF 0 "register_operand" "=f")
9954         (neg:DF (float_extend:DF
9955                   (match_operand:SF 1 "register_operand" "0"))))]
9956   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9957   "fchs"
9958   [(set_attr "type" "fsgn")
9959    (set_attr "mode" "DF")])
9960
9961 (define_insn "*negextenddfxf2"
9962   [(set (match_operand:XF 0 "register_operand" "=f")
9963         (neg:XF (float_extend:XF
9964                   (match_operand:DF 1 "register_operand" "0"))))]
9965   "TARGET_80387"
9966   "fchs"
9967   [(set_attr "type" "fsgn")
9968    (set_attr "mode" "XF")])
9969
9970 (define_insn "*negextendsfxf2"
9971   [(set (match_operand:XF 0 "register_operand" "=f")
9972         (neg:XF (float_extend:XF
9973                   (match_operand:SF 1 "register_operand" "0"))))]
9974   "TARGET_80387"
9975   "fchs"
9976   [(set_attr "type" "fsgn")
9977    (set_attr "mode" "XF")])
9978
9979 (define_insn "*absextendsfdf2"
9980   [(set (match_operand:DF 0 "register_operand" "=f")
9981         (abs:DF (float_extend:DF
9982                   (match_operand:SF 1 "register_operand" "0"))))]
9983   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9984   "fabs"
9985   [(set_attr "type" "fsgn")
9986    (set_attr "mode" "DF")])
9987
9988 (define_insn "*absextenddfxf2"
9989   [(set (match_operand:XF 0 "register_operand" "=f")
9990         (abs:XF (float_extend:XF
9991           (match_operand:DF 1 "register_operand" "0"))))]
9992   "TARGET_80387"
9993   "fabs"
9994   [(set_attr "type" "fsgn")
9995    (set_attr "mode" "XF")])
9996
9997 (define_insn "*absextendsfxf2"
9998   [(set (match_operand:XF 0 "register_operand" "=f")
9999         (abs:XF (float_extend:XF
10000           (match_operand:SF 1 "register_operand" "0"))))]
10001   "TARGET_80387"
10002   "fabs"
10003   [(set_attr "type" "fsgn")
10004    (set_attr "mode" "XF")])
10005 \f
10006 ;; One complement instructions
10007
10008 (define_expand "one_cmpldi2"
10009   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10010         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10011   "TARGET_64BIT"
10012   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10013
10014 (define_insn "*one_cmpldi2_1_rex64"
10015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10016         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10017   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10018   "not{q}\t%0"
10019   [(set_attr "type" "negnot")
10020    (set_attr "mode" "DI")])
10021
10022 (define_insn "*one_cmpldi2_2_rex64"
10023   [(set (reg FLAGS_REG)
10024         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10025                  (const_int 0)))
10026    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10027         (not:DI (match_dup 1)))]
10028   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10029    && ix86_unary_operator_ok (NOT, DImode, operands)"
10030   "#"
10031   [(set_attr "type" "alu1")
10032    (set_attr "mode" "DI")])
10033
10034 (define_split
10035   [(set (match_operand 0 "flags_reg_operand" "")
10036         (match_operator 2 "compare_operator"
10037           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10038            (const_int 0)]))
10039    (set (match_operand:DI 1 "nonimmediate_operand" "")
10040         (not:DI (match_dup 3)))]
10041   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10042   [(parallel [(set (match_dup 0)
10043                    (match_op_dup 2
10044                      [(xor:DI (match_dup 3) (const_int -1))
10045                       (const_int 0)]))
10046               (set (match_dup 1)
10047                    (xor:DI (match_dup 3) (const_int -1)))])]
10048   "")
10049
10050 (define_expand "one_cmplsi2"
10051   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10052         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10053   ""
10054   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10055
10056 (define_insn "*one_cmplsi2_1"
10057   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10058         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10059   "ix86_unary_operator_ok (NOT, SImode, operands)"
10060   "not{l}\t%0"
10061   [(set_attr "type" "negnot")
10062    (set_attr "mode" "SI")])
10063
10064 ;; ??? Currently never generated - xor is used instead.
10065 (define_insn "*one_cmplsi2_1_zext"
10066   [(set (match_operand:DI 0 "register_operand" "=r")
10067         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10068   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10069   "not{l}\t%k0"
10070   [(set_attr "type" "negnot")
10071    (set_attr "mode" "SI")])
10072
10073 (define_insn "*one_cmplsi2_2"
10074   [(set (reg FLAGS_REG)
10075         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10076                  (const_int 0)))
10077    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10078         (not:SI (match_dup 1)))]
10079   "ix86_match_ccmode (insn, CCNOmode)
10080    && ix86_unary_operator_ok (NOT, SImode, operands)"
10081   "#"
10082   [(set_attr "type" "alu1")
10083    (set_attr "mode" "SI")])
10084
10085 (define_split
10086   [(set (match_operand 0 "flags_reg_operand" "")
10087         (match_operator 2 "compare_operator"
10088           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10089            (const_int 0)]))
10090    (set (match_operand:SI 1 "nonimmediate_operand" "")
10091         (not:SI (match_dup 3)))]
10092   "ix86_match_ccmode (insn, CCNOmode)"
10093   [(parallel [(set (match_dup 0)
10094                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10095                                     (const_int 0)]))
10096               (set (match_dup 1)
10097                    (xor:SI (match_dup 3) (const_int -1)))])]
10098   "")
10099
10100 ;; ??? Currently never generated - xor is used instead.
10101 (define_insn "*one_cmplsi2_2_zext"
10102   [(set (reg FLAGS_REG)
10103         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10104                  (const_int 0)))
10105    (set (match_operand:DI 0 "register_operand" "=r")
10106         (zero_extend:DI (not:SI (match_dup 1))))]
10107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10108    && ix86_unary_operator_ok (NOT, SImode, operands)"
10109   "#"
10110   [(set_attr "type" "alu1")
10111    (set_attr "mode" "SI")])
10112
10113 (define_split
10114   [(set (match_operand 0 "flags_reg_operand" "")
10115         (match_operator 2 "compare_operator"
10116           [(not:SI (match_operand:SI 3 "register_operand" ""))
10117            (const_int 0)]))
10118    (set (match_operand:DI 1 "register_operand" "")
10119         (zero_extend:DI (not:SI (match_dup 3))))]
10120   "ix86_match_ccmode (insn, CCNOmode)"
10121   [(parallel [(set (match_dup 0)
10122                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10123                                     (const_int 0)]))
10124               (set (match_dup 1)
10125                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10126   "")
10127
10128 (define_expand "one_cmplhi2"
10129   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10130         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10131   "TARGET_HIMODE_MATH"
10132   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10133
10134 (define_insn "*one_cmplhi2_1"
10135   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10136         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10137   "ix86_unary_operator_ok (NOT, HImode, operands)"
10138   "not{w}\t%0"
10139   [(set_attr "type" "negnot")
10140    (set_attr "mode" "HI")])
10141
10142 (define_insn "*one_cmplhi2_2"
10143   [(set (reg FLAGS_REG)
10144         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10145                  (const_int 0)))
10146    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10147         (not:HI (match_dup 1)))]
10148   "ix86_match_ccmode (insn, CCNOmode)
10149    && ix86_unary_operator_ok (NEG, HImode, operands)"
10150   "#"
10151   [(set_attr "type" "alu1")
10152    (set_attr "mode" "HI")])
10153
10154 (define_split
10155   [(set (match_operand 0 "flags_reg_operand" "")
10156         (match_operator 2 "compare_operator"
10157           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10158            (const_int 0)]))
10159    (set (match_operand:HI 1 "nonimmediate_operand" "")
10160         (not:HI (match_dup 3)))]
10161   "ix86_match_ccmode (insn, CCNOmode)"
10162   [(parallel [(set (match_dup 0)
10163                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10164                                     (const_int 0)]))
10165               (set (match_dup 1)
10166                    (xor:HI (match_dup 3) (const_int -1)))])]
10167   "")
10168
10169 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10170 (define_expand "one_cmplqi2"
10171   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10172         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10173   "TARGET_QIMODE_MATH"
10174   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10175
10176 (define_insn "*one_cmplqi2_1"
10177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10178         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10179   "ix86_unary_operator_ok (NOT, QImode, operands)"
10180   "@
10181    not{b}\t%0
10182    not{l}\t%k0"
10183   [(set_attr "type" "negnot")
10184    (set_attr "mode" "QI,SI")])
10185
10186 (define_insn "*one_cmplqi2_2"
10187   [(set (reg FLAGS_REG)
10188         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10189                  (const_int 0)))
10190    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10191         (not:QI (match_dup 1)))]
10192   "ix86_match_ccmode (insn, CCNOmode)
10193    && ix86_unary_operator_ok (NOT, QImode, operands)"
10194   "#"
10195   [(set_attr "type" "alu1")
10196    (set_attr "mode" "QI")])
10197
10198 (define_split
10199   [(set (match_operand 0 "flags_reg_operand" "")
10200         (match_operator 2 "compare_operator"
10201           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10202            (const_int 0)]))
10203    (set (match_operand:QI 1 "nonimmediate_operand" "")
10204         (not:QI (match_dup 3)))]
10205   "ix86_match_ccmode (insn, CCNOmode)"
10206   [(parallel [(set (match_dup 0)
10207                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10208                                     (const_int 0)]))
10209               (set (match_dup 1)
10210                    (xor:QI (match_dup 3) (const_int -1)))])]
10211   "")
10212 \f
10213 ;; Arithmetic shift instructions
10214
10215 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10216 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10217 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10218 ;; from the assembler input.
10219 ;;
10220 ;; This instruction shifts the target reg/mem as usual, but instead of
10221 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10222 ;; is a left shift double, bits are taken from the high order bits of
10223 ;; reg, else if the insn is a shift right double, bits are taken from the
10224 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10225 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10226 ;;
10227 ;; Since sh[lr]d does not change the `reg' operand, that is done
10228 ;; separately, making all shifts emit pairs of shift double and normal
10229 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10230 ;; support a 63 bit shift, each shift where the count is in a reg expands
10231 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10232 ;;
10233 ;; If the shift count is a constant, we need never emit more than one
10234 ;; shift pair, instead using moves and sign extension for counts greater
10235 ;; than 31.
10236
10237 (define_expand "ashlti3"
10238   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10239                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10240                               (match_operand:QI 2 "nonmemory_operand" "")))
10241               (clobber (reg:CC FLAGS_REG))])]
10242   "TARGET_64BIT"
10243 {
10244   if (! immediate_operand (operands[2], QImode))
10245     {
10246       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10247       DONE;
10248     }
10249   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10250   DONE;
10251 })
10252
10253 (define_insn "ashlti3_1"
10254   [(set (match_operand:TI 0 "register_operand" "=r")
10255         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10256                    (match_operand:QI 2 "register_operand" "c")))
10257    (clobber (match_scratch:DI 3 "=&r"))
10258    (clobber (reg:CC FLAGS_REG))]
10259   "TARGET_64BIT"
10260   "#"
10261   [(set_attr "type" "multi")])
10262
10263 (define_insn "*ashlti3_2"
10264   [(set (match_operand:TI 0 "register_operand" "=r")
10265         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10266                    (match_operand:QI 2 "immediate_operand" "O")))
10267    (clobber (reg:CC FLAGS_REG))]
10268   "TARGET_64BIT"
10269   "#"
10270   [(set_attr "type" "multi")])
10271
10272 (define_split
10273   [(set (match_operand:TI 0 "register_operand" "")
10274         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10275                    (match_operand:QI 2 "register_operand" "")))
10276    (clobber (match_scratch:DI 3 ""))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_64BIT && reload_completed"
10279   [(const_int 0)]
10280   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10281
10282 (define_split
10283   [(set (match_operand:TI 0 "register_operand" "")
10284         (ashift:TI (match_operand:TI 1 "register_operand" "")
10285                    (match_operand:QI 2 "immediate_operand" "")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "TARGET_64BIT && reload_completed"
10288   [(const_int 0)]
10289   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10290
10291 (define_insn "x86_64_shld"
10292   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10293         (ior:DI (ashift:DI (match_dup 0)
10294                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10295                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10296                   (minus:QI (const_int 64) (match_dup 2)))))
10297    (clobber (reg:CC FLAGS_REG))]
10298   "TARGET_64BIT"
10299   "@
10300    shld{q}\t{%2, %1, %0|%0, %1, %2}
10301    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10302   [(set_attr "type" "ishift")
10303    (set_attr "prefix_0f" "1")
10304    (set_attr "mode" "DI")
10305    (set_attr "athlon_decode" "vector")])
10306
10307 (define_expand "x86_64_shift_adj"
10308   [(set (reg:CCZ FLAGS_REG)
10309         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10310                              (const_int 64))
10311                      (const_int 0)))
10312    (set (match_operand:DI 0 "register_operand" "")
10313         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10314                          (match_operand:DI 1 "register_operand" "")
10315                          (match_dup 0)))
10316    (set (match_dup 1)
10317         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10318                          (match_operand:DI 3 "register_operand" "r")
10319                          (match_dup 1)))]
10320   "TARGET_64BIT"
10321   "")
10322
10323 (define_expand "ashldi3"
10324   [(set (match_operand:DI 0 "shiftdi_operand" "")
10325         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10326                    (match_operand:QI 2 "nonmemory_operand" "")))]
10327   ""
10328   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10329
10330 (define_insn "*ashldi3_1_rex64"
10331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10332         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10333                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10334    (clobber (reg:CC FLAGS_REG))]
10335   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10336 {
10337   switch (get_attr_type (insn))
10338     {
10339     case TYPE_ALU:
10340       gcc_assert (operands[2] == const1_rtx);
10341       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10342       return "add{q}\t{%0, %0|%0, %0}";
10343
10344     case TYPE_LEA:
10345       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10346       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10347       operands[1] = gen_rtx_MULT (DImode, operands[1],
10348                                   GEN_INT (1 << INTVAL (operands[2])));
10349       return "lea{q}\t{%a1, %0|%0, %a1}";
10350
10351     default:
10352       if (REG_P (operands[2]))
10353         return "sal{q}\t{%b2, %0|%0, %b2}";
10354       else if (operands[2] == const1_rtx
10355                && (TARGET_SHIFT1 || optimize_size))
10356         return "sal{q}\t%0";
10357       else
10358         return "sal{q}\t{%2, %0|%0, %2}";
10359     }
10360 }
10361   [(set (attr "type")
10362      (cond [(eq_attr "alternative" "1")
10363               (const_string "lea")
10364             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10365                           (const_int 0))
10366                       (match_operand 0 "register_operand" ""))
10367                  (match_operand 2 "const1_operand" ""))
10368               (const_string "alu")
10369            ]
10370            (const_string "ishift")))
10371    (set_attr "mode" "DI")])
10372
10373 ;; Convert lea to the lea pattern to avoid flags dependency.
10374 (define_split
10375   [(set (match_operand:DI 0 "register_operand" "")
10376         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10377                    (match_operand:QI 2 "immediate_operand" "")))
10378    (clobber (reg:CC FLAGS_REG))]
10379   "TARGET_64BIT && reload_completed
10380    && true_regnum (operands[0]) != true_regnum (operands[1])"
10381   [(set (match_dup 0)
10382         (mult:DI (match_dup 1)
10383                  (match_dup 2)))]
10384   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10385
10386 ;; This pattern can't accept a variable shift count, since shifts by
10387 ;; zero don't affect the flags.  We assume that shifts by constant
10388 ;; zero are optimized away.
10389 (define_insn "*ashldi3_cmp_rex64"
10390   [(set (reg FLAGS_REG)
10391         (compare
10392           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10393                      (match_operand:QI 2 "immediate_operand" "e"))
10394           (const_int 0)))
10395    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10396         (ashift:DI (match_dup 1) (match_dup 2)))]
10397   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10398    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10399 {
10400   switch (get_attr_type (insn))
10401     {
10402     case TYPE_ALU:
10403       gcc_assert (operands[2] == const1_rtx);
10404       return "add{q}\t{%0, %0|%0, %0}";
10405
10406     default:
10407       if (REG_P (operands[2]))
10408         return "sal{q}\t{%b2, %0|%0, %b2}";
10409       else if (operands[2] == const1_rtx
10410                && (TARGET_SHIFT1 || optimize_size))
10411         return "sal{q}\t%0";
10412       else
10413         return "sal{q}\t{%2, %0|%0, %2}";
10414     }
10415 }
10416   [(set (attr "type")
10417      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10418                           (const_int 0))
10419                       (match_operand 0 "register_operand" ""))
10420                  (match_operand 2 "const1_operand" ""))
10421               (const_string "alu")
10422            ]
10423            (const_string "ishift")))
10424    (set_attr "mode" "DI")])
10425
10426 (define_insn "*ashldi3_1"
10427   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10428         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10429                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10430    (clobber (reg:CC FLAGS_REG))]
10431   "!TARGET_64BIT"
10432   "#"
10433   [(set_attr "type" "multi")])
10434
10435 ;; By default we don't ask for a scratch register, because when DImode
10436 ;; values are manipulated, registers are already at a premium.  But if
10437 ;; we have one handy, we won't turn it away.
10438 (define_peephole2
10439   [(match_scratch:SI 3 "r")
10440    (parallel [(set (match_operand:DI 0 "register_operand" "")
10441                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10442                               (match_operand:QI 2 "nonmemory_operand" "")))
10443               (clobber (reg:CC FLAGS_REG))])
10444    (match_dup 3)]
10445   "!TARGET_64BIT && TARGET_CMOVE"
10446   [(const_int 0)]
10447   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10448
10449 (define_split
10450   [(set (match_operand:DI 0 "register_operand" "")
10451         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10452                    (match_operand:QI 2 "nonmemory_operand" "")))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10455                      ? flow2_completed : reload_completed)"
10456   [(const_int 0)]
10457   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10458
10459 (define_insn "x86_shld_1"
10460   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10461         (ior:SI (ashift:SI (match_dup 0)
10462                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10463                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10464                   (minus:QI (const_int 32) (match_dup 2)))))
10465    (clobber (reg:CC FLAGS_REG))]
10466   ""
10467   "@
10468    shld{l}\t{%2, %1, %0|%0, %1, %2}
10469    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10470   [(set_attr "type" "ishift")
10471    (set_attr "prefix_0f" "1")
10472    (set_attr "mode" "SI")
10473    (set_attr "pent_pair" "np")
10474    (set_attr "athlon_decode" "vector")])
10475
10476 (define_expand "x86_shift_adj_1"
10477   [(set (reg:CCZ FLAGS_REG)
10478         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10479                              (const_int 32))
10480                      (const_int 0)))
10481    (set (match_operand:SI 0 "register_operand" "")
10482         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10483                          (match_operand:SI 1 "register_operand" "")
10484                          (match_dup 0)))
10485    (set (match_dup 1)
10486         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10487                          (match_operand:SI 3 "register_operand" "r")
10488                          (match_dup 1)))]
10489   "TARGET_CMOVE"
10490   "")
10491
10492 (define_expand "x86_shift_adj_2"
10493   [(use (match_operand:SI 0 "register_operand" ""))
10494    (use (match_operand:SI 1 "register_operand" ""))
10495    (use (match_operand:QI 2 "register_operand" ""))]
10496   ""
10497 {
10498   rtx label = gen_label_rtx ();
10499   rtx tmp;
10500
10501   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10502
10503   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10504   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10505   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10506                               gen_rtx_LABEL_REF (VOIDmode, label),
10507                               pc_rtx);
10508   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10509   JUMP_LABEL (tmp) = label;
10510
10511   emit_move_insn (operands[0], operands[1]);
10512   ix86_expand_clear (operands[1]);
10513
10514   emit_label (label);
10515   LABEL_NUSES (label) = 1;
10516
10517   DONE;
10518 })
10519
10520 (define_expand "ashlsi3"
10521   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10522         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10523                    (match_operand:QI 2 "nonmemory_operand" "")))
10524    (clobber (reg:CC FLAGS_REG))]
10525   ""
10526   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10527
10528 (define_insn "*ashlsi3_1"
10529   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10530         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10531                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10534 {
10535   switch (get_attr_type (insn))
10536     {
10537     case TYPE_ALU:
10538       gcc_assert (operands[2] == const1_rtx);
10539       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10540       return "add{l}\t{%0, %0|%0, %0}";
10541
10542     case TYPE_LEA:
10543       return "#";
10544
10545     default:
10546       if (REG_P (operands[2]))
10547         return "sal{l}\t{%b2, %0|%0, %b2}";
10548       else if (operands[2] == const1_rtx
10549                && (TARGET_SHIFT1 || optimize_size))
10550         return "sal{l}\t%0";
10551       else
10552         return "sal{l}\t{%2, %0|%0, %2}";
10553     }
10554 }
10555   [(set (attr "type")
10556      (cond [(eq_attr "alternative" "1")
10557               (const_string "lea")
10558             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10559                           (const_int 0))
10560                       (match_operand 0 "register_operand" ""))
10561                  (match_operand 2 "const1_operand" ""))
10562               (const_string "alu")
10563            ]
10564            (const_string "ishift")))
10565    (set_attr "mode" "SI")])
10566
10567 ;; Convert lea to the lea pattern to avoid flags dependency.
10568 (define_split
10569   [(set (match_operand 0 "register_operand" "")
10570         (ashift (match_operand 1 "index_register_operand" "")
10571                 (match_operand:QI 2 "const_int_operand" "")))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "reload_completed
10574    && true_regnum (operands[0]) != true_regnum (operands[1])
10575    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10576   [(const_int 0)]
10577 {
10578   rtx pat;
10579   enum machine_mode mode = GET_MODE (operands[0]);
10580
10581   if (GET_MODE_SIZE (mode) < 4)
10582     operands[0] = gen_lowpart (SImode, operands[0]);
10583   if (mode != Pmode)
10584     operands[1] = gen_lowpart (Pmode, operands[1]);
10585   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10586
10587   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10588   if (Pmode != SImode)
10589     pat = gen_rtx_SUBREG (SImode, pat, 0);
10590   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10591   DONE;
10592 })
10593
10594 ;; Rare case of shifting RSP is handled by generating move and shift
10595 (define_split
10596   [(set (match_operand 0 "register_operand" "")
10597         (ashift (match_operand 1 "register_operand" "")
10598                 (match_operand:QI 2 "const_int_operand" "")))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "reload_completed
10601    && true_regnum (operands[0]) != true_regnum (operands[1])"
10602   [(const_int 0)]
10603 {
10604   rtx pat, clob;
10605   emit_move_insn (operands[0], operands[1]);
10606   pat = gen_rtx_SET (VOIDmode, operands[0],
10607                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10608                                      operands[0], operands[2]));
10609   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10610   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10611   DONE;
10612 })
10613
10614 (define_insn "*ashlsi3_1_zext"
10615   [(set (match_operand:DI 0 "register_operand" "=r,r")
10616         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10617                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10618    (clobber (reg:CC FLAGS_REG))]
10619   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10620 {
10621   switch (get_attr_type (insn))
10622     {
10623     case TYPE_ALU:
10624       gcc_assert (operands[2] == const1_rtx);
10625       return "add{l}\t{%k0, %k0|%k0, %k0}";
10626
10627     case TYPE_LEA:
10628       return "#";
10629
10630     default:
10631       if (REG_P (operands[2]))
10632         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10633       else if (operands[2] == const1_rtx
10634                && (TARGET_SHIFT1 || optimize_size))
10635         return "sal{l}\t%k0";
10636       else
10637         return "sal{l}\t{%2, %k0|%k0, %2}";
10638     }
10639 }
10640   [(set (attr "type")
10641      (cond [(eq_attr "alternative" "1")
10642               (const_string "lea")
10643             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10644                      (const_int 0))
10645                  (match_operand 2 "const1_operand" ""))
10646               (const_string "alu")
10647            ]
10648            (const_string "ishift")))
10649    (set_attr "mode" "SI")])
10650
10651 ;; Convert lea to the lea pattern to avoid flags dependency.
10652 (define_split
10653   [(set (match_operand:DI 0 "register_operand" "")
10654         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10655                                 (match_operand:QI 2 "const_int_operand" ""))))
10656    (clobber (reg:CC FLAGS_REG))]
10657   "TARGET_64BIT && reload_completed
10658    && true_regnum (operands[0]) != true_regnum (operands[1])"
10659   [(set (match_dup 0) (zero_extend:DI
10660                         (subreg:SI (mult:SI (match_dup 1)
10661                                             (match_dup 2)) 0)))]
10662 {
10663   operands[1] = gen_lowpart (Pmode, operands[1]);
10664   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10665 })
10666
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags.  We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashlsi3_cmp"
10671   [(set (reg FLAGS_REG)
10672         (compare
10673           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10674                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10675           (const_int 0)))
10676    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10677         (ashift:SI (match_dup 1) (match_dup 2)))]
10678   "ix86_match_ccmode (insn, CCGOCmode)
10679    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10680 {
10681   switch (get_attr_type (insn))
10682     {
10683     case TYPE_ALU:
10684       gcc_assert (operands[2] == const1_rtx);
10685       return "add{l}\t{%0, %0|%0, %0}";
10686
10687     default:
10688       if (REG_P (operands[2]))
10689         return "sal{l}\t{%b2, %0|%0, %b2}";
10690       else if (operands[2] == const1_rtx
10691                && (TARGET_SHIFT1 || optimize_size))
10692         return "sal{l}\t%0";
10693       else
10694         return "sal{l}\t{%2, %0|%0, %2}";
10695     }
10696 }
10697   [(set (attr "type")
10698      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10699                           (const_int 0))
10700                       (match_operand 0 "register_operand" ""))
10701                  (match_operand 2 "const1_operand" ""))
10702               (const_string "alu")
10703            ]
10704            (const_string "ishift")))
10705    (set_attr "mode" "SI")])
10706
10707 (define_insn "*ashlsi3_cmp_zext"
10708   [(set (reg FLAGS_REG)
10709         (compare
10710           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10711                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10712           (const_int 0)))
10713    (set (match_operand:DI 0 "register_operand" "=r")
10714         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10715   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10716    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10717 {
10718   switch (get_attr_type (insn))
10719     {
10720     case TYPE_ALU:
10721       gcc_assert (operands[2] == const1_rtx);
10722       return "add{l}\t{%k0, %k0|%k0, %k0}";
10723
10724     default:
10725       if (REG_P (operands[2]))
10726         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10727       else if (operands[2] == const1_rtx
10728                && (TARGET_SHIFT1 || optimize_size))
10729         return "sal{l}\t%k0";
10730       else
10731         return "sal{l}\t{%2, %k0|%k0, %2}";
10732     }
10733 }
10734   [(set (attr "type")
10735      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10736                      (const_int 0))
10737                  (match_operand 2 "const1_operand" ""))
10738               (const_string "alu")
10739            ]
10740            (const_string "ishift")))
10741    (set_attr "mode" "SI")])
10742
10743 (define_expand "ashlhi3"
10744   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10745         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10746                    (match_operand:QI 2 "nonmemory_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_HIMODE_MATH"
10749   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10750
10751 (define_insn "*ashlhi3_1_lea"
10752   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10753         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10754                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "!TARGET_PARTIAL_REG_STALL
10757    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10758 {
10759   switch (get_attr_type (insn))
10760     {
10761     case TYPE_LEA:
10762       return "#";
10763     case TYPE_ALU:
10764       gcc_assert (operands[2] == const1_rtx);
10765       return "add{w}\t{%0, %0|%0, %0}";
10766
10767     default:
10768       if (REG_P (operands[2]))
10769         return "sal{w}\t{%b2, %0|%0, %b2}";
10770       else if (operands[2] == const1_rtx
10771                && (TARGET_SHIFT1 || optimize_size))
10772         return "sal{w}\t%0";
10773       else
10774         return "sal{w}\t{%2, %0|%0, %2}";
10775     }
10776 }
10777   [(set (attr "type")
10778      (cond [(eq_attr "alternative" "1")
10779               (const_string "lea")
10780             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781                           (const_int 0))
10782                       (match_operand 0 "register_operand" ""))
10783                  (match_operand 2 "const1_operand" ""))
10784               (const_string "alu")
10785            ]
10786            (const_string "ishift")))
10787    (set_attr "mode" "HI,SI")])
10788
10789 (define_insn "*ashlhi3_1"
10790   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10791         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10792                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10793    (clobber (reg:CC FLAGS_REG))]
10794   "TARGET_PARTIAL_REG_STALL
10795    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10796 {
10797   switch (get_attr_type (insn))
10798     {
10799     case TYPE_ALU:
10800       gcc_assert (operands[2] == const1_rtx);
10801       return "add{w}\t{%0, %0|%0, %0}";
10802
10803     default:
10804       if (REG_P (operands[2]))
10805         return "sal{w}\t{%b2, %0|%0, %b2}";
10806       else if (operands[2] == const1_rtx
10807                && (TARGET_SHIFT1 || optimize_size))
10808         return "sal{w}\t%0";
10809       else
10810         return "sal{w}\t{%2, %0|%0, %2}";
10811     }
10812 }
10813   [(set (attr "type")
10814      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10815                           (const_int 0))
10816                       (match_operand 0 "register_operand" ""))
10817                  (match_operand 2 "const1_operand" ""))
10818               (const_string "alu")
10819            ]
10820            (const_string "ishift")))
10821    (set_attr "mode" "HI")])
10822
10823 ;; This pattern can't accept a variable shift count, since shifts by
10824 ;; zero don't affect the flags.  We assume that shifts by constant
10825 ;; zero are optimized away.
10826 (define_insn "*ashlhi3_cmp"
10827   [(set (reg FLAGS_REG)
10828         (compare
10829           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10830                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10831           (const_int 0)))
10832    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10833         (ashift:HI (match_dup 1) (match_dup 2)))]
10834   "ix86_match_ccmode (insn, CCGOCmode)
10835    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10836 {
10837   switch (get_attr_type (insn))
10838     {
10839     case TYPE_ALU:
10840       gcc_assert (operands[2] == const1_rtx);
10841       return "add{w}\t{%0, %0|%0, %0}";
10842
10843     default:
10844       if (REG_P (operands[2]))
10845         return "sal{w}\t{%b2, %0|%0, %b2}";
10846       else if (operands[2] == const1_rtx
10847                && (TARGET_SHIFT1 || optimize_size))
10848         return "sal{w}\t%0";
10849       else
10850         return "sal{w}\t{%2, %0|%0, %2}";
10851     }
10852 }
10853   [(set (attr "type")
10854      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10855                           (const_int 0))
10856                       (match_operand 0 "register_operand" ""))
10857                  (match_operand 2 "const1_operand" ""))
10858               (const_string "alu")
10859            ]
10860            (const_string "ishift")))
10861    (set_attr "mode" "HI")])
10862
10863 (define_expand "ashlqi3"
10864   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10865         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10866                    (match_operand:QI 2 "nonmemory_operand" "")))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "TARGET_QIMODE_MATH"
10869   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10870
10871 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10872
10873 (define_insn "*ashlqi3_1_lea"
10874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10875         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10876                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10877    (clobber (reg:CC FLAGS_REG))]
10878   "!TARGET_PARTIAL_REG_STALL
10879    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10880 {
10881   switch (get_attr_type (insn))
10882     {
10883     case TYPE_LEA:
10884       return "#";
10885     case TYPE_ALU:
10886       gcc_assert (operands[2] == const1_rtx);
10887       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10888         return "add{l}\t{%k0, %k0|%k0, %k0}";
10889       else
10890         return "add{b}\t{%0, %0|%0, %0}";
10891
10892     default:
10893       if (REG_P (operands[2]))
10894         {
10895           if (get_attr_mode (insn) == MODE_SI)
10896             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10897           else
10898             return "sal{b}\t{%b2, %0|%0, %b2}";
10899         }
10900       else if (operands[2] == const1_rtx
10901                && (TARGET_SHIFT1 || optimize_size))
10902         {
10903           if (get_attr_mode (insn) == MODE_SI)
10904             return "sal{l}\t%0";
10905           else
10906             return "sal{b}\t%0";
10907         }
10908       else
10909         {
10910           if (get_attr_mode (insn) == MODE_SI)
10911             return "sal{l}\t{%2, %k0|%k0, %2}";
10912           else
10913             return "sal{b}\t{%2, %0|%0, %2}";
10914         }
10915     }
10916 }
10917   [(set (attr "type")
10918      (cond [(eq_attr "alternative" "2")
10919               (const_string "lea")
10920             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10921                           (const_int 0))
10922                       (match_operand 0 "register_operand" ""))
10923                  (match_operand 2 "const1_operand" ""))
10924               (const_string "alu")
10925            ]
10926            (const_string "ishift")))
10927    (set_attr "mode" "QI,SI,SI")])
10928
10929 (define_insn "*ashlqi3_1"
10930   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10931         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10932                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10933    (clobber (reg:CC FLAGS_REG))]
10934   "TARGET_PARTIAL_REG_STALL
10935    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10936 {
10937   switch (get_attr_type (insn))
10938     {
10939     case TYPE_ALU:
10940       gcc_assert (operands[2] == const1_rtx);
10941       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10942         return "add{l}\t{%k0, %k0|%k0, %k0}";
10943       else
10944         return "add{b}\t{%0, %0|%0, %0}";
10945
10946     default:
10947       if (REG_P (operands[2]))
10948         {
10949           if (get_attr_mode (insn) == MODE_SI)
10950             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10951           else
10952             return "sal{b}\t{%b2, %0|%0, %b2}";
10953         }
10954       else if (operands[2] == const1_rtx
10955                && (TARGET_SHIFT1 || optimize_size))
10956         {
10957           if (get_attr_mode (insn) == MODE_SI)
10958             return "sal{l}\t%0";
10959           else
10960             return "sal{b}\t%0";
10961         }
10962       else
10963         {
10964           if (get_attr_mode (insn) == MODE_SI)
10965             return "sal{l}\t{%2, %k0|%k0, %2}";
10966           else
10967             return "sal{b}\t{%2, %0|%0, %2}";
10968         }
10969     }
10970 }
10971   [(set (attr "type")
10972      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973                           (const_int 0))
10974                       (match_operand 0 "register_operand" ""))
10975                  (match_operand 2 "const1_operand" ""))
10976               (const_string "alu")
10977            ]
10978            (const_string "ishift")))
10979    (set_attr "mode" "QI,SI")])
10980
10981 ;; This pattern can't accept a variable shift count, since shifts by
10982 ;; zero don't affect the flags.  We assume that shifts by constant
10983 ;; zero are optimized away.
10984 (define_insn "*ashlqi3_cmp"
10985   [(set (reg FLAGS_REG)
10986         (compare
10987           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10988                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10989           (const_int 0)))
10990    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10991         (ashift:QI (match_dup 1) (match_dup 2)))]
10992   "ix86_match_ccmode (insn, CCGOCmode)
10993    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10994 {
10995   switch (get_attr_type (insn))
10996     {
10997     case TYPE_ALU:
10998       gcc_assert (operands[2] == const1_rtx);
10999       return "add{b}\t{%0, %0|%0, %0}";
11000
11001     default:
11002       if (REG_P (operands[2]))
11003         return "sal{b}\t{%b2, %0|%0, %b2}";
11004       else if (operands[2] == const1_rtx
11005                && (TARGET_SHIFT1 || optimize_size))
11006         return "sal{b}\t%0";
11007       else
11008         return "sal{b}\t{%2, %0|%0, %2}";
11009     }
11010 }
11011   [(set (attr "type")
11012      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013                           (const_int 0))
11014                       (match_operand 0 "register_operand" ""))
11015                  (match_operand 2 "const1_operand" ""))
11016               (const_string "alu")
11017            ]
11018            (const_string "ishift")))
11019    (set_attr "mode" "QI")])
11020
11021 ;; See comment above `ashldi3' about how this works.
11022
11023 (define_expand "ashrti3"
11024   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11025                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11026                                 (match_operand:QI 2 "nonmemory_operand" "")))
11027               (clobber (reg:CC FLAGS_REG))])]
11028   "TARGET_64BIT"
11029 {
11030   if (! immediate_operand (operands[2], QImode))
11031     {
11032       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11033       DONE;
11034     }
11035   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11036   DONE;
11037 })
11038
11039 (define_insn "ashrti3_1"
11040   [(set (match_operand:TI 0 "register_operand" "=r")
11041         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11042                      (match_operand:QI 2 "register_operand" "c")))
11043    (clobber (match_scratch:DI 3 "=&r"))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT"
11046   "#"
11047   [(set_attr "type" "multi")])
11048
11049 (define_insn "*ashrti3_2"
11050   [(set (match_operand:TI 0 "register_operand" "=r")
11051         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11052                      (match_operand:QI 2 "immediate_operand" "O")))
11053    (clobber (reg:CC FLAGS_REG))]
11054   "TARGET_64BIT"
11055   "#"
11056   [(set_attr "type" "multi")])
11057
11058 (define_split
11059   [(set (match_operand:TI 0 "register_operand" "")
11060         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11061                      (match_operand:QI 2 "register_operand" "")))
11062    (clobber (match_scratch:DI 3 ""))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "TARGET_64BIT && reload_completed"
11065   [(const_int 0)]
11066   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11067
11068 (define_split
11069   [(set (match_operand:TI 0 "register_operand" "")
11070         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11071                      (match_operand:QI 2 "immediate_operand" "")))
11072    (clobber (reg:CC FLAGS_REG))]
11073   "TARGET_64BIT && reload_completed"
11074   [(const_int 0)]
11075   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11076
11077 (define_insn "x86_64_shrd"
11078   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11079         (ior:DI (ashiftrt:DI (match_dup 0)
11080                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11081                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11082                   (minus:QI (const_int 64) (match_dup 2)))))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "TARGET_64BIT"
11085   "@
11086    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11087    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11088   [(set_attr "type" "ishift")
11089    (set_attr "prefix_0f" "1")
11090    (set_attr "mode" "DI")
11091    (set_attr "athlon_decode" "vector")])
11092
11093 (define_expand "ashrdi3"
11094   [(set (match_operand:DI 0 "shiftdi_operand" "")
11095         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11096                      (match_operand:QI 2 "nonmemory_operand" "")))]
11097   ""
11098   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11099
11100 (define_insn "*ashrdi3_63_rex64"
11101   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11102         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11103                      (match_operand:DI 2 "const_int_operand" "i,i")))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "TARGET_64BIT && INTVAL (operands[2]) == 63
11106    && (TARGET_USE_CLTD || optimize_size)
11107    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11108   "@
11109    {cqto|cqo}
11110    sar{q}\t{%2, %0|%0, %2}"
11111   [(set_attr "type" "imovx,ishift")
11112    (set_attr "prefix_0f" "0,*")
11113    (set_attr "length_immediate" "0,*")
11114    (set_attr "modrm" "0,1")
11115    (set_attr "mode" "DI")])
11116
11117 (define_insn "*ashrdi3_1_one_bit_rex64"
11118   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11119         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11120                      (match_operand:QI 2 "const1_operand" "")))
11121    (clobber (reg:CC FLAGS_REG))]
11122   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11123    && (TARGET_SHIFT1 || optimize_size)"
11124   "sar{q}\t%0"
11125   [(set_attr "type" "ishift")
11126    (set (attr "length") 
11127      (if_then_else (match_operand:DI 0 "register_operand" "") 
11128         (const_string "2")
11129         (const_string "*")))])
11130
11131 (define_insn "*ashrdi3_1_rex64"
11132   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11133         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11134                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11137   "@
11138    sar{q}\t{%2, %0|%0, %2}
11139    sar{q}\t{%b2, %0|%0, %b2}"
11140   [(set_attr "type" "ishift")
11141    (set_attr "mode" "DI")])
11142
11143 ;; This pattern can't accept a variable shift count, since shifts by
11144 ;; zero don't affect the flags.  We assume that shifts by constant
11145 ;; zero are optimized away.
11146 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11147   [(set (reg FLAGS_REG)
11148         (compare
11149           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11150                        (match_operand:QI 2 "const1_operand" ""))
11151           (const_int 0)))
11152    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11153         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11154   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11155    && (TARGET_SHIFT1 || optimize_size)
11156    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11157   "sar{q}\t%0"
11158   [(set_attr "type" "ishift")
11159    (set (attr "length") 
11160      (if_then_else (match_operand:DI 0 "register_operand" "") 
11161         (const_string "2")
11162         (const_string "*")))])
11163
11164 ;; This pattern can't accept a variable shift count, since shifts by
11165 ;; zero don't affect the flags.  We assume that shifts by constant
11166 ;; zero are optimized away.
11167 (define_insn "*ashrdi3_cmp_rex64"
11168   [(set (reg FLAGS_REG)
11169         (compare
11170           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11171                        (match_operand:QI 2 "const_int_operand" "n"))
11172           (const_int 0)))
11173    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11174         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11175   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11176    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11177   "sar{q}\t{%2, %0|%0, %2}"
11178   [(set_attr "type" "ishift")
11179    (set_attr "mode" "DI")])
11180
11181 (define_insn "*ashrdi3_1"
11182   [(set (match_operand:DI 0 "register_operand" "=r")
11183         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11184                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11185    (clobber (reg:CC FLAGS_REG))]
11186   "!TARGET_64BIT"
11187   "#"
11188   [(set_attr "type" "multi")])
11189
11190 ;; By default we don't ask for a scratch register, because when DImode
11191 ;; values are manipulated, registers are already at a premium.  But if
11192 ;; we have one handy, we won't turn it away.
11193 (define_peephole2
11194   [(match_scratch:SI 3 "r")
11195    (parallel [(set (match_operand:DI 0 "register_operand" "")
11196                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11197                                 (match_operand:QI 2 "nonmemory_operand" "")))
11198               (clobber (reg:CC FLAGS_REG))])
11199    (match_dup 3)]
11200   "!TARGET_64BIT && TARGET_CMOVE"
11201   [(const_int 0)]
11202   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11203
11204 (define_split
11205   [(set (match_operand:DI 0 "register_operand" "")
11206         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11207                      (match_operand:QI 2 "nonmemory_operand" "")))
11208    (clobber (reg:CC FLAGS_REG))]
11209   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11210                      ? flow2_completed : reload_completed)"
11211   [(const_int 0)]
11212   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11213
11214 (define_insn "x86_shrd_1"
11215   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11216         (ior:SI (ashiftrt:SI (match_dup 0)
11217                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11218                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11219                   (minus:QI (const_int 32) (match_dup 2)))))
11220    (clobber (reg:CC FLAGS_REG))]
11221   ""
11222   "@
11223    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11224    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11225   [(set_attr "type" "ishift")
11226    (set_attr "prefix_0f" "1")
11227    (set_attr "pent_pair" "np")
11228    (set_attr "mode" "SI")])
11229
11230 (define_expand "x86_shift_adj_3"
11231   [(use (match_operand:SI 0 "register_operand" ""))
11232    (use (match_operand:SI 1 "register_operand" ""))
11233    (use (match_operand:QI 2 "register_operand" ""))]
11234   ""
11235 {
11236   rtx label = gen_label_rtx ();
11237   rtx tmp;
11238
11239   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11240
11241   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11242   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11243   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11244                               gen_rtx_LABEL_REF (VOIDmode, label),
11245                               pc_rtx);
11246   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11247   JUMP_LABEL (tmp) = label;
11248
11249   emit_move_insn (operands[0], operands[1]);
11250   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11251
11252   emit_label (label);
11253   LABEL_NUSES (label) = 1;
11254
11255   DONE;
11256 })
11257
11258 (define_insn "ashrsi3_31"
11259   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11260         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11261                      (match_operand:SI 2 "const_int_operand" "i,i")))
11262    (clobber (reg:CC FLAGS_REG))]
11263   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11264    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11265   "@
11266    {cltd|cdq}
11267    sar{l}\t{%2, %0|%0, %2}"
11268   [(set_attr "type" "imovx,ishift")
11269    (set_attr "prefix_0f" "0,*")
11270    (set_attr "length_immediate" "0,*")
11271    (set_attr "modrm" "0,1")
11272    (set_attr "mode" "SI")])
11273
11274 (define_insn "*ashrsi3_31_zext"
11275   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11276         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11277                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11278    (clobber (reg:CC FLAGS_REG))]
11279   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11280    && INTVAL (operands[2]) == 31
11281    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11282   "@
11283    {cltd|cdq}
11284    sar{l}\t{%2, %k0|%k0, %2}"
11285   [(set_attr "type" "imovx,ishift")
11286    (set_attr "prefix_0f" "0,*")
11287    (set_attr "length_immediate" "0,*")
11288    (set_attr "modrm" "0,1")
11289    (set_attr "mode" "SI")])
11290
11291 (define_expand "ashrsi3"
11292   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11293         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11294                      (match_operand:QI 2 "nonmemory_operand" "")))
11295    (clobber (reg:CC FLAGS_REG))]
11296   ""
11297   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11298
11299 (define_insn "*ashrsi3_1_one_bit"
11300   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11301         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const1_operand" "")))
11303    (clobber (reg:CC FLAGS_REG))]
11304   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11305    && (TARGET_SHIFT1 || optimize_size)"
11306   "sar{l}\t%0"
11307   [(set_attr "type" "ishift")
11308    (set (attr "length") 
11309      (if_then_else (match_operand:SI 0 "register_operand" "") 
11310         (const_string "2")
11311         (const_string "*")))])
11312
11313 (define_insn "*ashrsi3_1_one_bit_zext"
11314   [(set (match_operand:DI 0 "register_operand" "=r")
11315         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11316                                      (match_operand:QI 2 "const1_operand" ""))))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11319    && (TARGET_SHIFT1 || optimize_size)"
11320   "sar{l}\t%k0"
11321   [(set_attr "type" "ishift")
11322    (set_attr "length" "2")])
11323
11324 (define_insn "*ashrsi3_1"
11325   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11326         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11327                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11330   "@
11331    sar{l}\t{%2, %0|%0, %2}
11332    sar{l}\t{%b2, %0|%0, %b2}"
11333   [(set_attr "type" "ishift")
11334    (set_attr "mode" "SI")])
11335
11336 (define_insn "*ashrsi3_1_zext"
11337   [(set (match_operand:DI 0 "register_operand" "=r,r")
11338         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11339                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11340    (clobber (reg:CC FLAGS_REG))]
11341   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11342   "@
11343    sar{l}\t{%2, %k0|%k0, %2}
11344    sar{l}\t{%b2, %k0|%k0, %b2}"
11345   [(set_attr "type" "ishift")
11346    (set_attr "mode" "SI")])
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags.  We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrsi3_one_bit_cmp"
11352   [(set (reg FLAGS_REG)
11353         (compare
11354           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355                        (match_operand:QI 2 "const1_operand" ""))
11356           (const_int 0)))
11357    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11359   "ix86_match_ccmode (insn, CCGOCmode)
11360    && (TARGET_SHIFT1 || optimize_size)
11361    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11362   "sar{l}\t%0"
11363   [(set_attr "type" "ishift")
11364    (set (attr "length") 
11365      (if_then_else (match_operand:SI 0 "register_operand" "") 
11366         (const_string "2")
11367         (const_string "*")))])
11368
11369 (define_insn "*ashrsi3_one_bit_cmp_zext"
11370   [(set (reg FLAGS_REG)
11371         (compare
11372           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11373                        (match_operand:QI 2 "const1_operand" ""))
11374           (const_int 0)))
11375    (set (match_operand:DI 0 "register_operand" "=r")
11376         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11377   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11378    && (TARGET_SHIFT1 || optimize_size)
11379    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11380   "sar{l}\t%k0"
11381   [(set_attr "type" "ishift")
11382    (set_attr "length" "2")])
11383
11384 ;; This pattern can't accept a variable shift count, since shifts by
11385 ;; zero don't affect the flags.  We assume that shifts by constant
11386 ;; zero are optimized away.
11387 (define_insn "*ashrsi3_cmp"
11388   [(set (reg FLAGS_REG)
11389         (compare
11390           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11391                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11392           (const_int 0)))
11393    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11394         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11395   "ix86_match_ccmode (insn, CCGOCmode)
11396    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11397   "sar{l}\t{%2, %0|%0, %2}"
11398   [(set_attr "type" "ishift")
11399    (set_attr "mode" "SI")])
11400
11401 (define_insn "*ashrsi3_cmp_zext"
11402   [(set (reg FLAGS_REG)
11403         (compare
11404           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11405                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11406           (const_int 0)))
11407    (set (match_operand:DI 0 "register_operand" "=r")
11408         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11409   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11411   "sar{l}\t{%2, %k0|%k0, %2}"
11412   [(set_attr "type" "ishift")
11413    (set_attr "mode" "SI")])
11414
11415 (define_expand "ashrhi3"
11416   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11417         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11418                      (match_operand:QI 2 "nonmemory_operand" "")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "TARGET_HIMODE_MATH"
11421   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11422
11423 (define_insn "*ashrhi3_1_one_bit"
11424   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11426                      (match_operand:QI 2 "const1_operand" "")))
11427    (clobber (reg:CC FLAGS_REG))]
11428   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11429    && (TARGET_SHIFT1 || optimize_size)"
11430   "sar{w}\t%0"
11431   [(set_attr "type" "ishift")
11432    (set (attr "length") 
11433      (if_then_else (match_operand 0 "register_operand" "") 
11434         (const_string "2")
11435         (const_string "*")))])
11436
11437 (define_insn "*ashrhi3_1"
11438   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11439         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11440                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11441    (clobber (reg:CC FLAGS_REG))]
11442   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443   "@
11444    sar{w}\t{%2, %0|%0, %2}
11445    sar{w}\t{%b2, %0|%0, %b2}"
11446   [(set_attr "type" "ishift")
11447    (set_attr "mode" "HI")])
11448
11449 ;; This pattern can't accept a variable shift count, since shifts by
11450 ;; zero don't affect the flags.  We assume that shifts by constant
11451 ;; zero are optimized away.
11452 (define_insn "*ashrhi3_one_bit_cmp"
11453   [(set (reg FLAGS_REG)
11454         (compare
11455           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11456                        (match_operand:QI 2 "const1_operand" ""))
11457           (const_int 0)))
11458    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11459         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11460   "ix86_match_ccmode (insn, CCGOCmode)
11461    && (TARGET_SHIFT1 || optimize_size)
11462    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11463   "sar{w}\t%0"
11464   [(set_attr "type" "ishift")
11465    (set (attr "length") 
11466      (if_then_else (match_operand 0 "register_operand" "") 
11467         (const_string "2")
11468         (const_string "*")))])
11469
11470 ;; This pattern can't accept a variable shift count, since shifts by
11471 ;; zero don't affect the flags.  We assume that shifts by constant
11472 ;; zero are optimized away.
11473 (define_insn "*ashrhi3_cmp"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11477                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11478           (const_int 0)))
11479    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11480         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11481   "ix86_match_ccmode (insn, CCGOCmode)
11482    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11483   "sar{w}\t{%2, %0|%0, %2}"
11484   [(set_attr "type" "ishift")
11485    (set_attr "mode" "HI")])
11486
11487 (define_expand "ashrqi3"
11488   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11489         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11490                      (match_operand:QI 2 "nonmemory_operand" "")))
11491    (clobber (reg:CC FLAGS_REG))]
11492   "TARGET_QIMODE_MATH"
11493   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11494
11495 (define_insn "*ashrqi3_1_one_bit"
11496   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11497         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11498                      (match_operand:QI 2 "const1_operand" "")))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11501    && (TARGET_SHIFT1 || optimize_size)"
11502   "sar{b}\t%0"
11503   [(set_attr "type" "ishift")
11504    (set (attr "length") 
11505      (if_then_else (match_operand 0 "register_operand" "") 
11506         (const_string "2")
11507         (const_string "*")))])
11508
11509 (define_insn "*ashrqi3_1_one_bit_slp"
11510   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11511         (ashiftrt:QI (match_dup 0)
11512                      (match_operand:QI 1 "const1_operand" "")))
11513    (clobber (reg:CC FLAGS_REG))]
11514   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11515    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11516    && (TARGET_SHIFT1 || optimize_size)"
11517   "sar{b}\t%0"
11518   [(set_attr "type" "ishift1")
11519    (set (attr "length") 
11520      (if_then_else (match_operand 0 "register_operand" "") 
11521         (const_string "2")
11522         (const_string "*")))])
11523
11524 (define_insn "*ashrqi3_1"
11525   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11526         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11527                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11528    (clobber (reg:CC FLAGS_REG))]
11529   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11530   "@
11531    sar{b}\t{%2, %0|%0, %2}
11532    sar{b}\t{%b2, %0|%0, %b2}"
11533   [(set_attr "type" "ishift")
11534    (set_attr "mode" "QI")])
11535
11536 (define_insn "*ashrqi3_1_slp"
11537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11538         (ashiftrt:QI (match_dup 0)
11539                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11540    (clobber (reg:CC FLAGS_REG))]
11541   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11542    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11543   "@
11544    sar{b}\t{%1, %0|%0, %1}
11545    sar{b}\t{%b1, %0|%0, %b1}"
11546   [(set_attr "type" "ishift1")
11547    (set_attr "mode" "QI")])
11548
11549 ;; This pattern can't accept a variable shift count, since shifts by
11550 ;; zero don't affect the flags.  We assume that shifts by constant
11551 ;; zero are optimized away.
11552 (define_insn "*ashrqi3_one_bit_cmp"
11553   [(set (reg FLAGS_REG)
11554         (compare
11555           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11556                        (match_operand:QI 2 "const1_operand" "I"))
11557           (const_int 0)))
11558    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11559         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11560   "ix86_match_ccmode (insn, CCGOCmode)
11561    && (TARGET_SHIFT1 || optimize_size)
11562    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11563   "sar{b}\t%0"
11564   [(set_attr "type" "ishift")
11565    (set (attr "length") 
11566      (if_then_else (match_operand 0 "register_operand" "") 
11567         (const_string "2")
11568         (const_string "*")))])
11569
11570 ;; This pattern can't accept a variable shift count, since shifts by
11571 ;; zero don't affect the flags.  We assume that shifts by constant
11572 ;; zero are optimized away.
11573 (define_insn "*ashrqi3_cmp"
11574   [(set (reg FLAGS_REG)
11575         (compare
11576           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11577                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11578           (const_int 0)))
11579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11580         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11581   "ix86_match_ccmode (insn, CCGOCmode)
11582    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11583   "sar{b}\t{%2, %0|%0, %2}"
11584   [(set_attr "type" "ishift")
11585    (set_attr "mode" "QI")])
11586 \f
11587 ;; Logical shift instructions
11588
11589 ;; See comment above `ashldi3' about how this works.
11590
11591 (define_expand "lshrti3"
11592   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11593                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11594                                 (match_operand:QI 2 "nonmemory_operand" "")))
11595               (clobber (reg:CC FLAGS_REG))])]
11596   "TARGET_64BIT"
11597 {
11598   if (! immediate_operand (operands[2], QImode))
11599     {
11600       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11601       DONE;
11602     }
11603   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11604   DONE;
11605 })
11606
11607 (define_insn "lshrti3_1"
11608   [(set (match_operand:TI 0 "register_operand" "=r")
11609         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11610                      (match_operand:QI 2 "register_operand" "c")))
11611    (clobber (match_scratch:DI 3 "=&r"))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "TARGET_64BIT"
11614   "#"
11615   [(set_attr "type" "multi")])
11616
11617 (define_insn "*lshrti3_2"
11618   [(set (match_operand:TI 0 "register_operand" "=r")
11619         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11620                      (match_operand:QI 2 "immediate_operand" "O")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "TARGET_64BIT"
11623   "#"
11624   [(set_attr "type" "multi")])
11625
11626 (define_split 
11627   [(set (match_operand:TI 0 "register_operand" "")
11628         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11629                      (match_operand:QI 2 "register_operand" "")))
11630    (clobber (match_scratch:DI 3 ""))
11631    (clobber (reg:CC FLAGS_REG))]
11632   "TARGET_64BIT && reload_completed"
11633   [(const_int 0)]
11634   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11635
11636 (define_split 
11637   [(set (match_operand:TI 0 "register_operand" "")
11638         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11639                      (match_operand:QI 2 "immediate_operand" "")))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "TARGET_64BIT && reload_completed"
11642   [(const_int 0)]
11643   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11644
11645 (define_expand "lshrdi3"
11646   [(set (match_operand:DI 0 "shiftdi_operand" "")
11647         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11648                      (match_operand:QI 2 "nonmemory_operand" "")))]
11649   ""
11650   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11651
11652 (define_insn "*lshrdi3_1_one_bit_rex64"
11653   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11654         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11655                      (match_operand:QI 2 "const1_operand" "")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11658    && (TARGET_SHIFT1 || optimize_size)"
11659   "shr{q}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set (attr "length") 
11662      (if_then_else (match_operand:DI 0 "register_operand" "") 
11663         (const_string "2")
11664         (const_string "*")))])
11665
11666 (define_insn "*lshrdi3_1_rex64"
11667   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11668         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11669                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11670    (clobber (reg:CC FLAGS_REG))]
11671   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672   "@
11673    shr{q}\t{%2, %0|%0, %2}
11674    shr{q}\t{%b2, %0|%0, %b2}"
11675   [(set_attr "type" "ishift")
11676    (set_attr "mode" "DI")])
11677
11678 ;; This pattern can't accept a variable shift count, since shifts by
11679 ;; zero don't affect the flags.  We assume that shifts by constant
11680 ;; zero are optimized away.
11681 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11682   [(set (reg FLAGS_REG)
11683         (compare
11684           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11685                        (match_operand:QI 2 "const1_operand" ""))
11686           (const_int 0)))
11687    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11688         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11689   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11690    && (TARGET_SHIFT1 || optimize_size)
11691    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11692   "shr{q}\t%0"
11693   [(set_attr "type" "ishift")
11694    (set (attr "length") 
11695      (if_then_else (match_operand:DI 0 "register_operand" "") 
11696         (const_string "2")
11697         (const_string "*")))])
11698
11699 ;; This pattern can't accept a variable shift count, since shifts by
11700 ;; zero don't affect the flags.  We assume that shifts by constant
11701 ;; zero are optimized away.
11702 (define_insn "*lshrdi3_cmp_rex64"
11703   [(set (reg FLAGS_REG)
11704         (compare
11705           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706                        (match_operand:QI 2 "const_int_operand" "e"))
11707           (const_int 0)))
11708    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11709         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11710   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11712   "shr{q}\t{%2, %0|%0, %2}"
11713   [(set_attr "type" "ishift")
11714    (set_attr "mode" "DI")])
11715
11716 (define_insn "*lshrdi3_1"
11717   [(set (match_operand:DI 0 "register_operand" "=r")
11718         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11719                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "!TARGET_64BIT"
11722   "#"
11723   [(set_attr "type" "multi")])
11724
11725 ;; By default we don't ask for a scratch register, because when DImode
11726 ;; values are manipulated, registers are already at a premium.  But if
11727 ;; we have one handy, we won't turn it away.
11728 (define_peephole2
11729   [(match_scratch:SI 3 "r")
11730    (parallel [(set (match_operand:DI 0 "register_operand" "")
11731                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11732                                 (match_operand:QI 2 "nonmemory_operand" "")))
11733               (clobber (reg:CC FLAGS_REG))])
11734    (match_dup 3)]
11735   "!TARGET_64BIT && TARGET_CMOVE"
11736   [(const_int 0)]
11737   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11738
11739 (define_split 
11740   [(set (match_operand:DI 0 "register_operand" "")
11741         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11742                      (match_operand:QI 2 "nonmemory_operand" "")))
11743    (clobber (reg:CC FLAGS_REG))]
11744   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11745                      ? flow2_completed : reload_completed)"
11746   [(const_int 0)]
11747   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11748
11749 (define_expand "lshrsi3"
11750   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11751         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11752                      (match_operand:QI 2 "nonmemory_operand" "")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   ""
11755   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11756
11757 (define_insn "*lshrsi3_1_one_bit"
11758   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11759         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11760                      (match_operand:QI 2 "const1_operand" "")))
11761    (clobber (reg:CC FLAGS_REG))]
11762   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11763    && (TARGET_SHIFT1 || optimize_size)"
11764   "shr{l}\t%0"
11765   [(set_attr "type" "ishift")
11766    (set (attr "length") 
11767      (if_then_else (match_operand:SI 0 "register_operand" "") 
11768         (const_string "2")
11769         (const_string "*")))])
11770
11771 (define_insn "*lshrsi3_1_one_bit_zext"
11772   [(set (match_operand:DI 0 "register_operand" "=r")
11773         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11774                      (match_operand:QI 2 "const1_operand" "")))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11777    && (TARGET_SHIFT1 || optimize_size)"
11778   "shr{l}\t%k0"
11779   [(set_attr "type" "ishift")
11780    (set_attr "length" "2")])
11781
11782 (define_insn "*lshrsi3_1"
11783   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11784         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11785                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11786    (clobber (reg:CC FLAGS_REG))]
11787   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11788   "@
11789    shr{l}\t{%2, %0|%0, %2}
11790    shr{l}\t{%b2, %0|%0, %b2}"
11791   [(set_attr "type" "ishift")
11792    (set_attr "mode" "SI")])
11793
11794 (define_insn "*lshrsi3_1_zext"
11795   [(set (match_operand:DI 0 "register_operand" "=r,r")
11796         (zero_extend:DI
11797           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11798                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11801   "@
11802    shr{l}\t{%2, %k0|%k0, %2}
11803    shr{l}\t{%b2, %k0|%k0, %b2}"
11804   [(set_attr "type" "ishift")
11805    (set_attr "mode" "SI")])
11806
11807 ;; This pattern can't accept a variable shift count, since shifts by
11808 ;; zero don't affect the flags.  We assume that shifts by constant
11809 ;; zero are optimized away.
11810 (define_insn "*lshrsi3_one_bit_cmp"
11811   [(set (reg FLAGS_REG)
11812         (compare
11813           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814                        (match_operand:QI 2 "const1_operand" ""))
11815           (const_int 0)))
11816    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11817         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11818   "ix86_match_ccmode (insn, CCGOCmode)
11819    && (TARGET_SHIFT1 || optimize_size)
11820    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11821   "shr{l}\t%0"
11822   [(set_attr "type" "ishift")
11823    (set (attr "length") 
11824      (if_then_else (match_operand:SI 0 "register_operand" "") 
11825         (const_string "2")
11826         (const_string "*")))])
11827
11828 (define_insn "*lshrsi3_cmp_one_bit_zext"
11829   [(set (reg FLAGS_REG)
11830         (compare
11831           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11832                        (match_operand:QI 2 "const1_operand" ""))
11833           (const_int 0)))
11834    (set (match_operand:DI 0 "register_operand" "=r")
11835         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11836   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11837    && (TARGET_SHIFT1 || optimize_size)
11838    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11839   "shr{l}\t%k0"
11840   [(set_attr "type" "ishift")
11841    (set_attr "length" "2")])
11842
11843 ;; This pattern can't accept a variable shift count, since shifts by
11844 ;; zero don't affect the flags.  We assume that shifts by constant
11845 ;; zero are optimized away.
11846 (define_insn "*lshrsi3_cmp"
11847   [(set (reg FLAGS_REG)
11848         (compare
11849           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11850                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11851           (const_int 0)))
11852    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11853         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11854   "ix86_match_ccmode (insn, CCGOCmode)
11855    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11856   "shr{l}\t{%2, %0|%0, %2}"
11857   [(set_attr "type" "ishift")
11858    (set_attr "mode" "SI")])
11859
11860 (define_insn "*lshrsi3_cmp_zext"
11861   [(set (reg FLAGS_REG)
11862         (compare
11863           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11864                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11865           (const_int 0)))
11866    (set (match_operand:DI 0 "register_operand" "=r")
11867         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11868   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11869    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11870   "shr{l}\t{%2, %k0|%k0, %2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "SI")])
11873
11874 (define_expand "lshrhi3"
11875   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11876         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11877                      (match_operand:QI 2 "nonmemory_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_HIMODE_MATH"
11880   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11881
11882 (define_insn "*lshrhi3_1_one_bit"
11883   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11885                      (match_operand:QI 2 "const1_operand" "")))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "shr{w}\t%0"
11890   [(set_attr "type" "ishift")
11891    (set (attr "length") 
11892      (if_then_else (match_operand 0 "register_operand" "") 
11893         (const_string "2")
11894         (const_string "*")))])
11895
11896 (define_insn "*lshrhi3_1"
11897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11898         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11899                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11902   "@
11903    shr{w}\t{%2, %0|%0, %2}
11904    shr{w}\t{%b2, %0|%0, %b2}"
11905   [(set_attr "type" "ishift")
11906    (set_attr "mode" "HI")])
11907
11908 ;; This pattern can't accept a variable shift count, since shifts by
11909 ;; zero don't affect the flags.  We assume that shifts by constant
11910 ;; zero are optimized away.
11911 (define_insn "*lshrhi3_one_bit_cmp"
11912   [(set (reg FLAGS_REG)
11913         (compare
11914           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11915                        (match_operand:QI 2 "const1_operand" ""))
11916           (const_int 0)))
11917    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11918         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11919   "ix86_match_ccmode (insn, CCGOCmode)
11920    && (TARGET_SHIFT1 || optimize_size)
11921    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11922   "shr{w}\t%0"
11923   [(set_attr "type" "ishift")
11924    (set (attr "length") 
11925      (if_then_else (match_operand:SI 0 "register_operand" "") 
11926         (const_string "2")
11927         (const_string "*")))])
11928
11929 ;; This pattern can't accept a variable shift count, since shifts by
11930 ;; zero don't affect the flags.  We assume that shifts by constant
11931 ;; zero are optimized away.
11932 (define_insn "*lshrhi3_cmp"
11933   [(set (reg FLAGS_REG)
11934         (compare
11935           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11936                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11937           (const_int 0)))
11938    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11939         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11940   "ix86_match_ccmode (insn, CCGOCmode)
11941    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11942   "shr{w}\t{%2, %0|%0, %2}"
11943   [(set_attr "type" "ishift")
11944    (set_attr "mode" "HI")])
11945
11946 (define_expand "lshrqi3"
11947   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11948         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11949                      (match_operand:QI 2 "nonmemory_operand" "")))
11950    (clobber (reg:CC FLAGS_REG))]
11951   "TARGET_QIMODE_MATH"
11952   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11953
11954 (define_insn "*lshrqi3_1_one_bit"
11955   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11956         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11957                      (match_operand:QI 2 "const1_operand" "")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11960    && (TARGET_SHIFT1 || optimize_size)"
11961   "shr{b}\t%0"
11962   [(set_attr "type" "ishift")
11963    (set (attr "length") 
11964      (if_then_else (match_operand 0 "register_operand" "") 
11965         (const_string "2")
11966         (const_string "*")))])
11967
11968 (define_insn "*lshrqi3_1_one_bit_slp"
11969   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11970         (lshiftrt:QI (match_dup 0)
11971                      (match_operand:QI 1 "const1_operand" "")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11974    && (TARGET_SHIFT1 || optimize_size)"
11975   "shr{b}\t%0"
11976   [(set_attr "type" "ishift1")
11977    (set (attr "length") 
11978      (if_then_else (match_operand 0 "register_operand" "") 
11979         (const_string "2")
11980         (const_string "*")))])
11981
11982 (define_insn "*lshrqi3_1"
11983   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11984         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11985                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986    (clobber (reg:CC FLAGS_REG))]
11987   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11988   "@
11989    shr{b}\t{%2, %0|%0, %2}
11990    shr{b}\t{%b2, %0|%0, %b2}"
11991   [(set_attr "type" "ishift")
11992    (set_attr "mode" "QI")])
11993
11994 (define_insn "*lshrqi3_1_slp"
11995   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11996         (lshiftrt:QI (match_dup 0)
11997                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11998    (clobber (reg:CC FLAGS_REG))]
11999   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12000    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12001   "@
12002    shr{b}\t{%1, %0|%0, %1}
12003    shr{b}\t{%b1, %0|%0, %b1}"
12004   [(set_attr "type" "ishift1")
12005    (set_attr "mode" "QI")])
12006
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags.  We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*lshrqi2_one_bit_cmp"
12011   [(set (reg FLAGS_REG)
12012         (compare
12013           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12014                        (match_operand:QI 2 "const1_operand" ""))
12015           (const_int 0)))
12016    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12017         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12018   "ix86_match_ccmode (insn, CCGOCmode)
12019    && (TARGET_SHIFT1 || optimize_size)
12020    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12021   "shr{b}\t%0"
12022   [(set_attr "type" "ishift")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:SI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12027
12028 ;; This pattern can't accept a variable shift count, since shifts by
12029 ;; zero don't affect the flags.  We assume that shifts by constant
12030 ;; zero are optimized away.
12031 (define_insn "*lshrqi2_cmp"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036           (const_int 0)))
12037    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12038         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12039   "ix86_match_ccmode (insn, CCGOCmode)
12040    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12041   "shr{b}\t{%2, %0|%0, %2}"
12042   [(set_attr "type" "ishift")
12043    (set_attr "mode" "QI")])
12044 \f
12045 ;; Rotate instructions
12046
12047 (define_expand "rotldi3"
12048   [(set (match_operand:DI 0 "shiftdi_operand" "")
12049         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12050                    (match_operand:QI 2 "nonmemory_operand" "")))
12051    (clobber (reg:CC FLAGS_REG))]
12052  ""
12053 {
12054   if (TARGET_64BIT)
12055     {
12056       ix86_expand_binary_operator (ROTATE, DImode, operands);
12057       DONE;
12058     }
12059   if (!const_1_to_31_operand (operands[2], VOIDmode))
12060     FAIL;
12061   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12062   DONE;
12063 })
12064
12065 ;; Implement rotation using two double-precision shift instructions
12066 ;; and a scratch register.   
12067 (define_insn_and_split "ix86_rotldi3"
12068  [(set (match_operand:DI 0 "register_operand" "=r")
12069        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12070                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12071   (clobber (reg:CC FLAGS_REG))
12072   (clobber (match_scratch:SI 3 "=&r"))]
12073  "!TARGET_64BIT"
12074  "" 
12075  "&& reload_completed"
12076  [(set (match_dup 3) (match_dup 4))
12077   (parallel
12078    [(set (match_dup 4)
12079          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12080                  (lshiftrt:SI (match_dup 5)
12081                               (minus:QI (const_int 32) (match_dup 2)))))
12082     (clobber (reg:CC FLAGS_REG))])
12083   (parallel
12084    [(set (match_dup 5)
12085          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12086                  (lshiftrt:SI (match_dup 3)
12087                               (minus:QI (const_int 32) (match_dup 2)))))
12088     (clobber (reg:CC FLAGS_REG))])]
12089  "split_di (operands, 1, operands + 4, operands + 5);")
12090  
12091 (define_insn "*rotlsi3_1_one_bit_rex64"
12092   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12093         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12094                    (match_operand:QI 2 "const1_operand" "")))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12097    && (TARGET_SHIFT1 || optimize_size)"
12098   "rol{q}\t%0"
12099   [(set_attr "type" "rotate")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:DI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12104
12105 (define_insn "*rotldi3_1_rex64"
12106   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12107         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12108                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12109    (clobber (reg:CC FLAGS_REG))]
12110   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12111   "@
12112    rol{q}\t{%2, %0|%0, %2}
12113    rol{q}\t{%b2, %0|%0, %b2}"
12114   [(set_attr "type" "rotate")
12115    (set_attr "mode" "DI")])
12116
12117 (define_expand "rotlsi3"
12118   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12119         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12120                    (match_operand:QI 2 "nonmemory_operand" "")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   ""
12123   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12124
12125 (define_insn "*rotlsi3_1_one_bit"
12126   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12127         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12128                    (match_operand:QI 2 "const1_operand" "")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12131    && (TARGET_SHIFT1 || optimize_size)"
12132   "rol{l}\t%0"
12133   [(set_attr "type" "rotate")
12134    (set (attr "length") 
12135      (if_then_else (match_operand:SI 0 "register_operand" "") 
12136         (const_string "2")
12137         (const_string "*")))])
12138
12139 (define_insn "*rotlsi3_1_one_bit_zext"
12140   [(set (match_operand:DI 0 "register_operand" "=r")
12141         (zero_extend:DI
12142           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12143                      (match_operand:QI 2 "const1_operand" ""))))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12146    && (TARGET_SHIFT1 || optimize_size)"
12147   "rol{l}\t%k0"
12148   [(set_attr "type" "rotate")
12149    (set_attr "length" "2")])
12150
12151 (define_insn "*rotlsi3_1"
12152   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12153         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12154                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12157   "@
12158    rol{l}\t{%2, %0|%0, %2}
12159    rol{l}\t{%b2, %0|%0, %b2}"
12160   [(set_attr "type" "rotate")
12161    (set_attr "mode" "SI")])
12162
12163 (define_insn "*rotlsi3_1_zext"
12164   [(set (match_operand:DI 0 "register_operand" "=r,r")
12165         (zero_extend:DI
12166           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12167                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12170   "@
12171    rol{l}\t{%2, %k0|%k0, %2}
12172    rol{l}\t{%b2, %k0|%k0, %b2}"
12173   [(set_attr "type" "rotate")
12174    (set_attr "mode" "SI")])
12175
12176 (define_expand "rotlhi3"
12177   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12178         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12179                    (match_operand:QI 2 "nonmemory_operand" "")))
12180    (clobber (reg:CC FLAGS_REG))]
12181   "TARGET_HIMODE_MATH"
12182   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12183
12184 (define_insn "*rotlhi3_1_one_bit"
12185   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12186         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12187                    (match_operand:QI 2 "const1_operand" "")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12190    && (TARGET_SHIFT1 || optimize_size)"
12191   "rol{w}\t%0"
12192   [(set_attr "type" "rotate")
12193    (set (attr "length") 
12194      (if_then_else (match_operand 0 "register_operand" "") 
12195         (const_string "2")
12196         (const_string "*")))])
12197
12198 (define_insn "*rotlhi3_1"
12199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12200         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12201                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12204   "@
12205    rol{w}\t{%2, %0|%0, %2}
12206    rol{w}\t{%b2, %0|%0, %b2}"
12207   [(set_attr "type" "rotate")
12208    (set_attr "mode" "HI")])
12209
12210 (define_expand "rotlqi3"
12211   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12212         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12213                    (match_operand:QI 2 "nonmemory_operand" "")))
12214    (clobber (reg:CC FLAGS_REG))]
12215   "TARGET_QIMODE_MATH"
12216   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12217
12218 (define_insn "*rotlqi3_1_one_bit_slp"
12219   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12220         (rotate:QI (match_dup 0)
12221                    (match_operand:QI 1 "const1_operand" "")))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12224    && (TARGET_SHIFT1 || optimize_size)"
12225   "rol{b}\t%0"
12226   [(set_attr "type" "rotate1")
12227    (set (attr "length") 
12228      (if_then_else (match_operand 0 "register_operand" "") 
12229         (const_string "2")
12230         (const_string "*")))])
12231
12232 (define_insn "*rotlqi3_1_one_bit"
12233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12234         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12235                    (match_operand:QI 2 "const1_operand" "")))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12238    && (TARGET_SHIFT1 || optimize_size)"
12239   "rol{b}\t%0"
12240   [(set_attr "type" "rotate")
12241    (set (attr "length") 
12242      (if_then_else (match_operand 0 "register_operand" "") 
12243         (const_string "2")
12244         (const_string "*")))])
12245
12246 (define_insn "*rotlqi3_1_slp"
12247   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12248         (rotate:QI (match_dup 0)
12249                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12250    (clobber (reg:CC FLAGS_REG))]
12251   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12252    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12253   "@
12254    rol{b}\t{%1, %0|%0, %1}
12255    rol{b}\t{%b1, %0|%0, %b1}"
12256   [(set_attr "type" "rotate1")
12257    (set_attr "mode" "QI")])
12258
12259 (define_insn "*rotlqi3_1"
12260   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12261         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12262                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12263    (clobber (reg:CC FLAGS_REG))]
12264   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12265   "@
12266    rol{b}\t{%2, %0|%0, %2}
12267    rol{b}\t{%b2, %0|%0, %b2}"
12268   [(set_attr "type" "rotate")
12269    (set_attr "mode" "QI")])
12270
12271 (define_expand "rotrdi3"
12272   [(set (match_operand:DI 0 "shiftdi_operand" "")
12273         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12274                    (match_operand:QI 2 "nonmemory_operand" "")))
12275    (clobber (reg:CC FLAGS_REG))]
12276  ""
12277 {
12278   if (TARGET_64BIT)
12279     {
12280       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12281       DONE;
12282     }
12283   if (!const_1_to_31_operand (operands[2], VOIDmode))
12284     FAIL;
12285   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12286   DONE;
12287 })
12288   
12289 ;; Implement rotation using two double-precision shift instructions
12290 ;; and a scratch register.   
12291 (define_insn_and_split "ix86_rotrdi3"
12292  [(set (match_operand:DI 0 "register_operand" "=r")
12293        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12294                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12295   (clobber (reg:CC FLAGS_REG))
12296   (clobber (match_scratch:SI 3 "=&r"))]
12297  "!TARGET_64BIT"
12298  ""
12299  "&& reload_completed"
12300  [(set (match_dup 3) (match_dup 4))
12301   (parallel
12302    [(set (match_dup 4)
12303          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12304                  (ashift:SI (match_dup 5)
12305                             (minus:QI (const_int 32) (match_dup 2)))))
12306     (clobber (reg:CC FLAGS_REG))])
12307   (parallel
12308    [(set (match_dup 5)
12309          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12310                  (ashift:SI (match_dup 3)
12311                             (minus:QI (const_int 32) (match_dup 2)))))
12312     (clobber (reg:CC FLAGS_REG))])]
12313  "split_di (operands, 1, operands + 4, operands + 5);")
12314
12315 (define_insn "*rotrdi3_1_one_bit_rex64"
12316   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12317         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12318                      (match_operand:QI 2 "const1_operand" "")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12321    && (TARGET_SHIFT1 || optimize_size)"
12322   "ror{q}\t%0"
12323   [(set_attr "type" "rotate")
12324    (set (attr "length") 
12325      (if_then_else (match_operand:DI 0 "register_operand" "") 
12326         (const_string "2")
12327         (const_string "*")))])
12328
12329 (define_insn "*rotrdi3_1_rex64"
12330   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12331         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12332                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12333    (clobber (reg:CC FLAGS_REG))]
12334   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12335   "@
12336    ror{q}\t{%2, %0|%0, %2}
12337    ror{q}\t{%b2, %0|%0, %b2}"
12338   [(set_attr "type" "rotate")
12339    (set_attr "mode" "DI")])
12340
12341 (define_expand "rotrsi3"
12342   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12343         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12344                      (match_operand:QI 2 "nonmemory_operand" "")))
12345    (clobber (reg:CC FLAGS_REG))]
12346   ""
12347   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12348
12349 (define_insn "*rotrsi3_1_one_bit"
12350   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12351         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12352                      (match_operand:QI 2 "const1_operand" "")))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12355    && (TARGET_SHIFT1 || optimize_size)"
12356   "ror{l}\t%0"
12357   [(set_attr "type" "rotate")
12358    (set (attr "length") 
12359      (if_then_else (match_operand:SI 0 "register_operand" "") 
12360         (const_string "2")
12361         (const_string "*")))])
12362
12363 (define_insn "*rotrsi3_1_one_bit_zext"
12364   [(set (match_operand:DI 0 "register_operand" "=r")
12365         (zero_extend:DI
12366           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12367                        (match_operand:QI 2 "const1_operand" ""))))
12368    (clobber (reg:CC FLAGS_REG))]
12369   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12370    && (TARGET_SHIFT1 || optimize_size)"
12371   "ror{l}\t%k0"
12372   [(set_attr "type" "rotate")
12373    (set (attr "length") 
12374      (if_then_else (match_operand:SI 0 "register_operand" "") 
12375         (const_string "2")
12376         (const_string "*")))])
12377
12378 (define_insn "*rotrsi3_1"
12379   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12380         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12381                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12382    (clobber (reg:CC FLAGS_REG))]
12383   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12384   "@
12385    ror{l}\t{%2, %0|%0, %2}
12386    ror{l}\t{%b2, %0|%0, %b2}"
12387   [(set_attr "type" "rotate")
12388    (set_attr "mode" "SI")])
12389
12390 (define_insn "*rotrsi3_1_zext"
12391   [(set (match_operand:DI 0 "register_operand" "=r,r")
12392         (zero_extend:DI
12393           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12394                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12397   "@
12398    ror{l}\t{%2, %k0|%k0, %2}
12399    ror{l}\t{%b2, %k0|%k0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "SI")])
12402
12403 (define_expand "rotrhi3"
12404   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12405         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12406                      (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_HIMODE_MATH"
12409   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12410
12411 (define_insn "*rotrhi3_one_bit"
12412   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12413         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12414                      (match_operand:QI 2 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "ror{w}\t%0"
12419   [(set_attr "type" "rotate")
12420    (set (attr "length") 
12421      (if_then_else (match_operand 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12424
12425 (define_insn "*rotrhi3"
12426   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12427         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12428                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12431   "@
12432    ror{w}\t{%2, %0|%0, %2}
12433    ror{w}\t{%b2, %0|%0, %b2}"
12434   [(set_attr "type" "rotate")
12435    (set_attr "mode" "HI")])
12436
12437 (define_expand "rotrqi3"
12438   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12439         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12440                      (match_operand:QI 2 "nonmemory_operand" "")))
12441    (clobber (reg:CC FLAGS_REG))]
12442   "TARGET_QIMODE_MATH"
12443   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12444
12445 (define_insn "*rotrqi3_1_one_bit"
12446   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12447         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12448                      (match_operand:QI 2 "const1_operand" "")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12451    && (TARGET_SHIFT1 || optimize_size)"
12452   "ror{b}\t%0"
12453   [(set_attr "type" "rotate")
12454    (set (attr "length") 
12455      (if_then_else (match_operand 0 "register_operand" "") 
12456         (const_string "2")
12457         (const_string "*")))])
12458
12459 (define_insn "*rotrqi3_1_one_bit_slp"
12460   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12461         (rotatert:QI (match_dup 0)
12462                      (match_operand:QI 1 "const1_operand" "")))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12465    && (TARGET_SHIFT1 || optimize_size)"
12466   "ror{b}\t%0"
12467   [(set_attr "type" "rotate1")
12468    (set (attr "length") 
12469      (if_then_else (match_operand 0 "register_operand" "") 
12470         (const_string "2")
12471         (const_string "*")))])
12472
12473 (define_insn "*rotrqi3_1"
12474   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12475         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12476                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12477    (clobber (reg:CC FLAGS_REG))]
12478   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12479   "@
12480    ror{b}\t{%2, %0|%0, %2}
12481    ror{b}\t{%b2, %0|%0, %b2}"
12482   [(set_attr "type" "rotate")
12483    (set_attr "mode" "QI")])
12484
12485 (define_insn "*rotrqi3_1_slp"
12486   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12487         (rotatert:QI (match_dup 0)
12488                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12489    (clobber (reg:CC FLAGS_REG))]
12490   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12492   "@
12493    ror{b}\t{%1, %0|%0, %1}
12494    ror{b}\t{%b1, %0|%0, %b1}"
12495   [(set_attr "type" "rotate1")
12496    (set_attr "mode" "QI")])
12497 \f
12498 ;; Bit set / bit test instructions
12499
12500 (define_expand "extv"
12501   [(set (match_operand:SI 0 "register_operand" "")
12502         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12503                          (match_operand:SI 2 "immediate_operand" "")
12504                          (match_operand:SI 3 "immediate_operand" "")))]
12505   ""
12506 {
12507   /* Handle extractions from %ah et al.  */
12508   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12509     FAIL;
12510
12511   /* From mips.md: extract_bit_field doesn't verify that our source
12512      matches the predicate, so check it again here.  */
12513   if (! ext_register_operand (operands[1], VOIDmode))
12514     FAIL;
12515 })
12516
12517 (define_expand "extzv"
12518   [(set (match_operand:SI 0 "register_operand" "")
12519         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12520                          (match_operand:SI 2 "immediate_operand" "")
12521                          (match_operand:SI 3 "immediate_operand" "")))]
12522   ""
12523 {
12524   /* Handle extractions from %ah et al.  */
12525   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12526     FAIL;
12527
12528   /* From mips.md: extract_bit_field doesn't verify that our source
12529      matches the predicate, so check it again here.  */
12530   if (! ext_register_operand (operands[1], VOIDmode))
12531     FAIL;
12532 })
12533
12534 (define_expand "insv"
12535   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12536                       (match_operand 1 "immediate_operand" "")
12537                       (match_operand 2 "immediate_operand" ""))
12538         (match_operand 3 "register_operand" ""))]
12539   ""
12540 {
12541   /* Handle extractions from %ah et al.  */
12542   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12543     FAIL;
12544
12545   /* From mips.md: insert_bit_field doesn't verify that our source
12546      matches the predicate, so check it again here.  */
12547   if (! ext_register_operand (operands[0], VOIDmode))
12548     FAIL;
12549
12550   if (TARGET_64BIT)
12551     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12552   else
12553     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12554
12555   DONE;
12556 })
12557
12558 ;; %%% bts, btr, btc, bt.
12559 ;; In general these instructions are *slow* when applied to memory,
12560 ;; since they enforce atomic operation.  When applied to registers,
12561 ;; it depends on the cpu implementation.  They're never faster than
12562 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12563 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12564 ;; within the instruction itself, so operating on bits in the high
12565 ;; 32-bits of a register becomes easier.
12566 ;;
12567 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12568 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12569 ;; negdf respectively, so they can never be disabled entirely.
12570
12571 (define_insn "*btsq"
12572   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12573                          (const_int 1)
12574                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12575         (const_int 1))
12576    (clobber (reg:CC FLAGS_REG))]
12577   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12578   "bts{q} %1,%0"
12579   [(set_attr "type" "alu1")])
12580
12581 (define_insn "*btrq"
12582   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12583                          (const_int 1)
12584                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12585         (const_int 0))
12586    (clobber (reg:CC FLAGS_REG))]
12587   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12588   "btr{q} %1,%0"
12589   [(set_attr "type" "alu1")])
12590
12591 (define_insn "*btcq"
12592   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12593                          (const_int 1)
12594                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12595         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12596    (clobber (reg:CC FLAGS_REG))]
12597   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12598   "btc{q} %1,%0"
12599   [(set_attr "type" "alu1")])
12600
12601 ;; Allow Nocona to avoid these instructions if a register is available.
12602
12603 (define_peephole2
12604   [(match_scratch:DI 2 "r")
12605    (parallel [(set (zero_extract:DI
12606                      (match_operand:DI 0 "register_operand" "")
12607                      (const_int 1)
12608                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12609                    (const_int 1))
12610               (clobber (reg:CC FLAGS_REG))])]
12611   "TARGET_64BIT && !TARGET_USE_BT"
12612   [(const_int 0)]
12613 {
12614   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12615   rtx op1;
12616
12617   if (HOST_BITS_PER_WIDE_INT >= 64)
12618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619   else if (i < HOST_BITS_PER_WIDE_INT)
12620     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12621   else
12622     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12623
12624   op1 = immed_double_const (lo, hi, DImode);
12625   if (i >= 31)
12626     {
12627       emit_move_insn (operands[2], op1);
12628       op1 = operands[2];
12629     }
12630
12631   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12632   DONE;
12633 })
12634
12635 (define_peephole2
12636   [(match_scratch:DI 2 "r")
12637    (parallel [(set (zero_extract:DI
12638                      (match_operand:DI 0 "register_operand" "")
12639                      (const_int 1)
12640                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12641                    (const_int 0))
12642               (clobber (reg:CC FLAGS_REG))])]
12643   "TARGET_64BIT && !TARGET_USE_BT"
12644   [(const_int 0)]
12645 {
12646   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12647   rtx op1;
12648
12649   if (HOST_BITS_PER_WIDE_INT >= 64)
12650     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12651   else if (i < HOST_BITS_PER_WIDE_INT)
12652     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653   else
12654     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12655
12656   op1 = immed_double_const (~lo, ~hi, DImode);
12657   if (i >= 32)
12658     {
12659       emit_move_insn (operands[2], op1);
12660       op1 = operands[2];
12661     }
12662
12663   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12664   DONE;
12665 })
12666
12667 (define_peephole2
12668   [(match_scratch:DI 2 "r")
12669    (parallel [(set (zero_extract:DI
12670                      (match_operand:DI 0 "register_operand" "")
12671                      (const_int 1)
12672                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12673               (not:DI (zero_extract:DI
12674                         (match_dup 0) (const_int 1) (match_dup 1))))
12675               (clobber (reg:CC FLAGS_REG))])]
12676   "TARGET_64BIT && !TARGET_USE_BT"
12677   [(const_int 0)]
12678 {
12679   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12680   rtx op1;
12681
12682   if (HOST_BITS_PER_WIDE_INT >= 64)
12683     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12684   else if (i < HOST_BITS_PER_WIDE_INT)
12685     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12686   else
12687     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12688
12689   op1 = immed_double_const (lo, hi, DImode);
12690   if (i >= 31)
12691     {
12692       emit_move_insn (operands[2], op1);
12693       op1 = operands[2];
12694     }
12695
12696   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12697   DONE;
12698 })
12699 \f
12700 ;; Store-flag instructions.
12701
12702 ;; For all sCOND expanders, also expand the compare or test insn that
12703 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12704
12705 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12706 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12707 ;; way, which can later delete the movzx if only QImode is needed.
12708
12709 (define_expand "seq"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12712   ""
12713   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12714
12715 (define_expand "sne"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12718   ""
12719   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12720
12721 (define_expand "sgt"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12724   ""
12725   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12726
12727 (define_expand "sgtu"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12730   ""
12731   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12732
12733 (define_expand "slt"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12736   ""
12737   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12738
12739 (define_expand "sltu"
12740   [(set (match_operand:QI 0 "register_operand" "")
12741         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12742   ""
12743   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12744
12745 (define_expand "sge"
12746   [(set (match_operand:QI 0 "register_operand" "")
12747         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12748   ""
12749   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12750
12751 (define_expand "sgeu"
12752   [(set (match_operand:QI 0 "register_operand" "")
12753         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12754   ""
12755   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12756
12757 (define_expand "sle"
12758   [(set (match_operand:QI 0 "register_operand" "")
12759         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12760   ""
12761   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12762
12763 (define_expand "sleu"
12764   [(set (match_operand:QI 0 "register_operand" "")
12765         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12766   ""
12767   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12768
12769 (define_expand "sunordered"
12770   [(set (match_operand:QI 0 "register_operand" "")
12771         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12772   "TARGET_80387 || TARGET_SSE"
12773   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12774
12775 (define_expand "sordered"
12776   [(set (match_operand:QI 0 "register_operand" "")
12777         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12778   "TARGET_80387"
12779   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12780
12781 (define_expand "suneq"
12782   [(set (match_operand:QI 0 "register_operand" "")
12783         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12784   "TARGET_80387 || TARGET_SSE"
12785   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12786
12787 (define_expand "sunge"
12788   [(set (match_operand:QI 0 "register_operand" "")
12789         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12790   "TARGET_80387 || TARGET_SSE"
12791   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12792
12793 (define_expand "sungt"
12794   [(set (match_operand:QI 0 "register_operand" "")
12795         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12796   "TARGET_80387 || TARGET_SSE"
12797   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12798
12799 (define_expand "sunle"
12800   [(set (match_operand:QI 0 "register_operand" "")
12801         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12802   "TARGET_80387 || TARGET_SSE"
12803   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12804
12805 (define_expand "sunlt"
12806   [(set (match_operand:QI 0 "register_operand" "")
12807         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12808   "TARGET_80387 || TARGET_SSE"
12809   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12810
12811 (define_expand "sltgt"
12812   [(set (match_operand:QI 0 "register_operand" "")
12813         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12814   "TARGET_80387 || TARGET_SSE"
12815   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12816
12817 (define_insn "*setcc_1"
12818   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12819         (match_operator:QI 1 "ix86_comparison_operator"
12820           [(reg FLAGS_REG) (const_int 0)]))]
12821   ""
12822   "set%C1\t%0"
12823   [(set_attr "type" "setcc")
12824    (set_attr "mode" "QI")])
12825
12826 (define_insn "*setcc_2"
12827   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12828         (match_operator:QI 1 "ix86_comparison_operator"
12829           [(reg FLAGS_REG) (const_int 0)]))]
12830   ""
12831   "set%C1\t%0"
12832   [(set_attr "type" "setcc")
12833    (set_attr "mode" "QI")])
12834
12835 ;; In general it is not safe to assume too much about CCmode registers,
12836 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12837 ;; conditions this is safe on x86, so help combine not create
12838 ;;
12839 ;;      seta    %al
12840 ;;      testb   %al, %al
12841 ;;      sete    %al
12842
12843 (define_split 
12844   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12845         (ne:QI (match_operator 1 "ix86_comparison_operator"
12846                  [(reg FLAGS_REG) (const_int 0)])
12847             (const_int 0)))]
12848   ""
12849   [(set (match_dup 0) (match_dup 1))]
12850 {
12851   PUT_MODE (operands[1], QImode);
12852 })
12853
12854 (define_split 
12855   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12856         (ne:QI (match_operator 1 "ix86_comparison_operator"
12857                  [(reg FLAGS_REG) (const_int 0)])
12858             (const_int 0)))]
12859   ""
12860   [(set (match_dup 0) (match_dup 1))]
12861 {
12862   PUT_MODE (operands[1], QImode);
12863 })
12864
12865 (define_split 
12866   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12867         (eq:QI (match_operator 1 "ix86_comparison_operator"
12868                  [(reg FLAGS_REG) (const_int 0)])
12869             (const_int 0)))]
12870   ""
12871   [(set (match_dup 0) (match_dup 1))]
12872 {
12873   rtx new_op1 = copy_rtx (operands[1]);
12874   operands[1] = new_op1;
12875   PUT_MODE (new_op1, QImode);
12876   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12877                                              GET_MODE (XEXP (new_op1, 0))));
12878
12879   /* Make sure that (a) the CCmode we have for the flags is strong
12880      enough for the reversed compare or (b) we have a valid FP compare.  */
12881   if (! ix86_comparison_operator (new_op1, VOIDmode))
12882     FAIL;
12883 })
12884
12885 (define_split 
12886   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12887         (eq:QI (match_operator 1 "ix86_comparison_operator"
12888                  [(reg FLAGS_REG) (const_int 0)])
12889             (const_int 0)))]
12890   ""
12891   [(set (match_dup 0) (match_dup 1))]
12892 {
12893   rtx new_op1 = copy_rtx (operands[1]);
12894   operands[1] = new_op1;
12895   PUT_MODE (new_op1, QImode);
12896   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12897                                              GET_MODE (XEXP (new_op1, 0))));
12898
12899   /* Make sure that (a) the CCmode we have for the flags is strong
12900      enough for the reversed compare or (b) we have a valid FP compare.  */
12901   if (! ix86_comparison_operator (new_op1, VOIDmode))
12902     FAIL;
12903 })
12904
12905 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12906 ;; subsequent logical operations are used to imitate conditional moves.
12907 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12908 ;; it directly.
12909
12910 (define_insn "*sse_setccsf"
12911   [(set (match_operand:SF 0 "register_operand" "=x")
12912         (match_operator:SF 1 "sse_comparison_operator"
12913           [(match_operand:SF 2 "register_operand" "0")
12914            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12915   "TARGET_SSE"
12916   "cmp%D1ss\t{%3, %0|%0, %3}"
12917   [(set_attr "type" "ssecmp")
12918    (set_attr "mode" "SF")])
12919
12920 (define_insn "*sse_setccdf"
12921   [(set (match_operand:DF 0 "register_operand" "=Y")
12922         (match_operator:DF 1 "sse_comparison_operator"
12923           [(match_operand:DF 2 "register_operand" "0")
12924            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12925   "TARGET_SSE2"
12926   "cmp%D1sd\t{%3, %0|%0, %3}"
12927   [(set_attr "type" "ssecmp")
12928    (set_attr "mode" "DF")])
12929 \f
12930 ;; Basic conditional jump instructions.
12931 ;; We ignore the overflow flag for signed branch instructions.
12932
12933 ;; For all bCOND expanders, also expand the compare or test insn that
12934 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12935
12936 (define_expand "beq"
12937   [(set (pc)
12938         (if_then_else (match_dup 1)
12939                       (label_ref (match_operand 0 "" ""))
12940                       (pc)))]
12941   ""
12942   "ix86_expand_branch (EQ, operands[0]); DONE;")
12943
12944 (define_expand "bne"
12945   [(set (pc)
12946         (if_then_else (match_dup 1)
12947                       (label_ref (match_operand 0 "" ""))
12948                       (pc)))]
12949   ""
12950   "ix86_expand_branch (NE, operands[0]); DONE;")
12951
12952 (define_expand "bgt"
12953   [(set (pc)
12954         (if_then_else (match_dup 1)
12955                       (label_ref (match_operand 0 "" ""))
12956                       (pc)))]
12957   ""
12958   "ix86_expand_branch (GT, operands[0]); DONE;")
12959
12960 (define_expand "bgtu"
12961   [(set (pc)
12962         (if_then_else (match_dup 1)
12963                       (label_ref (match_operand 0 "" ""))
12964                       (pc)))]
12965   ""
12966   "ix86_expand_branch (GTU, operands[0]); DONE;")
12967
12968 (define_expand "blt"
12969   [(set (pc)
12970         (if_then_else (match_dup 1)
12971                       (label_ref (match_operand 0 "" ""))
12972                       (pc)))]
12973   ""
12974   "ix86_expand_branch (LT, operands[0]); DONE;")
12975
12976 (define_expand "bltu"
12977   [(set (pc)
12978         (if_then_else (match_dup 1)
12979                       (label_ref (match_operand 0 "" ""))
12980                       (pc)))]
12981   ""
12982   "ix86_expand_branch (LTU, operands[0]); DONE;")
12983
12984 (define_expand "bge"
12985   [(set (pc)
12986         (if_then_else (match_dup 1)
12987                       (label_ref (match_operand 0 "" ""))
12988                       (pc)))]
12989   ""
12990   "ix86_expand_branch (GE, operands[0]); DONE;")
12991
12992 (define_expand "bgeu"
12993   [(set (pc)
12994         (if_then_else (match_dup 1)
12995                       (label_ref (match_operand 0 "" ""))
12996                       (pc)))]
12997   ""
12998   "ix86_expand_branch (GEU, operands[0]); DONE;")
12999
13000 (define_expand "ble"
13001   [(set (pc)
13002         (if_then_else (match_dup 1)
13003                       (label_ref (match_operand 0 "" ""))
13004                       (pc)))]
13005   ""
13006   "ix86_expand_branch (LE, operands[0]); DONE;")
13007
13008 (define_expand "bleu"
13009   [(set (pc)
13010         (if_then_else (match_dup 1)
13011                       (label_ref (match_operand 0 "" ""))
13012                       (pc)))]
13013   ""
13014   "ix86_expand_branch (LEU, operands[0]); DONE;")
13015
13016 (define_expand "bunordered"
13017   [(set (pc)
13018         (if_then_else (match_dup 1)
13019                       (label_ref (match_operand 0 "" ""))
13020                       (pc)))]
13021   "TARGET_80387 || TARGET_SSE_MATH"
13022   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13023
13024 (define_expand "bordered"
13025   [(set (pc)
13026         (if_then_else (match_dup 1)
13027                       (label_ref (match_operand 0 "" ""))
13028                       (pc)))]
13029   "TARGET_80387 || TARGET_SSE_MATH"
13030   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13031
13032 (define_expand "buneq"
13033   [(set (pc)
13034         (if_then_else (match_dup 1)
13035                       (label_ref (match_operand 0 "" ""))
13036                       (pc)))]
13037   "TARGET_80387 || TARGET_SSE_MATH"
13038   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13039
13040 (define_expand "bunge"
13041   [(set (pc)
13042         (if_then_else (match_dup 1)
13043                       (label_ref (match_operand 0 "" ""))
13044                       (pc)))]
13045   "TARGET_80387 || TARGET_SSE_MATH"
13046   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13047
13048 (define_expand "bungt"
13049   [(set (pc)
13050         (if_then_else (match_dup 1)
13051                       (label_ref (match_operand 0 "" ""))
13052                       (pc)))]
13053   "TARGET_80387 || TARGET_SSE_MATH"
13054   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13055
13056 (define_expand "bunle"
13057   [(set (pc)
13058         (if_then_else (match_dup 1)
13059                       (label_ref (match_operand 0 "" ""))
13060                       (pc)))]
13061   "TARGET_80387 || TARGET_SSE_MATH"
13062   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13063
13064 (define_expand "bunlt"
13065   [(set (pc)
13066         (if_then_else (match_dup 1)
13067                       (label_ref (match_operand 0 "" ""))
13068                       (pc)))]
13069   "TARGET_80387 || TARGET_SSE_MATH"
13070   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13071
13072 (define_expand "bltgt"
13073   [(set (pc)
13074         (if_then_else (match_dup 1)
13075                       (label_ref (match_operand 0 "" ""))
13076                       (pc)))]
13077   "TARGET_80387 || TARGET_SSE_MATH"
13078   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13079
13080 (define_insn "*jcc_1"
13081   [(set (pc)
13082         (if_then_else (match_operator 1 "ix86_comparison_operator"
13083                                       [(reg FLAGS_REG) (const_int 0)])
13084                       (label_ref (match_operand 0 "" ""))
13085                       (pc)))]
13086   ""
13087   "%+j%C1\t%l0"
13088   [(set_attr "type" "ibr")
13089    (set_attr "modrm" "0")
13090    (set (attr "length")
13091            (if_then_else (and (ge (minus (match_dup 0) (pc))
13092                                   (const_int -126))
13093                               (lt (minus (match_dup 0) (pc))
13094                                   (const_int 128)))
13095              (const_int 2)
13096              (const_int 6)))])
13097
13098 (define_insn "*jcc_2"
13099   [(set (pc)
13100         (if_then_else (match_operator 1 "ix86_comparison_operator"
13101                                       [(reg FLAGS_REG) (const_int 0)])
13102                       (pc)
13103                       (label_ref (match_operand 0 "" ""))))]
13104   ""
13105   "%+j%c1\t%l0"
13106   [(set_attr "type" "ibr")
13107    (set_attr "modrm" "0")
13108    (set (attr "length")
13109            (if_then_else (and (ge (minus (match_dup 0) (pc))
13110                                   (const_int -126))
13111                               (lt (minus (match_dup 0) (pc))
13112                                   (const_int 128)))
13113              (const_int 2)
13114              (const_int 6)))])
13115
13116 ;; In general it is not safe to assume too much about CCmode registers,
13117 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13118 ;; conditions this is safe on x86, so help combine not create
13119 ;;
13120 ;;      seta    %al
13121 ;;      testb   %al, %al
13122 ;;      je      Lfoo
13123
13124 (define_split 
13125   [(set (pc)
13126         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13127                                       [(reg FLAGS_REG) (const_int 0)])
13128                           (const_int 0))
13129                       (label_ref (match_operand 1 "" ""))
13130                       (pc)))]
13131   ""
13132   [(set (pc)
13133         (if_then_else (match_dup 0)
13134                       (label_ref (match_dup 1))
13135                       (pc)))]
13136 {
13137   PUT_MODE (operands[0], VOIDmode);
13138 })
13139   
13140 (define_split 
13141   [(set (pc)
13142         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13143                                       [(reg FLAGS_REG) (const_int 0)])
13144                           (const_int 0))
13145                       (label_ref (match_operand 1 "" ""))
13146                       (pc)))]
13147   ""
13148   [(set (pc)
13149         (if_then_else (match_dup 0)
13150                       (label_ref (match_dup 1))
13151                       (pc)))]
13152 {
13153   rtx new_op0 = copy_rtx (operands[0]);
13154   operands[0] = new_op0;
13155   PUT_MODE (new_op0, VOIDmode);
13156   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13157                                              GET_MODE (XEXP (new_op0, 0))));
13158
13159   /* Make sure that (a) the CCmode we have for the flags is strong
13160      enough for the reversed compare or (b) we have a valid FP compare.  */
13161   if (! ix86_comparison_operator (new_op0, VOIDmode))
13162     FAIL;
13163 })
13164
13165 ;; Define combination compare-and-branch fp compare instructions to use
13166 ;; during early optimization.  Splitting the operation apart early makes
13167 ;; for bad code when we want to reverse the operation.
13168
13169 (define_insn "*fp_jcc_1_mixed"
13170   [(set (pc)
13171         (if_then_else (match_operator 0 "comparison_operator"
13172                         [(match_operand 1 "register_operand" "f#x,x#f")
13173                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13174           (label_ref (match_operand 3 "" ""))
13175           (pc)))
13176    (clobber (reg:CCFP FPSR_REG))
13177    (clobber (reg:CCFP FLAGS_REG))]
13178   "TARGET_MIX_SSE_I387
13179    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13180    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182   "#")
13183
13184 (define_insn "*fp_jcc_1_sse"
13185   [(set (pc)
13186         (if_then_else (match_operator 0 "comparison_operator"
13187                         [(match_operand 1 "register_operand" "x")
13188                          (match_operand 2 "nonimmediate_operand" "xm")])
13189           (label_ref (match_operand 3 "" ""))
13190           (pc)))
13191    (clobber (reg:CCFP FPSR_REG))
13192    (clobber (reg:CCFP FLAGS_REG))]
13193   "TARGET_SSE_MATH
13194    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13195    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13196    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13197   "#")
13198
13199 (define_insn "*fp_jcc_1_387"
13200   [(set (pc)
13201         (if_then_else (match_operator 0 "comparison_operator"
13202                         [(match_operand 1 "register_operand" "f")
13203                          (match_operand 2 "register_operand" "f")])
13204           (label_ref (match_operand 3 "" ""))
13205           (pc)))
13206    (clobber (reg:CCFP FPSR_REG))
13207    (clobber (reg:CCFP FLAGS_REG))]
13208   "TARGET_CMOVE && TARGET_80387
13209    && FLOAT_MODE_P (GET_MODE (operands[1]))
13210    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13211    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13212   "#")
13213
13214 (define_insn "*fp_jcc_2_mixed"
13215   [(set (pc)
13216         (if_then_else (match_operator 0 "comparison_operator"
13217                         [(match_operand 1 "register_operand" "f#x,x#f")
13218                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13219           (pc)
13220           (label_ref (match_operand 3 "" ""))))
13221    (clobber (reg:CCFP FPSR_REG))
13222    (clobber (reg:CCFP FLAGS_REG))]
13223   "TARGET_MIX_SSE_I387
13224    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13225    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13226    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227   "#")
13228
13229 (define_insn "*fp_jcc_2_sse"
13230   [(set (pc)
13231         (if_then_else (match_operator 0 "comparison_operator"
13232                         [(match_operand 1 "register_operand" "x")
13233                          (match_operand 2 "nonimmediate_operand" "xm")])
13234           (pc)
13235           (label_ref (match_operand 3 "" ""))))
13236    (clobber (reg:CCFP FPSR_REG))
13237    (clobber (reg:CCFP FLAGS_REG))]
13238   "TARGET_SSE_MATH
13239    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13240    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13241    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13242   "#")
13243
13244 (define_insn "*fp_jcc_2_387"
13245   [(set (pc)
13246         (if_then_else (match_operator 0 "comparison_operator"
13247                         [(match_operand 1 "register_operand" "f")
13248                          (match_operand 2 "register_operand" "f")])
13249           (pc)
13250           (label_ref (match_operand 3 "" ""))))
13251    (clobber (reg:CCFP FPSR_REG))
13252    (clobber (reg:CCFP FLAGS_REG))]
13253   "TARGET_CMOVE && TARGET_80387
13254    && FLOAT_MODE_P (GET_MODE (operands[1]))
13255    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13256    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13257   "#")
13258
13259 (define_insn "*fp_jcc_3_387"
13260   [(set (pc)
13261         (if_then_else (match_operator 0 "comparison_operator"
13262                         [(match_operand 1 "register_operand" "f")
13263                          (match_operand 2 "nonimmediate_operand" "fm")])
13264           (label_ref (match_operand 3 "" ""))
13265           (pc)))
13266    (clobber (reg:CCFP FPSR_REG))
13267    (clobber (reg:CCFP FLAGS_REG))
13268    (clobber (match_scratch:HI 4 "=a"))]
13269   "TARGET_80387
13270    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13271    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13272    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13273    && SELECT_CC_MODE (GET_CODE (operands[0]),
13274                       operands[1], operands[2]) == CCFPmode
13275    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13276   "#")
13277
13278 (define_insn "*fp_jcc_4_387"
13279   [(set (pc)
13280         (if_then_else (match_operator 0 "comparison_operator"
13281                         [(match_operand 1 "register_operand" "f")
13282                          (match_operand 2 "nonimmediate_operand" "fm")])
13283           (pc)
13284           (label_ref (match_operand 3 "" ""))))
13285    (clobber (reg:CCFP FPSR_REG))
13286    (clobber (reg:CCFP FLAGS_REG))
13287    (clobber (match_scratch:HI 4 "=a"))]
13288   "TARGET_80387
13289    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13290    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13291    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13292    && SELECT_CC_MODE (GET_CODE (operands[0]),
13293                       operands[1], operands[2]) == CCFPmode
13294    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13295   "#")
13296
13297 (define_insn "*fp_jcc_5_387"
13298   [(set (pc)
13299         (if_then_else (match_operator 0 "comparison_operator"
13300                         [(match_operand 1 "register_operand" "f")
13301                          (match_operand 2 "register_operand" "f")])
13302           (label_ref (match_operand 3 "" ""))
13303           (pc)))
13304    (clobber (reg:CCFP FPSR_REG))
13305    (clobber (reg:CCFP FLAGS_REG))
13306    (clobber (match_scratch:HI 4 "=a"))]
13307   "TARGET_80387
13308    && FLOAT_MODE_P (GET_MODE (operands[1]))
13309    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13310    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13311   "#")
13312
13313 (define_insn "*fp_jcc_6_387"
13314   [(set (pc)
13315         (if_then_else (match_operator 0 "comparison_operator"
13316                         [(match_operand 1 "register_operand" "f")
13317                          (match_operand 2 "register_operand" "f")])
13318           (pc)
13319           (label_ref (match_operand 3 "" ""))))
13320    (clobber (reg:CCFP FPSR_REG))
13321    (clobber (reg:CCFP FLAGS_REG))
13322    (clobber (match_scratch:HI 4 "=a"))]
13323   "TARGET_80387
13324    && FLOAT_MODE_P (GET_MODE (operands[1]))
13325    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13326    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13327   "#")
13328
13329 (define_insn "*fp_jcc_7_387"
13330   [(set (pc)
13331         (if_then_else (match_operator 0 "comparison_operator"
13332                         [(match_operand 1 "register_operand" "f")
13333                          (match_operand 2 "const0_operand" "X")])
13334           (label_ref (match_operand 3 "" ""))
13335           (pc)))
13336    (clobber (reg:CCFP FPSR_REG))
13337    (clobber (reg:CCFP FLAGS_REG))
13338    (clobber (match_scratch:HI 4 "=a"))]
13339   "TARGET_80387
13340    && FLOAT_MODE_P (GET_MODE (operands[1]))
13341    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13342    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13343    && SELECT_CC_MODE (GET_CODE (operands[0]),
13344                       operands[1], operands[2]) == CCFPmode
13345    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13346   "#")
13347
13348 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13349 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13350 ;; with a precedence over other operators and is always put in the first
13351 ;; place. Swap condition and operands to match ficom instruction.
13352
13353 (define_insn "*fp_jcc_8<mode>_387"
13354   [(set (pc)
13355         (if_then_else (match_operator 0 "comparison_operator"
13356                         [(match_operator 1 "float_operator"
13357                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13358                            (match_operand 3 "register_operand" "f,f")])
13359           (label_ref (match_operand 4 "" ""))
13360           (pc)))
13361    (clobber (reg:CCFP FPSR_REG))
13362    (clobber (reg:CCFP FLAGS_REG))
13363    (clobber (match_scratch:HI 5 "=a,a"))]
13364   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13365    && FLOAT_MODE_P (GET_MODE (operands[3]))
13366    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13367    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13368    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13369    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13370   "#")
13371
13372 (define_split
13373   [(set (pc)
13374         (if_then_else (match_operator 0 "comparison_operator"
13375                         [(match_operand 1 "register_operand" "")
13376                          (match_operand 2 "nonimmediate_operand" "")])
13377           (match_operand 3 "" "")
13378           (match_operand 4 "" "")))
13379    (clobber (reg:CCFP FPSR_REG))
13380    (clobber (reg:CCFP FLAGS_REG))]
13381   "reload_completed"
13382   [(const_int 0)]
13383 {
13384   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13385                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13386   DONE;
13387 })
13388
13389 (define_split
13390   [(set (pc)
13391         (if_then_else (match_operator 0 "comparison_operator"
13392                         [(match_operand 1 "register_operand" "")
13393                          (match_operand 2 "general_operand" "")])
13394           (match_operand 3 "" "")
13395           (match_operand 4 "" "")))
13396    (clobber (reg:CCFP FPSR_REG))
13397    (clobber (reg:CCFP FLAGS_REG))
13398    (clobber (match_scratch:HI 5 "=a"))]
13399   "reload_completed"
13400   [(const_int 0)]
13401 {
13402   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13403                         operands[3], operands[4], operands[5], NULL_RTX);
13404   DONE;
13405 })
13406
13407 (define_split
13408   [(set (pc)
13409         (if_then_else (match_operator 0 "comparison_operator"
13410                         [(match_operator 1 "float_operator"
13411                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13412                            (match_operand 3 "register_operand" "")])
13413           (match_operand 4 "" "")
13414           (match_operand 5 "" "")))
13415    (clobber (reg:CCFP FPSR_REG))
13416    (clobber (reg:CCFP FLAGS_REG))
13417    (clobber (match_scratch:HI 6 "=a"))]
13418   "reload_completed"
13419   [(const_int 0)]
13420 {
13421   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13422   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13423                         operands[3], operands[7],
13424                         operands[4], operands[5], operands[6], NULL_RTX);
13425   DONE;
13426 })
13427
13428 ;; %%% Kill this when reload knows how to do it.
13429 (define_split
13430   [(set (pc)
13431         (if_then_else (match_operator 0 "comparison_operator"
13432                         [(match_operator 1 "float_operator"
13433                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13434                            (match_operand 3 "register_operand" "")])
13435           (match_operand 4 "" "")
13436           (match_operand 5 "" "")))
13437    (clobber (reg:CCFP FPSR_REG))
13438    (clobber (reg:CCFP FLAGS_REG))
13439    (clobber (match_scratch:HI 6 "=a"))]
13440   "reload_completed"
13441   [(const_int 0)]
13442 {
13443   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13444   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13445   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13446                         operands[3], operands[7],
13447                         operands[4], operands[5], operands[6], operands[2]);
13448   DONE;
13449 })
13450 \f
13451 ;; Unconditional and other jump instructions
13452
13453 (define_insn "jump"
13454   [(set (pc)
13455         (label_ref (match_operand 0 "" "")))]
13456   ""
13457   "jmp\t%l0"
13458   [(set_attr "type" "ibr")
13459    (set (attr "length")
13460            (if_then_else (and (ge (minus (match_dup 0) (pc))
13461                                   (const_int -126))
13462                               (lt (minus (match_dup 0) (pc))
13463                                   (const_int 128)))
13464              (const_int 2)
13465              (const_int 5)))
13466    (set_attr "modrm" "0")])
13467
13468 (define_expand "indirect_jump"
13469   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13470   ""
13471   "")
13472
13473 (define_insn "*indirect_jump"
13474   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13475   "!TARGET_64BIT"
13476   "jmp\t%A0"
13477   [(set_attr "type" "ibr")
13478    (set_attr "length_immediate" "0")])
13479
13480 (define_insn "*indirect_jump_rtx64"
13481   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13482   "TARGET_64BIT"
13483   "jmp\t%A0"
13484   [(set_attr "type" "ibr")
13485    (set_attr "length_immediate" "0")])
13486
13487 (define_expand "tablejump"
13488   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13489               (use (label_ref (match_operand 1 "" "")))])]
13490   ""
13491 {
13492   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13493      relative.  Convert the relative address to an absolute address.  */
13494   if (flag_pic)
13495     {
13496       rtx op0, op1;
13497       enum rtx_code code;
13498
13499       if (TARGET_64BIT)
13500         {
13501           code = PLUS;
13502           op0 = operands[0];
13503           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13504         }
13505       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13506         {
13507           code = PLUS;
13508           op0 = operands[0];
13509           op1 = pic_offset_table_rtx;
13510         }
13511       else
13512         {
13513           code = MINUS;
13514           op0 = pic_offset_table_rtx;
13515           op1 = operands[0];
13516         }
13517
13518       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13519                                          OPTAB_DIRECT);
13520     }
13521 })
13522
13523 (define_insn "*tablejump_1"
13524   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13525    (use (label_ref (match_operand 1 "" "")))]
13526   "!TARGET_64BIT"
13527   "jmp\t%A0"
13528   [(set_attr "type" "ibr")
13529    (set_attr "length_immediate" "0")])
13530
13531 (define_insn "*tablejump_1_rtx64"
13532   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13533    (use (label_ref (match_operand 1 "" "")))]
13534   "TARGET_64BIT"
13535   "jmp\t%A0"
13536   [(set_attr "type" "ibr")
13537    (set_attr "length_immediate" "0")])
13538 \f
13539 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13540
13541 (define_peephole2
13542   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13543    (set (match_operand:QI 1 "register_operand" "")
13544         (match_operator:QI 2 "ix86_comparison_operator"
13545           [(reg FLAGS_REG) (const_int 0)]))
13546    (set (match_operand 3 "q_regs_operand" "")
13547         (zero_extend (match_dup 1)))]
13548   "(peep2_reg_dead_p (3, operands[1])
13549     || operands_match_p (operands[1], operands[3]))
13550    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13551   [(set (match_dup 4) (match_dup 0))
13552    (set (strict_low_part (match_dup 5))
13553         (match_dup 2))]
13554 {
13555   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13556   operands[5] = gen_lowpart (QImode, operands[3]);
13557   ix86_expand_clear (operands[3]);
13558 })
13559
13560 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13561
13562 (define_peephole2
13563   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13564    (set (match_operand:QI 1 "register_operand" "")
13565         (match_operator:QI 2 "ix86_comparison_operator"
13566           [(reg FLAGS_REG) (const_int 0)]))
13567    (parallel [(set (match_operand 3 "q_regs_operand" "")
13568                    (zero_extend (match_dup 1)))
13569               (clobber (reg:CC FLAGS_REG))])]
13570   "(peep2_reg_dead_p (3, operands[1])
13571     || operands_match_p (operands[1], operands[3]))
13572    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13573   [(set (match_dup 4) (match_dup 0))
13574    (set (strict_low_part (match_dup 5))
13575         (match_dup 2))]
13576 {
13577   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13578   operands[5] = gen_lowpart (QImode, operands[3]);
13579   ix86_expand_clear (operands[3]);
13580 })
13581 \f
13582 ;; Call instructions.
13583
13584 ;; The predicates normally associated with named expanders are not properly
13585 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13586 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13587
13588 ;; Call subroutine returning no value.
13589
13590 (define_expand "call_pop"
13591   [(parallel [(call (match_operand:QI 0 "" "")
13592                     (match_operand:SI 1 "" ""))
13593               (set (reg:SI SP_REG)
13594                    (plus:SI (reg:SI SP_REG)
13595                             (match_operand:SI 3 "" "")))])]
13596   "!TARGET_64BIT"
13597 {
13598   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13599   DONE;
13600 })
13601
13602 (define_insn "*call_pop_0"
13603   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13604          (match_operand:SI 1 "" ""))
13605    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13606                             (match_operand:SI 2 "immediate_operand" "")))]
13607   "!TARGET_64BIT"
13608 {
13609   if (SIBLING_CALL_P (insn))
13610     return "jmp\t%P0";
13611   else
13612     return "call\t%P0";
13613 }
13614   [(set_attr "type" "call")])
13615   
13616 (define_insn "*call_pop_1"
13617   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13618          (match_operand:SI 1 "" ""))
13619    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13620                             (match_operand:SI 2 "immediate_operand" "i")))]
13621   "!TARGET_64BIT"
13622 {
13623   if (constant_call_address_operand (operands[0], Pmode))
13624     {
13625       if (SIBLING_CALL_P (insn))
13626         return "jmp\t%P0";
13627       else
13628         return "call\t%P0";
13629     }
13630   if (SIBLING_CALL_P (insn))
13631     return "jmp\t%A0";
13632   else
13633     return "call\t%A0";
13634 }
13635   [(set_attr "type" "call")])
13636
13637 (define_expand "call"
13638   [(call (match_operand:QI 0 "" "")
13639          (match_operand 1 "" ""))
13640    (use (match_operand 2 "" ""))]
13641   ""
13642 {
13643   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13644   DONE;
13645 })
13646
13647 (define_expand "sibcall"
13648   [(call (match_operand:QI 0 "" "")
13649          (match_operand 1 "" ""))
13650    (use (match_operand 2 "" ""))]
13651   ""
13652 {
13653   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13654   DONE;
13655 })
13656
13657 (define_insn "*call_0"
13658   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13659          (match_operand 1 "" ""))]
13660   ""
13661 {
13662   if (SIBLING_CALL_P (insn))
13663     return "jmp\t%P0";
13664   else
13665     return "call\t%P0";
13666 }
13667   [(set_attr "type" "call")])
13668
13669 (define_insn "*call_1"
13670   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13671          (match_operand 1 "" ""))]
13672   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13673 {
13674   if (constant_call_address_operand (operands[0], Pmode))
13675     return "call\t%P0";
13676   return "call\t%A0";
13677 }
13678   [(set_attr "type" "call")])
13679
13680 (define_insn "*sibcall_1"
13681   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13682          (match_operand 1 "" ""))]
13683   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13684 {
13685   if (constant_call_address_operand (operands[0], Pmode))
13686     return "jmp\t%P0";
13687   return "jmp\t%A0";
13688 }
13689   [(set_attr "type" "call")])
13690
13691 (define_insn "*call_1_rex64"
13692   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13693          (match_operand 1 "" ""))]
13694   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13695 {
13696   if (constant_call_address_operand (operands[0], Pmode))
13697     return "call\t%P0";
13698   return "call\t%A0";
13699 }
13700   [(set_attr "type" "call")])
13701
13702 (define_insn "*sibcall_1_rex64"
13703   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13704          (match_operand 1 "" ""))]
13705   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13706   "jmp\t%P0"
13707   [(set_attr "type" "call")])
13708
13709 (define_insn "*sibcall_1_rex64_v"
13710   [(call (mem:QI (reg:DI 40))
13711          (match_operand 0 "" ""))]
13712   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13713   "jmp\t*%%r11"
13714   [(set_attr "type" "call")])
13715
13716
13717 ;; Call subroutine, returning value in operand 0
13718
13719 (define_expand "call_value_pop"
13720   [(parallel [(set (match_operand 0 "" "")
13721                    (call (match_operand:QI 1 "" "")
13722                          (match_operand:SI 2 "" "")))
13723               (set (reg:SI SP_REG)
13724                    (plus:SI (reg:SI SP_REG)
13725                             (match_operand:SI 4 "" "")))])]
13726   "!TARGET_64BIT"
13727 {
13728   ix86_expand_call (operands[0], operands[1], operands[2],
13729                     operands[3], operands[4], 0);
13730   DONE;
13731 })
13732
13733 (define_expand "call_value"
13734   [(set (match_operand 0 "" "")
13735         (call (match_operand:QI 1 "" "")
13736               (match_operand:SI 2 "" "")))
13737    (use (match_operand:SI 3 "" ""))]
13738   ;; Operand 2 not used on the i386.
13739   ""
13740 {
13741   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13742   DONE;
13743 })
13744
13745 (define_expand "sibcall_value"
13746   [(set (match_operand 0 "" "")
13747         (call (match_operand:QI 1 "" "")
13748               (match_operand:SI 2 "" "")))
13749    (use (match_operand:SI 3 "" ""))]
13750   ;; Operand 2 not used on the i386.
13751   ""
13752 {
13753   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13754   DONE;
13755 })
13756
13757 ;; Call subroutine returning any type.
13758
13759 (define_expand "untyped_call"
13760   [(parallel [(call (match_operand 0 "" "")
13761                     (const_int 0))
13762               (match_operand 1 "" "")
13763               (match_operand 2 "" "")])]
13764   ""
13765 {
13766   int i;
13767
13768   /* In order to give reg-stack an easier job in validating two
13769      coprocessor registers as containing a possible return value,
13770      simply pretend the untyped call returns a complex long double
13771      value.  */
13772
13773   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13774                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13775                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13776                     NULL, 0);
13777
13778   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13779     {
13780       rtx set = XVECEXP (operands[2], 0, i);
13781       emit_move_insn (SET_DEST (set), SET_SRC (set));
13782     }
13783
13784   /* The optimizer does not know that the call sets the function value
13785      registers we stored in the result block.  We avoid problems by
13786      claiming that all hard registers are used and clobbered at this
13787      point.  */
13788   emit_insn (gen_blockage (const0_rtx));
13789
13790   DONE;
13791 })
13792 \f
13793 ;; Prologue and epilogue instructions
13794
13795 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13796 ;; all of memory.  This blocks insns from being moved across this point.
13797
13798 (define_insn "blockage"
13799   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13800   ""
13801   ""
13802   [(set_attr "length" "0")])
13803
13804 ;; Insn emitted into the body of a function to return from a function.
13805 ;; This is only done if the function's epilogue is known to be simple.
13806 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13807
13808 (define_expand "return"
13809   [(return)]
13810   "ix86_can_use_return_insn_p ()"
13811 {
13812   if (current_function_pops_args)
13813     {
13814       rtx popc = GEN_INT (current_function_pops_args);
13815       emit_jump_insn (gen_return_pop_internal (popc));
13816       DONE;
13817     }
13818 })
13819
13820 (define_insn "return_internal"
13821   [(return)]
13822   "reload_completed"
13823   "ret"
13824   [(set_attr "length" "1")
13825    (set_attr "length_immediate" "0")
13826    (set_attr "modrm" "0")])
13827
13828 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13829 ;; instruction Athlon and K8 have.
13830
13831 (define_insn "return_internal_long"
13832   [(return)
13833    (unspec [(const_int 0)] UNSPEC_REP)]
13834   "reload_completed"
13835   "rep {;} ret"
13836   [(set_attr "length" "1")
13837    (set_attr "length_immediate" "0")
13838    (set_attr "prefix_rep" "1")
13839    (set_attr "modrm" "0")])
13840
13841 (define_insn "return_pop_internal"
13842   [(return)
13843    (use (match_operand:SI 0 "const_int_operand" ""))]
13844   "reload_completed"
13845   "ret\t%0"
13846   [(set_attr "length" "3")
13847    (set_attr "length_immediate" "2")
13848    (set_attr "modrm" "0")])
13849
13850 (define_insn "return_indirect_internal"
13851   [(return)
13852    (use (match_operand:SI 0 "register_operand" "r"))]
13853   "reload_completed"
13854   "jmp\t%A0"
13855   [(set_attr "type" "ibr")
13856    (set_attr "length_immediate" "0")])
13857
13858 (define_insn "nop"
13859   [(const_int 0)]
13860   ""
13861   "nop"
13862   [(set_attr "length" "1")
13863    (set_attr "length_immediate" "0")
13864    (set_attr "modrm" "0")])
13865
13866 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13867 ;; branch prediction penalty for the third jump in a 16-byte
13868 ;; block on K8.
13869
13870 (define_insn "align"
13871   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13872   ""
13873 {
13874 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13875   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13876 #else
13877   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13878      The align insn is used to avoid 3 jump instructions in the row to improve
13879      branch prediction and the benefits hardly outweight the cost of extra 8
13880      nops on the average inserted by full alignment pseudo operation.  */
13881 #endif
13882   return "";
13883 }
13884   [(set_attr "length" "16")])
13885
13886 (define_expand "prologue"
13887   [(const_int 1)]
13888   ""
13889   "ix86_expand_prologue (); DONE;")
13890
13891 (define_insn "set_got"
13892   [(set (match_operand:SI 0 "register_operand" "=r")
13893         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13894    (clobber (reg:CC FLAGS_REG))]
13895   "!TARGET_64BIT"
13896   { return output_set_got (operands[0], NULL_RTX); }
13897   [(set_attr "type" "multi")
13898    (set_attr "length" "12")])
13899
13900 (define_insn "set_got_labelled"
13901   [(set (match_operand:SI 0 "register_operand" "=r")
13902         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13903          UNSPEC_SET_GOT))
13904    (clobber (reg:CC FLAGS_REG))]
13905   "!TARGET_64BIT"
13906   { return output_set_got (operands[0], operands[1]); }
13907   [(set_attr "type" "multi")
13908    (set_attr "length" "12")])
13909
13910 (define_insn "set_got_rex64"
13911   [(set (match_operand:DI 0 "register_operand" "=r")
13912         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13913   "TARGET_64BIT"
13914   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13915   [(set_attr "type" "lea")
13916    (set_attr "length" "6")])
13917
13918 (define_expand "epilogue"
13919   [(const_int 1)]
13920   ""
13921   "ix86_expand_epilogue (1); DONE;")
13922
13923 (define_expand "sibcall_epilogue"
13924   [(const_int 1)]
13925   ""
13926   "ix86_expand_epilogue (0); DONE;")
13927
13928 (define_expand "eh_return"
13929   [(use (match_operand 0 "register_operand" ""))]
13930   ""
13931 {
13932   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13933
13934   /* Tricky bit: we write the address of the handler to which we will
13935      be returning into someone else's stack frame, one word below the
13936      stack address we wish to restore.  */
13937   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13938   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13939   tmp = gen_rtx_MEM (Pmode, tmp);
13940   emit_move_insn (tmp, ra);
13941
13942   if (Pmode == SImode)
13943     emit_jump_insn (gen_eh_return_si (sa));
13944   else
13945     emit_jump_insn (gen_eh_return_di (sa));
13946   emit_barrier ();
13947   DONE;
13948 })
13949
13950 (define_insn_and_split "eh_return_si"
13951   [(set (pc) 
13952         (unspec [(match_operand:SI 0 "register_operand" "c")]
13953                  UNSPEC_EH_RETURN))]
13954   "!TARGET_64BIT"
13955   "#"
13956   "reload_completed"
13957   [(const_int 1)]
13958   "ix86_expand_epilogue (2); DONE;")
13959
13960 (define_insn_and_split "eh_return_di"
13961   [(set (pc) 
13962         (unspec [(match_operand:DI 0 "register_operand" "c")]
13963                  UNSPEC_EH_RETURN))]
13964   "TARGET_64BIT"
13965   "#"
13966   "reload_completed"
13967   [(const_int 1)]
13968   "ix86_expand_epilogue (2); DONE;")
13969
13970 (define_insn "leave"
13971   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13972    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13973    (clobber (mem:BLK (scratch)))]
13974   "!TARGET_64BIT"
13975   "leave"
13976   [(set_attr "type" "leave")])
13977
13978 (define_insn "leave_rex64"
13979   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13980    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13981    (clobber (mem:BLK (scratch)))]
13982   "TARGET_64BIT"
13983   "leave"
13984   [(set_attr "type" "leave")])
13985 \f
13986 (define_expand "ffssi2"
13987   [(parallel
13988      [(set (match_operand:SI 0 "register_operand" "") 
13989            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13990       (clobber (match_scratch:SI 2 ""))
13991       (clobber (reg:CC FLAGS_REG))])]
13992   ""
13993   "")
13994
13995 (define_insn_and_split "*ffs_cmove"
13996   [(set (match_operand:SI 0 "register_operand" "=r") 
13997         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13998    (clobber (match_scratch:SI 2 "=&r"))
13999    (clobber (reg:CC FLAGS_REG))]
14000   "TARGET_CMOVE"
14001   "#"
14002   "&& reload_completed"
14003   [(set (match_dup 2) (const_int -1))
14004    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14005               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14006    (set (match_dup 0) (if_then_else:SI
14007                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14008                         (match_dup 2)
14009                         (match_dup 0)))
14010    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14011               (clobber (reg:CC FLAGS_REG))])]
14012   "")
14013
14014 (define_insn_and_split "*ffs_no_cmove"
14015   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14016         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14017    (clobber (match_scratch:SI 2 "=&q"))
14018    (clobber (reg:CC FLAGS_REG))]
14019   ""
14020   "#"
14021   "reload_completed"
14022   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14023               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14024    (set (strict_low_part (match_dup 3))
14025         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14026    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14027               (clobber (reg:CC FLAGS_REG))])
14028    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14029               (clobber (reg:CC FLAGS_REG))])
14030    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14031               (clobber (reg:CC FLAGS_REG))])]
14032 {
14033   operands[3] = gen_lowpart (QImode, operands[2]);
14034   ix86_expand_clear (operands[2]);
14035 })
14036
14037 (define_insn "*ffssi_1"
14038   [(set (reg:CCZ FLAGS_REG)
14039         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14040                      (const_int 0)))
14041    (set (match_operand:SI 0 "register_operand" "=r")
14042         (ctz:SI (match_dup 1)))]
14043   ""
14044   "bsf{l}\t{%1, %0|%0, %1}"
14045   [(set_attr "prefix_0f" "1")])
14046
14047 (define_expand "ffsdi2"
14048   [(parallel
14049      [(set (match_operand:DI 0 "register_operand" "") 
14050            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14051       (clobber (match_scratch:DI 2 ""))
14052       (clobber (reg:CC FLAGS_REG))])]
14053   "TARGET_64BIT && TARGET_CMOVE"
14054   "")
14055
14056 (define_insn_and_split "*ffs_rex64"
14057   [(set (match_operand:DI 0 "register_operand" "=r") 
14058         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14059    (clobber (match_scratch:DI 2 "=&r"))
14060    (clobber (reg:CC FLAGS_REG))]
14061   "TARGET_64BIT && TARGET_CMOVE"
14062   "#"
14063   "&& reload_completed"
14064   [(set (match_dup 2) (const_int -1))
14065    (parallel [(set (reg:CCZ FLAGS_REG)
14066                    (compare:CCZ (match_dup 1) (const_int 0)))
14067               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14068    (set (match_dup 0) (if_then_else:DI
14069                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14070                         (match_dup 2)
14071                         (match_dup 0)))
14072    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14073               (clobber (reg:CC FLAGS_REG))])]
14074   "")
14075
14076 (define_insn "*ffsdi_1"
14077   [(set (reg:CCZ FLAGS_REG)
14078         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14079                      (const_int 0)))
14080    (set (match_operand:DI 0 "register_operand" "=r")
14081         (ctz:DI (match_dup 1)))]
14082   "TARGET_64BIT"
14083   "bsf{q}\t{%1, %0|%0, %1}"
14084   [(set_attr "prefix_0f" "1")])
14085
14086 (define_insn "ctzsi2"
14087   [(set (match_operand:SI 0 "register_operand" "=r")
14088         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsf{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14093
14094 (define_insn "ctzdi2"
14095   [(set (match_operand:DI 0 "register_operand" "=r")
14096         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14097    (clobber (reg:CC FLAGS_REG))]
14098   "TARGET_64BIT"
14099   "bsf{q}\t{%1, %0|%0, %1}"
14100   [(set_attr "prefix_0f" "1")])
14101
14102 (define_expand "clzsi2"
14103   [(parallel
14104      [(set (match_operand:SI 0 "register_operand" "")
14105            (minus:SI (const_int 31)
14106                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107       (clobber (reg:CC FLAGS_REG))])
14108    (parallel
14109      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110       (clobber (reg:CC FLAGS_REG))])]
14111   ""
14112   "")
14113
14114 (define_insn "*bsr"
14115   [(set (match_operand:SI 0 "register_operand" "=r")
14116         (minus:SI (const_int 31)
14117                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118    (clobber (reg:CC FLAGS_REG))]
14119   ""
14120   "bsr{l}\t{%1, %0|%0, %1}"
14121   [(set_attr "prefix_0f" "1")])
14122
14123 (define_expand "clzdi2"
14124   [(parallel
14125      [(set (match_operand:DI 0 "register_operand" "")
14126            (minus:DI (const_int 63)
14127                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14128       (clobber (reg:CC FLAGS_REG))])
14129    (parallel
14130      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14131       (clobber (reg:CC FLAGS_REG))])]
14132   "TARGET_64BIT"
14133   "")
14134
14135 (define_insn "*bsr_rex64"
14136   [(set (match_operand:DI 0 "register_operand" "=r")
14137         (minus:DI (const_int 63)
14138                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14139    (clobber (reg:CC FLAGS_REG))]
14140   "TARGET_64BIT"
14141   "bsr{q}\t{%1, %0|%0, %1}"
14142   [(set_attr "prefix_0f" "1")])
14143 \f
14144 ;; Thread-local storage patterns for ELF.
14145 ;;
14146 ;; Note that these code sequences must appear exactly as shown
14147 ;; in order to allow linker relaxation.
14148
14149 (define_insn "*tls_global_dynamic_32_gnu"
14150   [(set (match_operand:SI 0 "register_operand" "=a")
14151         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14152                     (match_operand:SI 2 "tls_symbolic_operand" "")
14153                     (match_operand:SI 3 "call_insn_operand" "")]
14154                     UNSPEC_TLS_GD))
14155    (clobber (match_scratch:SI 4 "=d"))
14156    (clobber (match_scratch:SI 5 "=c"))
14157    (clobber (reg:CC FLAGS_REG))]
14158   "!TARGET_64BIT && TARGET_GNU_TLS"
14159   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14160   [(set_attr "type" "multi")
14161    (set_attr "length" "12")])
14162
14163 (define_insn "*tls_global_dynamic_32_sun"
14164   [(set (match_operand:SI 0 "register_operand" "=a")
14165         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14166                     (match_operand:SI 2 "tls_symbolic_operand" "")
14167                     (match_operand:SI 3 "call_insn_operand" "")]
14168                     UNSPEC_TLS_GD))
14169    (clobber (match_scratch:SI 4 "=d"))
14170    (clobber (match_scratch:SI 5 "=c"))
14171    (clobber (reg:CC FLAGS_REG))]
14172   "!TARGET_64BIT && TARGET_SUN_TLS"
14173   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14174         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14175   [(set_attr "type" "multi")
14176    (set_attr "length" "14")])
14177
14178 (define_expand "tls_global_dynamic_32"
14179   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14180                    (unspec:SI
14181                     [(match_dup 2)
14182                      (match_operand:SI 1 "tls_symbolic_operand" "")
14183                      (match_dup 3)]
14184                     UNSPEC_TLS_GD))
14185               (clobber (match_scratch:SI 4 ""))
14186               (clobber (match_scratch:SI 5 ""))
14187               (clobber (reg:CC FLAGS_REG))])]
14188   ""
14189 {
14190   if (flag_pic)
14191     operands[2] = pic_offset_table_rtx;
14192   else
14193     {
14194       operands[2] = gen_reg_rtx (Pmode);
14195       emit_insn (gen_set_got (operands[2]));
14196     }
14197   if (TARGET_GNU2_TLS)
14198     {
14199        emit_insn (gen_tls_dynamic_gnu2_32
14200                   (operands[0], operands[1], operands[2]));
14201        DONE;
14202     }
14203   operands[3] = ix86_tls_get_addr ();
14204 })
14205
14206 (define_insn "*tls_global_dynamic_64"
14207   [(set (match_operand:DI 0 "register_operand" "=a")
14208         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14209                  (match_operand:DI 3 "" "")))
14210    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14211               UNSPEC_TLS_GD)]
14212   "TARGET_64BIT"
14213   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14214   [(set_attr "type" "multi")
14215    (set_attr "length" "16")])
14216
14217 (define_expand "tls_global_dynamic_64"
14218   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14219                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14220               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14221                          UNSPEC_TLS_GD)])]
14222   ""
14223 {
14224   if (TARGET_GNU2_TLS)
14225     {
14226        emit_insn (gen_tls_dynamic_gnu2_64
14227                   (operands[0], operands[1]));
14228        DONE;
14229     }
14230   operands[2] = ix86_tls_get_addr ();
14231 })
14232
14233 (define_insn "*tls_local_dynamic_base_32_gnu"
14234   [(set (match_operand:SI 0 "register_operand" "=a")
14235         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14236                     (match_operand:SI 2 "call_insn_operand" "")]
14237                    UNSPEC_TLS_LD_BASE))
14238    (clobber (match_scratch:SI 3 "=d"))
14239    (clobber (match_scratch:SI 4 "=c"))
14240    (clobber (reg:CC FLAGS_REG))]
14241   "!TARGET_64BIT && TARGET_GNU_TLS"
14242   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14243   [(set_attr "type" "multi")
14244    (set_attr "length" "11")])
14245
14246 (define_insn "*tls_local_dynamic_base_32_sun"
14247   [(set (match_operand:SI 0 "register_operand" "=a")
14248         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14249                     (match_operand:SI 2 "call_insn_operand" "")]
14250                    UNSPEC_TLS_LD_BASE))
14251    (clobber (match_scratch:SI 3 "=d"))
14252    (clobber (match_scratch:SI 4 "=c"))
14253    (clobber (reg:CC FLAGS_REG))]
14254   "!TARGET_64BIT && TARGET_SUN_TLS"
14255   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14256         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14257   [(set_attr "type" "multi")
14258    (set_attr "length" "13")])
14259
14260 (define_expand "tls_local_dynamic_base_32"
14261   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14262                    (unspec:SI [(match_dup 1) (match_dup 2)]
14263                               UNSPEC_TLS_LD_BASE))
14264               (clobber (match_scratch:SI 3 ""))
14265               (clobber (match_scratch:SI 4 ""))
14266               (clobber (reg:CC FLAGS_REG))])]
14267   ""
14268 {
14269   if (flag_pic)
14270     operands[1] = pic_offset_table_rtx;
14271   else
14272     {
14273       operands[1] = gen_reg_rtx (Pmode);
14274       emit_insn (gen_set_got (operands[1]));
14275     }
14276   if (TARGET_GNU2_TLS)
14277     {
14278        emit_insn (gen_tls_dynamic_gnu2_32
14279                   (operands[0], ix86_tls_module_base (), operands[1]));
14280        DONE;
14281     }
14282   operands[2] = ix86_tls_get_addr ();
14283 })
14284
14285 (define_insn "*tls_local_dynamic_base_64"
14286   [(set (match_operand:DI 0 "register_operand" "=a")
14287         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14288                  (match_operand:DI 2 "" "")))
14289    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14290   "TARGET_64BIT"
14291   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14292   [(set_attr "type" "multi")
14293    (set_attr "length" "12")])
14294
14295 (define_expand "tls_local_dynamic_base_64"
14296   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14297                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14298               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14299   ""
14300 {
14301   if (TARGET_GNU2_TLS)
14302     {
14303        emit_insn (gen_tls_dynamic_gnu2_64
14304                   (operands[0], ix86_tls_module_base ()));
14305        DONE;
14306     }
14307   operands[1] = ix86_tls_get_addr ();
14308 })
14309
14310 ;; Local dynamic of a single variable is a lose.  Show combine how
14311 ;; to convert that back to global dynamic.
14312
14313 (define_insn_and_split "*tls_local_dynamic_32_once"
14314   [(set (match_operand:SI 0 "register_operand" "=a")
14315         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14316                              (match_operand:SI 2 "call_insn_operand" "")]
14317                             UNSPEC_TLS_LD_BASE)
14318                  (const:SI (unspec:SI
14319                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14320                             UNSPEC_DTPOFF))))
14321    (clobber (match_scratch:SI 4 "=d"))
14322    (clobber (match_scratch:SI 5 "=c"))
14323    (clobber (reg:CC FLAGS_REG))]
14324   ""
14325   "#"
14326   ""
14327   [(parallel [(set (match_dup 0)
14328                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14329                               UNSPEC_TLS_GD))
14330               (clobber (match_dup 4))
14331               (clobber (match_dup 5))
14332               (clobber (reg:CC FLAGS_REG))])]
14333   "")
14334
14335 ;; Load and add the thread base pointer from %gs:0.
14336
14337 (define_insn "*load_tp_si"
14338   [(set (match_operand:SI 0 "register_operand" "=r")
14339         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14340   "!TARGET_64BIT"
14341   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14342   [(set_attr "type" "imov")
14343    (set_attr "modrm" "0")
14344    (set_attr "length" "7")
14345    (set_attr "memory" "load")
14346    (set_attr "imm_disp" "false")])
14347
14348 (define_insn "*add_tp_si"
14349   [(set (match_operand:SI 0 "register_operand" "=r")
14350         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14351                  (match_operand:SI 1 "register_operand" "0")))
14352    (clobber (reg:CC FLAGS_REG))]
14353   "!TARGET_64BIT"
14354   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14355   [(set_attr "type" "alu")
14356    (set_attr "modrm" "0")
14357    (set_attr "length" "7")
14358    (set_attr "memory" "load")
14359    (set_attr "imm_disp" "false")])
14360
14361 (define_insn "*load_tp_di"
14362   [(set (match_operand:DI 0 "register_operand" "=r")
14363         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14364   "TARGET_64BIT"
14365   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14366   [(set_attr "type" "imov")
14367    (set_attr "modrm" "0")
14368    (set_attr "length" "7")
14369    (set_attr "memory" "load")
14370    (set_attr "imm_disp" "false")])
14371
14372 (define_insn "*add_tp_di"
14373   [(set (match_operand:DI 0 "register_operand" "=r")
14374         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14375                  (match_operand:DI 1 "register_operand" "0")))
14376    (clobber (reg:CC FLAGS_REG))]
14377   "TARGET_64BIT"
14378   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14379   [(set_attr "type" "alu")
14380    (set_attr "modrm" "0")
14381    (set_attr "length" "7")
14382    (set_attr "memory" "load")
14383    (set_attr "imm_disp" "false")])
14384
14385 ;; GNU2 TLS patterns can be split.
14386
14387 (define_expand "tls_dynamic_gnu2_32"
14388   [(set (match_dup 3)
14389         (plus:SI (match_operand:SI 2 "register_operand" "")
14390                  (const:SI
14391                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14392                              UNSPEC_TLSDESC))))
14393    (parallel
14394     [(set (match_operand:SI 0 "register_operand" "")
14395           (unspec:SI [(match_dup 1) (match_dup 3)
14396                       (match_dup 2) (reg:SI SP_REG)]
14397                       UNSPEC_TLSDESC))
14398      (clobber (reg:CC FLAGS_REG))])]
14399   "!TARGET_64BIT && TARGET_GNU2_TLS"
14400 {
14401   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14402   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14403 })
14404
14405 (define_insn "*tls_dynamic_lea_32"
14406   [(set (match_operand:SI 0 "register_operand" "=r")
14407         (plus:SI (match_operand:SI 1 "register_operand" "b")
14408                  (const:SI
14409                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14410                               UNSPEC_TLSDESC))))]
14411   "!TARGET_64BIT && TARGET_GNU2_TLS"
14412   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14413   [(set_attr "type" "lea")
14414    (set_attr "mode" "SI")
14415    (set_attr "length" "6")
14416    (set_attr "length_address" "4")])
14417
14418 (define_insn "*tls_dynamic_call_32"
14419   [(set (match_operand:SI 0 "register_operand" "=a")
14420         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14421                     (match_operand:SI 2 "register_operand" "0")
14422                     ;; we have to make sure %ebx still points to the GOT
14423                     (match_operand:SI 3 "register_operand" "b")
14424                     (reg:SI SP_REG)]
14425                    UNSPEC_TLSDESC))
14426    (clobber (reg:CC FLAGS_REG))]
14427   "!TARGET_64BIT && TARGET_GNU2_TLS"
14428   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14429   [(set_attr "type" "call")
14430    (set_attr "length" "2")
14431    (set_attr "length_address" "0")])
14432
14433 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14434   [(set (match_operand:SI 0 "register_operand" "=&a")
14435         (plus:SI
14436          (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14437                   (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14438                               (match_operand:SI 5 "" "")
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   [(parallel
14450     [(set (match_dup 0)
14451           (plus:SI (match_dup 3)
14452                    (match_dup 5)))
14453      (clobber (reg:CC FLAGS_REG))])]
14454 {
14455   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14456   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14457 })
14458
14459 (define_expand "tls_dynamic_gnu2_64"
14460   [(set (match_dup 2)
14461         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14462                    UNSPEC_TLSDESC))
14463    (parallel
14464     [(set (match_operand:DI 0 "register_operand" "")
14465           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14466                      UNSPEC_TLSDESC))
14467      (clobber (reg:CC FLAGS_REG))])]
14468   "TARGET_64BIT && TARGET_GNU2_TLS"
14469 {
14470   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14471   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14472 })
14473
14474 (define_insn "*tls_dynamic_lea_64"
14475   [(set (match_operand:DI 0 "register_operand" "=r")
14476         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14477                    UNSPEC_TLSDESC))]
14478   "TARGET_64BIT && TARGET_GNU2_TLS"
14479   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14480   [(set_attr "type" "lea")
14481    (set_attr "mode" "DI")
14482    (set_attr "length" "7")
14483    (set_attr "length_address" "4")])
14484
14485 (define_insn "*tls_dynamic_call_64"
14486   [(set (match_operand:DI 0 "register_operand" "=a")
14487         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14488                     (match_operand:DI 2 "register_operand" "0")
14489                     (reg:DI SP_REG)]
14490                    UNSPEC_TLSDESC))
14491    (clobber (reg:CC FLAGS_REG))]
14492   "TARGET_64BIT && TARGET_GNU2_TLS"
14493   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14494   [(set_attr "type" "call")
14495    (set_attr "length" "2")
14496    (set_attr "length_address" "0")])
14497
14498 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14499   [(set (match_operand:DI 0 "register_operand" "=&a")
14500         (plus:DI
14501          (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14502                   (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14503                               (match_operand:DI 4 "" "")
14504                               (reg:DI SP_REG)]
14505                               UNSPEC_TLSDESC))
14506          (const:DI (unspec:DI
14507                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14508                     UNSPEC_DTPOFF))))
14509    (clobber (reg:CC FLAGS_REG))]
14510   "TARGET_64BIT && TARGET_GNU2_TLS"
14511   "#"
14512   ""
14513   [(parallel
14514     [(set (match_dup 0)
14515           (plus:DI (match_dup 2)
14516                    (match_dup 4)))
14517      (clobber (reg:CC FLAGS_REG))])]
14518 {
14519   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14520   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14521 })
14522
14523 ;;
14524 \f
14525 ;; These patterns match the binary 387 instructions for addM3, subM3,
14526 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14527 ;; SFmode.  The first is the normal insn, the second the same insn but
14528 ;; with one operand a conversion, and the third the same insn but with
14529 ;; the other operand a conversion.  The conversion may be SFmode or
14530 ;; SImode if the target mode DFmode, but only SImode if the target mode
14531 ;; is SFmode.
14532
14533 ;; Gcc is slightly more smart about handling normal two address instructions
14534 ;; so use special patterns for add and mull.
14535
14536 (define_insn "*fop_sf_comm_mixed"
14537   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14538         (match_operator:SF 3 "binary_fp_operator"
14539                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14540                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14541   "TARGET_MIX_SSE_I387
14542    && COMMUTATIVE_ARITH_P (operands[3])
14543    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14544   "* return output_387_binary_op (insn, operands);"
14545   [(set (attr "type") 
14546         (if_then_else (eq_attr "alternative" "1")
14547            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14548               (const_string "ssemul")
14549               (const_string "sseadd"))
14550            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14551               (const_string "fmul")
14552               (const_string "fop"))))
14553    (set_attr "mode" "SF")])
14554
14555 (define_insn "*fop_sf_comm_sse"
14556   [(set (match_operand:SF 0 "register_operand" "=x")
14557         (match_operator:SF 3 "binary_fp_operator"
14558                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14559                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14560   "TARGET_SSE_MATH
14561    && COMMUTATIVE_ARITH_P (operands[3])
14562    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14563   "* return output_387_binary_op (insn, operands);"
14564   [(set (attr "type") 
14565         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14566            (const_string "ssemul")
14567            (const_string "sseadd")))
14568    (set_attr "mode" "SF")])
14569
14570 (define_insn "*fop_sf_comm_i387"
14571   [(set (match_operand:SF 0 "register_operand" "=f")
14572         (match_operator:SF 3 "binary_fp_operator"
14573                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14574                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14575   "TARGET_80387
14576    && COMMUTATIVE_ARITH_P (operands[3])
14577    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14578   "* return output_387_binary_op (insn, operands);"
14579   [(set (attr "type") 
14580         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14581            (const_string "fmul")
14582            (const_string "fop")))
14583    (set_attr "mode" "SF")])
14584
14585 (define_insn "*fop_sf_1_mixed"
14586   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14587         (match_operator:SF 3 "binary_fp_operator"
14588                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14589                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14590   "TARGET_MIX_SSE_I387
14591    && !COMMUTATIVE_ARITH_P (operands[3])
14592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14593   "* return output_387_binary_op (insn, operands);"
14594   [(set (attr "type") 
14595         (cond [(and (eq_attr "alternative" "2")
14596                     (match_operand:SF 3 "mult_operator" ""))
14597                  (const_string "ssemul")
14598                (and (eq_attr "alternative" "2")
14599                     (match_operand:SF 3 "div_operator" ""))
14600                  (const_string "ssediv")
14601                (eq_attr "alternative" "2")
14602                  (const_string "sseadd")
14603                (match_operand:SF 3 "mult_operator" "") 
14604                  (const_string "fmul")
14605                (match_operand:SF 3 "div_operator" "") 
14606                  (const_string "fdiv")
14607               ]
14608               (const_string "fop")))
14609    (set_attr "mode" "SF")])
14610
14611 (define_insn "*fop_sf_1_sse"
14612   [(set (match_operand:SF 0 "register_operand" "=x")
14613         (match_operator:SF 3 "binary_fp_operator"
14614                         [(match_operand:SF 1 "register_operand" "0")
14615                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14616   "TARGET_SSE_MATH
14617    && !COMMUTATIVE_ARITH_P (operands[3])"
14618   "* return output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:SF 3 "mult_operator" "")
14621                  (const_string "ssemul")
14622                (match_operand:SF 3 "div_operator" "")
14623                  (const_string "ssediv")
14624               ]
14625               (const_string "sseadd")))
14626    (set_attr "mode" "SF")])
14627
14628 ;; This pattern is not fully shadowed by the pattern above.
14629 (define_insn "*fop_sf_1_i387"
14630   [(set (match_operand:SF 0 "register_operand" "=f,f")
14631         (match_operator:SF 3 "binary_fp_operator"
14632                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14633                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14634   "TARGET_80387 && !TARGET_SSE_MATH
14635    && !COMMUTATIVE_ARITH_P (operands[3])
14636    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14637   "* return output_387_binary_op (insn, operands);"
14638   [(set (attr "type") 
14639         (cond [(match_operand:SF 3 "mult_operator" "") 
14640                  (const_string "fmul")
14641                (match_operand:SF 3 "div_operator" "") 
14642                  (const_string "fdiv")
14643               ]
14644               (const_string "fop")))
14645    (set_attr "mode" "SF")])
14646
14647 ;; ??? Add SSE splitters for these!
14648 (define_insn "*fop_sf_2<mode>_i387"
14649   [(set (match_operand:SF 0 "register_operand" "=f,f")
14650         (match_operator:SF 3 "binary_fp_operator"
14651           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14652            (match_operand:SF 2 "register_operand" "0,0")]))]
14653   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14654   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14655   [(set (attr "type") 
14656         (cond [(match_operand:SF 3 "mult_operator" "") 
14657                  (const_string "fmul")
14658                (match_operand:SF 3 "div_operator" "") 
14659                  (const_string "fdiv")
14660               ]
14661               (const_string "fop")))
14662    (set_attr "fp_int_src" "true")
14663    (set_attr "mode" "<MODE>")])
14664
14665 (define_insn "*fop_sf_3<mode>_i387"
14666   [(set (match_operand:SF 0 "register_operand" "=f,f")
14667         (match_operator:SF 3 "binary_fp_operator"
14668           [(match_operand:SF 1 "register_operand" "0,0")
14669            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14670   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14671   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14672   [(set (attr "type") 
14673         (cond [(match_operand:SF 3 "mult_operator" "") 
14674                  (const_string "fmul")
14675                (match_operand:SF 3 "div_operator" "") 
14676                  (const_string "fdiv")
14677               ]
14678               (const_string "fop")))
14679    (set_attr "fp_int_src" "true")
14680    (set_attr "mode" "<MODE>")])
14681
14682 (define_insn "*fop_df_comm_mixed"
14683   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14684         (match_operator:DF 3 "binary_fp_operator"
14685                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14686                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14687   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14688    && COMMUTATIVE_ARITH_P (operands[3])
14689    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14690   "* return output_387_binary_op (insn, operands);"
14691   [(set (attr "type") 
14692         (if_then_else (eq_attr "alternative" "1")
14693            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14694               (const_string "ssemul")
14695               (const_string "sseadd"))
14696            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14697               (const_string "fmul")
14698               (const_string "fop"))))
14699    (set_attr "mode" "DF")])
14700
14701 (define_insn "*fop_df_comm_sse"
14702   [(set (match_operand:DF 0 "register_operand" "=Y")
14703         (match_operator:DF 3 "binary_fp_operator"
14704                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14705                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14706   "TARGET_SSE2 && TARGET_SSE_MATH
14707    && COMMUTATIVE_ARITH_P (operands[3])
14708    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14709   "* return output_387_binary_op (insn, operands);"
14710   [(set (attr "type") 
14711         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14712            (const_string "ssemul")
14713            (const_string "sseadd")))
14714    (set_attr "mode" "DF")])
14715
14716 (define_insn "*fop_df_comm_i387"
14717   [(set (match_operand:DF 0 "register_operand" "=f")
14718         (match_operator:DF 3 "binary_fp_operator"
14719                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14720                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14721   "TARGET_80387
14722    && COMMUTATIVE_ARITH_P (operands[3])
14723    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14724   "* return output_387_binary_op (insn, operands);"
14725   [(set (attr "type") 
14726         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14727            (const_string "fmul")
14728            (const_string "fop")))
14729    (set_attr "mode" "DF")])
14730
14731 (define_insn "*fop_df_1_mixed"
14732   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14733         (match_operator:DF 3 "binary_fp_operator"
14734                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14735                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14736   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14737    && !COMMUTATIVE_ARITH_P (operands[3])
14738    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14739   "* return output_387_binary_op (insn, operands);"
14740   [(set (attr "type") 
14741         (cond [(and (eq_attr "alternative" "2")
14742                     (match_operand:SF 3 "mult_operator" ""))
14743                  (const_string "ssemul")
14744                (and (eq_attr "alternative" "2")
14745                     (match_operand:SF 3 "div_operator" ""))
14746                  (const_string "ssediv")
14747                (eq_attr "alternative" "2")
14748                  (const_string "sseadd")
14749                (match_operand:DF 3 "mult_operator" "") 
14750                  (const_string "fmul")
14751                (match_operand:DF 3 "div_operator" "") 
14752                  (const_string "fdiv")
14753               ]
14754               (const_string "fop")))
14755    (set_attr "mode" "DF")])
14756
14757 (define_insn "*fop_df_1_sse"
14758   [(set (match_operand:DF 0 "register_operand" "=Y")
14759         (match_operator:DF 3 "binary_fp_operator"
14760                         [(match_operand:DF 1 "register_operand" "0")
14761                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14762   "TARGET_SSE2 && TARGET_SSE_MATH
14763    && !COMMUTATIVE_ARITH_P (operands[3])"
14764   "* return output_387_binary_op (insn, operands);"
14765   [(set_attr "mode" "DF")
14766    (set (attr "type") 
14767         (cond [(match_operand:SF 3 "mult_operator" "")
14768                  (const_string "ssemul")
14769                (match_operand:SF 3 "div_operator" "")
14770                  (const_string "ssediv")
14771               ]
14772               (const_string "sseadd")))])
14773
14774 ;; This pattern is not fully shadowed by the pattern above.
14775 (define_insn "*fop_df_1_i387"
14776   [(set (match_operand:DF 0 "register_operand" "=f,f")
14777         (match_operator:DF 3 "binary_fp_operator"
14778                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14779                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14780   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14781    && !COMMUTATIVE_ARITH_P (operands[3])
14782    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14783   "* return output_387_binary_op (insn, operands);"
14784   [(set (attr "type") 
14785         (cond [(match_operand:DF 3 "mult_operator" "") 
14786                  (const_string "fmul")
14787                (match_operand:DF 3 "div_operator" "")
14788                  (const_string "fdiv")
14789               ]
14790               (const_string "fop")))
14791    (set_attr "mode" "DF")])
14792
14793 ;; ??? Add SSE splitters for these!
14794 (define_insn "*fop_df_2<mode>_i387"
14795   [(set (match_operand:DF 0 "register_operand" "=f,f")
14796         (match_operator:DF 3 "binary_fp_operator"
14797            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14798             (match_operand:DF 2 "register_operand" "0,0")]))]
14799   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14800    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14801   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14802   [(set (attr "type") 
14803         (cond [(match_operand:DF 3 "mult_operator" "") 
14804                  (const_string "fmul")
14805                (match_operand:DF 3 "div_operator" "") 
14806                  (const_string "fdiv")
14807               ]
14808               (const_string "fop")))
14809    (set_attr "fp_int_src" "true")
14810    (set_attr "mode" "<MODE>")])
14811
14812 (define_insn "*fop_df_3<mode>_i387"
14813   [(set (match_operand:DF 0 "register_operand" "=f,f")
14814         (match_operator:DF 3 "binary_fp_operator"
14815            [(match_operand:DF 1 "register_operand" "0,0")
14816             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14817   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14818    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14819   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14820   [(set (attr "type") 
14821         (cond [(match_operand:DF 3 "mult_operator" "") 
14822                  (const_string "fmul")
14823                (match_operand:DF 3 "div_operator" "") 
14824                  (const_string "fdiv")
14825               ]
14826               (const_string "fop")))
14827    (set_attr "fp_int_src" "true")
14828    (set_attr "mode" "<MODE>")])
14829
14830 (define_insn "*fop_df_4_i387"
14831   [(set (match_operand:DF 0 "register_operand" "=f,f")
14832         (match_operator:DF 3 "binary_fp_operator"
14833            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14834             (match_operand:DF 2 "register_operand" "0,f")]))]
14835   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14836    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14837   "* return output_387_binary_op (insn, operands);"
14838   [(set (attr "type") 
14839         (cond [(match_operand:DF 3 "mult_operator" "") 
14840                  (const_string "fmul")
14841                (match_operand:DF 3 "div_operator" "") 
14842                  (const_string "fdiv")
14843               ]
14844               (const_string "fop")))
14845    (set_attr "mode" "SF")])
14846
14847 (define_insn "*fop_df_5_i387"
14848   [(set (match_operand:DF 0 "register_operand" "=f,f")
14849         (match_operator:DF 3 "binary_fp_operator"
14850           [(match_operand:DF 1 "register_operand" "0,f")
14851            (float_extend:DF
14852             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14853   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14854   "* return output_387_binary_op (insn, operands);"
14855   [(set (attr "type") 
14856         (cond [(match_operand:DF 3 "mult_operator" "") 
14857                  (const_string "fmul")
14858                (match_operand:DF 3 "div_operator" "") 
14859                  (const_string "fdiv")
14860               ]
14861               (const_string "fop")))
14862    (set_attr "mode" "SF")])
14863
14864 (define_insn "*fop_df_6_i387"
14865   [(set (match_operand:DF 0 "register_operand" "=f,f")
14866         (match_operator:DF 3 "binary_fp_operator"
14867           [(float_extend:DF
14868             (match_operand:SF 1 "register_operand" "0,f"))
14869            (float_extend:DF
14870             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14871   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14872   "* return output_387_binary_op (insn, operands);"
14873   [(set (attr "type") 
14874         (cond [(match_operand:DF 3 "mult_operator" "") 
14875                  (const_string "fmul")
14876                (match_operand:DF 3 "div_operator" "") 
14877                  (const_string "fdiv")
14878               ]
14879               (const_string "fop")))
14880    (set_attr "mode" "SF")])
14881
14882 (define_insn "*fop_xf_comm_i387"
14883   [(set (match_operand:XF 0 "register_operand" "=f")
14884         (match_operator:XF 3 "binary_fp_operator"
14885                         [(match_operand:XF 1 "register_operand" "%0")
14886                          (match_operand:XF 2 "register_operand" "f")]))]
14887   "TARGET_80387
14888    && COMMUTATIVE_ARITH_P (operands[3])"
14889   "* return output_387_binary_op (insn, operands);"
14890   [(set (attr "type") 
14891         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14892            (const_string "fmul")
14893            (const_string "fop")))
14894    (set_attr "mode" "XF")])
14895
14896 (define_insn "*fop_xf_1_i387"
14897   [(set (match_operand:XF 0 "register_operand" "=f,f")
14898         (match_operator:XF 3 "binary_fp_operator"
14899                         [(match_operand:XF 1 "register_operand" "0,f")
14900                          (match_operand:XF 2 "register_operand" "f,0")]))]
14901   "TARGET_80387
14902    && !COMMUTATIVE_ARITH_P (operands[3])"
14903   "* return output_387_binary_op (insn, operands);"
14904   [(set (attr "type") 
14905         (cond [(match_operand:XF 3 "mult_operator" "") 
14906                  (const_string "fmul")
14907                (match_operand:XF 3 "div_operator" "") 
14908                  (const_string "fdiv")
14909               ]
14910               (const_string "fop")))
14911    (set_attr "mode" "XF")])
14912
14913 (define_insn "*fop_xf_2<mode>_i387"
14914   [(set (match_operand:XF 0 "register_operand" "=f,f")
14915         (match_operator:XF 3 "binary_fp_operator"
14916            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14917             (match_operand:XF 2 "register_operand" "0,0")]))]
14918   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14919   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14920   [(set (attr "type") 
14921         (cond [(match_operand:XF 3 "mult_operator" "") 
14922                  (const_string "fmul")
14923                (match_operand:XF 3 "div_operator" "") 
14924                  (const_string "fdiv")
14925               ]
14926               (const_string "fop")))
14927    (set_attr "fp_int_src" "true")
14928    (set_attr "mode" "<MODE>")])
14929
14930 (define_insn "*fop_xf_3<mode>_i387"
14931   [(set (match_operand:XF 0 "register_operand" "=f,f")
14932         (match_operator:XF 3 "binary_fp_operator"
14933           [(match_operand:XF 1 "register_operand" "0,0")
14934            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14935   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14936   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14937   [(set (attr "type") 
14938         (cond [(match_operand:XF 3 "mult_operator" "") 
14939                  (const_string "fmul")
14940                (match_operand:XF 3 "div_operator" "") 
14941                  (const_string "fdiv")
14942               ]
14943               (const_string "fop")))
14944    (set_attr "fp_int_src" "true")
14945    (set_attr "mode" "<MODE>")])
14946
14947 (define_insn "*fop_xf_4_i387"
14948   [(set (match_operand:XF 0 "register_operand" "=f,f")
14949         (match_operator:XF 3 "binary_fp_operator"
14950            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14951             (match_operand:XF 2 "register_operand" "0,f")]))]
14952   "TARGET_80387"
14953   "* return output_387_binary_op (insn, operands);"
14954   [(set (attr "type") 
14955         (cond [(match_operand:XF 3 "mult_operator" "") 
14956                  (const_string "fmul")
14957                (match_operand:XF 3 "div_operator" "") 
14958                  (const_string "fdiv")
14959               ]
14960               (const_string "fop")))
14961    (set_attr "mode" "SF")])
14962
14963 (define_insn "*fop_xf_5_i387"
14964   [(set (match_operand:XF 0 "register_operand" "=f,f")
14965         (match_operator:XF 3 "binary_fp_operator"
14966           [(match_operand:XF 1 "register_operand" "0,f")
14967            (float_extend:XF
14968             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14969   "TARGET_80387"
14970   "* return output_387_binary_op (insn, operands);"
14971   [(set (attr "type") 
14972         (cond [(match_operand:XF 3 "mult_operator" "") 
14973                  (const_string "fmul")
14974                (match_operand:XF 3 "div_operator" "") 
14975                  (const_string "fdiv")
14976               ]
14977               (const_string "fop")))
14978    (set_attr "mode" "SF")])
14979
14980 (define_insn "*fop_xf_6_i387"
14981   [(set (match_operand:XF 0 "register_operand" "=f,f")
14982         (match_operator:XF 3 "binary_fp_operator"
14983           [(float_extend:XF
14984             (match_operand 1 "register_operand" "0,f"))
14985            (float_extend:XF
14986             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14987   "TARGET_80387"
14988   "* return output_387_binary_op (insn, operands);"
14989   [(set (attr "type") 
14990         (cond [(match_operand:XF 3 "mult_operator" "") 
14991                  (const_string "fmul")
14992                (match_operand:XF 3 "div_operator" "") 
14993                  (const_string "fdiv")
14994               ]
14995               (const_string "fop")))
14996    (set_attr "mode" "SF")])
14997
14998 (define_split
14999   [(set (match_operand 0 "register_operand" "")
15000         (match_operator 3 "binary_fp_operator"
15001            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15002             (match_operand 2 "register_operand" "")]))]
15003   "TARGET_80387 && reload_completed
15004    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15005   [(const_int 0)]
15006
15007   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15008   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15009   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15010                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15011                                           GET_MODE (operands[3]),
15012                                           operands[4],
15013                                           operands[2])));
15014   ix86_free_from_memory (GET_MODE (operands[1]));
15015   DONE;
15016 })
15017
15018 (define_split
15019   [(set (match_operand 0 "register_operand" "")
15020         (match_operator 3 "binary_fp_operator"
15021            [(match_operand 1 "register_operand" "")
15022             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15023   "TARGET_80387 && reload_completed
15024    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15025   [(const_int 0)]
15026 {
15027   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15028   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15029   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15030                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15031                                           GET_MODE (operands[3]),
15032                                           operands[1],
15033                                           operands[4])));
15034   ix86_free_from_memory (GET_MODE (operands[2]));
15035   DONE;
15036 })
15037 \f
15038 ;; FPU special functions.
15039
15040 (define_expand "sqrtsf2"
15041   [(set (match_operand:SF 0 "register_operand" "")
15042         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15043   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15044 {
15045   if (!TARGET_SSE_MATH)
15046     operands[1] = force_reg (SFmode, operands[1]);
15047 })
15048
15049 (define_insn "*sqrtsf2_mixed"
15050   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15051         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15052   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15053   "@
15054    fsqrt
15055    sqrtss\t{%1, %0|%0, %1}"
15056   [(set_attr "type" "fpspc,sse")
15057    (set_attr "mode" "SF,SF")
15058    (set_attr "athlon_decode" "direct,*")])
15059
15060 (define_insn "*sqrtsf2_sse"
15061   [(set (match_operand:SF 0 "register_operand" "=x")
15062         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15063   "TARGET_SSE_MATH"
15064   "sqrtss\t{%1, %0|%0, %1}"
15065   [(set_attr "type" "sse")
15066    (set_attr "mode" "SF")
15067    (set_attr "athlon_decode" "*")])
15068
15069 (define_insn "*sqrtsf2_i387"
15070   [(set (match_operand:SF 0 "register_operand" "=f")
15071         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15072   "TARGET_USE_FANCY_MATH_387"
15073   "fsqrt"
15074   [(set_attr "type" "fpspc")
15075    (set_attr "mode" "SF")
15076    (set_attr "athlon_decode" "direct")])
15077
15078 (define_expand "sqrtdf2"
15079   [(set (match_operand:DF 0 "register_operand" "")
15080         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15081   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15082 {
15083   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15084     operands[1] = force_reg (DFmode, operands[1]);
15085 })
15086
15087 (define_insn "*sqrtdf2_mixed"
15088   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15089         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15090   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15091   "@
15092    fsqrt
15093    sqrtsd\t{%1, %0|%0, %1}"
15094   [(set_attr "type" "fpspc,sse")
15095    (set_attr "mode" "DF,DF")
15096    (set_attr "athlon_decode" "direct,*")])
15097
15098 (define_insn "*sqrtdf2_sse"
15099   [(set (match_operand:DF 0 "register_operand" "=Y")
15100         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15101   "TARGET_SSE2 && TARGET_SSE_MATH"
15102   "sqrtsd\t{%1, %0|%0, %1}"
15103   [(set_attr "type" "sse")
15104    (set_attr "mode" "DF")
15105    (set_attr "athlon_decode" "*")])
15106
15107 (define_insn "*sqrtdf2_i387"
15108   [(set (match_operand:DF 0 "register_operand" "=f")
15109         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15110   "TARGET_USE_FANCY_MATH_387"
15111   "fsqrt"
15112   [(set_attr "type" "fpspc")
15113    (set_attr "mode" "DF")
15114    (set_attr "athlon_decode" "direct")])
15115
15116 (define_insn "*sqrtextendsfdf2_i387"
15117   [(set (match_operand:DF 0 "register_operand" "=f")
15118         (sqrt:DF (float_extend:DF
15119                   (match_operand:SF 1 "register_operand" "0"))))]
15120   "TARGET_USE_FANCY_MATH_387
15121    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15122   "fsqrt"
15123   [(set_attr "type" "fpspc")
15124    (set_attr "mode" "DF")
15125    (set_attr "athlon_decode" "direct")])
15126
15127 (define_insn "sqrtxf2"
15128   [(set (match_operand:XF 0 "register_operand" "=f")
15129         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15130   "TARGET_USE_FANCY_MATH_387 
15131    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15132   "fsqrt"
15133   [(set_attr "type" "fpspc")
15134    (set_attr "mode" "XF")
15135    (set_attr "athlon_decode" "direct")])
15136
15137 (define_insn "*sqrtextendsfxf2_i387"
15138   [(set (match_operand:XF 0 "register_operand" "=f")
15139         (sqrt:XF (float_extend:XF
15140                   (match_operand:SF 1 "register_operand" "0"))))]
15141   "TARGET_USE_FANCY_MATH_387"
15142   "fsqrt"
15143   [(set_attr "type" "fpspc")
15144    (set_attr "mode" "XF")
15145    (set_attr "athlon_decode" "direct")])
15146
15147 (define_insn "*sqrtextenddfxf2_i387"
15148   [(set (match_operand:XF 0 "register_operand" "=f")
15149         (sqrt:XF (float_extend:XF
15150                   (match_operand:DF 1 "register_operand" "0"))))]
15151   "TARGET_USE_FANCY_MATH_387"
15152   "fsqrt"
15153   [(set_attr "type" "fpspc")
15154    (set_attr "mode" "XF")
15155    (set_attr "athlon_decode" "direct")])
15156
15157 (define_insn "fpremxf4"
15158   [(set (match_operand:XF 0 "register_operand" "=f")
15159         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15160                     (match_operand:XF 3 "register_operand" "1")]
15161                    UNSPEC_FPREM_F))
15162    (set (match_operand:XF 1 "register_operand" "=u")
15163         (unspec:XF [(match_dup 2) (match_dup 3)]
15164                    UNSPEC_FPREM_U))
15165    (set (reg:CCFP FPSR_REG)
15166         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15167   "TARGET_USE_FANCY_MATH_387
15168    && flag_unsafe_math_optimizations"
15169   "fprem"
15170   [(set_attr "type" "fpspc")
15171    (set_attr "mode" "XF")])
15172
15173 (define_expand "fmodsf3"
15174   [(use (match_operand:SF 0 "register_operand" ""))
15175    (use (match_operand:SF 1 "register_operand" ""))
15176    (use (match_operand:SF 2 "register_operand" ""))]
15177   "TARGET_USE_FANCY_MATH_387
15178    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15179    && flag_unsafe_math_optimizations"
15180 {
15181   rtx label = gen_label_rtx ();
15182
15183   rtx op1 = gen_reg_rtx (XFmode);
15184   rtx op2 = gen_reg_rtx (XFmode);
15185
15186   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15187   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15188
15189   emit_label (label);
15190
15191   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15192   ix86_emit_fp_unordered_jump (label);
15193
15194   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15195   DONE;
15196 })
15197
15198 (define_expand "fmoddf3"
15199   [(use (match_operand:DF 0 "register_operand" ""))
15200    (use (match_operand:DF 1 "register_operand" ""))
15201    (use (match_operand:DF 2 "register_operand" ""))]
15202   "TARGET_USE_FANCY_MATH_387
15203    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15204    && flag_unsafe_math_optimizations"
15205 {
15206   rtx label = gen_label_rtx ();
15207
15208   rtx op1 = gen_reg_rtx (XFmode);
15209   rtx op2 = gen_reg_rtx (XFmode);
15210
15211   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15212   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15213
15214   emit_label (label);
15215
15216   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15217   ix86_emit_fp_unordered_jump (label);
15218
15219   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15220   DONE;
15221 })
15222
15223 (define_expand "fmodxf3"
15224   [(use (match_operand:XF 0 "register_operand" ""))
15225    (use (match_operand:XF 1 "register_operand" ""))
15226    (use (match_operand:XF 2 "register_operand" ""))]
15227   "TARGET_USE_FANCY_MATH_387
15228    && flag_unsafe_math_optimizations"
15229 {
15230   rtx label = gen_label_rtx ();
15231
15232   emit_label (label);
15233
15234   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15235                            operands[1], operands[2]));
15236   ix86_emit_fp_unordered_jump (label);
15237
15238   emit_move_insn (operands[0], operands[1]);
15239   DONE;
15240 })
15241
15242 (define_insn "fprem1xf4"
15243   [(set (match_operand:XF 0 "register_operand" "=f")
15244         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15245                     (match_operand:XF 3 "register_operand" "1")]
15246                    UNSPEC_FPREM1_F))
15247    (set (match_operand:XF 1 "register_operand" "=u")
15248         (unspec:XF [(match_dup 2) (match_dup 3)]
15249                    UNSPEC_FPREM1_U))
15250    (set (reg:CCFP FPSR_REG)
15251         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15252   "TARGET_USE_FANCY_MATH_387
15253    && flag_unsafe_math_optimizations"
15254   "fprem1"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "XF")])
15257
15258 (define_expand "dremsf3"
15259   [(use (match_operand:SF 0 "register_operand" ""))
15260    (use (match_operand:SF 1 "register_operand" ""))
15261    (use (match_operand:SF 2 "register_operand" ""))]
15262   "TARGET_USE_FANCY_MATH_387
15263    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15264    && flag_unsafe_math_optimizations"
15265 {
15266   rtx label = gen_label_rtx ();
15267
15268   rtx op1 = gen_reg_rtx (XFmode);
15269   rtx op2 = gen_reg_rtx (XFmode);
15270
15271   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15272   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15273
15274   emit_label (label);
15275
15276   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15277   ix86_emit_fp_unordered_jump (label);
15278
15279   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15280   DONE;
15281 })
15282
15283 (define_expand "dremdf3"
15284   [(use (match_operand:DF 0 "register_operand" ""))
15285    (use (match_operand:DF 1 "register_operand" ""))
15286    (use (match_operand:DF 2 "register_operand" ""))]
15287   "TARGET_USE_FANCY_MATH_387
15288    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15289    && flag_unsafe_math_optimizations"
15290 {
15291   rtx label = gen_label_rtx ();
15292
15293   rtx op1 = gen_reg_rtx (XFmode);
15294   rtx op2 = gen_reg_rtx (XFmode);
15295
15296   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15297   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15298
15299   emit_label (label);
15300
15301   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15302   ix86_emit_fp_unordered_jump (label);
15303
15304   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15305   DONE;
15306 })
15307
15308 (define_expand "dremxf3"
15309   [(use (match_operand:XF 0 "register_operand" ""))
15310    (use (match_operand:XF 1 "register_operand" ""))
15311    (use (match_operand:XF 2 "register_operand" ""))]
15312   "TARGET_USE_FANCY_MATH_387
15313    && flag_unsafe_math_optimizations"
15314 {
15315   rtx label = gen_label_rtx ();
15316
15317   emit_label (label);
15318
15319   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15320                             operands[1], operands[2]));
15321   ix86_emit_fp_unordered_jump (label);
15322
15323   emit_move_insn (operands[0], operands[1]);
15324   DONE;
15325 })
15326
15327 (define_insn "*sindf2"
15328   [(set (match_operand:DF 0 "register_operand" "=f")
15329         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15332    && flag_unsafe_math_optimizations"
15333   "fsin"
15334   [(set_attr "type" "fpspc")
15335    (set_attr "mode" "DF")])
15336
15337 (define_insn "*sinsf2"
15338   [(set (match_operand:SF 0 "register_operand" "=f")
15339         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15340   "TARGET_USE_FANCY_MATH_387
15341    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15342    && flag_unsafe_math_optimizations"
15343   "fsin"
15344   [(set_attr "type" "fpspc")
15345    (set_attr "mode" "SF")])
15346
15347 (define_insn "*sinextendsfdf2"
15348   [(set (match_operand:DF 0 "register_operand" "=f")
15349         (unspec:DF [(float_extend:DF
15350                      (match_operand:SF 1 "register_operand" "0"))]
15351                    UNSPEC_SIN))]
15352   "TARGET_USE_FANCY_MATH_387
15353    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15354    && flag_unsafe_math_optimizations"
15355   "fsin"
15356   [(set_attr "type" "fpspc")
15357    (set_attr "mode" "DF")])
15358
15359 (define_insn "*sinxf2"
15360   [(set (match_operand:XF 0 "register_operand" "=f")
15361         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15362   "TARGET_USE_FANCY_MATH_387
15363    && flag_unsafe_math_optimizations"
15364   "fsin"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "XF")])
15367
15368 (define_insn "*cosdf2"
15369   [(set (match_operand:DF 0 "register_operand" "=f")
15370         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15371   "TARGET_USE_FANCY_MATH_387
15372    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15373    && flag_unsafe_math_optimizations"
15374   "fcos"
15375   [(set_attr "type" "fpspc")
15376    (set_attr "mode" "DF")])
15377
15378 (define_insn "*cossf2"
15379   [(set (match_operand:SF 0 "register_operand" "=f")
15380         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15383    && flag_unsafe_math_optimizations"
15384   "fcos"
15385   [(set_attr "type" "fpspc")
15386    (set_attr "mode" "SF")])
15387
15388 (define_insn "*cosextendsfdf2"
15389   [(set (match_operand:DF 0 "register_operand" "=f")
15390         (unspec:DF [(float_extend:DF
15391                      (match_operand:SF 1 "register_operand" "0"))]
15392                    UNSPEC_COS))]
15393   "TARGET_USE_FANCY_MATH_387
15394    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15395    && flag_unsafe_math_optimizations"
15396   "fcos"
15397   [(set_attr "type" "fpspc")
15398    (set_attr "mode" "DF")])
15399
15400 (define_insn "*cosxf2"
15401   [(set (match_operand:XF 0 "register_operand" "=f")
15402         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15403   "TARGET_USE_FANCY_MATH_387
15404    && flag_unsafe_math_optimizations"
15405   "fcos"
15406   [(set_attr "type" "fpspc")
15407    (set_attr "mode" "XF")])
15408
15409 ;; With sincos pattern defined, sin and cos builtin function will be
15410 ;; expanded to sincos pattern with one of its outputs left unused. 
15411 ;; Cse pass  will detected, if two sincos patterns can be combined,
15412 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15413 ;; depending on the unused output.
15414
15415 (define_insn "sincosdf3"
15416   [(set (match_operand:DF 0 "register_operand" "=f")
15417         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15418                    UNSPEC_SINCOS_COS))
15419    (set (match_operand:DF 1 "register_operand" "=u")
15420         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15421   "TARGET_USE_FANCY_MATH_387
15422    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15423    && flag_unsafe_math_optimizations"
15424   "fsincos"
15425   [(set_attr "type" "fpspc")
15426    (set_attr "mode" "DF")])
15427
15428 (define_split
15429   [(set (match_operand:DF 0 "register_operand" "")
15430         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15431                    UNSPEC_SINCOS_COS))
15432    (set (match_operand:DF 1 "register_operand" "")
15433         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15434   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15435    && !reload_completed && !reload_in_progress"
15436   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15437   "")
15438
15439 (define_split
15440   [(set (match_operand:DF 0 "register_operand" "")
15441         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15442                    UNSPEC_SINCOS_COS))
15443    (set (match_operand:DF 1 "register_operand" "")
15444         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15445   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15446    && !reload_completed && !reload_in_progress"
15447   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15448   "")
15449
15450 (define_insn "sincossf3"
15451   [(set (match_operand:SF 0 "register_operand" "=f")
15452         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15453                    UNSPEC_SINCOS_COS))
15454    (set (match_operand:SF 1 "register_operand" "=u")
15455         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15456   "TARGET_USE_FANCY_MATH_387
15457    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15458    && flag_unsafe_math_optimizations"
15459   "fsincos"
15460   [(set_attr "type" "fpspc")
15461    (set_attr "mode" "SF")])
15462
15463 (define_split
15464   [(set (match_operand:SF 0 "register_operand" "")
15465         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15466                    UNSPEC_SINCOS_COS))
15467    (set (match_operand:SF 1 "register_operand" "")
15468         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15469   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15470    && !reload_completed && !reload_in_progress"
15471   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15472   "")
15473
15474 (define_split
15475   [(set (match_operand:SF 0 "register_operand" "")
15476         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15477                    UNSPEC_SINCOS_COS))
15478    (set (match_operand:SF 1 "register_operand" "")
15479         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15480   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15481    && !reload_completed && !reload_in_progress"
15482   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15483   "")
15484
15485 (define_insn "*sincosextendsfdf3"
15486   [(set (match_operand:DF 0 "register_operand" "=f")
15487         (unspec:DF [(float_extend:DF
15488                      (match_operand:SF 2 "register_operand" "0"))]
15489                    UNSPEC_SINCOS_COS))
15490    (set (match_operand:DF 1 "register_operand" "=u")
15491         (unspec:DF [(float_extend:DF
15492                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15495    && flag_unsafe_math_optimizations"
15496   "fsincos"
15497   [(set_attr "type" "fpspc")
15498    (set_attr "mode" "DF")])
15499
15500 (define_split
15501   [(set (match_operand:DF 0 "register_operand" "")
15502         (unspec:DF [(float_extend:DF
15503                      (match_operand:SF 2 "register_operand" ""))]
15504                    UNSPEC_SINCOS_COS))
15505    (set (match_operand:DF 1 "register_operand" "")
15506         (unspec:DF [(float_extend:DF
15507                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15508   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15509    && !reload_completed && !reload_in_progress"
15510   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15511                                    (match_dup 2))] UNSPEC_SIN))]
15512   "")
15513
15514 (define_split
15515   [(set (match_operand:DF 0 "register_operand" "")
15516         (unspec:DF [(float_extend:DF
15517                      (match_operand:SF 2 "register_operand" ""))]
15518                    UNSPEC_SINCOS_COS))
15519    (set (match_operand:DF 1 "register_operand" "")
15520         (unspec:DF [(float_extend:DF
15521                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15522   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15523    && !reload_completed && !reload_in_progress"
15524   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15525                                    (match_dup 2))] UNSPEC_COS))]
15526   "")
15527
15528 (define_insn "sincosxf3"
15529   [(set (match_operand:XF 0 "register_operand" "=f")
15530         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15531                    UNSPEC_SINCOS_COS))
15532    (set (match_operand:XF 1 "register_operand" "=u")
15533         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15534   "TARGET_USE_FANCY_MATH_387
15535    && flag_unsafe_math_optimizations"
15536   "fsincos"
15537   [(set_attr "type" "fpspc")
15538    (set_attr "mode" "XF")])
15539
15540 (define_split
15541   [(set (match_operand:XF 0 "register_operand" "")
15542         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15543                    UNSPEC_SINCOS_COS))
15544    (set (match_operand:XF 1 "register_operand" "")
15545         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15546   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15547    && !reload_completed && !reload_in_progress"
15548   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15549   "")
15550
15551 (define_split
15552   [(set (match_operand:XF 0 "register_operand" "")
15553         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15554                    UNSPEC_SINCOS_COS))
15555    (set (match_operand:XF 1 "register_operand" "")
15556         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15557   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15558    && !reload_completed && !reload_in_progress"
15559   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15560   "")
15561
15562 (define_insn "*tandf3_1"
15563   [(set (match_operand:DF 0 "register_operand" "=f")
15564         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15565                    UNSPEC_TAN_ONE))
15566    (set (match_operand:DF 1 "register_operand" "=u")
15567         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15570    && flag_unsafe_math_optimizations"
15571   "fptan"
15572   [(set_attr "type" "fpspc")
15573    (set_attr "mode" "DF")])
15574
15575 ;; optimize sequence: fptan
15576 ;;                    fstp    %st(0)
15577 ;;                    fld1
15578 ;; into fptan insn.
15579
15580 (define_peephole2
15581   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15582                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15583                              UNSPEC_TAN_ONE))
15584              (set (match_operand:DF 1 "register_operand" "")
15585                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15586    (set (match_dup 0)
15587         (match_operand:DF 3 "immediate_operand" ""))]
15588   "standard_80387_constant_p (operands[3]) == 2"
15589   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15590              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15591   "")
15592
15593 (define_expand "tandf2"
15594   [(parallel [(set (match_dup 2)
15595                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15596                               UNSPEC_TAN_ONE))
15597               (set (match_operand:DF 0 "register_operand" "")
15598                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15599   "TARGET_USE_FANCY_MATH_387
15600    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15601    && flag_unsafe_math_optimizations"
15602 {
15603   operands[2] = gen_reg_rtx (DFmode);
15604 })
15605
15606 (define_insn "*tansf3_1"
15607   [(set (match_operand:SF 0 "register_operand" "=f")
15608         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15609                    UNSPEC_TAN_ONE))
15610    (set (match_operand:SF 1 "register_operand" "=u")
15611         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15614    && flag_unsafe_math_optimizations"
15615   "fptan"
15616   [(set_attr "type" "fpspc")
15617    (set_attr "mode" "SF")])
15618
15619 ;; optimize sequence: fptan
15620 ;;                    fstp    %st(0)
15621 ;;                    fld1
15622 ;; into fptan insn.
15623
15624 (define_peephole2
15625   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15626                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15627                              UNSPEC_TAN_ONE))
15628              (set (match_operand:SF 1 "register_operand" "")
15629                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15630    (set (match_dup 0)
15631         (match_operand:SF 3 "immediate_operand" ""))]
15632   "standard_80387_constant_p (operands[3]) == 2"
15633   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15634              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15635   "")
15636
15637 (define_expand "tansf2"
15638   [(parallel [(set (match_dup 2)
15639                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15640                               UNSPEC_TAN_ONE))
15641               (set (match_operand:SF 0 "register_operand" "")
15642                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15643   "TARGET_USE_FANCY_MATH_387
15644    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15645    && flag_unsafe_math_optimizations"
15646 {
15647   operands[2] = gen_reg_rtx (SFmode);
15648 })
15649
15650 (define_insn "*tanxf3_1"
15651   [(set (match_operand:XF 0 "register_operand" "=f")
15652         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15653                    UNSPEC_TAN_ONE))
15654    (set (match_operand:XF 1 "register_operand" "=u")
15655         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15656   "TARGET_USE_FANCY_MATH_387
15657    && flag_unsafe_math_optimizations"
15658   "fptan"
15659   [(set_attr "type" "fpspc")
15660    (set_attr "mode" "XF")])
15661
15662 ;; optimize sequence: fptan
15663 ;;                    fstp    %st(0)
15664 ;;                    fld1
15665 ;; into fptan insn.
15666
15667 (define_peephole2
15668   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15669                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15670                              UNSPEC_TAN_ONE))
15671              (set (match_operand:XF 1 "register_operand" "")
15672                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15673    (set (match_dup 0)
15674         (match_operand:XF 3 "immediate_operand" ""))]
15675   "standard_80387_constant_p (operands[3]) == 2"
15676   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15677              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15678   "")
15679
15680 (define_expand "tanxf2"
15681   [(parallel [(set (match_dup 2)
15682                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15683                               UNSPEC_TAN_ONE))
15684               (set (match_operand:XF 0 "register_operand" "")
15685                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15686   "TARGET_USE_FANCY_MATH_387
15687    && flag_unsafe_math_optimizations"
15688 {
15689   operands[2] = gen_reg_rtx (XFmode);
15690 })
15691
15692 (define_insn "atan2df3_1"
15693   [(set (match_operand:DF 0 "register_operand" "=f")
15694         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15695                     (match_operand:DF 1 "register_operand" "u")]
15696                    UNSPEC_FPATAN))
15697    (clobber (match_scratch:DF 3 "=1"))]
15698   "TARGET_USE_FANCY_MATH_387
15699    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15700    && flag_unsafe_math_optimizations"
15701   "fpatan"
15702   [(set_attr "type" "fpspc")
15703    (set_attr "mode" "DF")])
15704
15705 (define_expand "atan2df3"
15706   [(use (match_operand:DF 0 "register_operand" ""))
15707    (use (match_operand:DF 2 "register_operand" ""))
15708    (use (match_operand:DF 1 "register_operand" ""))]
15709   "TARGET_USE_FANCY_MATH_387
15710    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15711    && flag_unsafe_math_optimizations"
15712 {
15713   rtx copy = gen_reg_rtx (DFmode);
15714   emit_move_insn (copy, operands[1]);
15715   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15716   DONE;
15717 })
15718
15719 (define_expand "atandf2"
15720   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15721                    (unspec:DF [(match_dup 2)
15722                                (match_operand:DF 1 "register_operand" "")]
15723                     UNSPEC_FPATAN))
15724               (clobber (match_scratch:DF 3 ""))])]
15725   "TARGET_USE_FANCY_MATH_387
15726    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15727    && flag_unsafe_math_optimizations"
15728 {
15729   operands[2] = gen_reg_rtx (DFmode);
15730   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15731 })
15732
15733 (define_insn "atan2sf3_1"
15734   [(set (match_operand:SF 0 "register_operand" "=f")
15735         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15736                     (match_operand:SF 1 "register_operand" "u")]
15737                    UNSPEC_FPATAN))
15738    (clobber (match_scratch:SF 3 "=1"))]
15739   "TARGET_USE_FANCY_MATH_387
15740    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15741    && flag_unsafe_math_optimizations"
15742   "fpatan"
15743   [(set_attr "type" "fpspc")
15744    (set_attr "mode" "SF")])
15745
15746 (define_expand "atan2sf3"
15747   [(use (match_operand:SF 0 "register_operand" ""))
15748    (use (match_operand:SF 2 "register_operand" ""))
15749    (use (match_operand:SF 1 "register_operand" ""))]
15750   "TARGET_USE_FANCY_MATH_387
15751    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15752    && flag_unsafe_math_optimizations"
15753 {
15754   rtx copy = gen_reg_rtx (SFmode);
15755   emit_move_insn (copy, operands[1]);
15756   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15757   DONE;
15758 })
15759
15760 (define_expand "atansf2"
15761   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15762                    (unspec:SF [(match_dup 2)
15763                                (match_operand:SF 1 "register_operand" "")]
15764                     UNSPEC_FPATAN))
15765               (clobber (match_scratch:SF 3 ""))])]
15766   "TARGET_USE_FANCY_MATH_387
15767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15768    && flag_unsafe_math_optimizations"
15769 {
15770   operands[2] = gen_reg_rtx (SFmode);
15771   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15772 })
15773
15774 (define_insn "atan2xf3_1"
15775   [(set (match_operand:XF 0 "register_operand" "=f")
15776         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15777                     (match_operand:XF 1 "register_operand" "u")]
15778                    UNSPEC_FPATAN))
15779    (clobber (match_scratch:XF 3 "=1"))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && flag_unsafe_math_optimizations"
15782   "fpatan"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "XF")])
15785
15786 (define_expand "atan2xf3"
15787   [(use (match_operand:XF 0 "register_operand" ""))
15788    (use (match_operand:XF 2 "register_operand" ""))
15789    (use (match_operand:XF 1 "register_operand" ""))]
15790   "TARGET_USE_FANCY_MATH_387
15791    && flag_unsafe_math_optimizations"
15792 {
15793   rtx copy = gen_reg_rtx (XFmode);
15794   emit_move_insn (copy, operands[1]);
15795   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15796   DONE;
15797 })
15798
15799 (define_expand "atanxf2"
15800   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15801                    (unspec:XF [(match_dup 2)
15802                                (match_operand:XF 1 "register_operand" "")]
15803                     UNSPEC_FPATAN))
15804               (clobber (match_scratch:XF 3 ""))])]
15805   "TARGET_USE_FANCY_MATH_387
15806    && flag_unsafe_math_optimizations"
15807 {
15808   operands[2] = gen_reg_rtx (XFmode);
15809   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15810 })
15811
15812 (define_expand "asindf2"
15813   [(set (match_dup 2)
15814         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15815    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15816    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15817    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15818    (parallel [(set (match_dup 7)
15819                    (unspec:XF [(match_dup 6) (match_dup 2)]
15820                               UNSPEC_FPATAN))
15821               (clobber (match_scratch:XF 8 ""))])
15822    (set (match_operand:DF 0 "register_operand" "")
15823         (float_truncate:DF (match_dup 7)))]
15824   "TARGET_USE_FANCY_MATH_387
15825    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15826    && flag_unsafe_math_optimizations"
15827 {
15828   int i;
15829
15830   for (i=2; i<8; i++)
15831     operands[i] = gen_reg_rtx (XFmode);
15832
15833   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15834 })
15835
15836 (define_expand "asinsf2"
15837   [(set (match_dup 2)
15838         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15839    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15840    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15841    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15842    (parallel [(set (match_dup 7)
15843                    (unspec:XF [(match_dup 6) (match_dup 2)]
15844                               UNSPEC_FPATAN))
15845               (clobber (match_scratch:XF 8 ""))])
15846    (set (match_operand:SF 0 "register_operand" "")
15847         (float_truncate:SF (match_dup 7)))]
15848   "TARGET_USE_FANCY_MATH_387
15849    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15850    && flag_unsafe_math_optimizations"
15851 {
15852   int i;
15853
15854   for (i=2; i<8; i++)
15855     operands[i] = gen_reg_rtx (XFmode);
15856
15857   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15858 })
15859
15860 (define_expand "asinxf2"
15861   [(set (match_dup 2)
15862         (mult:XF (match_operand:XF 1 "register_operand" "")
15863                  (match_dup 1)))
15864    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15865    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15866    (parallel [(set (match_operand:XF 0 "register_operand" "")
15867                    (unspec:XF [(match_dup 5) (match_dup 1)]
15868                               UNSPEC_FPATAN))
15869               (clobber (match_scratch:XF 6 ""))])]
15870   "TARGET_USE_FANCY_MATH_387
15871    && flag_unsafe_math_optimizations"
15872 {
15873   int i;
15874
15875   for (i=2; i<6; i++)
15876     operands[i] = gen_reg_rtx (XFmode);
15877
15878   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15879 })
15880
15881 (define_expand "acosdf2"
15882   [(set (match_dup 2)
15883         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15884    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15885    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15886    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15887    (parallel [(set (match_dup 7)
15888                    (unspec:XF [(match_dup 2) (match_dup 6)]
15889                               UNSPEC_FPATAN))
15890               (clobber (match_scratch:XF 8 ""))])
15891    (set (match_operand:DF 0 "register_operand" "")
15892         (float_truncate:DF (match_dup 7)))]
15893   "TARGET_USE_FANCY_MATH_387
15894    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15895    && flag_unsafe_math_optimizations"
15896 {
15897   int i;
15898
15899   for (i=2; i<8; i++)
15900     operands[i] = gen_reg_rtx (XFmode);
15901
15902   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15903 })
15904
15905 (define_expand "acossf2"
15906   [(set (match_dup 2)
15907         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15908    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15909    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15910    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15911    (parallel [(set (match_dup 7)
15912                    (unspec:XF [(match_dup 2) (match_dup 6)]
15913                               UNSPEC_FPATAN))
15914               (clobber (match_scratch:XF 8 ""))])
15915    (set (match_operand:SF 0 "register_operand" "")
15916         (float_truncate:SF (match_dup 7)))]
15917   "TARGET_USE_FANCY_MATH_387
15918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15919    && flag_unsafe_math_optimizations"
15920 {
15921   int i;
15922
15923   for (i=2; i<8; i++)
15924     operands[i] = gen_reg_rtx (XFmode);
15925
15926   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15927 })
15928
15929 (define_expand "acosxf2"
15930   [(set (match_dup 2)
15931         (mult:XF (match_operand:XF 1 "register_operand" "")
15932                  (match_dup 1)))
15933    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15934    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15935    (parallel [(set (match_operand:XF 0 "register_operand" "")
15936                    (unspec:XF [(match_dup 1) (match_dup 5)]
15937                               UNSPEC_FPATAN))
15938               (clobber (match_scratch:XF 6 ""))])]
15939   "TARGET_USE_FANCY_MATH_387
15940    && flag_unsafe_math_optimizations"
15941 {
15942   int i;
15943
15944   for (i=2; i<6; i++)
15945     operands[i] = gen_reg_rtx (XFmode);
15946
15947   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15948 })
15949
15950 (define_insn "fyl2x_xf3"
15951   [(set (match_operand:XF 0 "register_operand" "=f")
15952         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15953                     (match_operand:XF 1 "register_operand" "u")]
15954                    UNSPEC_FYL2X))
15955    (clobber (match_scratch:XF 3 "=1"))]
15956   "TARGET_USE_FANCY_MATH_387
15957    && flag_unsafe_math_optimizations"
15958   "fyl2x"
15959   [(set_attr "type" "fpspc")
15960    (set_attr "mode" "XF")])
15961
15962 (define_expand "logsf2"
15963   [(set (match_dup 2)
15964         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15965    (parallel [(set (match_dup 4)
15966                    (unspec:XF [(match_dup 2)
15967                                (match_dup 3)] UNSPEC_FYL2X))
15968               (clobber (match_scratch:XF 5 ""))])
15969    (set (match_operand:SF 0 "register_operand" "")
15970         (float_truncate:SF (match_dup 4)))]
15971   "TARGET_USE_FANCY_MATH_387
15972    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15973    && flag_unsafe_math_optimizations"
15974 {
15975   rtx temp;
15976
15977   operands[2] = gen_reg_rtx (XFmode);
15978   operands[3] = gen_reg_rtx (XFmode);
15979   operands[4] = gen_reg_rtx (XFmode);
15980
15981   temp = standard_80387_constant_rtx (4); /* fldln2 */
15982   emit_move_insn (operands[3], temp);
15983 })
15984
15985 (define_expand "logdf2"
15986   [(set (match_dup 2)
15987         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15988    (parallel [(set (match_dup 4)
15989                    (unspec:XF [(match_dup 2)
15990                                (match_dup 3)] UNSPEC_FYL2X))
15991               (clobber (match_scratch:XF 5 ""))])
15992    (set (match_operand:DF 0 "register_operand" "")
15993         (float_truncate:DF (match_dup 4)))]
15994   "TARGET_USE_FANCY_MATH_387
15995    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15996    && flag_unsafe_math_optimizations"
15997 {
15998   rtx temp;
15999
16000   operands[2] = gen_reg_rtx (XFmode);
16001   operands[3] = gen_reg_rtx (XFmode);
16002   operands[4] = gen_reg_rtx (XFmode);
16003
16004   temp = standard_80387_constant_rtx (4); /* fldln2 */
16005   emit_move_insn (operands[3], temp);
16006 })
16007
16008 (define_expand "logxf2"
16009   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16011                                (match_dup 2)] UNSPEC_FYL2X))
16012               (clobber (match_scratch:XF 3 ""))])]
16013   "TARGET_USE_FANCY_MATH_387
16014    && flag_unsafe_math_optimizations"
16015 {
16016   rtx temp;
16017
16018   operands[2] = gen_reg_rtx (XFmode);
16019   temp = standard_80387_constant_rtx (4); /* fldln2 */
16020   emit_move_insn (operands[2], temp);
16021 })
16022
16023 (define_expand "log10sf2"
16024   [(set (match_dup 2)
16025         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16026    (parallel [(set (match_dup 4)
16027                    (unspec:XF [(match_dup 2)
16028                                (match_dup 3)] UNSPEC_FYL2X))
16029               (clobber (match_scratch:XF 5 ""))])
16030    (set (match_operand:SF 0 "register_operand" "")
16031         (float_truncate:SF (match_dup 4)))]
16032   "TARGET_USE_FANCY_MATH_387
16033    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16034    && flag_unsafe_math_optimizations"
16035 {
16036   rtx temp;
16037
16038   operands[2] = gen_reg_rtx (XFmode);
16039   operands[3] = gen_reg_rtx (XFmode);
16040   operands[4] = gen_reg_rtx (XFmode);
16041
16042   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16043   emit_move_insn (operands[3], temp);
16044 })
16045
16046 (define_expand "log10df2"
16047   [(set (match_dup 2)
16048         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16049    (parallel [(set (match_dup 4)
16050                    (unspec:XF [(match_dup 2)
16051                                (match_dup 3)] UNSPEC_FYL2X))
16052               (clobber (match_scratch:XF 5 ""))])
16053    (set (match_operand:DF 0 "register_operand" "")
16054         (float_truncate:DF (match_dup 4)))]
16055   "TARGET_USE_FANCY_MATH_387
16056    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16057    && flag_unsafe_math_optimizations"
16058 {
16059   rtx temp;
16060
16061   operands[2] = gen_reg_rtx (XFmode);
16062   operands[3] = gen_reg_rtx (XFmode);
16063   operands[4] = gen_reg_rtx (XFmode);
16064
16065   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16066   emit_move_insn (operands[3], temp);
16067 })
16068
16069 (define_expand "log10xf2"
16070   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16071                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16072                                (match_dup 2)] UNSPEC_FYL2X))
16073               (clobber (match_scratch:XF 3 ""))])]
16074   "TARGET_USE_FANCY_MATH_387
16075    && flag_unsafe_math_optimizations"
16076 {
16077   rtx temp;
16078
16079   operands[2] = gen_reg_rtx (XFmode);
16080   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16081   emit_move_insn (operands[2], temp);
16082 })
16083
16084 (define_expand "log2sf2"
16085   [(set (match_dup 2)
16086         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16087    (parallel [(set (match_dup 4)
16088                    (unspec:XF [(match_dup 2)
16089                                (match_dup 3)] UNSPEC_FYL2X))
16090               (clobber (match_scratch:XF 5 ""))])
16091    (set (match_operand:SF 0 "register_operand" "")
16092         (float_truncate:SF (match_dup 4)))]
16093   "TARGET_USE_FANCY_MATH_387
16094    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16095    && flag_unsafe_math_optimizations"
16096 {
16097   operands[2] = gen_reg_rtx (XFmode);
16098   operands[3] = gen_reg_rtx (XFmode);
16099   operands[4] = gen_reg_rtx (XFmode);
16100
16101   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16102 })
16103
16104 (define_expand "log2df2"
16105   [(set (match_dup 2)
16106         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16107    (parallel [(set (match_dup 4)
16108                    (unspec:XF [(match_dup 2)
16109                                (match_dup 3)] UNSPEC_FYL2X))
16110               (clobber (match_scratch:XF 5 ""))])
16111    (set (match_operand:DF 0 "register_operand" "")
16112         (float_truncate:DF (match_dup 4)))]
16113   "TARGET_USE_FANCY_MATH_387
16114    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16116 {
16117   operands[2] = gen_reg_rtx (XFmode);
16118   operands[3] = gen_reg_rtx (XFmode);
16119   operands[4] = gen_reg_rtx (XFmode);
16120
16121   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16122 })
16123
16124 (define_expand "log2xf2"
16125   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16126                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16127                                (match_dup 2)] UNSPEC_FYL2X))
16128               (clobber (match_scratch:XF 3 ""))])]
16129   "TARGET_USE_FANCY_MATH_387
16130    && flag_unsafe_math_optimizations"
16131 {
16132   operands[2] = gen_reg_rtx (XFmode);
16133   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16134 })
16135
16136 (define_insn "fyl2xp1_xf3"
16137   [(set (match_operand:XF 0 "register_operand" "=f")
16138         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16139                     (match_operand:XF 1 "register_operand" "u")]
16140                    UNSPEC_FYL2XP1))
16141    (clobber (match_scratch:XF 3 "=1"))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && flag_unsafe_math_optimizations"
16144   "fyl2xp1"
16145   [(set_attr "type" "fpspc")
16146    (set_attr "mode" "XF")])
16147
16148 (define_expand "log1psf2"
16149   [(use (match_operand:SF 0 "register_operand" ""))
16150    (use (match_operand:SF 1 "register_operand" ""))]
16151   "TARGET_USE_FANCY_MATH_387
16152    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16153    && flag_unsafe_math_optimizations"
16154 {
16155   rtx op0 = gen_reg_rtx (XFmode);
16156   rtx op1 = gen_reg_rtx (XFmode);
16157
16158   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16159   ix86_emit_i387_log1p (op0, op1);
16160   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16161   DONE;
16162 })
16163
16164 (define_expand "log1pdf2"
16165   [(use (match_operand:DF 0 "register_operand" ""))
16166    (use (match_operand:DF 1 "register_operand" ""))]
16167   "TARGET_USE_FANCY_MATH_387
16168    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16169    && flag_unsafe_math_optimizations"
16170 {
16171   rtx op0 = gen_reg_rtx (XFmode);
16172   rtx op1 = gen_reg_rtx (XFmode);
16173
16174   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16175   ix86_emit_i387_log1p (op0, op1);
16176   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16177   DONE;
16178 })
16179
16180 (define_expand "log1pxf2"
16181   [(use (match_operand:XF 0 "register_operand" ""))
16182    (use (match_operand:XF 1 "register_operand" ""))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16185 {
16186   ix86_emit_i387_log1p (operands[0], operands[1]);
16187   DONE;
16188 })
16189
16190 (define_insn "*fxtractxf3"
16191   [(set (match_operand:XF 0 "register_operand" "=f")
16192         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16193                    UNSPEC_XTRACT_FRACT))
16194    (set (match_operand:XF 1 "register_operand" "=u")
16195         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16196   "TARGET_USE_FANCY_MATH_387
16197    && flag_unsafe_math_optimizations"
16198   "fxtract"
16199   [(set_attr "type" "fpspc")
16200    (set_attr "mode" "XF")])
16201
16202 (define_expand "logbsf2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16205    (parallel [(set (match_dup 3)
16206                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16207               (set (match_dup 4)
16208                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16209    (set (match_operand:SF 0 "register_operand" "")
16210         (float_truncate:SF (match_dup 4)))]
16211   "TARGET_USE_FANCY_MATH_387
16212    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16213    && flag_unsafe_math_optimizations"
16214 {
16215   operands[2] = gen_reg_rtx (XFmode);
16216   operands[3] = gen_reg_rtx (XFmode);
16217   operands[4] = gen_reg_rtx (XFmode);
16218 })
16219
16220 (define_expand "logbdf2"
16221   [(set (match_dup 2)
16222         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16223    (parallel [(set (match_dup 3)
16224                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16225               (set (match_dup 4)
16226                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16227    (set (match_operand:DF 0 "register_operand" "")
16228         (float_truncate:DF (match_dup 4)))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16231    && flag_unsafe_math_optimizations"
16232 {
16233   operands[2] = gen_reg_rtx (XFmode);
16234   operands[3] = gen_reg_rtx (XFmode);
16235   operands[4] = gen_reg_rtx (XFmode);
16236 })
16237
16238 (define_expand "logbxf2"
16239   [(parallel [(set (match_dup 2)
16240                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16241                               UNSPEC_XTRACT_FRACT))
16242               (set (match_operand:XF 0 "register_operand" "")
16243                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16246 {
16247   operands[2] = gen_reg_rtx (XFmode);
16248 })
16249
16250 (define_expand "ilogbsi2"
16251   [(parallel [(set (match_dup 2)
16252                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16253                               UNSPEC_XTRACT_FRACT))
16254               (set (match_operand:XF 3 "register_operand" "")
16255                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16256    (parallel [(set (match_operand:SI 0 "register_operand" "")
16257                    (fix:SI (match_dup 3)))
16258               (clobber (reg:CC FLAGS_REG))])]
16259   "TARGET_USE_FANCY_MATH_387
16260    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16261    && flag_unsafe_math_optimizations"
16262 {
16263   operands[2] = gen_reg_rtx (XFmode);
16264   operands[3] = gen_reg_rtx (XFmode);
16265 })
16266
16267 (define_insn "*f2xm1xf2"
16268   [(set (match_operand:XF 0 "register_operand" "=f")
16269         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16270          UNSPEC_F2XM1))]
16271   "TARGET_USE_FANCY_MATH_387
16272    && flag_unsafe_math_optimizations"
16273   "f2xm1"
16274   [(set_attr "type" "fpspc")
16275    (set_attr "mode" "XF")])
16276
16277 (define_insn "*fscalexf4"
16278   [(set (match_operand:XF 0 "register_operand" "=f")
16279         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16280                     (match_operand:XF 3 "register_operand" "1")]
16281                    UNSPEC_FSCALE_FRACT))
16282    (set (match_operand:XF 1 "register_operand" "=u")
16283         (unspec:XF [(match_dup 2) (match_dup 3)]
16284                    UNSPEC_FSCALE_EXP))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16287   "fscale"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "XF")])
16290
16291 (define_expand "expsf2"
16292   [(set (match_dup 2)
16293         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16294    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16295    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16296    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16297    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16298    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16299    (parallel [(set (match_dup 10)
16300                    (unspec:XF [(match_dup 9) (match_dup 5)]
16301                               UNSPEC_FSCALE_FRACT))
16302               (set (match_dup 11)
16303                    (unspec:XF [(match_dup 9) (match_dup 5)]
16304                               UNSPEC_FSCALE_EXP))])
16305    (set (match_operand:SF 0 "register_operand" "")
16306         (float_truncate:SF (match_dup 10)))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16310 {
16311   rtx temp;
16312   int i;
16313
16314   for (i=2; i<12; i++)
16315     operands[i] = gen_reg_rtx (XFmode);
16316   temp = standard_80387_constant_rtx (5); /* fldl2e */
16317   emit_move_insn (operands[3], temp);
16318   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16319 })
16320
16321 (define_expand "expdf2"
16322   [(set (match_dup 2)
16323         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16324    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16325    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16326    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16327    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16328    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16329    (parallel [(set (match_dup 10)
16330                    (unspec:XF [(match_dup 9) (match_dup 5)]
16331                               UNSPEC_FSCALE_FRACT))
16332               (set (match_dup 11)
16333                    (unspec:XF [(match_dup 9) (match_dup 5)]
16334                               UNSPEC_FSCALE_EXP))])
16335    (set (match_operand:DF 0 "register_operand" "")
16336         (float_truncate:DF (match_dup 10)))]
16337   "TARGET_USE_FANCY_MATH_387
16338    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16339    && flag_unsafe_math_optimizations"
16340 {
16341   rtx temp;
16342   int i;
16343
16344   for (i=2; i<12; i++)
16345     operands[i] = gen_reg_rtx (XFmode);
16346   temp = standard_80387_constant_rtx (5); /* fldl2e */
16347   emit_move_insn (operands[3], temp);
16348   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16349 })
16350
16351 (define_expand "expxf2"
16352   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16353                                (match_dup 2)))
16354    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16355    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16356    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16357    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16358    (parallel [(set (match_operand:XF 0 "register_operand" "")
16359                    (unspec:XF [(match_dup 8) (match_dup 4)]
16360                               UNSPEC_FSCALE_FRACT))
16361               (set (match_dup 9)
16362                    (unspec:XF [(match_dup 8) (match_dup 4)]
16363                               UNSPEC_FSCALE_EXP))])]
16364   "TARGET_USE_FANCY_MATH_387
16365    && flag_unsafe_math_optimizations"
16366 {
16367   rtx temp;
16368   int i;
16369
16370   for (i=2; i<10; i++)
16371     operands[i] = gen_reg_rtx (XFmode);
16372   temp = standard_80387_constant_rtx (5); /* fldl2e */
16373   emit_move_insn (operands[2], temp);
16374   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16375 })
16376
16377 (define_expand "exp10sf2"
16378   [(set (match_dup 2)
16379         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16380    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16381    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16382    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16383    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16384    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16385    (parallel [(set (match_dup 10)
16386                    (unspec:XF [(match_dup 9) (match_dup 5)]
16387                               UNSPEC_FSCALE_FRACT))
16388               (set (match_dup 11)
16389                    (unspec:XF [(match_dup 9) (match_dup 5)]
16390                               UNSPEC_FSCALE_EXP))])
16391    (set (match_operand:SF 0 "register_operand" "")
16392         (float_truncate:SF (match_dup 10)))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16395    && flag_unsafe_math_optimizations"
16396 {
16397   rtx temp;
16398   int i;
16399
16400   for (i=2; i<12; i++)
16401     operands[i] = gen_reg_rtx (XFmode);
16402   temp = standard_80387_constant_rtx (6); /* fldl2t */
16403   emit_move_insn (operands[3], temp);
16404   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16405 })
16406
16407 (define_expand "exp10df2"
16408   [(set (match_dup 2)
16409         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16410    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16411    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16412    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16413    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16414    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16415    (parallel [(set (match_dup 10)
16416                    (unspec:XF [(match_dup 9) (match_dup 5)]
16417                               UNSPEC_FSCALE_FRACT))
16418               (set (match_dup 11)
16419                    (unspec:XF [(match_dup 9) (match_dup 5)]
16420                               UNSPEC_FSCALE_EXP))])
16421    (set (match_operand:DF 0 "register_operand" "")
16422         (float_truncate:DF (match_dup 10)))]
16423   "TARGET_USE_FANCY_MATH_387
16424    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16425    && flag_unsafe_math_optimizations"
16426 {
16427   rtx temp;
16428   int i;
16429
16430   for (i=2; i<12; i++)
16431     operands[i] = gen_reg_rtx (XFmode);
16432   temp = standard_80387_constant_rtx (6); /* fldl2t */
16433   emit_move_insn (operands[3], temp);
16434   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16435 })
16436
16437 (define_expand "exp10xf2"
16438   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16439                                (match_dup 2)))
16440    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16441    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16442    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16443    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16444    (parallel [(set (match_operand:XF 0 "register_operand" "")
16445                    (unspec:XF [(match_dup 8) (match_dup 4)]
16446                               UNSPEC_FSCALE_FRACT))
16447               (set (match_dup 9)
16448                    (unspec:XF [(match_dup 8) (match_dup 4)]
16449                               UNSPEC_FSCALE_EXP))])]
16450   "TARGET_USE_FANCY_MATH_387
16451    && flag_unsafe_math_optimizations"
16452 {
16453   rtx temp;
16454   int i;
16455
16456   for (i=2; i<10; i++)
16457     operands[i] = gen_reg_rtx (XFmode);
16458   temp = standard_80387_constant_rtx (6); /* fldl2t */
16459   emit_move_insn (operands[2], temp);
16460   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16461 })
16462
16463 (define_expand "exp2sf2"
16464   [(set (match_dup 2)
16465         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16466    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16467    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16468    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16469    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16470    (parallel [(set (match_dup 8)
16471                    (unspec:XF [(match_dup 7) (match_dup 3)]
16472                               UNSPEC_FSCALE_FRACT))
16473               (set (match_dup 9)
16474                    (unspec:XF [(match_dup 7) (match_dup 3)]
16475                               UNSPEC_FSCALE_EXP))])
16476    (set (match_operand:SF 0 "register_operand" "")
16477         (float_truncate:SF (match_dup 8)))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16480    && flag_unsafe_math_optimizations"
16481 {
16482   int i;
16483
16484   for (i=2; i<10; i++)
16485     operands[i] = gen_reg_rtx (XFmode);
16486   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16487 })
16488
16489 (define_expand "exp2df2"
16490   [(set (match_dup 2)
16491         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16492    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16493    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16494    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16495    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16496    (parallel [(set (match_dup 8)
16497                    (unspec:XF [(match_dup 7) (match_dup 3)]
16498                               UNSPEC_FSCALE_FRACT))
16499               (set (match_dup 9)
16500                    (unspec:XF [(match_dup 7) (match_dup 3)]
16501                               UNSPEC_FSCALE_EXP))])
16502    (set (match_operand:DF 0 "register_operand" "")
16503         (float_truncate:DF (match_dup 8)))]
16504   "TARGET_USE_FANCY_MATH_387
16505    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16506    && flag_unsafe_math_optimizations"
16507 {
16508   int i;
16509
16510   for (i=2; i<10; i++)
16511     operands[i] = gen_reg_rtx (XFmode);
16512   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16513 })
16514
16515 (define_expand "exp2xf2"
16516   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16517    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16518    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16519    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16520    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16521    (parallel [(set (match_operand:XF 0 "register_operand" "")
16522                    (unspec:XF [(match_dup 7) (match_dup 3)]
16523                               UNSPEC_FSCALE_FRACT))
16524               (set (match_dup 8)
16525                    (unspec:XF [(match_dup 7) (match_dup 3)]
16526                               UNSPEC_FSCALE_EXP))])]
16527   "TARGET_USE_FANCY_MATH_387
16528    && flag_unsafe_math_optimizations"
16529 {
16530   int i;
16531
16532   for (i=2; i<9; i++)
16533     operands[i] = gen_reg_rtx (XFmode);
16534   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16535 })
16536
16537 (define_expand "expm1df2"
16538   [(set (match_dup 2)
16539         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16540    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16541    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16542    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16543    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16544    (parallel [(set (match_dup 8)
16545                    (unspec:XF [(match_dup 7) (match_dup 5)]
16546                               UNSPEC_FSCALE_FRACT))
16547                    (set (match_dup 9)
16548                    (unspec:XF [(match_dup 7) (match_dup 5)]
16549                               UNSPEC_FSCALE_EXP))])
16550    (parallel [(set (match_dup 11)
16551                    (unspec:XF [(match_dup 10) (match_dup 9)]
16552                               UNSPEC_FSCALE_FRACT))
16553               (set (match_dup 12)
16554                    (unspec:XF [(match_dup 10) (match_dup 9)]
16555                               UNSPEC_FSCALE_EXP))])
16556    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16557    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16558    (set (match_operand:DF 0 "register_operand" "")
16559         (float_truncate:DF (match_dup 14)))]
16560   "TARGET_USE_FANCY_MATH_387
16561    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16562    && flag_unsafe_math_optimizations"
16563 {
16564   rtx temp;
16565   int i;
16566
16567   for (i=2; i<15; i++)
16568     operands[i] = gen_reg_rtx (XFmode);
16569   temp = standard_80387_constant_rtx (5); /* fldl2e */
16570   emit_move_insn (operands[3], temp);
16571   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16572 })
16573
16574 (define_expand "expm1sf2"
16575   [(set (match_dup 2)
16576         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16577    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16578    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16579    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16580    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16581    (parallel [(set (match_dup 8)
16582                    (unspec:XF [(match_dup 7) (match_dup 5)]
16583                               UNSPEC_FSCALE_FRACT))
16584                    (set (match_dup 9)
16585                    (unspec:XF [(match_dup 7) (match_dup 5)]
16586                               UNSPEC_FSCALE_EXP))])
16587    (parallel [(set (match_dup 11)
16588                    (unspec:XF [(match_dup 10) (match_dup 9)]
16589                               UNSPEC_FSCALE_FRACT))
16590               (set (match_dup 12)
16591                    (unspec:XF [(match_dup 10) (match_dup 9)]
16592                               UNSPEC_FSCALE_EXP))])
16593    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16594    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16595    (set (match_operand:SF 0 "register_operand" "")
16596         (float_truncate:SF (match_dup 14)))]
16597   "TARGET_USE_FANCY_MATH_387
16598    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16599    && flag_unsafe_math_optimizations"
16600 {
16601   rtx temp;
16602   int i;
16603
16604   for (i=2; i<15; i++)
16605     operands[i] = gen_reg_rtx (XFmode);
16606   temp = standard_80387_constant_rtx (5); /* fldl2e */
16607   emit_move_insn (operands[3], temp);
16608   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16609 })
16610
16611 (define_expand "expm1xf2"
16612   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16613                                (match_dup 2)))
16614    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16615    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16616    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16617    (parallel [(set (match_dup 7)
16618                    (unspec:XF [(match_dup 6) (match_dup 4)]
16619                               UNSPEC_FSCALE_FRACT))
16620                    (set (match_dup 8)
16621                    (unspec:XF [(match_dup 6) (match_dup 4)]
16622                               UNSPEC_FSCALE_EXP))])
16623    (parallel [(set (match_dup 10)
16624                    (unspec:XF [(match_dup 9) (match_dup 8)]
16625                               UNSPEC_FSCALE_FRACT))
16626               (set (match_dup 11)
16627                    (unspec:XF [(match_dup 9) (match_dup 8)]
16628                               UNSPEC_FSCALE_EXP))])
16629    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16630    (set (match_operand:XF 0 "register_operand" "")
16631         (plus:XF (match_dup 12) (match_dup 7)))]
16632   "TARGET_USE_FANCY_MATH_387
16633    && flag_unsafe_math_optimizations"
16634 {
16635   rtx temp;
16636   int i;
16637
16638   for (i=2; i<13; i++)
16639     operands[i] = gen_reg_rtx (XFmode);
16640   temp = standard_80387_constant_rtx (5); /* fldl2e */
16641   emit_move_insn (operands[2], temp);
16642   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16643 })
16644
16645 (define_expand "ldexpdf3"
16646   [(set (match_dup 3)
16647         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16648    (set (match_dup 4)
16649         (float:XF (match_operand:SI 2 "register_operand" "")))
16650    (parallel [(set (match_dup 5)
16651                    (unspec:XF [(match_dup 3) (match_dup 4)]
16652                               UNSPEC_FSCALE_FRACT))
16653               (set (match_dup 6)
16654                    (unspec:XF [(match_dup 3) (match_dup 4)]
16655                               UNSPEC_FSCALE_EXP))])
16656    (set (match_operand:DF 0 "register_operand" "")
16657         (float_truncate:DF (match_dup 5)))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16660    && flag_unsafe_math_optimizations"
16661 {
16662   int i;
16663
16664   for (i=3; i<7; i++)
16665     operands[i] = gen_reg_rtx (XFmode);
16666 })
16667
16668 (define_expand "ldexpsf3"
16669   [(set (match_dup 3)
16670         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16671    (set (match_dup 4)
16672         (float:XF (match_operand:SI 2 "register_operand" "")))
16673    (parallel [(set (match_dup 5)
16674                    (unspec:XF [(match_dup 3) (match_dup 4)]
16675                               UNSPEC_FSCALE_FRACT))
16676               (set (match_dup 6)
16677                    (unspec:XF [(match_dup 3) (match_dup 4)]
16678                               UNSPEC_FSCALE_EXP))])
16679    (set (match_operand:SF 0 "register_operand" "")
16680         (float_truncate:SF (match_dup 5)))]
16681   "TARGET_USE_FANCY_MATH_387
16682    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16683    && flag_unsafe_math_optimizations"
16684 {
16685   int i;
16686
16687   for (i=3; i<7; i++)
16688     operands[i] = gen_reg_rtx (XFmode);
16689 })
16690
16691 (define_expand "ldexpxf3"
16692   [(set (match_dup 3)
16693         (float:XF (match_operand:SI 2 "register_operand" "")))
16694    (parallel [(set (match_operand:XF 0 " register_operand" "")
16695                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16696                                (match_dup 3)]
16697                               UNSPEC_FSCALE_FRACT))
16698               (set (match_dup 4)
16699                    (unspec:XF [(match_dup 1) (match_dup 3)]
16700                               UNSPEC_FSCALE_EXP))])]
16701   "TARGET_USE_FANCY_MATH_387
16702    && flag_unsafe_math_optimizations"
16703 {
16704   int i;
16705
16706   for (i=3; i<5; i++)
16707     operands[i] = gen_reg_rtx (XFmode);
16708 })
16709 \f
16710
16711 (define_insn "frndintxf2"
16712   [(set (match_operand:XF 0 "register_operand" "=f")
16713         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16714          UNSPEC_FRNDINT))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && flag_unsafe_math_optimizations"
16717   "frndint"
16718   [(set_attr "type" "fpspc")
16719    (set_attr "mode" "XF")])
16720
16721 (define_expand "rintdf2"
16722   [(use (match_operand:DF 0 "register_operand" ""))
16723    (use (match_operand:DF 1 "register_operand" ""))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16726    && flag_unsafe_math_optimizations"
16727 {
16728   rtx op0 = gen_reg_rtx (XFmode);
16729   rtx op1 = gen_reg_rtx (XFmode);
16730
16731   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16732   emit_insn (gen_frndintxf2 (op0, op1));
16733
16734   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16735   DONE;
16736 })
16737
16738 (define_expand "rintsf2"
16739   [(use (match_operand:SF 0 "register_operand" ""))
16740    (use (match_operand:SF 1 "register_operand" ""))]
16741   "TARGET_USE_FANCY_MATH_387
16742    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16743    && flag_unsafe_math_optimizations"
16744 {
16745   rtx op0 = gen_reg_rtx (XFmode);
16746   rtx op1 = gen_reg_rtx (XFmode);
16747
16748   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16749   emit_insn (gen_frndintxf2 (op0, op1));
16750
16751   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16752   DONE;
16753 })
16754
16755 (define_expand "rintxf2"
16756   [(use (match_operand:XF 0 "register_operand" ""))
16757    (use (match_operand:XF 1 "register_operand" ""))]
16758   "TARGET_USE_FANCY_MATH_387
16759    && flag_unsafe_math_optimizations"
16760 {
16761   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16762   DONE;
16763 })
16764
16765 (define_insn_and_split "*fistdi2_1"
16766   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16767         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16768          UNSPEC_FIST))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && flag_unsafe_math_optimizations
16771    && !(reload_completed || reload_in_progress)"
16772   "#"
16773   "&& 1"
16774   [(const_int 0)]
16775 {
16776   if (memory_operand (operands[0], VOIDmode))
16777     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16778   else
16779     {
16780       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16781       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16782                                          operands[2]));
16783     }
16784   DONE;
16785 }
16786   [(set_attr "type" "fpspc")
16787    (set_attr "mode" "DI")])
16788
16789 (define_insn "fistdi2"
16790   [(set (match_operand:DI 0 "memory_operand" "=m")
16791         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16792          UNSPEC_FIST))
16793    (clobber (match_scratch:XF 2 "=&1f"))]
16794   "TARGET_USE_FANCY_MATH_387
16795    && flag_unsafe_math_optimizations"
16796   "* return output_fix_trunc (insn, operands, 0);"
16797   [(set_attr "type" "fpspc")
16798    (set_attr "mode" "DI")])
16799
16800 (define_insn "fistdi2_with_temp"
16801   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16802         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16803          UNSPEC_FIST))
16804    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16805    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16806   "TARGET_USE_FANCY_MATH_387
16807    && flag_unsafe_math_optimizations"
16808   "#"
16809   [(set_attr "type" "fpspc")
16810    (set_attr "mode" "DI")])
16811
16812 (define_split 
16813   [(set (match_operand:DI 0 "register_operand" "")
16814         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16815          UNSPEC_FIST))
16816    (clobber (match_operand:DI 2 "memory_operand" ""))
16817    (clobber (match_scratch 3 ""))]
16818   "reload_completed"
16819   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16820               (clobber (match_dup 3))])
16821    (set (match_dup 0) (match_dup 2))]
16822   "")
16823
16824 (define_split 
16825   [(set (match_operand:DI 0 "memory_operand" "")
16826         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16827          UNSPEC_FIST))
16828    (clobber (match_operand:DI 2 "memory_operand" ""))
16829    (clobber (match_scratch 3 ""))]
16830   "reload_completed"
16831   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16832               (clobber (match_dup 3))])]
16833   "")
16834
16835 (define_insn_and_split "*fist<mode>2_1"
16836   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16837         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16838          UNSPEC_FIST))]
16839   "TARGET_USE_FANCY_MATH_387
16840    && flag_unsafe_math_optimizations
16841    && !(reload_completed || reload_in_progress)"
16842   "#"
16843   "&& 1"
16844   [(const_int 0)]
16845 {
16846   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16847   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16848                                         operands[2]));
16849   DONE;
16850 }
16851   [(set_attr "type" "fpspc")
16852    (set_attr "mode" "<MODE>")])
16853
16854 (define_insn "fist<mode>2"
16855   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16856         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16857          UNSPEC_FIST))]
16858   "TARGET_USE_FANCY_MATH_387
16859    && flag_unsafe_math_optimizations"
16860   "* return output_fix_trunc (insn, operands, 0);"
16861   [(set_attr "type" "fpspc")
16862    (set_attr "mode" "<MODE>")])
16863
16864 (define_insn "fist<mode>2_with_temp"
16865   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16866         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16867          UNSPEC_FIST))
16868    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations"
16871   "#"
16872   [(set_attr "type" "fpspc")
16873    (set_attr "mode" "<MODE>")])
16874
16875 (define_split 
16876   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16877         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16878          UNSPEC_FIST))
16879    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16880   "reload_completed"
16881   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16882                        UNSPEC_FIST))
16883    (set (match_dup 0) (match_dup 2))]
16884   "")
16885
16886 (define_split 
16887   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16888         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16889          UNSPEC_FIST))
16890    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16891   "reload_completed"
16892   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16893                        UNSPEC_FIST))]
16894   "")
16895
16896 (define_expand "lrint<mode>2"
16897   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16898         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16899          UNSPEC_FIST))]
16900   "TARGET_USE_FANCY_MATH_387
16901    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16902    && flag_unsafe_math_optimizations"
16903   "")
16904
16905 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16906 (define_insn_and_split "frndintxf2_floor"
16907   [(set (match_operand:XF 0 "register_operand" "=f")
16908         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16909          UNSPEC_FRNDINT_FLOOR))
16910    (clobber (reg:CC FLAGS_REG))]
16911   "TARGET_USE_FANCY_MATH_387
16912    && flag_unsafe_math_optimizations
16913    && !(reload_completed || reload_in_progress)"
16914   "#"
16915   "&& 1"
16916   [(const_int 0)]
16917 {
16918   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16919
16920   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16921   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16922
16923   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16924                                         operands[2], operands[3]));
16925   DONE;
16926 }
16927   [(set_attr "type" "frndint")
16928    (set_attr "i387_cw" "floor")
16929    (set_attr "mode" "XF")])
16930
16931 (define_insn "frndintxf2_floor_i387"
16932   [(set (match_operand:XF 0 "register_operand" "=f")
16933         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16934          UNSPEC_FRNDINT_FLOOR))
16935    (use (match_operand:HI 2 "memory_operand" "m"))
16936    (use (match_operand:HI 3 "memory_operand" "m"))]
16937   "TARGET_USE_FANCY_MATH_387
16938    && flag_unsafe_math_optimizations"
16939   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16940   [(set_attr "type" "frndint")
16941    (set_attr "i387_cw" "floor")
16942    (set_attr "mode" "XF")])
16943
16944 (define_expand "floorxf2"
16945   [(use (match_operand:XF 0 "register_operand" ""))
16946    (use (match_operand:XF 1 "register_operand" ""))]
16947   "TARGET_USE_FANCY_MATH_387
16948    && flag_unsafe_math_optimizations"
16949 {
16950   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16951   DONE;
16952 })
16953
16954 (define_expand "floordf2"
16955   [(use (match_operand:DF 0 "register_operand" ""))
16956    (use (match_operand:DF 1 "register_operand" ""))]
16957   "TARGET_USE_FANCY_MATH_387
16958    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16959    && flag_unsafe_math_optimizations"
16960 {
16961   rtx op0 = gen_reg_rtx (XFmode);
16962   rtx op1 = gen_reg_rtx (XFmode);
16963
16964   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16965   emit_insn (gen_frndintxf2_floor (op0, op1));
16966
16967   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16968   DONE;
16969 })
16970
16971 (define_expand "floorsf2"
16972   [(use (match_operand:SF 0 "register_operand" ""))
16973    (use (match_operand:SF 1 "register_operand" ""))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16976    && flag_unsafe_math_optimizations"
16977 {
16978   rtx op0 = gen_reg_rtx (XFmode);
16979   rtx op1 = gen_reg_rtx (XFmode);
16980
16981   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16982   emit_insn (gen_frndintxf2_floor (op0, op1));
16983
16984   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16985   DONE;
16986 })
16987
16988 (define_insn_and_split "*fist<mode>2_floor_1"
16989   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16990         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16991          UNSPEC_FIST_FLOOR))
16992    (clobber (reg:CC FLAGS_REG))]
16993   "TARGET_USE_FANCY_MATH_387
16994    && flag_unsafe_math_optimizations
16995    && !(reload_completed || reload_in_progress)"
16996   "#"
16997   "&& 1"
16998   [(const_int 0)]
16999 {
17000   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17001
17002   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17003   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17004   if (memory_operand (operands[0], VOIDmode))
17005     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17006                                       operands[2], operands[3]));
17007   else
17008     {
17009       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17010       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17011                                                   operands[2], operands[3],
17012                                                   operands[4]));
17013     }
17014   DONE;
17015 }
17016   [(set_attr "type" "fistp")
17017    (set_attr "i387_cw" "floor")
17018    (set_attr "mode" "<MODE>")])
17019
17020 (define_insn "fistdi2_floor"
17021   [(set (match_operand:DI 0 "memory_operand" "=m")
17022         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17023          UNSPEC_FIST_FLOOR))
17024    (use (match_operand:HI 2 "memory_operand" "m"))
17025    (use (match_operand:HI 3 "memory_operand" "m"))
17026    (clobber (match_scratch:XF 4 "=&1f"))]
17027   "TARGET_USE_FANCY_MATH_387
17028    && flag_unsafe_math_optimizations"
17029   "* return output_fix_trunc (insn, operands, 0);"
17030   [(set_attr "type" "fistp")
17031    (set_attr "i387_cw" "floor")
17032    (set_attr "mode" "DI")])
17033
17034 (define_insn "fistdi2_floor_with_temp"
17035   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17036         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17037          UNSPEC_FIST_FLOOR))
17038    (use (match_operand:HI 2 "memory_operand" "m,m"))
17039    (use (match_operand:HI 3 "memory_operand" "m,m"))
17040    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17041    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17042   "TARGET_USE_FANCY_MATH_387
17043    && flag_unsafe_math_optimizations"
17044   "#"
17045   [(set_attr "type" "fistp")
17046    (set_attr "i387_cw" "floor")
17047    (set_attr "mode" "DI")])
17048
17049 (define_split 
17050   [(set (match_operand:DI 0 "register_operand" "")
17051         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17052          UNSPEC_FIST_FLOOR))
17053    (use (match_operand:HI 2 "memory_operand" ""))
17054    (use (match_operand:HI 3 "memory_operand" ""))
17055    (clobber (match_operand:DI 4 "memory_operand" ""))
17056    (clobber (match_scratch 5 ""))]
17057   "reload_completed"
17058   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17059               (use (match_dup 2))
17060               (use (match_dup 3))
17061               (clobber (match_dup 5))])
17062    (set (match_dup 0) (match_dup 4))]
17063   "")
17064
17065 (define_split 
17066   [(set (match_operand:DI 0 "memory_operand" "")
17067         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17068          UNSPEC_FIST_FLOOR))
17069    (use (match_operand:HI 2 "memory_operand" ""))
17070    (use (match_operand:HI 3 "memory_operand" ""))
17071    (clobber (match_operand:DI 4 "memory_operand" ""))
17072    (clobber (match_scratch 5 ""))]
17073   "reload_completed"
17074   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17075               (use (match_dup 2))
17076               (use (match_dup 3))
17077               (clobber (match_dup 5))])]
17078   "")
17079
17080 (define_insn "fist<mode>2_floor"
17081   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17082         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17083          UNSPEC_FIST_FLOOR))
17084    (use (match_operand:HI 2 "memory_operand" "m"))
17085    (use (match_operand:HI 3 "memory_operand" "m"))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations"
17088   "* return output_fix_trunc (insn, operands, 0);"
17089   [(set_attr "type" "fistp")
17090    (set_attr "i387_cw" "floor")
17091    (set_attr "mode" "<MODE>")])
17092
17093 (define_insn "fist<mode>2_floor_with_temp"
17094   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17095         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17096          UNSPEC_FIST_FLOOR))
17097    (use (match_operand:HI 2 "memory_operand" "m,m"))
17098    (use (match_operand:HI 3 "memory_operand" "m,m"))
17099    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17100   "TARGET_USE_FANCY_MATH_387
17101    && flag_unsafe_math_optimizations"
17102   "#"
17103   [(set_attr "type" "fistp")
17104    (set_attr "i387_cw" "floor")
17105    (set_attr "mode" "<MODE>")])
17106
17107 (define_split 
17108   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17109         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17110          UNSPEC_FIST_FLOOR))
17111    (use (match_operand:HI 2 "memory_operand" ""))
17112    (use (match_operand:HI 3 "memory_operand" ""))
17113    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17114   "reload_completed"
17115   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17116                                   UNSPEC_FIST_FLOOR))
17117               (use (match_dup 2))
17118               (use (match_dup 3))])
17119    (set (match_dup 0) (match_dup 4))]
17120   "")
17121
17122 (define_split 
17123   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17124         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17125          UNSPEC_FIST_FLOOR))
17126    (use (match_operand:HI 2 "memory_operand" ""))
17127    (use (match_operand:HI 3 "memory_operand" ""))
17128    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17129   "reload_completed"
17130   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17131                                   UNSPEC_FIST_FLOOR))
17132               (use (match_dup 2))
17133               (use (match_dup 3))])]
17134   "")
17135
17136 (define_expand "lfloor<mode>2"
17137   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17138                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17139                     UNSPEC_FIST_FLOOR))
17140               (clobber (reg:CC FLAGS_REG))])]
17141   "TARGET_USE_FANCY_MATH_387
17142    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17143    && flag_unsafe_math_optimizations"
17144   "")
17145
17146 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17147 (define_insn_and_split "frndintxf2_ceil"
17148   [(set (match_operand:XF 0 "register_operand" "=f")
17149         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17150          UNSPEC_FRNDINT_CEIL))
17151    (clobber (reg:CC FLAGS_REG))]
17152   "TARGET_USE_FANCY_MATH_387
17153    && flag_unsafe_math_optimizations
17154    && !(reload_completed || reload_in_progress)"
17155   "#"
17156   "&& 1"
17157   [(const_int 0)]
17158 {
17159   ix86_optimize_mode_switching[I387_CEIL] = 1;
17160
17161   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17162   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17163
17164   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17165                                        operands[2], operands[3]));
17166   DONE;
17167 }
17168   [(set_attr "type" "frndint")
17169    (set_attr "i387_cw" "ceil")
17170    (set_attr "mode" "XF")])
17171
17172 (define_insn "frndintxf2_ceil_i387"
17173   [(set (match_operand:XF 0 "register_operand" "=f")
17174         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17175          UNSPEC_FRNDINT_CEIL))
17176    (use (match_operand:HI 2 "memory_operand" "m"))
17177    (use (match_operand:HI 3 "memory_operand" "m"))]
17178   "TARGET_USE_FANCY_MATH_387
17179    && flag_unsafe_math_optimizations"
17180   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17181   [(set_attr "type" "frndint")
17182    (set_attr "i387_cw" "ceil")
17183    (set_attr "mode" "XF")])
17184
17185 (define_expand "ceilxf2"
17186   [(use (match_operand:XF 0 "register_operand" ""))
17187    (use (match_operand:XF 1 "register_operand" ""))]
17188   "TARGET_USE_FANCY_MATH_387
17189    && flag_unsafe_math_optimizations"
17190 {
17191   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17192   DONE;
17193 })
17194
17195 (define_expand "ceildf2"
17196   [(use (match_operand:DF 0 "register_operand" ""))
17197    (use (match_operand:DF 1 "register_operand" ""))]
17198   "TARGET_USE_FANCY_MATH_387
17199    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17200    && flag_unsafe_math_optimizations"
17201 {
17202   rtx op0 = gen_reg_rtx (XFmode);
17203   rtx op1 = gen_reg_rtx (XFmode);
17204
17205   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17206   emit_insn (gen_frndintxf2_ceil (op0, op1));
17207
17208   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17209   DONE;
17210 })
17211
17212 (define_expand "ceilsf2"
17213   [(use (match_operand:SF 0 "register_operand" ""))
17214    (use (match_operand:SF 1 "register_operand" ""))]
17215   "TARGET_USE_FANCY_MATH_387
17216    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17217    && flag_unsafe_math_optimizations"
17218 {
17219   rtx op0 = gen_reg_rtx (XFmode);
17220   rtx op1 = gen_reg_rtx (XFmode);
17221
17222   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17223   emit_insn (gen_frndintxf2_ceil (op0, op1));
17224
17225   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17226   DONE;
17227 })
17228
17229 (define_insn_and_split "*fist<mode>2_ceil_1"
17230   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17231         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17232          UNSPEC_FIST_CEIL))
17233    (clobber (reg:CC FLAGS_REG))]
17234   "TARGET_USE_FANCY_MATH_387
17235    && flag_unsafe_math_optimizations
17236    && !(reload_completed || reload_in_progress)"
17237   "#"
17238   "&& 1"
17239   [(const_int 0)]
17240 {
17241   ix86_optimize_mode_switching[I387_CEIL] = 1;
17242
17243   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17244   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17245   if (memory_operand (operands[0], VOIDmode))
17246     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17247                                      operands[2], operands[3]));
17248   else
17249     {
17250       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17251       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17252                                                  operands[2], operands[3],
17253                                                  operands[4]));
17254     }
17255   DONE;
17256 }
17257   [(set_attr "type" "fistp")
17258    (set_attr "i387_cw" "ceil")
17259    (set_attr "mode" "<MODE>")])
17260
17261 (define_insn "fistdi2_ceil"
17262   [(set (match_operand:DI 0 "memory_operand" "=m")
17263         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17264          UNSPEC_FIST_CEIL))
17265    (use (match_operand:HI 2 "memory_operand" "m"))
17266    (use (match_operand:HI 3 "memory_operand" "m"))
17267    (clobber (match_scratch:XF 4 "=&1f"))]
17268   "TARGET_USE_FANCY_MATH_387
17269    && flag_unsafe_math_optimizations"
17270   "* return output_fix_trunc (insn, operands, 0);"
17271   [(set_attr "type" "fistp")
17272    (set_attr "i387_cw" "ceil")
17273    (set_attr "mode" "DI")])
17274
17275 (define_insn "fistdi2_ceil_with_temp"
17276   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17277         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17278          UNSPEC_FIST_CEIL))
17279    (use (match_operand:HI 2 "memory_operand" "m,m"))
17280    (use (match_operand:HI 3 "memory_operand" "m,m"))
17281    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17282    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17283   "TARGET_USE_FANCY_MATH_387
17284    && flag_unsafe_math_optimizations"
17285   "#"
17286   [(set_attr "type" "fistp")
17287    (set_attr "i387_cw" "ceil")
17288    (set_attr "mode" "DI")])
17289
17290 (define_split 
17291   [(set (match_operand:DI 0 "register_operand" "")
17292         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17293          UNSPEC_FIST_CEIL))
17294    (use (match_operand:HI 2 "memory_operand" ""))
17295    (use (match_operand:HI 3 "memory_operand" ""))
17296    (clobber (match_operand:DI 4 "memory_operand" ""))
17297    (clobber (match_scratch 5 ""))]
17298   "reload_completed"
17299   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17300               (use (match_dup 2))
17301               (use (match_dup 3))
17302               (clobber (match_dup 5))])
17303    (set (match_dup 0) (match_dup 4))]
17304   "")
17305
17306 (define_split 
17307   [(set (match_operand:DI 0 "memory_operand" "")
17308         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17309          UNSPEC_FIST_CEIL))
17310    (use (match_operand:HI 2 "memory_operand" ""))
17311    (use (match_operand:HI 3 "memory_operand" ""))
17312    (clobber (match_operand:DI 4 "memory_operand" ""))
17313    (clobber (match_scratch 5 ""))]
17314   "reload_completed"
17315   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17316               (use (match_dup 2))
17317               (use (match_dup 3))
17318               (clobber (match_dup 5))])]
17319   "")
17320
17321 (define_insn "fist<mode>2_ceil"
17322   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17323         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17324          UNSPEC_FIST_CEIL))
17325    (use (match_operand:HI 2 "memory_operand" "m"))
17326    (use (match_operand:HI 3 "memory_operand" "m"))]
17327   "TARGET_USE_FANCY_MATH_387
17328    && flag_unsafe_math_optimizations"
17329   "* return output_fix_trunc (insn, operands, 0);"
17330   [(set_attr "type" "fistp")
17331    (set_attr "i387_cw" "ceil")
17332    (set_attr "mode" "<MODE>")])
17333
17334 (define_insn "fist<mode>2_ceil_with_temp"
17335   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17336         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17337          UNSPEC_FIST_CEIL))
17338    (use (match_operand:HI 2 "memory_operand" "m,m"))
17339    (use (match_operand:HI 3 "memory_operand" "m,m"))
17340    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && flag_unsafe_math_optimizations"
17343   "#"
17344   [(set_attr "type" "fistp")
17345    (set_attr "i387_cw" "ceil")
17346    (set_attr "mode" "<MODE>")])
17347
17348 (define_split 
17349   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17350         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17351          UNSPEC_FIST_CEIL))
17352    (use (match_operand:HI 2 "memory_operand" ""))
17353    (use (match_operand:HI 3 "memory_operand" ""))
17354    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17355   "reload_completed"
17356   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17357                                   UNSPEC_FIST_CEIL))
17358               (use (match_dup 2))
17359               (use (match_dup 3))])
17360    (set (match_dup 0) (match_dup 4))]
17361   "")
17362
17363 (define_split 
17364   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17365         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17366          UNSPEC_FIST_CEIL))
17367    (use (match_operand:HI 2 "memory_operand" ""))
17368    (use (match_operand:HI 3 "memory_operand" ""))
17369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17370   "reload_completed"
17371   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17372                                   UNSPEC_FIST_CEIL))
17373               (use (match_dup 2))
17374               (use (match_dup 3))])]
17375   "")
17376
17377 (define_expand "lceil<mode>2"
17378   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17379                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17380                     UNSPEC_FIST_CEIL))
17381               (clobber (reg:CC FLAGS_REG))])]
17382   "TARGET_USE_FANCY_MATH_387
17383    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17384    && flag_unsafe_math_optimizations"
17385   "")
17386
17387 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17388 (define_insn_and_split "frndintxf2_trunc"
17389   [(set (match_operand:XF 0 "register_operand" "=f")
17390         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17391          UNSPEC_FRNDINT_TRUNC))
17392    (clobber (reg:CC FLAGS_REG))]
17393   "TARGET_USE_FANCY_MATH_387
17394    && flag_unsafe_math_optimizations
17395    && !(reload_completed || reload_in_progress)"
17396   "#"
17397   "&& 1"
17398   [(const_int 0)]
17399 {
17400   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17401
17402   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17403   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17404
17405   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17406                                         operands[2], operands[3]));
17407   DONE;
17408 }
17409   [(set_attr "type" "frndint")
17410    (set_attr "i387_cw" "trunc")
17411    (set_attr "mode" "XF")])
17412
17413 (define_insn "frndintxf2_trunc_i387"
17414   [(set (match_operand:XF 0 "register_operand" "=f")
17415         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17416          UNSPEC_FRNDINT_TRUNC))
17417    (use (match_operand:HI 2 "memory_operand" "m"))
17418    (use (match_operand:HI 3 "memory_operand" "m"))]
17419   "TARGET_USE_FANCY_MATH_387
17420    && flag_unsafe_math_optimizations"
17421   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17422   [(set_attr "type" "frndint")
17423    (set_attr "i387_cw" "trunc")
17424    (set_attr "mode" "XF")])
17425
17426 (define_expand "btruncxf2"
17427   [(use (match_operand:XF 0 "register_operand" ""))
17428    (use (match_operand:XF 1 "register_operand" ""))]
17429   "TARGET_USE_FANCY_MATH_387
17430    && flag_unsafe_math_optimizations"
17431 {
17432   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17433   DONE;
17434 })
17435
17436 (define_expand "btruncdf2"
17437   [(use (match_operand:DF 0 "register_operand" ""))
17438    (use (match_operand:DF 1 "register_operand" ""))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17441    && flag_unsafe_math_optimizations"
17442 {
17443   rtx op0 = gen_reg_rtx (XFmode);
17444   rtx op1 = gen_reg_rtx (XFmode);
17445
17446   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17447   emit_insn (gen_frndintxf2_trunc (op0, op1));
17448
17449   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17450   DONE;
17451 })
17452
17453 (define_expand "btruncsf2"
17454   [(use (match_operand:SF 0 "register_operand" ""))
17455    (use (match_operand:SF 1 "register_operand" ""))]
17456   "TARGET_USE_FANCY_MATH_387
17457    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17458    && flag_unsafe_math_optimizations"
17459 {
17460   rtx op0 = gen_reg_rtx (XFmode);
17461   rtx op1 = gen_reg_rtx (XFmode);
17462
17463   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17464   emit_insn (gen_frndintxf2_trunc (op0, op1));
17465
17466   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17467   DONE;
17468 })
17469
17470 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17471 (define_insn_and_split "frndintxf2_mask_pm"
17472   [(set (match_operand:XF 0 "register_operand" "=f")
17473         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17474          UNSPEC_FRNDINT_MASK_PM))
17475    (clobber (reg:CC FLAGS_REG))]
17476   "TARGET_USE_FANCY_MATH_387
17477    && flag_unsafe_math_optimizations
17478    && !(reload_completed || reload_in_progress)"
17479   "#"
17480   "&& 1"
17481   [(const_int 0)]
17482 {
17483   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17484
17485   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17486   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17487
17488   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17489                                           operands[2], operands[3]));
17490   DONE;
17491 }
17492   [(set_attr "type" "frndint")
17493    (set_attr "i387_cw" "mask_pm")
17494    (set_attr "mode" "XF")])
17495
17496 (define_insn "frndintxf2_mask_pm_i387"
17497   [(set (match_operand:XF 0 "register_operand" "=f")
17498         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17499          UNSPEC_FRNDINT_MASK_PM))
17500    (use (match_operand:HI 2 "memory_operand" "m"))
17501    (use (match_operand:HI 3 "memory_operand" "m"))]
17502   "TARGET_USE_FANCY_MATH_387
17503    && flag_unsafe_math_optimizations"
17504   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17505   [(set_attr "type" "frndint")
17506    (set_attr "i387_cw" "mask_pm")
17507    (set_attr "mode" "XF")])
17508
17509 (define_expand "nearbyintxf2"
17510   [(use (match_operand:XF 0 "register_operand" ""))
17511    (use (match_operand:XF 1 "register_operand" ""))]
17512   "TARGET_USE_FANCY_MATH_387
17513    && flag_unsafe_math_optimizations"
17514 {
17515   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17516
17517   DONE;
17518 })
17519
17520 (define_expand "nearbyintdf2"
17521   [(use (match_operand:DF 0 "register_operand" ""))
17522    (use (match_operand:DF 1 "register_operand" ""))]
17523   "TARGET_USE_FANCY_MATH_387
17524    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17525    && flag_unsafe_math_optimizations"
17526 {
17527   rtx op0 = gen_reg_rtx (XFmode);
17528   rtx op1 = gen_reg_rtx (XFmode);
17529
17530   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17531   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17532
17533   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17534   DONE;
17535 })
17536
17537 (define_expand "nearbyintsf2"
17538   [(use (match_operand:SF 0 "register_operand" ""))
17539    (use (match_operand:SF 1 "register_operand" ""))]
17540   "TARGET_USE_FANCY_MATH_387
17541    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17542    && flag_unsafe_math_optimizations"
17543 {
17544   rtx op0 = gen_reg_rtx (XFmode);
17545   rtx op1 = gen_reg_rtx (XFmode);
17546
17547   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17548   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17549
17550   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17551   DONE;
17552 })
17553
17554 \f
17555 ;; Block operation instructions
17556
17557 (define_insn "cld"
17558  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17559  ""
17560  "cld"
17561   [(set_attr "type" "cld")])
17562
17563 (define_expand "movmemsi"
17564   [(use (match_operand:BLK 0 "memory_operand" ""))
17565    (use (match_operand:BLK 1 "memory_operand" ""))
17566    (use (match_operand:SI 2 "nonmemory_operand" ""))
17567    (use (match_operand:SI 3 "const_int_operand" ""))]
17568   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17569 {
17570  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17571    DONE;
17572  else
17573    FAIL;
17574 })
17575
17576 (define_expand "movmemdi"
17577   [(use (match_operand:BLK 0 "memory_operand" ""))
17578    (use (match_operand:BLK 1 "memory_operand" ""))
17579    (use (match_operand:DI 2 "nonmemory_operand" ""))
17580    (use (match_operand:DI 3 "const_int_operand" ""))]
17581   "TARGET_64BIT"
17582 {
17583  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17584    DONE;
17585  else
17586    FAIL;
17587 })
17588
17589 ;; Most CPUs don't like single string operations
17590 ;; Handle this case here to simplify previous expander.
17591
17592 (define_expand "strmov"
17593   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17594    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17595    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17596               (clobber (reg:CC FLAGS_REG))])
17597    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17598               (clobber (reg:CC FLAGS_REG))])]
17599   ""
17600 {
17601   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17602
17603   /* If .md ever supports :P for Pmode, these can be directly
17604      in the pattern above.  */
17605   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17606   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17607
17608   if (TARGET_SINGLE_STRINGOP || optimize_size)
17609     {
17610       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17611                                       operands[2], operands[3],
17612                                       operands[5], operands[6]));
17613       DONE;
17614     }
17615
17616   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17617 })
17618
17619 (define_expand "strmov_singleop"
17620   [(parallel [(set (match_operand 1 "memory_operand" "")
17621                    (match_operand 3 "memory_operand" ""))
17622               (set (match_operand 0 "register_operand" "")
17623                    (match_operand 4 "" ""))
17624               (set (match_operand 2 "register_operand" "")
17625                    (match_operand 5 "" ""))
17626               (use (reg:SI DIRFLAG_REG))])]
17627   "TARGET_SINGLE_STRINGOP || optimize_size"
17628   "")
17629
17630 (define_insn "*strmovdi_rex_1"
17631   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17632         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17633    (set (match_operand:DI 0 "register_operand" "=D")
17634         (plus:DI (match_dup 2)
17635                  (const_int 8)))
17636    (set (match_operand:DI 1 "register_operand" "=S")
17637         (plus:DI (match_dup 3)
17638                  (const_int 8)))
17639    (use (reg:SI DIRFLAG_REG))]
17640   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17641   "movsq"
17642   [(set_attr "type" "str")
17643    (set_attr "mode" "DI")
17644    (set_attr "memory" "both")])
17645
17646 (define_insn "*strmovsi_1"
17647   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17648         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17649    (set (match_operand:SI 0 "register_operand" "=D")
17650         (plus:SI (match_dup 2)
17651                  (const_int 4)))
17652    (set (match_operand:SI 1 "register_operand" "=S")
17653         (plus:SI (match_dup 3)
17654                  (const_int 4)))
17655    (use (reg:SI DIRFLAG_REG))]
17656   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17657   "{movsl|movsd}"
17658   [(set_attr "type" "str")
17659    (set_attr "mode" "SI")
17660    (set_attr "memory" "both")])
17661
17662 (define_insn "*strmovsi_rex_1"
17663   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17664         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17665    (set (match_operand:DI 0 "register_operand" "=D")
17666         (plus:DI (match_dup 2)
17667                  (const_int 4)))
17668    (set (match_operand:DI 1 "register_operand" "=S")
17669         (plus:DI (match_dup 3)
17670                  (const_int 4)))
17671    (use (reg:SI DIRFLAG_REG))]
17672   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17673   "{movsl|movsd}"
17674   [(set_attr "type" "str")
17675    (set_attr "mode" "SI")
17676    (set_attr "memory" "both")])
17677
17678 (define_insn "*strmovhi_1"
17679   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17680         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17681    (set (match_operand:SI 0 "register_operand" "=D")
17682         (plus:SI (match_dup 2)
17683                  (const_int 2)))
17684    (set (match_operand:SI 1 "register_operand" "=S")
17685         (plus:SI (match_dup 3)
17686                  (const_int 2)))
17687    (use (reg:SI DIRFLAG_REG))]
17688   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17689   "movsw"
17690   [(set_attr "type" "str")
17691    (set_attr "memory" "both")
17692    (set_attr "mode" "HI")])
17693
17694 (define_insn "*strmovhi_rex_1"
17695   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17696         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17697    (set (match_operand:DI 0 "register_operand" "=D")
17698         (plus:DI (match_dup 2)
17699                  (const_int 2)))
17700    (set (match_operand:DI 1 "register_operand" "=S")
17701         (plus:DI (match_dup 3)
17702                  (const_int 2)))
17703    (use (reg:SI DIRFLAG_REG))]
17704   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17705   "movsw"
17706   [(set_attr "type" "str")
17707    (set_attr "memory" "both")
17708    (set_attr "mode" "HI")])
17709
17710 (define_insn "*strmovqi_1"
17711   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17712         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17713    (set (match_operand:SI 0 "register_operand" "=D")
17714         (plus:SI (match_dup 2)
17715                  (const_int 1)))
17716    (set (match_operand:SI 1 "register_operand" "=S")
17717         (plus:SI (match_dup 3)
17718                  (const_int 1)))
17719    (use (reg:SI DIRFLAG_REG))]
17720   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17721   "movsb"
17722   [(set_attr "type" "str")
17723    (set_attr "memory" "both")
17724    (set_attr "mode" "QI")])
17725
17726 (define_insn "*strmovqi_rex_1"
17727   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17728         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17729    (set (match_operand:DI 0 "register_operand" "=D")
17730         (plus:DI (match_dup 2)
17731                  (const_int 1)))
17732    (set (match_operand:DI 1 "register_operand" "=S")
17733         (plus:DI (match_dup 3)
17734                  (const_int 1)))
17735    (use (reg:SI DIRFLAG_REG))]
17736   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17737   "movsb"
17738   [(set_attr "type" "str")
17739    (set_attr "memory" "both")
17740    (set_attr "mode" "QI")])
17741
17742 (define_expand "rep_mov"
17743   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17744               (set (match_operand 0 "register_operand" "")
17745                    (match_operand 5 "" ""))
17746               (set (match_operand 2 "register_operand" "")
17747                    (match_operand 6 "" ""))
17748               (set (match_operand 1 "memory_operand" "")
17749                    (match_operand 3 "memory_operand" ""))
17750               (use (match_dup 4))
17751               (use (reg:SI DIRFLAG_REG))])]
17752   ""
17753   "")
17754
17755 (define_insn "*rep_movdi_rex64"
17756   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17757    (set (match_operand:DI 0 "register_operand" "=D") 
17758         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17759                             (const_int 3))
17760                  (match_operand:DI 3 "register_operand" "0")))
17761    (set (match_operand:DI 1 "register_operand" "=S") 
17762         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17763                  (match_operand:DI 4 "register_operand" "1")))
17764    (set (mem:BLK (match_dup 3))
17765         (mem:BLK (match_dup 4)))
17766    (use (match_dup 5))
17767    (use (reg:SI DIRFLAG_REG))]
17768   "TARGET_64BIT"
17769   "{rep\;movsq|rep movsq}"
17770   [(set_attr "type" "str")
17771    (set_attr "prefix_rep" "1")
17772    (set_attr "memory" "both")
17773    (set_attr "mode" "DI")])
17774
17775 (define_insn "*rep_movsi"
17776   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17777    (set (match_operand:SI 0 "register_operand" "=D") 
17778         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17779                             (const_int 2))
17780                  (match_operand:SI 3 "register_operand" "0")))
17781    (set (match_operand:SI 1 "register_operand" "=S") 
17782         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17783                  (match_operand:SI 4 "register_operand" "1")))
17784    (set (mem:BLK (match_dup 3))
17785         (mem:BLK (match_dup 4)))
17786    (use (match_dup 5))
17787    (use (reg:SI DIRFLAG_REG))]
17788   "!TARGET_64BIT"
17789   "{rep\;movsl|rep movsd}"
17790   [(set_attr "type" "str")
17791    (set_attr "prefix_rep" "1")
17792    (set_attr "memory" "both")
17793    (set_attr "mode" "SI")])
17794
17795 (define_insn "*rep_movsi_rex64"
17796   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17797    (set (match_operand:DI 0 "register_operand" "=D") 
17798         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17799                             (const_int 2))
17800                  (match_operand:DI 3 "register_operand" "0")))
17801    (set (match_operand:DI 1 "register_operand" "=S") 
17802         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17803                  (match_operand:DI 4 "register_operand" "1")))
17804    (set (mem:BLK (match_dup 3))
17805         (mem:BLK (match_dup 4)))
17806    (use (match_dup 5))
17807    (use (reg:SI DIRFLAG_REG))]
17808   "TARGET_64BIT"
17809   "{rep\;movsl|rep movsd}"
17810   [(set_attr "type" "str")
17811    (set_attr "prefix_rep" "1")
17812    (set_attr "memory" "both")
17813    (set_attr "mode" "SI")])
17814
17815 (define_insn "*rep_movqi"
17816   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17817    (set (match_operand:SI 0 "register_operand" "=D") 
17818         (plus:SI (match_operand:SI 3 "register_operand" "0")
17819                  (match_operand:SI 5 "register_operand" "2")))
17820    (set (match_operand:SI 1 "register_operand" "=S") 
17821         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17822    (set (mem:BLK (match_dup 3))
17823         (mem:BLK (match_dup 4)))
17824    (use (match_dup 5))
17825    (use (reg:SI DIRFLAG_REG))]
17826   "!TARGET_64BIT"
17827   "{rep\;movsb|rep movsb}"
17828   [(set_attr "type" "str")
17829    (set_attr "prefix_rep" "1")
17830    (set_attr "memory" "both")
17831    (set_attr "mode" "SI")])
17832
17833 (define_insn "*rep_movqi_rex64"
17834   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17835    (set (match_operand:DI 0 "register_operand" "=D") 
17836         (plus:DI (match_operand:DI 3 "register_operand" "0")
17837                  (match_operand:DI 5 "register_operand" "2")))
17838    (set (match_operand:DI 1 "register_operand" "=S") 
17839         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17840    (set (mem:BLK (match_dup 3))
17841         (mem:BLK (match_dup 4)))
17842    (use (match_dup 5))
17843    (use (reg:SI DIRFLAG_REG))]
17844   "TARGET_64BIT"
17845   "{rep\;movsb|rep movsb}"
17846   [(set_attr "type" "str")
17847    (set_attr "prefix_rep" "1")
17848    (set_attr "memory" "both")
17849    (set_attr "mode" "SI")])
17850
17851 (define_expand "setmemsi"
17852    [(use (match_operand:BLK 0 "memory_operand" ""))
17853     (use (match_operand:SI 1 "nonmemory_operand" ""))
17854     (use (match_operand 2 "const_int_operand" ""))
17855     (use (match_operand 3 "const_int_operand" ""))]
17856   ""
17857 {
17858  /* If value to set is not zero, use the library routine.  */
17859  if (operands[2] != const0_rtx)
17860    FAIL;
17861
17862  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17863    DONE;
17864  else
17865    FAIL;
17866 })
17867
17868 (define_expand "setmemdi"
17869    [(use (match_operand:BLK 0 "memory_operand" ""))
17870     (use (match_operand:DI 1 "nonmemory_operand" ""))
17871     (use (match_operand 2 "const_int_operand" ""))
17872     (use (match_operand 3 "const_int_operand" ""))]
17873   "TARGET_64BIT"
17874 {
17875  /* If value to set is not zero, use the library routine.  */
17876  if (operands[2] != const0_rtx)
17877    FAIL;
17878
17879  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17880    DONE;
17881  else
17882    FAIL;
17883 })
17884
17885 ;; Most CPUs don't like single string operations
17886 ;; Handle this case here to simplify previous expander.
17887
17888 (define_expand "strset"
17889   [(set (match_operand 1 "memory_operand" "")
17890         (match_operand 2 "register_operand" ""))
17891    (parallel [(set (match_operand 0 "register_operand" "")
17892                    (match_dup 3))
17893               (clobber (reg:CC FLAGS_REG))])]
17894   ""
17895 {
17896   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17897     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17898
17899   /* If .md ever supports :P for Pmode, this can be directly
17900      in the pattern above.  */
17901   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17902                               GEN_INT (GET_MODE_SIZE (GET_MODE
17903                                                       (operands[2]))));
17904   if (TARGET_SINGLE_STRINGOP || optimize_size)
17905     {
17906       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17907                                       operands[3]));
17908       DONE;
17909     }
17910 })
17911
17912 (define_expand "strset_singleop"
17913   [(parallel [(set (match_operand 1 "memory_operand" "")
17914                    (match_operand 2 "register_operand" ""))
17915               (set (match_operand 0 "register_operand" "")
17916                    (match_operand 3 "" ""))
17917               (use (reg:SI DIRFLAG_REG))])]
17918   "TARGET_SINGLE_STRINGOP || optimize_size"
17919   "")
17920
17921 (define_insn "*strsetdi_rex_1"
17922   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17923         (match_operand:DI 2 "register_operand" "a"))
17924    (set (match_operand:DI 0 "register_operand" "=D")
17925         (plus:DI (match_dup 1)
17926                  (const_int 8)))
17927    (use (reg:SI DIRFLAG_REG))]
17928   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17929   "stosq"
17930   [(set_attr "type" "str")
17931    (set_attr "memory" "store")
17932    (set_attr "mode" "DI")])
17933
17934 (define_insn "*strsetsi_1"
17935   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17936         (match_operand:SI 2 "register_operand" "a"))
17937    (set (match_operand:SI 0 "register_operand" "=D")
17938         (plus:SI (match_dup 1)
17939                  (const_int 4)))
17940    (use (reg:SI DIRFLAG_REG))]
17941   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17942   "{stosl|stosd}"
17943   [(set_attr "type" "str")
17944    (set_attr "memory" "store")
17945    (set_attr "mode" "SI")])
17946
17947 (define_insn "*strsetsi_rex_1"
17948   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17949         (match_operand:SI 2 "register_operand" "a"))
17950    (set (match_operand:DI 0 "register_operand" "=D")
17951         (plus:DI (match_dup 1)
17952                  (const_int 4)))
17953    (use (reg:SI DIRFLAG_REG))]
17954   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17955   "{stosl|stosd}"
17956   [(set_attr "type" "str")
17957    (set_attr "memory" "store")
17958    (set_attr "mode" "SI")])
17959
17960 (define_insn "*strsethi_1"
17961   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17962         (match_operand:HI 2 "register_operand" "a"))
17963    (set (match_operand:SI 0 "register_operand" "=D")
17964         (plus:SI (match_dup 1)
17965                  (const_int 2)))
17966    (use (reg:SI DIRFLAG_REG))]
17967   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17968   "stosw"
17969   [(set_attr "type" "str")
17970    (set_attr "memory" "store")
17971    (set_attr "mode" "HI")])
17972
17973 (define_insn "*strsethi_rex_1"
17974   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17975         (match_operand:HI 2 "register_operand" "a"))
17976    (set (match_operand:DI 0 "register_operand" "=D")
17977         (plus:DI (match_dup 1)
17978                  (const_int 2)))
17979    (use (reg:SI DIRFLAG_REG))]
17980   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17981   "stosw"
17982   [(set_attr "type" "str")
17983    (set_attr "memory" "store")
17984    (set_attr "mode" "HI")])
17985
17986 (define_insn "*strsetqi_1"
17987   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17988         (match_operand:QI 2 "register_operand" "a"))
17989    (set (match_operand:SI 0 "register_operand" "=D")
17990         (plus:SI (match_dup 1)
17991                  (const_int 1)))
17992    (use (reg:SI DIRFLAG_REG))]
17993   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17994   "stosb"
17995   [(set_attr "type" "str")
17996    (set_attr "memory" "store")
17997    (set_attr "mode" "QI")])
17998
17999 (define_insn "*strsetqi_rex_1"
18000   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18001         (match_operand:QI 2 "register_operand" "a"))
18002    (set (match_operand:DI 0 "register_operand" "=D")
18003         (plus:DI (match_dup 1)
18004                  (const_int 1)))
18005    (use (reg:SI DIRFLAG_REG))]
18006   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18007   "stosb"
18008   [(set_attr "type" "str")
18009    (set_attr "memory" "store")
18010    (set_attr "mode" "QI")])
18011
18012 (define_expand "rep_stos"
18013   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18014               (set (match_operand 0 "register_operand" "")
18015                    (match_operand 4 "" ""))
18016               (set (match_operand 2 "memory_operand" "") (const_int 0))
18017               (use (match_operand 3 "register_operand" ""))
18018               (use (match_dup 1))
18019               (use (reg:SI DIRFLAG_REG))])]
18020   ""
18021   "")
18022
18023 (define_insn "*rep_stosdi_rex64"
18024   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18025    (set (match_operand:DI 0 "register_operand" "=D") 
18026         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18027                             (const_int 3))
18028                  (match_operand:DI 3 "register_operand" "0")))
18029    (set (mem:BLK (match_dup 3))
18030         (const_int 0))
18031    (use (match_operand:DI 2 "register_operand" "a"))
18032    (use (match_dup 4))
18033    (use (reg:SI DIRFLAG_REG))]
18034   "TARGET_64BIT"
18035   "{rep\;stosq|rep stosq}"
18036   [(set_attr "type" "str")
18037    (set_attr "prefix_rep" "1")
18038    (set_attr "memory" "store")
18039    (set_attr "mode" "DI")])
18040
18041 (define_insn "*rep_stossi"
18042   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18043    (set (match_operand:SI 0 "register_operand" "=D") 
18044         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18045                             (const_int 2))
18046                  (match_operand:SI 3 "register_operand" "0")))
18047    (set (mem:BLK (match_dup 3))
18048         (const_int 0))
18049    (use (match_operand:SI 2 "register_operand" "a"))
18050    (use (match_dup 4))
18051    (use (reg:SI DIRFLAG_REG))]
18052   "!TARGET_64BIT"
18053   "{rep\;stosl|rep stosd}"
18054   [(set_attr "type" "str")
18055    (set_attr "prefix_rep" "1")
18056    (set_attr "memory" "store")
18057    (set_attr "mode" "SI")])
18058
18059 (define_insn "*rep_stossi_rex64"
18060   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18061    (set (match_operand:DI 0 "register_operand" "=D") 
18062         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18063                             (const_int 2))
18064                  (match_operand:DI 3 "register_operand" "0")))
18065    (set (mem:BLK (match_dup 3))
18066         (const_int 0))
18067    (use (match_operand:SI 2 "register_operand" "a"))
18068    (use (match_dup 4))
18069    (use (reg:SI DIRFLAG_REG))]
18070   "TARGET_64BIT"
18071   "{rep\;stosl|rep stosd}"
18072   [(set_attr "type" "str")
18073    (set_attr "prefix_rep" "1")
18074    (set_attr "memory" "store")
18075    (set_attr "mode" "SI")])
18076
18077 (define_insn "*rep_stosqi"
18078   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18079    (set (match_operand:SI 0 "register_operand" "=D") 
18080         (plus:SI (match_operand:SI 3 "register_operand" "0")
18081                  (match_operand:SI 4 "register_operand" "1")))
18082    (set (mem:BLK (match_dup 3))
18083         (const_int 0))
18084    (use (match_operand:QI 2 "register_operand" "a"))
18085    (use (match_dup 4))
18086    (use (reg:SI DIRFLAG_REG))]
18087   "!TARGET_64BIT"
18088   "{rep\;stosb|rep stosb}"
18089   [(set_attr "type" "str")
18090    (set_attr "prefix_rep" "1")
18091    (set_attr "memory" "store")
18092    (set_attr "mode" "QI")])
18093
18094 (define_insn "*rep_stosqi_rex64"
18095   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18096    (set (match_operand:DI 0 "register_operand" "=D") 
18097         (plus:DI (match_operand:DI 3 "register_operand" "0")
18098                  (match_operand:DI 4 "register_operand" "1")))
18099    (set (mem:BLK (match_dup 3))
18100         (const_int 0))
18101    (use (match_operand:QI 2 "register_operand" "a"))
18102    (use (match_dup 4))
18103    (use (reg:SI DIRFLAG_REG))]
18104   "TARGET_64BIT"
18105   "{rep\;stosb|rep stosb}"
18106   [(set_attr "type" "str")
18107    (set_attr "prefix_rep" "1")
18108    (set_attr "memory" "store")
18109    (set_attr "mode" "QI")])
18110
18111 (define_expand "cmpstrnsi"
18112   [(set (match_operand:SI 0 "register_operand" "")
18113         (compare:SI (match_operand:BLK 1 "general_operand" "")
18114                     (match_operand:BLK 2 "general_operand" "")))
18115    (use (match_operand 3 "general_operand" ""))
18116    (use (match_operand 4 "immediate_operand" ""))]
18117   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18118 {
18119   rtx addr1, addr2, out, outlow, count, countreg, align;
18120
18121   /* Can't use this if the user has appropriated esi or edi.  */
18122   if (global_regs[4] || global_regs[5])
18123     FAIL;
18124
18125   out = operands[0];
18126   if (GET_CODE (out) != REG)
18127     out = gen_reg_rtx (SImode);
18128
18129   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18130   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18131   if (addr1 != XEXP (operands[1], 0))
18132     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18133   if (addr2 != XEXP (operands[2], 0))
18134     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18135
18136   count = operands[3];
18137   countreg = ix86_zero_extend_to_Pmode (count);
18138
18139   /* %%% Iff we are testing strict equality, we can use known alignment
18140      to good advantage.  This may be possible with combine, particularly
18141      once cc0 is dead.  */
18142   align = operands[4];
18143
18144   emit_insn (gen_cld ());
18145   if (GET_CODE (count) == CONST_INT)
18146     {
18147       if (INTVAL (count) == 0)
18148         {
18149           emit_move_insn (operands[0], const0_rtx);
18150           DONE;
18151         }
18152       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18153                                      operands[1], operands[2]));
18154     }
18155   else
18156     {
18157       if (TARGET_64BIT)
18158         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18159       else
18160         emit_insn (gen_cmpsi_1 (countreg, countreg));
18161       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18162                                   operands[1], operands[2]));
18163     }
18164
18165   outlow = gen_lowpart (QImode, out);
18166   emit_insn (gen_cmpintqi (outlow));
18167   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18168
18169   if (operands[0] != out)
18170     emit_move_insn (operands[0], out);
18171
18172   DONE;
18173 })
18174
18175 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18176
18177 (define_expand "cmpintqi"
18178   [(set (match_dup 1)
18179         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18180    (set (match_dup 2)
18181         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18182    (parallel [(set (match_operand:QI 0 "register_operand" "")
18183                    (minus:QI (match_dup 1)
18184                              (match_dup 2)))
18185               (clobber (reg:CC FLAGS_REG))])]
18186   ""
18187   "operands[1] = gen_reg_rtx (QImode);
18188    operands[2] = gen_reg_rtx (QImode);")
18189
18190 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18191 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18192
18193 (define_expand "cmpstrnqi_nz_1"
18194   [(parallel [(set (reg:CC FLAGS_REG)
18195                    (compare:CC (match_operand 4 "memory_operand" "")
18196                                (match_operand 5 "memory_operand" "")))
18197               (use (match_operand 2 "register_operand" ""))
18198               (use (match_operand:SI 3 "immediate_operand" ""))
18199               (use (reg:SI DIRFLAG_REG))
18200               (clobber (match_operand 0 "register_operand" ""))
18201               (clobber (match_operand 1 "register_operand" ""))
18202               (clobber (match_dup 2))])]
18203   ""
18204   "")
18205
18206 (define_insn "*cmpstrnqi_nz_1"
18207   [(set (reg:CC FLAGS_REG)
18208         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18209                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18210    (use (match_operand:SI 6 "register_operand" "2"))
18211    (use (match_operand:SI 3 "immediate_operand" "i"))
18212    (use (reg:SI DIRFLAG_REG))
18213    (clobber (match_operand:SI 0 "register_operand" "=S"))
18214    (clobber (match_operand:SI 1 "register_operand" "=D"))
18215    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18216   "!TARGET_64BIT"
18217   "repz{\;| }cmpsb"
18218   [(set_attr "type" "str")
18219    (set_attr "mode" "QI")
18220    (set_attr "prefix_rep" "1")])
18221
18222 (define_insn "*cmpstrnqi_nz_rex_1"
18223   [(set (reg:CC FLAGS_REG)
18224         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18225                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18226    (use (match_operand:DI 6 "register_operand" "2"))
18227    (use (match_operand:SI 3 "immediate_operand" "i"))
18228    (use (reg:SI DIRFLAG_REG))
18229    (clobber (match_operand:DI 0 "register_operand" "=S"))
18230    (clobber (match_operand:DI 1 "register_operand" "=D"))
18231    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18232   "TARGET_64BIT"
18233   "repz{\;| }cmpsb"
18234   [(set_attr "type" "str")
18235    (set_attr "mode" "QI")
18236    (set_attr "prefix_rep" "1")])
18237
18238 ;; The same, but the count is not known to not be zero.
18239
18240 (define_expand "cmpstrnqi_1"
18241   [(parallel [(set (reg:CC FLAGS_REG)
18242                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18243                                      (const_int 0))
18244                   (compare:CC (match_operand 4 "memory_operand" "")
18245                               (match_operand 5 "memory_operand" ""))
18246                   (const_int 0)))
18247               (use (match_operand:SI 3 "immediate_operand" ""))
18248               (use (reg:CC FLAGS_REG))
18249               (use (reg:SI DIRFLAG_REG))
18250               (clobber (match_operand 0 "register_operand" ""))
18251               (clobber (match_operand 1 "register_operand" ""))
18252               (clobber (match_dup 2))])]
18253   ""
18254   "")
18255
18256 (define_insn "*cmpstrnqi_1"
18257   [(set (reg:CC FLAGS_REG)
18258         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18259                              (const_int 0))
18260           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18261                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18262           (const_int 0)))
18263    (use (match_operand:SI 3 "immediate_operand" "i"))
18264    (use (reg:CC FLAGS_REG))
18265    (use (reg:SI DIRFLAG_REG))
18266    (clobber (match_operand:SI 0 "register_operand" "=S"))
18267    (clobber (match_operand:SI 1 "register_operand" "=D"))
18268    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18269   "!TARGET_64BIT"
18270   "repz{\;| }cmpsb"
18271   [(set_attr "type" "str")
18272    (set_attr "mode" "QI")
18273    (set_attr "prefix_rep" "1")])
18274
18275 (define_insn "*cmpstrnqi_rex_1"
18276   [(set (reg:CC FLAGS_REG)
18277         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18278                              (const_int 0))
18279           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18280                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18281           (const_int 0)))
18282    (use (match_operand:SI 3 "immediate_operand" "i"))
18283    (use (reg:CC FLAGS_REG))
18284    (use (reg:SI DIRFLAG_REG))
18285    (clobber (match_operand:DI 0 "register_operand" "=S"))
18286    (clobber (match_operand:DI 1 "register_operand" "=D"))
18287    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18288   "TARGET_64BIT"
18289   "repz{\;| }cmpsb"
18290   [(set_attr "type" "str")
18291    (set_attr "mode" "QI")
18292    (set_attr "prefix_rep" "1")])
18293
18294 (define_expand "strlensi"
18295   [(set (match_operand:SI 0 "register_operand" "")
18296         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18297                     (match_operand:QI 2 "immediate_operand" "")
18298                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18299   ""
18300 {
18301  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18302    DONE;
18303  else
18304    FAIL;
18305 })
18306
18307 (define_expand "strlendi"
18308   [(set (match_operand:DI 0 "register_operand" "")
18309         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18310                     (match_operand:QI 2 "immediate_operand" "")
18311                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18312   ""
18313 {
18314  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18315    DONE;
18316  else
18317    FAIL;
18318 })
18319
18320 (define_expand "strlenqi_1"
18321   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18322               (use (reg:SI DIRFLAG_REG))
18323               (clobber (match_operand 1 "register_operand" ""))
18324               (clobber (reg:CC FLAGS_REG))])]
18325   ""
18326   "")
18327
18328 (define_insn "*strlenqi_1"
18329   [(set (match_operand:SI 0 "register_operand" "=&c")
18330         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18331                     (match_operand:QI 2 "register_operand" "a")
18332                     (match_operand:SI 3 "immediate_operand" "i")
18333                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18334    (use (reg:SI DIRFLAG_REG))
18335    (clobber (match_operand:SI 1 "register_operand" "=D"))
18336    (clobber (reg:CC FLAGS_REG))]
18337   "!TARGET_64BIT"
18338   "repnz{\;| }scasb"
18339   [(set_attr "type" "str")
18340    (set_attr "mode" "QI")
18341    (set_attr "prefix_rep" "1")])
18342
18343 (define_insn "*strlenqi_rex_1"
18344   [(set (match_operand:DI 0 "register_operand" "=&c")
18345         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18346                     (match_operand:QI 2 "register_operand" "a")
18347                     (match_operand:DI 3 "immediate_operand" "i")
18348                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18349    (use (reg:SI DIRFLAG_REG))
18350    (clobber (match_operand:DI 1 "register_operand" "=D"))
18351    (clobber (reg:CC FLAGS_REG))]
18352   "TARGET_64BIT"
18353   "repnz{\;| }scasb"
18354   [(set_attr "type" "str")
18355    (set_attr "mode" "QI")
18356    (set_attr "prefix_rep" "1")])
18357
18358 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18359 ;; handled in combine, but it is not currently up to the task.
18360 ;; When used for their truth value, the cmpstrn* expanders generate
18361 ;; code like this:
18362 ;;
18363 ;;   repz cmpsb
18364 ;;   seta       %al
18365 ;;   setb       %dl
18366 ;;   cmpb       %al, %dl
18367 ;;   jcc        label
18368 ;;
18369 ;; The intermediate three instructions are unnecessary.
18370
18371 ;; This one handles cmpstrn*_nz_1...
18372 (define_peephole2
18373   [(parallel[
18374      (set (reg:CC FLAGS_REG)
18375           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18376                       (mem:BLK (match_operand 5 "register_operand" ""))))
18377      (use (match_operand 6 "register_operand" ""))
18378      (use (match_operand:SI 3 "immediate_operand" ""))
18379      (use (reg:SI DIRFLAG_REG))
18380      (clobber (match_operand 0 "register_operand" ""))
18381      (clobber (match_operand 1 "register_operand" ""))
18382      (clobber (match_operand 2 "register_operand" ""))])
18383    (set (match_operand:QI 7 "register_operand" "")
18384         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18385    (set (match_operand:QI 8 "register_operand" "")
18386         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18387    (set (reg FLAGS_REG)
18388         (compare (match_dup 7) (match_dup 8)))
18389   ]
18390   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18391   [(parallel[
18392      (set (reg:CC FLAGS_REG)
18393           (compare:CC (mem:BLK (match_dup 4))
18394                       (mem:BLK (match_dup 5))))
18395      (use (match_dup 6))
18396      (use (match_dup 3))
18397      (use (reg:SI DIRFLAG_REG))
18398      (clobber (match_dup 0))
18399      (clobber (match_dup 1))
18400      (clobber (match_dup 2))])]
18401   "")
18402
18403 ;; ...and this one handles cmpstrn*_1.
18404 (define_peephole2
18405   [(parallel[
18406      (set (reg:CC FLAGS_REG)
18407           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18408                                (const_int 0))
18409             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18410                         (mem:BLK (match_operand 5 "register_operand" "")))
18411             (const_int 0)))
18412      (use (match_operand:SI 3 "immediate_operand" ""))
18413      (use (reg:CC FLAGS_REG))
18414      (use (reg:SI DIRFLAG_REG))
18415      (clobber (match_operand 0 "register_operand" ""))
18416      (clobber (match_operand 1 "register_operand" ""))
18417      (clobber (match_operand 2 "register_operand" ""))])
18418    (set (match_operand:QI 7 "register_operand" "")
18419         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18420    (set (match_operand:QI 8 "register_operand" "")
18421         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18422    (set (reg FLAGS_REG)
18423         (compare (match_dup 7) (match_dup 8)))
18424   ]
18425   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18426   [(parallel[
18427      (set (reg:CC FLAGS_REG)
18428           (if_then_else:CC (ne (match_dup 6)
18429                                (const_int 0))
18430             (compare:CC (mem:BLK (match_dup 4))
18431                         (mem:BLK (match_dup 5)))
18432             (const_int 0)))
18433      (use (match_dup 3))
18434      (use (reg:CC FLAGS_REG))
18435      (use (reg:SI DIRFLAG_REG))
18436      (clobber (match_dup 0))
18437      (clobber (match_dup 1))
18438      (clobber (match_dup 2))])]
18439   "")
18440
18441
18442 \f
18443 ;; Conditional move instructions.
18444
18445 (define_expand "movdicc"
18446   [(set (match_operand:DI 0 "register_operand" "")
18447         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18448                          (match_operand:DI 2 "general_operand" "")
18449                          (match_operand:DI 3 "general_operand" "")))]
18450   "TARGET_64BIT"
18451   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18452
18453 (define_insn "x86_movdicc_0_m1_rex64"
18454   [(set (match_operand:DI 0 "register_operand" "=r")
18455         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18456           (const_int -1)
18457           (const_int 0)))
18458    (clobber (reg:CC FLAGS_REG))]
18459   "TARGET_64BIT"
18460   "sbb{q}\t%0, %0"
18461   ; Since we don't have the proper number of operands for an alu insn,
18462   ; fill in all the blanks.
18463   [(set_attr "type" "alu")
18464    (set_attr "pent_pair" "pu")
18465    (set_attr "memory" "none")
18466    (set_attr "imm_disp" "false")
18467    (set_attr "mode" "DI")
18468    (set_attr "length_immediate" "0")])
18469
18470 (define_insn "*movdicc_c_rex64"
18471   [(set (match_operand:DI 0 "register_operand" "=r,r")
18472         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18473                                 [(reg FLAGS_REG) (const_int 0)])
18474                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18475                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18476   "TARGET_64BIT && TARGET_CMOVE
18477    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18478   "@
18479    cmov%O2%C1\t{%2, %0|%0, %2}
18480    cmov%O2%c1\t{%3, %0|%0, %3}"
18481   [(set_attr "type" "icmov")
18482    (set_attr "mode" "DI")])
18483
18484 (define_expand "movsicc"
18485   [(set (match_operand:SI 0 "register_operand" "")
18486         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18487                          (match_operand:SI 2 "general_operand" "")
18488                          (match_operand:SI 3 "general_operand" "")))]
18489   ""
18490   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18491
18492 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18493 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18494 ;; So just document what we're doing explicitly.
18495
18496 (define_insn "x86_movsicc_0_m1"
18497   [(set (match_operand:SI 0 "register_operand" "=r")
18498         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18499           (const_int -1)
18500           (const_int 0)))
18501    (clobber (reg:CC FLAGS_REG))]
18502   ""
18503   "sbb{l}\t%0, %0"
18504   ; Since we don't have the proper number of operands for an alu insn,
18505   ; fill in all the blanks.
18506   [(set_attr "type" "alu")
18507    (set_attr "pent_pair" "pu")
18508    (set_attr "memory" "none")
18509    (set_attr "imm_disp" "false")
18510    (set_attr "mode" "SI")
18511    (set_attr "length_immediate" "0")])
18512
18513 (define_insn "*movsicc_noc"
18514   [(set (match_operand:SI 0 "register_operand" "=r,r")
18515         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18516                                 [(reg FLAGS_REG) (const_int 0)])
18517                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18518                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18519   "TARGET_CMOVE
18520    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18521   "@
18522    cmov%O2%C1\t{%2, %0|%0, %2}
18523    cmov%O2%c1\t{%3, %0|%0, %3}"
18524   [(set_attr "type" "icmov")
18525    (set_attr "mode" "SI")])
18526
18527 (define_expand "movhicc"
18528   [(set (match_operand:HI 0 "register_operand" "")
18529         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18530                          (match_operand:HI 2 "general_operand" "")
18531                          (match_operand:HI 3 "general_operand" "")))]
18532   "TARGET_HIMODE_MATH"
18533   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18534
18535 (define_insn "*movhicc_noc"
18536   [(set (match_operand:HI 0 "register_operand" "=r,r")
18537         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18538                                 [(reg FLAGS_REG) (const_int 0)])
18539                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18540                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18541   "TARGET_CMOVE
18542    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18543   "@
18544    cmov%O2%C1\t{%2, %0|%0, %2}
18545    cmov%O2%c1\t{%3, %0|%0, %3}"
18546   [(set_attr "type" "icmov")
18547    (set_attr "mode" "HI")])
18548
18549 (define_expand "movqicc"
18550   [(set (match_operand:QI 0 "register_operand" "")
18551         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18552                          (match_operand:QI 2 "general_operand" "")
18553                          (match_operand:QI 3 "general_operand" "")))]
18554   "TARGET_QIMODE_MATH"
18555   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18556
18557 (define_insn_and_split "*movqicc_noc"
18558   [(set (match_operand:QI 0 "register_operand" "=r,r")
18559         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18560                                 [(match_operand 4 "flags_reg_operand" "")
18561                                  (const_int 0)])
18562                       (match_operand:QI 2 "register_operand" "r,0")
18563                       (match_operand:QI 3 "register_operand" "0,r")))]
18564   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18565   "#"
18566   "&& reload_completed"
18567   [(set (match_dup 0)
18568         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18569                       (match_dup 2)
18570                       (match_dup 3)))]
18571   "operands[0] = gen_lowpart (SImode, operands[0]);
18572    operands[2] = gen_lowpart (SImode, operands[2]);
18573    operands[3] = gen_lowpart (SImode, operands[3]);"
18574   [(set_attr "type" "icmov")
18575    (set_attr "mode" "SI")])
18576
18577 (define_expand "movsfcc"
18578   [(set (match_operand:SF 0 "register_operand" "")
18579         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18580                          (match_operand:SF 2 "register_operand" "")
18581                          (match_operand:SF 3 "register_operand" "")))]
18582   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18583   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18584
18585 (define_insn "*movsfcc_1_387"
18586   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18587         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18588                                 [(reg FLAGS_REG) (const_int 0)])
18589                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18590                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18591   "TARGET_80387 && TARGET_CMOVE
18592    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18593   "@
18594    fcmov%F1\t{%2, %0|%0, %2}
18595    fcmov%f1\t{%3, %0|%0, %3}
18596    cmov%O2%C1\t{%2, %0|%0, %2}
18597    cmov%O2%c1\t{%3, %0|%0, %3}"
18598   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18599    (set_attr "mode" "SF,SF,SI,SI")])
18600
18601 (define_expand "movdfcc"
18602   [(set (match_operand:DF 0 "register_operand" "")
18603         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18604                          (match_operand:DF 2 "register_operand" "")
18605                          (match_operand:DF 3 "register_operand" "")))]
18606   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18607   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18608
18609 (define_insn "*movdfcc_1"
18610   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18611         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18612                                 [(reg FLAGS_REG) (const_int 0)])
18613                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18614                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18615   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18616    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18617   "@
18618    fcmov%F1\t{%2, %0|%0, %2}
18619    fcmov%f1\t{%3, %0|%0, %3}
18620    #
18621    #"
18622   [(set_attr "type" "fcmov,fcmov,multi,multi")
18623    (set_attr "mode" "DF")])
18624
18625 (define_insn "*movdfcc_1_rex64"
18626   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18627         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18628                                 [(reg FLAGS_REG) (const_int 0)])
18629                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18630                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18631   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18632    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18633   "@
18634    fcmov%F1\t{%2, %0|%0, %2}
18635    fcmov%f1\t{%3, %0|%0, %3}
18636    cmov%O2%C1\t{%2, %0|%0, %2}
18637    cmov%O2%c1\t{%3, %0|%0, %3}"
18638   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18639    (set_attr "mode" "DF")])
18640
18641 (define_split
18642   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18643         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18644                                 [(match_operand 4 "flags_reg_operand" "")
18645                                  (const_int 0)])
18646                       (match_operand:DF 2 "nonimmediate_operand" "")
18647                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18648   "!TARGET_64BIT && reload_completed"
18649   [(set (match_dup 2)
18650         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18651                       (match_dup 5)
18652                       (match_dup 7)))
18653    (set (match_dup 3)
18654         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18655                       (match_dup 6)
18656                       (match_dup 8)))]
18657   "split_di (operands+2, 1, operands+5, operands+6);
18658    split_di (operands+3, 1, operands+7, operands+8);
18659    split_di (operands, 1, operands+2, operands+3);")
18660
18661 (define_expand "movxfcc"
18662   [(set (match_operand:XF 0 "register_operand" "")
18663         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18664                          (match_operand:XF 2 "register_operand" "")
18665                          (match_operand:XF 3 "register_operand" "")))]
18666   "TARGET_80387 && TARGET_CMOVE"
18667   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18668
18669 (define_insn "*movxfcc_1"
18670   [(set (match_operand:XF 0 "register_operand" "=f,f")
18671         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18672                                 [(reg FLAGS_REG) (const_int 0)])
18673                       (match_operand:XF 2 "register_operand" "f,0")
18674                       (match_operand:XF 3 "register_operand" "0,f")))]
18675   "TARGET_80387 && TARGET_CMOVE"
18676   "@
18677    fcmov%F1\t{%2, %0|%0, %2}
18678    fcmov%f1\t{%3, %0|%0, %3}"
18679   [(set_attr "type" "fcmov")
18680    (set_attr "mode" "XF")])
18681
18682 ;; These versions of the min/max patterns are intentionally ignorant of
18683 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18684 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18685 ;; are undefined in this condition, we're certain this is correct.
18686
18687 (define_insn "sminsf3"
18688   [(set (match_operand:SF 0 "register_operand" "=x")
18689         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18690                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18691   "TARGET_SSE_MATH"
18692   "minss\t{%2, %0|%0, %2}"
18693   [(set_attr "type" "sseadd")
18694    (set_attr "mode" "SF")])
18695
18696 (define_insn "smaxsf3"
18697   [(set (match_operand:SF 0 "register_operand" "=x")
18698         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18699                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18700   "TARGET_SSE_MATH"
18701   "maxss\t{%2, %0|%0, %2}"
18702   [(set_attr "type" "sseadd")
18703    (set_attr "mode" "SF")])
18704
18705 (define_insn "smindf3"
18706   [(set (match_operand:DF 0 "register_operand" "=x")
18707         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18708                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18709   "TARGET_SSE2 && TARGET_SSE_MATH"
18710   "minsd\t{%2, %0|%0, %2}"
18711   [(set_attr "type" "sseadd")
18712    (set_attr "mode" "DF")])
18713
18714 (define_insn "smaxdf3"
18715   [(set (match_operand:DF 0 "register_operand" "=x")
18716         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18717                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18718   "TARGET_SSE2 && TARGET_SSE_MATH"
18719   "maxsd\t{%2, %0|%0, %2}"
18720   [(set_attr "type" "sseadd")
18721    (set_attr "mode" "DF")])
18722
18723 ;; These versions of the min/max patterns implement exactly the operations
18724 ;;   min = (op1 < op2 ? op1 : op2)
18725 ;;   max = (!(op1 < op2) ? op1 : op2)
18726 ;; Their operands are not commutative, and thus they may be used in the
18727 ;; presence of -0.0 and NaN.
18728
18729 (define_insn "*ieee_sminsf3"
18730   [(set (match_operand:SF 0 "register_operand" "=x")
18731         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18732                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18733                    UNSPEC_IEEE_MIN))]
18734   "TARGET_SSE_MATH"
18735   "minss\t{%2, %0|%0, %2}"
18736   [(set_attr "type" "sseadd")
18737    (set_attr "mode" "SF")])
18738
18739 (define_insn "*ieee_smaxsf3"
18740   [(set (match_operand:SF 0 "register_operand" "=x")
18741         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18742                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18743                    UNSPEC_IEEE_MAX))]
18744   "TARGET_SSE_MATH"
18745   "maxss\t{%2, %0|%0, %2}"
18746   [(set_attr "type" "sseadd")
18747    (set_attr "mode" "SF")])
18748
18749 (define_insn "*ieee_smindf3"
18750   [(set (match_operand:DF 0 "register_operand" "=x")
18751         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18752                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18753                    UNSPEC_IEEE_MIN))]
18754   "TARGET_SSE2 && TARGET_SSE_MATH"
18755   "minsd\t{%2, %0|%0, %2}"
18756   [(set_attr "type" "sseadd")
18757    (set_attr "mode" "DF")])
18758
18759 (define_insn "*ieee_smaxdf3"
18760   [(set (match_operand:DF 0 "register_operand" "=x")
18761         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18762                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18763                    UNSPEC_IEEE_MAX))]
18764   "TARGET_SSE2 && TARGET_SSE_MATH"
18765   "maxsd\t{%2, %0|%0, %2}"
18766   [(set_attr "type" "sseadd")
18767    (set_attr "mode" "DF")])
18768
18769 ;; Conditional addition patterns
18770 (define_expand "addqicc"
18771   [(match_operand:QI 0 "register_operand" "")
18772    (match_operand 1 "comparison_operator" "")
18773    (match_operand:QI 2 "register_operand" "")
18774    (match_operand:QI 3 "const_int_operand" "")]
18775   ""
18776   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18777
18778 (define_expand "addhicc"
18779   [(match_operand:HI 0 "register_operand" "")
18780    (match_operand 1 "comparison_operator" "")
18781    (match_operand:HI 2 "register_operand" "")
18782    (match_operand:HI 3 "const_int_operand" "")]
18783   ""
18784   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18785
18786 (define_expand "addsicc"
18787   [(match_operand:SI 0 "register_operand" "")
18788    (match_operand 1 "comparison_operator" "")
18789    (match_operand:SI 2 "register_operand" "")
18790    (match_operand:SI 3 "const_int_operand" "")]
18791   ""
18792   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18793
18794 (define_expand "adddicc"
18795   [(match_operand:DI 0 "register_operand" "")
18796    (match_operand 1 "comparison_operator" "")
18797    (match_operand:DI 2 "register_operand" "")
18798    (match_operand:DI 3 "const_int_operand" "")]
18799   "TARGET_64BIT"
18800   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18801
18802 \f
18803 ;; Misc patterns (?)
18804
18805 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18806 ;; Otherwise there will be nothing to keep
18807 ;; 
18808 ;; [(set (reg ebp) (reg esp))]
18809 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18810 ;;  (clobber (eflags)]
18811 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18812 ;;
18813 ;; in proper program order.
18814 (define_insn "pro_epilogue_adjust_stack_1"
18815   [(set (match_operand:SI 0 "register_operand" "=r,r")
18816         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18817                  (match_operand:SI 2 "immediate_operand" "i,i")))
18818    (clobber (reg:CC FLAGS_REG))
18819    (clobber (mem:BLK (scratch)))]
18820   "!TARGET_64BIT"
18821 {
18822   switch (get_attr_type (insn))
18823     {
18824     case TYPE_IMOV:
18825       return "mov{l}\t{%1, %0|%0, %1}";
18826
18827     case TYPE_ALU:
18828       if (GET_CODE (operands[2]) == CONST_INT
18829           && (INTVAL (operands[2]) == 128
18830               || (INTVAL (operands[2]) < 0
18831                   && INTVAL (operands[2]) != -128)))
18832         {
18833           operands[2] = GEN_INT (-INTVAL (operands[2]));
18834           return "sub{l}\t{%2, %0|%0, %2}";
18835         }
18836       return "add{l}\t{%2, %0|%0, %2}";
18837
18838     case TYPE_LEA:
18839       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18840       return "lea{l}\t{%a2, %0|%0, %a2}";
18841
18842     default:
18843       gcc_unreachable ();
18844     }
18845 }
18846   [(set (attr "type")
18847         (cond [(eq_attr "alternative" "0")
18848                  (const_string "alu")
18849                (match_operand:SI 2 "const0_operand" "")
18850                  (const_string "imov")
18851               ]
18852               (const_string "lea")))
18853    (set_attr "mode" "SI")])
18854
18855 (define_insn "pro_epilogue_adjust_stack_rex64"
18856   [(set (match_operand:DI 0 "register_operand" "=r,r")
18857         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18858                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18859    (clobber (reg:CC FLAGS_REG))
18860    (clobber (mem:BLK (scratch)))]
18861   "TARGET_64BIT"
18862 {
18863   switch (get_attr_type (insn))
18864     {
18865     case TYPE_IMOV:
18866       return "mov{q}\t{%1, %0|%0, %1}";
18867
18868     case TYPE_ALU:
18869       if (GET_CODE (operands[2]) == CONST_INT
18870           /* Avoid overflows.  */
18871           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18872           && (INTVAL (operands[2]) == 128
18873               || (INTVAL (operands[2]) < 0
18874                   && INTVAL (operands[2]) != -128)))
18875         {
18876           operands[2] = GEN_INT (-INTVAL (operands[2]));
18877           return "sub{q}\t{%2, %0|%0, %2}";
18878         }
18879       return "add{q}\t{%2, %0|%0, %2}";
18880
18881     case TYPE_LEA:
18882       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18883       return "lea{q}\t{%a2, %0|%0, %a2}";
18884
18885     default:
18886       gcc_unreachable ();
18887     }
18888 }
18889   [(set (attr "type")
18890         (cond [(eq_attr "alternative" "0")
18891                  (const_string "alu")
18892                (match_operand:DI 2 "const0_operand" "")
18893                  (const_string "imov")
18894               ]
18895               (const_string "lea")))
18896    (set_attr "mode" "DI")])
18897
18898 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18899   [(set (match_operand:DI 0 "register_operand" "=r,r")
18900         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18901                  (match_operand:DI 3 "immediate_operand" "i,i")))
18902    (use (match_operand:DI 2 "register_operand" "r,r"))
18903    (clobber (reg:CC FLAGS_REG))
18904    (clobber (mem:BLK (scratch)))]
18905   "TARGET_64BIT"
18906 {
18907   switch (get_attr_type (insn))
18908     {
18909     case TYPE_ALU:
18910       return "add{q}\t{%2, %0|%0, %2}";
18911
18912     case TYPE_LEA:
18913       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18914       return "lea{q}\t{%a2, %0|%0, %a2}";
18915
18916     default:
18917       gcc_unreachable ();
18918     }
18919 }
18920   [(set_attr "type" "alu,lea")
18921    (set_attr "mode" "DI")])
18922
18923 (define_expand "allocate_stack_worker"
18924   [(match_operand:SI 0 "register_operand" "")]
18925   "TARGET_STACK_PROBE"
18926 {
18927   if (reload_completed)
18928     {
18929       if (TARGET_64BIT)
18930         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18931       else
18932         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18933     }
18934   else
18935     {
18936       if (TARGET_64BIT)
18937         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18938       else
18939         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18940     }
18941   DONE;
18942 })
18943
18944 (define_insn "allocate_stack_worker_1"
18945   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18946     UNSPECV_STACK_PROBE)
18947    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18948    (clobber (match_scratch:SI 1 "=0"))
18949    (clobber (reg:CC FLAGS_REG))]
18950   "!TARGET_64BIT && TARGET_STACK_PROBE"
18951   "call\t__alloca"
18952   [(set_attr "type" "multi")
18953    (set_attr "length" "5")])
18954
18955 (define_expand "allocate_stack_worker_postreload"
18956   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18957                                     UNSPECV_STACK_PROBE)
18958               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18959               (clobber (match_dup 0))
18960               (clobber (reg:CC FLAGS_REG))])]
18961   ""
18962   "")
18963
18964 (define_insn "allocate_stack_worker_rex64"
18965   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18966     UNSPECV_STACK_PROBE)
18967    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18968    (clobber (match_scratch:DI 1 "=0"))
18969    (clobber (reg:CC FLAGS_REG))]
18970   "TARGET_64BIT && TARGET_STACK_PROBE"
18971   "call\t__alloca"
18972   [(set_attr "type" "multi")
18973    (set_attr "length" "5")])
18974
18975 (define_expand "allocate_stack_worker_rex64_postreload"
18976   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18977                                     UNSPECV_STACK_PROBE)
18978               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18979               (clobber (match_dup 0))
18980               (clobber (reg:CC FLAGS_REG))])]
18981   ""
18982   "")
18983
18984 (define_expand "allocate_stack"
18985   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18986                    (minus:SI (reg:SI SP_REG)
18987                              (match_operand:SI 1 "general_operand" "")))
18988               (clobber (reg:CC FLAGS_REG))])
18989    (parallel [(set (reg:SI SP_REG)
18990                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18991               (clobber (reg:CC FLAGS_REG))])]
18992   "TARGET_STACK_PROBE"
18993 {
18994 #ifdef CHECK_STACK_LIMIT
18995   if (GET_CODE (operands[1]) == CONST_INT
18996       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18997     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18998                            operands[1]));
18999   else 
19000 #endif
19001     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19002                                                             operands[1])));
19003
19004   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19005   DONE;
19006 })
19007
19008 (define_expand "builtin_setjmp_receiver"
19009   [(label_ref (match_operand 0 "" ""))]
19010   "!TARGET_64BIT && flag_pic"
19011 {
19012   if (TARGET_MACHO)
19013     {
19014       rtx xops[3];
19015       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19016       rtx label_rtx = gen_label_rtx ();
19017       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19018       xops[0] = xops[1] = picreg;
19019       xops[2] = gen_rtx_CONST (SImode,
19020                   gen_rtx_MINUS (SImode,
19021                     gen_rtx_LABEL_REF (SImode, label_rtx),
19022                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19023       ix86_expand_binary_operator (MINUS, SImode, xops);
19024     }
19025   else
19026     emit_insn (gen_set_got (pic_offset_table_rtx));
19027   DONE;
19028 })
19029 \f
19030 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19031
19032 (define_split
19033   [(set (match_operand 0 "register_operand" "")
19034         (match_operator 3 "promotable_binary_operator"
19035            [(match_operand 1 "register_operand" "")
19036             (match_operand 2 "aligned_operand" "")]))
19037    (clobber (reg:CC FLAGS_REG))]
19038   "! TARGET_PARTIAL_REG_STALL && reload_completed
19039    && ((GET_MODE (operands[0]) == HImode 
19040         && ((!optimize_size && !TARGET_FAST_PREFIX)
19041             || GET_CODE (operands[2]) != CONST_INT
19042             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19043        || (GET_MODE (operands[0]) == QImode 
19044            && (TARGET_PROMOTE_QImode || optimize_size)))"
19045   [(parallel [(set (match_dup 0)
19046                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19047               (clobber (reg:CC FLAGS_REG))])]
19048   "operands[0] = gen_lowpart (SImode, operands[0]);
19049    operands[1] = gen_lowpart (SImode, operands[1]);
19050    if (GET_CODE (operands[3]) != ASHIFT)
19051      operands[2] = gen_lowpart (SImode, operands[2]);
19052    PUT_MODE (operands[3], SImode);")
19053
19054 ; Promote the QImode tests, as i386 has encoding of the AND
19055 ; instruction with 32-bit sign-extended immediate and thus the
19056 ; instruction size is unchanged, except in the %eax case for
19057 ; which it is increased by one byte, hence the ! optimize_size.
19058 (define_split
19059   [(set (match_operand 0 "flags_reg_operand" "")
19060         (match_operator 2 "compare_operator"
19061           [(and (match_operand 3 "aligned_operand" "")
19062                 (match_operand 4 "const_int_operand" ""))
19063            (const_int 0)]))
19064    (set (match_operand 1 "register_operand" "")
19065         (and (match_dup 3) (match_dup 4)))]
19066   "! TARGET_PARTIAL_REG_STALL && reload_completed
19067    /* Ensure that the operand will remain sign-extended immediate.  */
19068    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19069    && ! optimize_size
19070    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19071        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19072   [(parallel [(set (match_dup 0)
19073                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19074                                     (const_int 0)]))
19075               (set (match_dup 1)
19076                    (and:SI (match_dup 3) (match_dup 4)))])]
19077 {
19078   operands[4]
19079     = gen_int_mode (INTVAL (operands[4])
19080                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19081   operands[1] = gen_lowpart (SImode, operands[1]);
19082   operands[3] = gen_lowpart (SImode, operands[3]);
19083 })
19084
19085 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19086 ; the TEST instruction with 32-bit sign-extended immediate and thus
19087 ; the instruction size would at least double, which is not what we
19088 ; want even with ! optimize_size.
19089 (define_split
19090   [(set (match_operand 0 "flags_reg_operand" "")
19091         (match_operator 1 "compare_operator"
19092           [(and (match_operand:HI 2 "aligned_operand" "")
19093                 (match_operand:HI 3 "const_int_operand" ""))
19094            (const_int 0)]))]
19095   "! TARGET_PARTIAL_REG_STALL && reload_completed
19096    /* Ensure that the operand will remain sign-extended immediate.  */
19097    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19098    && ! TARGET_FAST_PREFIX
19099    && ! optimize_size"
19100   [(set (match_dup 0)
19101         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19102                          (const_int 0)]))]
19103 {
19104   operands[3]
19105     = gen_int_mode (INTVAL (operands[3])
19106                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19107   operands[2] = gen_lowpart (SImode, operands[2]);
19108 })
19109
19110 (define_split
19111   [(set (match_operand 0 "register_operand" "")
19112         (neg (match_operand 1 "register_operand" "")))
19113    (clobber (reg:CC FLAGS_REG))]
19114   "! TARGET_PARTIAL_REG_STALL && reload_completed
19115    && (GET_MODE (operands[0]) == HImode
19116        || (GET_MODE (operands[0]) == QImode 
19117            && (TARGET_PROMOTE_QImode || optimize_size)))"
19118   [(parallel [(set (match_dup 0)
19119                    (neg:SI (match_dup 1)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   "operands[0] = gen_lowpart (SImode, operands[0]);
19122    operands[1] = gen_lowpart (SImode, operands[1]);")
19123
19124 (define_split
19125   [(set (match_operand 0 "register_operand" "")
19126         (not (match_operand 1 "register_operand" "")))]
19127   "! TARGET_PARTIAL_REG_STALL && reload_completed
19128    && (GET_MODE (operands[0]) == HImode
19129        || (GET_MODE (operands[0]) == QImode 
19130            && (TARGET_PROMOTE_QImode || optimize_size)))"
19131   [(set (match_dup 0)
19132         (not:SI (match_dup 1)))]
19133   "operands[0] = gen_lowpart (SImode, operands[0]);
19134    operands[1] = gen_lowpart (SImode, operands[1]);")
19135
19136 (define_split 
19137   [(set (match_operand 0 "register_operand" "")
19138         (if_then_else (match_operator 1 "comparison_operator" 
19139                                 [(reg FLAGS_REG) (const_int 0)])
19140                       (match_operand 2 "register_operand" "")
19141                       (match_operand 3 "register_operand" "")))]
19142   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19143    && (GET_MODE (operands[0]) == HImode
19144        || (GET_MODE (operands[0]) == QImode 
19145            && (TARGET_PROMOTE_QImode || optimize_size)))"
19146   [(set (match_dup 0)
19147         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19148   "operands[0] = gen_lowpart (SImode, operands[0]);
19149    operands[2] = gen_lowpart (SImode, operands[2]);
19150    operands[3] = gen_lowpart (SImode, operands[3]);")
19151                         
19152 \f
19153 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19154 ;; transform a complex memory operation into two memory to register operations.
19155
19156 ;; Don't push memory operands
19157 (define_peephole2
19158   [(set (match_operand:SI 0 "push_operand" "")
19159         (match_operand:SI 1 "memory_operand" ""))
19160    (match_scratch:SI 2 "r")]
19161   "!optimize_size && !TARGET_PUSH_MEMORY
19162    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19163   [(set (match_dup 2) (match_dup 1))
19164    (set (match_dup 0) (match_dup 2))]
19165   "")
19166
19167 (define_peephole2
19168   [(set (match_operand:DI 0 "push_operand" "")
19169         (match_operand:DI 1 "memory_operand" ""))
19170    (match_scratch:DI 2 "r")]
19171   "!optimize_size && !TARGET_PUSH_MEMORY
19172    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19173   [(set (match_dup 2) (match_dup 1))
19174    (set (match_dup 0) (match_dup 2))]
19175   "")
19176
19177 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19178 ;; SImode pushes.
19179 (define_peephole2
19180   [(set (match_operand:SF 0 "push_operand" "")
19181         (match_operand:SF 1 "memory_operand" ""))
19182    (match_scratch:SF 2 "r")]
19183   "!optimize_size && !TARGET_PUSH_MEMORY
19184    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19185   [(set (match_dup 2) (match_dup 1))
19186    (set (match_dup 0) (match_dup 2))]
19187   "")
19188
19189 (define_peephole2
19190   [(set (match_operand:HI 0 "push_operand" "")
19191         (match_operand:HI 1 "memory_operand" ""))
19192    (match_scratch:HI 2 "r")]
19193   "!optimize_size && !TARGET_PUSH_MEMORY
19194    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19195   [(set (match_dup 2) (match_dup 1))
19196    (set (match_dup 0) (match_dup 2))]
19197   "")
19198
19199 (define_peephole2
19200   [(set (match_operand:QI 0 "push_operand" "")
19201         (match_operand:QI 1 "memory_operand" ""))
19202    (match_scratch:QI 2 "q")]
19203   "!optimize_size && !TARGET_PUSH_MEMORY
19204    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19205   [(set (match_dup 2) (match_dup 1))
19206    (set (match_dup 0) (match_dup 2))]
19207   "")
19208
19209 ;; Don't move an immediate directly to memory when the instruction
19210 ;; gets too big.
19211 (define_peephole2
19212   [(match_scratch:SI 1 "r")
19213    (set (match_operand:SI 0 "memory_operand" "")
19214         (const_int 0))]
19215   "! optimize_size
19216    && ! TARGET_USE_MOV0
19217    && TARGET_SPLIT_LONG_MOVES
19218    && get_attr_length (insn) >= ix86_cost->large_insn
19219    && peep2_regno_dead_p (0, FLAGS_REG)"
19220   [(parallel [(set (match_dup 1) (const_int 0))
19221               (clobber (reg:CC FLAGS_REG))])
19222    (set (match_dup 0) (match_dup 1))]
19223   "")
19224
19225 (define_peephole2
19226   [(match_scratch:HI 1 "r")
19227    (set (match_operand:HI 0 "memory_operand" "")
19228         (const_int 0))]
19229   "! optimize_size
19230    && ! TARGET_USE_MOV0
19231    && TARGET_SPLIT_LONG_MOVES
19232    && get_attr_length (insn) >= ix86_cost->large_insn
19233    && peep2_regno_dead_p (0, FLAGS_REG)"
19234   [(parallel [(set (match_dup 2) (const_int 0))
19235               (clobber (reg:CC FLAGS_REG))])
19236    (set (match_dup 0) (match_dup 1))]
19237   "operands[2] = gen_lowpart (SImode, operands[1]);")
19238
19239 (define_peephole2
19240   [(match_scratch:QI 1 "q")
19241    (set (match_operand:QI 0 "memory_operand" "")
19242         (const_int 0))]
19243   "! optimize_size
19244    && ! TARGET_USE_MOV0
19245    && TARGET_SPLIT_LONG_MOVES
19246    && get_attr_length (insn) >= ix86_cost->large_insn
19247    && peep2_regno_dead_p (0, FLAGS_REG)"
19248   [(parallel [(set (match_dup 2) (const_int 0))
19249               (clobber (reg:CC FLAGS_REG))])
19250    (set (match_dup 0) (match_dup 1))]
19251   "operands[2] = gen_lowpart (SImode, operands[1]);")
19252
19253 (define_peephole2
19254   [(match_scratch:SI 2 "r")
19255    (set (match_operand:SI 0 "memory_operand" "")
19256         (match_operand:SI 1 "immediate_operand" ""))]
19257   "! optimize_size
19258    && get_attr_length (insn) >= ix86_cost->large_insn
19259    && TARGET_SPLIT_LONG_MOVES"
19260   [(set (match_dup 2) (match_dup 1))
19261    (set (match_dup 0) (match_dup 2))]
19262   "")
19263
19264 (define_peephole2
19265   [(match_scratch:HI 2 "r")
19266    (set (match_operand:HI 0 "memory_operand" "")
19267         (match_operand:HI 1 "immediate_operand" ""))]
19268   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19269   && TARGET_SPLIT_LONG_MOVES"
19270   [(set (match_dup 2) (match_dup 1))
19271    (set (match_dup 0) (match_dup 2))]
19272   "")
19273
19274 (define_peephole2
19275   [(match_scratch:QI 2 "q")
19276    (set (match_operand:QI 0 "memory_operand" "")
19277         (match_operand:QI 1 "immediate_operand" ""))]
19278   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19279   && TARGET_SPLIT_LONG_MOVES"
19280   [(set (match_dup 2) (match_dup 1))
19281    (set (match_dup 0) (match_dup 2))]
19282   "")
19283
19284 ;; Don't compare memory with zero, load and use a test instead.
19285 (define_peephole2
19286   [(set (match_operand 0 "flags_reg_operand" "")
19287         (match_operator 1 "compare_operator"
19288           [(match_operand:SI 2 "memory_operand" "")
19289            (const_int 0)]))
19290    (match_scratch:SI 3 "r")]
19291   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19292   [(set (match_dup 3) (match_dup 2))
19293    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19294   "")
19295
19296 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19297 ;; Don't split NOTs with a displacement operand, because resulting XOR
19298 ;; will not be pairable anyway.
19299 ;;
19300 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19301 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19302 ;; so this split helps here as well.
19303 ;;
19304 ;; Note: Can't do this as a regular split because we can't get proper
19305 ;; lifetime information then.
19306
19307 (define_peephole2
19308   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19309         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19310   "!optimize_size
19311    && peep2_regno_dead_p (0, FLAGS_REG)
19312    && ((TARGET_PENTIUM 
19313         && (GET_CODE (operands[0]) != MEM
19314             || !memory_displacement_operand (operands[0], SImode)))
19315        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19316   [(parallel [(set (match_dup 0)
19317                    (xor:SI (match_dup 1) (const_int -1)))
19318               (clobber (reg:CC FLAGS_REG))])]
19319   "")
19320
19321 (define_peephole2
19322   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19323         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19324   "!optimize_size
19325    && peep2_regno_dead_p (0, FLAGS_REG)
19326    && ((TARGET_PENTIUM 
19327         && (GET_CODE (operands[0]) != MEM
19328             || !memory_displacement_operand (operands[0], HImode)))
19329        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19330   [(parallel [(set (match_dup 0)
19331                    (xor:HI (match_dup 1) (const_int -1)))
19332               (clobber (reg:CC FLAGS_REG))])]
19333   "")
19334
19335 (define_peephole2
19336   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19337         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19338   "!optimize_size
19339    && peep2_regno_dead_p (0, FLAGS_REG)
19340    && ((TARGET_PENTIUM 
19341         && (GET_CODE (operands[0]) != MEM
19342             || !memory_displacement_operand (operands[0], QImode)))
19343        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19344   [(parallel [(set (match_dup 0)
19345                    (xor:QI (match_dup 1) (const_int -1)))
19346               (clobber (reg:CC FLAGS_REG))])]
19347   "")
19348
19349 ;; Non pairable "test imm, reg" instructions can be translated to
19350 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19351 ;; byte opcode instead of two, have a short form for byte operands),
19352 ;; so do it for other CPUs as well.  Given that the value was dead,
19353 ;; this should not create any new dependencies.  Pass on the sub-word
19354 ;; versions if we're concerned about partial register stalls.
19355
19356 (define_peephole2
19357   [(set (match_operand 0 "flags_reg_operand" "")
19358         (match_operator 1 "compare_operator"
19359           [(and:SI (match_operand:SI 2 "register_operand" "")
19360                    (match_operand:SI 3 "immediate_operand" ""))
19361            (const_int 0)]))]
19362   "ix86_match_ccmode (insn, CCNOmode)
19363    && (true_regnum (operands[2]) != 0
19364        || (GET_CODE (operands[3]) == CONST_INT
19365            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19366    && peep2_reg_dead_p (1, operands[2])"
19367   [(parallel
19368      [(set (match_dup 0)
19369            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19370                             (const_int 0)]))
19371       (set (match_dup 2)
19372            (and:SI (match_dup 2) (match_dup 3)))])]
19373   "")
19374
19375 ;; We don't need to handle HImode case, because it will be promoted to SImode
19376 ;; on ! TARGET_PARTIAL_REG_STALL
19377
19378 (define_peephole2
19379   [(set (match_operand 0 "flags_reg_operand" "")
19380         (match_operator 1 "compare_operator"
19381           [(and:QI (match_operand:QI 2 "register_operand" "")
19382                    (match_operand:QI 3 "immediate_operand" ""))
19383            (const_int 0)]))]
19384   "! TARGET_PARTIAL_REG_STALL
19385    && ix86_match_ccmode (insn, CCNOmode)
19386    && true_regnum (operands[2]) != 0
19387    && peep2_reg_dead_p (1, operands[2])"
19388   [(parallel
19389      [(set (match_dup 0)
19390            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19391                             (const_int 0)]))
19392       (set (match_dup 2)
19393            (and:QI (match_dup 2) (match_dup 3)))])]
19394   "")
19395
19396 (define_peephole2
19397   [(set (match_operand 0 "flags_reg_operand" "")
19398         (match_operator 1 "compare_operator"
19399           [(and:SI
19400              (zero_extract:SI
19401                (match_operand 2 "ext_register_operand" "")
19402                (const_int 8)
19403                (const_int 8))
19404              (match_operand 3 "const_int_operand" ""))
19405            (const_int 0)]))]
19406   "! TARGET_PARTIAL_REG_STALL
19407    && ix86_match_ccmode (insn, CCNOmode)
19408    && true_regnum (operands[2]) != 0
19409    && peep2_reg_dead_p (1, operands[2])"
19410   [(parallel [(set (match_dup 0)
19411                    (match_op_dup 1
19412                      [(and:SI
19413                         (zero_extract:SI
19414                           (match_dup 2)
19415                           (const_int 8)
19416                           (const_int 8))
19417                         (match_dup 3))
19418                       (const_int 0)]))
19419               (set (zero_extract:SI (match_dup 2)
19420                                     (const_int 8)
19421                                     (const_int 8))
19422                    (and:SI 
19423                      (zero_extract:SI
19424                        (match_dup 2)
19425                        (const_int 8)
19426                        (const_int 8))
19427                      (match_dup 3)))])]
19428   "")
19429
19430 ;; Don't do logical operations with memory inputs.
19431 (define_peephole2
19432   [(match_scratch:SI 2 "r")
19433    (parallel [(set (match_operand:SI 0 "register_operand" "")
19434                    (match_operator:SI 3 "arith_or_logical_operator"
19435                      [(match_dup 0)
19436                       (match_operand:SI 1 "memory_operand" "")]))
19437               (clobber (reg:CC FLAGS_REG))])]
19438   "! optimize_size && ! TARGET_READ_MODIFY"
19439   [(set (match_dup 2) (match_dup 1))
19440    (parallel [(set (match_dup 0)
19441                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19442               (clobber (reg:CC FLAGS_REG))])]
19443   "")
19444
19445 (define_peephole2
19446   [(match_scratch:SI 2 "r")
19447    (parallel [(set (match_operand:SI 0 "register_operand" "")
19448                    (match_operator:SI 3 "arith_or_logical_operator"
19449                      [(match_operand:SI 1 "memory_operand" "")
19450                       (match_dup 0)]))
19451               (clobber (reg:CC FLAGS_REG))])]
19452   "! optimize_size && ! TARGET_READ_MODIFY"
19453   [(set (match_dup 2) (match_dup 1))
19454    (parallel [(set (match_dup 0)
19455                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19456               (clobber (reg:CC FLAGS_REG))])]
19457   "")
19458
19459 ; Don't do logical operations with memory outputs
19460 ;
19461 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19462 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19463 ; the same decoder scheduling characteristics as the original.
19464
19465 (define_peephole2
19466   [(match_scratch:SI 2 "r")
19467    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19468                    (match_operator:SI 3 "arith_or_logical_operator"
19469                      [(match_dup 0)
19470                       (match_operand:SI 1 "nonmemory_operand" "")]))
19471               (clobber (reg:CC FLAGS_REG))])]
19472   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19473   [(set (match_dup 2) (match_dup 0))
19474    (parallel [(set (match_dup 2)
19475                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19476               (clobber (reg:CC FLAGS_REG))])
19477    (set (match_dup 0) (match_dup 2))]
19478   "")
19479
19480 (define_peephole2
19481   [(match_scratch:SI 2 "r")
19482    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19483                    (match_operator:SI 3 "arith_or_logical_operator"
19484                      [(match_operand:SI 1 "nonmemory_operand" "")
19485                       (match_dup 0)]))
19486               (clobber (reg:CC FLAGS_REG))])]
19487   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19488   [(set (match_dup 2) (match_dup 0))
19489    (parallel [(set (match_dup 2)
19490                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19491               (clobber (reg:CC FLAGS_REG))])
19492    (set (match_dup 0) (match_dup 2))]
19493   "")
19494
19495 ;; Attempt to always use XOR for zeroing registers.
19496 (define_peephole2
19497   [(set (match_operand 0 "register_operand" "")
19498         (match_operand 1 "const0_operand" ""))]
19499   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19500    && (! TARGET_USE_MOV0 || optimize_size)
19501    && GENERAL_REG_P (operands[0])
19502    && peep2_regno_dead_p (0, FLAGS_REG)"
19503   [(parallel [(set (match_dup 0) (const_int 0))
19504               (clobber (reg:CC FLAGS_REG))])]
19505 {
19506   operands[0] = gen_lowpart (word_mode, operands[0]);
19507 })
19508
19509 (define_peephole2
19510   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19511         (const_int 0))]
19512   "(GET_MODE (operands[0]) == QImode
19513     || GET_MODE (operands[0]) == HImode)
19514    && (! TARGET_USE_MOV0 || optimize_size)
19515    && peep2_regno_dead_p (0, FLAGS_REG)"
19516   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19517               (clobber (reg:CC FLAGS_REG))])])
19518
19519 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19520 (define_peephole2
19521   [(set (match_operand 0 "register_operand" "")
19522         (const_int -1))]
19523   "(GET_MODE (operands[0]) == HImode
19524     || GET_MODE (operands[0]) == SImode 
19525     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19526    && (optimize_size || TARGET_PENTIUM)
19527    && peep2_regno_dead_p (0, FLAGS_REG)"
19528   [(parallel [(set (match_dup 0) (const_int -1))
19529               (clobber (reg:CC FLAGS_REG))])]
19530   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19531                               operands[0]);")
19532
19533 ;; Attempt to convert simple leas to adds. These can be created by
19534 ;; move expanders.
19535 (define_peephole2
19536   [(set (match_operand:SI 0 "register_operand" "")
19537         (plus:SI (match_dup 0)
19538                  (match_operand:SI 1 "nonmemory_operand" "")))]
19539   "peep2_regno_dead_p (0, FLAGS_REG)"
19540   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19541               (clobber (reg:CC FLAGS_REG))])]
19542   "")
19543
19544 (define_peephole2
19545   [(set (match_operand:SI 0 "register_operand" "")
19546         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19547                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19548   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19549   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19550               (clobber (reg:CC FLAGS_REG))])]
19551   "operands[2] = gen_lowpart (SImode, operands[2]);")
19552
19553 (define_peephole2
19554   [(set (match_operand:DI 0 "register_operand" "")
19555         (plus:DI (match_dup 0)
19556                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19557   "peep2_regno_dead_p (0, FLAGS_REG)"
19558   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19559               (clobber (reg:CC FLAGS_REG))])]
19560   "")
19561
19562 (define_peephole2
19563   [(set (match_operand:SI 0 "register_operand" "")
19564         (mult:SI (match_dup 0)
19565                  (match_operand:SI 1 "const_int_operand" "")))]
19566   "exact_log2 (INTVAL (operands[1])) >= 0
19567    && peep2_regno_dead_p (0, FLAGS_REG)"
19568   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19569               (clobber (reg:CC FLAGS_REG))])]
19570   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19571
19572 (define_peephole2
19573   [(set (match_operand:DI 0 "register_operand" "")
19574         (mult:DI (match_dup 0)
19575                  (match_operand:DI 1 "const_int_operand" "")))]
19576   "exact_log2 (INTVAL (operands[1])) >= 0
19577    && peep2_regno_dead_p (0, FLAGS_REG)"
19578   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19579               (clobber (reg:CC FLAGS_REG))])]
19580   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19581
19582 (define_peephole2
19583   [(set (match_operand:SI 0 "register_operand" "")
19584         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19585                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19586   "exact_log2 (INTVAL (operands[2])) >= 0
19587    && REGNO (operands[0]) == REGNO (operands[1])
19588    && peep2_regno_dead_p (0, FLAGS_REG)"
19589   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19590               (clobber (reg:CC FLAGS_REG))])]
19591   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19592
19593 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19594 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19595 ;; many CPUs it is also faster, since special hardware to avoid esp
19596 ;; dependencies is present.
19597
19598 ;; While some of these conversions may be done using splitters, we use peepholes
19599 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19600
19601 ;; Convert prologue esp subtractions to push.
19602 ;; We need register to push.  In order to keep verify_flow_info happy we have
19603 ;; two choices
19604 ;; - use scratch and clobber it in order to avoid dependencies
19605 ;; - use already live register
19606 ;; We can't use the second way right now, since there is no reliable way how to
19607 ;; verify that given register is live.  First choice will also most likely in
19608 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19609 ;; call clobbered registers are dead.  We may want to use base pointer as an
19610 ;; alternative when no register is available later.
19611
19612 (define_peephole2
19613   [(match_scratch:SI 0 "r")
19614    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19615               (clobber (reg:CC FLAGS_REG))
19616               (clobber (mem:BLK (scratch)))])]
19617   "optimize_size || !TARGET_SUB_ESP_4"
19618   [(clobber (match_dup 0))
19619    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19620               (clobber (mem:BLK (scratch)))])])
19621
19622 (define_peephole2
19623   [(match_scratch:SI 0 "r")
19624    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19625               (clobber (reg:CC FLAGS_REG))
19626               (clobber (mem:BLK (scratch)))])]
19627   "optimize_size || !TARGET_SUB_ESP_8"
19628   [(clobber (match_dup 0))
19629    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19630    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631               (clobber (mem:BLK (scratch)))])])
19632
19633 ;; Convert esp subtractions to push.
19634 (define_peephole2
19635   [(match_scratch:SI 0 "r")
19636    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19637               (clobber (reg:CC FLAGS_REG))])]
19638   "optimize_size || !TARGET_SUB_ESP_4"
19639   [(clobber (match_dup 0))
19640    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19641
19642 (define_peephole2
19643   [(match_scratch:SI 0 "r")
19644    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19645               (clobber (reg:CC FLAGS_REG))])]
19646   "optimize_size || !TARGET_SUB_ESP_8"
19647   [(clobber (match_dup 0))
19648    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19649    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19650
19651 ;; Convert epilogue deallocator to pop.
19652 (define_peephole2
19653   [(match_scratch:SI 0 "r")
19654    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19655               (clobber (reg:CC FLAGS_REG))
19656               (clobber (mem:BLK (scratch)))])]
19657   "optimize_size || !TARGET_ADD_ESP_4"
19658   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19659               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19660               (clobber (mem:BLK (scratch)))])]
19661   "")
19662
19663 ;; Two pops case is tricky, since pop causes dependency on destination register.
19664 ;; We use two registers if available.
19665 (define_peephole2
19666   [(match_scratch:SI 0 "r")
19667    (match_scratch:SI 1 "r")
19668    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19669               (clobber (reg:CC FLAGS_REG))
19670               (clobber (mem:BLK (scratch)))])]
19671   "optimize_size || !TARGET_ADD_ESP_8"
19672   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19673               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19674               (clobber (mem:BLK (scratch)))])
19675    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19676               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19677   "")
19678
19679 (define_peephole2
19680   [(match_scratch:SI 0 "r")
19681    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19682               (clobber (reg:CC FLAGS_REG))
19683               (clobber (mem:BLK (scratch)))])]
19684   "optimize_size"
19685   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19686               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19687               (clobber (mem:BLK (scratch)))])
19688    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19689               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19690   "")
19691
19692 ;; Convert esp additions to pop.
19693 (define_peephole2
19694   [(match_scratch:SI 0 "r")
19695    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19696               (clobber (reg:CC FLAGS_REG))])]
19697   ""
19698   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19699               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19700   "")
19701
19702 ;; Two pops case is tricky, since pop causes dependency on destination register.
19703 ;; We use two registers if available.
19704 (define_peephole2
19705   [(match_scratch:SI 0 "r")
19706    (match_scratch:SI 1 "r")
19707    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19708               (clobber (reg:CC FLAGS_REG))])]
19709   ""
19710   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19711               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19712    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19713               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19714   "")
19715
19716 (define_peephole2
19717   [(match_scratch:SI 0 "r")
19718    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19719               (clobber (reg:CC FLAGS_REG))])]
19720   "optimize_size"
19721   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19722               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19723    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19724               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19725   "")
19726 \f
19727 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19728 ;; required and register dies.  Similarly for 128 to plus -128.
19729 (define_peephole2
19730   [(set (match_operand 0 "flags_reg_operand" "")
19731         (match_operator 1 "compare_operator"
19732           [(match_operand 2 "register_operand" "")
19733            (match_operand 3 "const_int_operand" "")]))]
19734   "(INTVAL (operands[3]) == -1
19735     || INTVAL (operands[3]) == 1
19736     || INTVAL (operands[3]) == 128)
19737    && ix86_match_ccmode (insn, CCGCmode)
19738    && peep2_reg_dead_p (1, operands[2])"
19739   [(parallel [(set (match_dup 0)
19740                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19741               (clobber (match_dup 2))])]
19742   "")
19743 \f
19744 (define_peephole2
19745   [(match_scratch:DI 0 "r")
19746    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19747               (clobber (reg:CC FLAGS_REG))
19748               (clobber (mem:BLK (scratch)))])]
19749   "optimize_size || !TARGET_SUB_ESP_4"
19750   [(clobber (match_dup 0))
19751    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19752               (clobber (mem:BLK (scratch)))])])
19753
19754 (define_peephole2
19755   [(match_scratch:DI 0 "r")
19756    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19757               (clobber (reg:CC FLAGS_REG))
19758               (clobber (mem:BLK (scratch)))])]
19759   "optimize_size || !TARGET_SUB_ESP_8"
19760   [(clobber (match_dup 0))
19761    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19762    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763               (clobber (mem:BLK (scratch)))])])
19764
19765 ;; Convert esp subtractions to push.
19766 (define_peephole2
19767   [(match_scratch:DI 0 "r")
19768    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19769               (clobber (reg:CC FLAGS_REG))])]
19770   "optimize_size || !TARGET_SUB_ESP_4"
19771   [(clobber (match_dup 0))
19772    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19773
19774 (define_peephole2
19775   [(match_scratch:DI 0 "r")
19776    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "optimize_size || !TARGET_SUB_ESP_8"
19779   [(clobber (match_dup 0))
19780    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19781    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19782
19783 ;; Convert epilogue deallocator to pop.
19784 (define_peephole2
19785   [(match_scratch:DI 0 "r")
19786    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19787               (clobber (reg:CC FLAGS_REG))
19788               (clobber (mem:BLK (scratch)))])]
19789   "optimize_size || !TARGET_ADD_ESP_4"
19790   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19791               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19792               (clobber (mem:BLK (scratch)))])]
19793   "")
19794
19795 ;; Two pops case is tricky, since pop causes dependency on destination register.
19796 ;; We use two registers if available.
19797 (define_peephole2
19798   [(match_scratch:DI 0 "r")
19799    (match_scratch:DI 1 "r")
19800    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19801               (clobber (reg:CC FLAGS_REG))
19802               (clobber (mem:BLK (scratch)))])]
19803   "optimize_size || !TARGET_ADD_ESP_8"
19804   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19805               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19806               (clobber (mem:BLK (scratch)))])
19807    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19808               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19809   "")
19810
19811 (define_peephole2
19812   [(match_scratch:DI 0 "r")
19813    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19814               (clobber (reg:CC FLAGS_REG))
19815               (clobber (mem:BLK (scratch)))])]
19816   "optimize_size"
19817   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19818               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19819               (clobber (mem:BLK (scratch)))])
19820    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19821               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19822   "")
19823
19824 ;; Convert esp additions to pop.
19825 (define_peephole2
19826   [(match_scratch:DI 0 "r")
19827    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19828               (clobber (reg:CC FLAGS_REG))])]
19829   ""
19830   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19831               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19832   "")
19833
19834 ;; Two pops case is tricky, since pop causes dependency on destination register.
19835 ;; We use two registers if available.
19836 (define_peephole2
19837   [(match_scratch:DI 0 "r")
19838    (match_scratch:DI 1 "r")
19839    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19840               (clobber (reg:CC FLAGS_REG))])]
19841   ""
19842   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19843               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19844    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19845               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19846   "")
19847
19848 (define_peephole2
19849   [(match_scratch:DI 0 "r")
19850    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19851               (clobber (reg:CC FLAGS_REG))])]
19852   "optimize_size"
19853   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19854               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19855    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19856               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19857   "")
19858 \f
19859 ;; Convert imul by three, five and nine into lea
19860 (define_peephole2
19861   [(parallel
19862     [(set (match_operand:SI 0 "register_operand" "")
19863           (mult:SI (match_operand:SI 1 "register_operand" "")
19864                    (match_operand:SI 2 "const_int_operand" "")))
19865      (clobber (reg:CC FLAGS_REG))])]
19866   "INTVAL (operands[2]) == 3
19867    || INTVAL (operands[2]) == 5
19868    || INTVAL (operands[2]) == 9"
19869   [(set (match_dup 0)
19870         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19871                  (match_dup 1)))]
19872   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19873
19874 (define_peephole2
19875   [(parallel
19876     [(set (match_operand:SI 0 "register_operand" "")
19877           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19878                    (match_operand:SI 2 "const_int_operand" "")))
19879      (clobber (reg:CC FLAGS_REG))])]
19880   "!optimize_size 
19881    && (INTVAL (operands[2]) == 3
19882        || INTVAL (operands[2]) == 5
19883        || INTVAL (operands[2]) == 9)"
19884   [(set (match_dup 0) (match_dup 1))
19885    (set (match_dup 0)
19886         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19887                  (match_dup 0)))]
19888   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19889
19890 (define_peephole2
19891   [(parallel
19892     [(set (match_operand:DI 0 "register_operand" "")
19893           (mult:DI (match_operand:DI 1 "register_operand" "")
19894                    (match_operand:DI 2 "const_int_operand" "")))
19895      (clobber (reg:CC FLAGS_REG))])]
19896   "TARGET_64BIT
19897    && (INTVAL (operands[2]) == 3
19898        || INTVAL (operands[2]) == 5
19899        || INTVAL (operands[2]) == 9)"
19900   [(set (match_dup 0)
19901         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19902                  (match_dup 1)))]
19903   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19904
19905 (define_peephole2
19906   [(parallel
19907     [(set (match_operand:DI 0 "register_operand" "")
19908           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19909                    (match_operand:DI 2 "const_int_operand" "")))
19910      (clobber (reg:CC FLAGS_REG))])]
19911   "TARGET_64BIT
19912    && !optimize_size 
19913    && (INTVAL (operands[2]) == 3
19914        || INTVAL (operands[2]) == 5
19915        || INTVAL (operands[2]) == 9)"
19916   [(set (match_dup 0) (match_dup 1))
19917    (set (match_dup 0)
19918         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19919                  (match_dup 0)))]
19920   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19921
19922 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19923 ;; imul $32bit_imm, reg, reg is direct decoded.
19924 (define_peephole2
19925   [(match_scratch:DI 3 "r")
19926    (parallel [(set (match_operand:DI 0 "register_operand" "")
19927                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19928                             (match_operand:DI 2 "immediate_operand" "")))
19929               (clobber (reg:CC FLAGS_REG))])]
19930   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19931    && (GET_CODE (operands[2]) != CONST_INT
19932        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19933   [(set (match_dup 3) (match_dup 1))
19934    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19935               (clobber (reg:CC FLAGS_REG))])]
19936 "")
19937
19938 (define_peephole2
19939   [(match_scratch:SI 3 "r")
19940    (parallel [(set (match_operand:SI 0 "register_operand" "")
19941                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19942                             (match_operand:SI 2 "immediate_operand" "")))
19943               (clobber (reg:CC FLAGS_REG))])]
19944   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19945    && (GET_CODE (operands[2]) != CONST_INT
19946        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19947   [(set (match_dup 3) (match_dup 1))
19948    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19949               (clobber (reg:CC FLAGS_REG))])]
19950 "")
19951
19952 (define_peephole2
19953   [(match_scratch:SI 3 "r")
19954    (parallel [(set (match_operand:DI 0 "register_operand" "")
19955                    (zero_extend:DI
19956                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19957                               (match_operand:SI 2 "immediate_operand" ""))))
19958               (clobber (reg:CC FLAGS_REG))])]
19959   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19960    && (GET_CODE (operands[2]) != CONST_INT
19961        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19962   [(set (match_dup 3) (match_dup 1))
19963    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19964               (clobber (reg:CC FLAGS_REG))])]
19965 "")
19966
19967 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19968 ;; Convert it into imul reg, reg
19969 ;; It would be better to force assembler to encode instruction using long
19970 ;; immediate, but there is apparently no way to do so.
19971 (define_peephole2
19972   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19973                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19974                             (match_operand:DI 2 "const_int_operand" "")))
19975               (clobber (reg:CC FLAGS_REG))])
19976    (match_scratch:DI 3 "r")]
19977   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19978    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19979   [(set (match_dup 3) (match_dup 2))
19980    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19981               (clobber (reg:CC FLAGS_REG))])]
19982 {
19983   if (!rtx_equal_p (operands[0], operands[1]))
19984     emit_move_insn (operands[0], operands[1]);
19985 })
19986
19987 (define_peephole2
19988   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19989                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19990                             (match_operand:SI 2 "const_int_operand" "")))
19991               (clobber (reg:CC FLAGS_REG))])
19992    (match_scratch:SI 3 "r")]
19993   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19994    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19995   [(set (match_dup 3) (match_dup 2))
19996    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19997               (clobber (reg:CC FLAGS_REG))])]
19998 {
19999   if (!rtx_equal_p (operands[0], operands[1]))
20000     emit_move_insn (operands[0], operands[1]);
20001 })
20002
20003 (define_peephole2
20004   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20005                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20006                             (match_operand:HI 2 "immediate_operand" "")))
20007               (clobber (reg:CC FLAGS_REG))])
20008    (match_scratch:HI 3 "r")]
20009   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20010   [(set (match_dup 3) (match_dup 2))
20011    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20012               (clobber (reg:CC FLAGS_REG))])]
20013 {
20014   if (!rtx_equal_p (operands[0], operands[1]))
20015     emit_move_insn (operands[0], operands[1]);
20016 })
20017
20018 ;; After splitting up read-modify operations, array accesses with memory
20019 ;; operands might end up in form:
20020 ;;  sall    $2, %eax
20021 ;;  movl    4(%esp), %edx
20022 ;;  addl    %edx, %eax
20023 ;; instead of pre-splitting:
20024 ;;  sall    $2, %eax
20025 ;;  addl    4(%esp), %eax
20026 ;; Turn it into:
20027 ;;  movl    4(%esp), %edx
20028 ;;  leal    (%edx,%eax,4), %eax
20029
20030 (define_peephole2
20031   [(parallel [(set (match_operand 0 "register_operand" "")
20032                    (ashift (match_operand 1 "register_operand" "")
20033                            (match_operand 2 "const_int_operand" "")))
20034                (clobber (reg:CC FLAGS_REG))])
20035    (set (match_operand 3 "register_operand")
20036         (match_operand 4 "x86_64_general_operand" ""))
20037    (parallel [(set (match_operand 5 "register_operand" "")
20038                    (plus (match_operand 6 "register_operand" "")
20039                          (match_operand 7 "register_operand" "")))
20040                    (clobber (reg:CC FLAGS_REG))])]
20041   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20042    /* Validate MODE for lea.  */
20043    && ((!TARGET_PARTIAL_REG_STALL
20044         && (GET_MODE (operands[0]) == QImode
20045             || GET_MODE (operands[0]) == HImode))
20046        || GET_MODE (operands[0]) == SImode 
20047        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20048    /* We reorder load and the shift.  */
20049    && !rtx_equal_p (operands[1], operands[3])
20050    && !reg_overlap_mentioned_p (operands[0], operands[4])
20051    /* Last PLUS must consist of operand 0 and 3.  */
20052    && !rtx_equal_p (operands[0], operands[3])
20053    && (rtx_equal_p (operands[3], operands[6])
20054        || rtx_equal_p (operands[3], operands[7]))
20055    && (rtx_equal_p (operands[0], operands[6])
20056        || rtx_equal_p (operands[0], operands[7]))
20057    /* The intermediate operand 0 must die or be same as output.  */
20058    && (rtx_equal_p (operands[0], operands[5])
20059        || peep2_reg_dead_p (3, operands[0]))"
20060   [(set (match_dup 3) (match_dup 4))
20061    (set (match_dup 0) (match_dup 1))]
20062 {
20063   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20064   int scale = 1 << INTVAL (operands[2]);
20065   rtx index = gen_lowpart (Pmode, operands[1]);
20066   rtx base = gen_lowpart (Pmode, operands[3]);
20067   rtx dest = gen_lowpart (mode, operands[5]);
20068
20069   operands[1] = gen_rtx_PLUS (Pmode, base,
20070                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20071   if (mode != Pmode)
20072     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20073   operands[0] = dest;
20074 })
20075 \f
20076 ;; Call-value patterns last so that the wildcard operand does not
20077 ;; disrupt insn-recog's switch tables.
20078
20079 (define_insn "*call_value_pop_0"
20080   [(set (match_operand 0 "" "")
20081         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20082               (match_operand:SI 2 "" "")))
20083    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20084                             (match_operand:SI 3 "immediate_operand" "")))]
20085   "!TARGET_64BIT"
20086 {
20087   if (SIBLING_CALL_P (insn))
20088     return "jmp\t%P1";
20089   else
20090     return "call\t%P1";
20091 }
20092   [(set_attr "type" "callv")])
20093
20094 (define_insn "*call_value_pop_1"
20095   [(set (match_operand 0 "" "")
20096         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20097               (match_operand:SI 2 "" "")))
20098    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20099                             (match_operand:SI 3 "immediate_operand" "i")))]
20100   "!TARGET_64BIT"
20101 {
20102   if (constant_call_address_operand (operands[1], Pmode))
20103     {
20104       if (SIBLING_CALL_P (insn))
20105         return "jmp\t%P1";
20106       else
20107         return "call\t%P1";
20108     }
20109   if (SIBLING_CALL_P (insn))
20110     return "jmp\t%A1";
20111   else
20112     return "call\t%A1";
20113 }
20114   [(set_attr "type" "callv")])
20115
20116 (define_insn "*call_value_0"
20117   [(set (match_operand 0 "" "")
20118         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20119               (match_operand:SI 2 "" "")))]
20120   "!TARGET_64BIT"
20121 {
20122   if (SIBLING_CALL_P (insn))
20123     return "jmp\t%P1";
20124   else
20125     return "call\t%P1";
20126 }
20127   [(set_attr "type" "callv")])
20128
20129 (define_insn "*call_value_0_rex64"
20130   [(set (match_operand 0 "" "")
20131         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20132               (match_operand:DI 2 "const_int_operand" "")))]
20133   "TARGET_64BIT"
20134 {
20135   if (SIBLING_CALL_P (insn))
20136     return "jmp\t%P1";
20137   else
20138     return "call\t%P1";
20139 }
20140   [(set_attr "type" "callv")])
20141
20142 (define_insn "*call_value_1"
20143   [(set (match_operand 0 "" "")
20144         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20145               (match_operand:SI 2 "" "")))]
20146   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20147 {
20148   if (constant_call_address_operand (operands[1], Pmode))
20149     return "call\t%P1";
20150   return "call\t%A1";
20151 }
20152   [(set_attr "type" "callv")])
20153
20154 (define_insn "*sibcall_value_1"
20155   [(set (match_operand 0 "" "")
20156         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20157               (match_operand:SI 2 "" "")))]
20158   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20159 {
20160   if (constant_call_address_operand (operands[1], Pmode))
20161     return "jmp\t%P1";
20162   return "jmp\t%A1";
20163 }
20164   [(set_attr "type" "callv")])
20165
20166 (define_insn "*call_value_1_rex64"
20167   [(set (match_operand 0 "" "")
20168         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20169               (match_operand:DI 2 "" "")))]
20170   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20171 {
20172   if (constant_call_address_operand (operands[1], Pmode))
20173     return "call\t%P1";
20174   return "call\t%A1";
20175 }
20176   [(set_attr "type" "callv")])
20177
20178 (define_insn "*sibcall_value_1_rex64"
20179   [(set (match_operand 0 "" "")
20180         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20181               (match_operand:DI 2 "" "")))]
20182   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20183   "jmp\t%P1"
20184   [(set_attr "type" "callv")])
20185
20186 (define_insn "*sibcall_value_1_rex64_v"
20187   [(set (match_operand 0 "" "")
20188         (call (mem:QI (reg:DI 40))
20189               (match_operand:DI 1 "" "")))]
20190   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20191   "jmp\t*%%r11"
20192   [(set_attr "type" "callv")])
20193 \f
20194 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20195 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20196 ;; caught for use by garbage collectors and the like.  Using an insn that
20197 ;; maps to SIGILL makes it more likely the program will rightfully die.
20198 ;; Keeping with tradition, "6" is in honor of #UD.
20199 (define_insn "trap"
20200   [(trap_if (const_int 1) (const_int 6))]
20201   ""
20202   ".word\t0x0b0f"
20203   [(set_attr "length" "2")])
20204
20205 (define_expand "sse_prologue_save"
20206   [(parallel [(set (match_operand:BLK 0 "" "")
20207                    (unspec:BLK [(reg:DI 21)
20208                                 (reg:DI 22)
20209                                 (reg:DI 23)
20210                                 (reg:DI 24)
20211                                 (reg:DI 25)
20212                                 (reg:DI 26)
20213                                 (reg:DI 27)
20214                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20215               (use (match_operand:DI 1 "register_operand" ""))
20216               (use (match_operand:DI 2 "immediate_operand" ""))
20217               (use (label_ref:DI (match_operand 3 "" "")))])]
20218   "TARGET_64BIT"
20219   "")
20220
20221 (define_insn "*sse_prologue_save_insn"
20222   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20223                           (match_operand:DI 4 "const_int_operand" "n")))
20224         (unspec:BLK [(reg:DI 21)
20225                      (reg:DI 22)
20226                      (reg:DI 23)
20227                      (reg:DI 24)
20228                      (reg:DI 25)
20229                      (reg:DI 26)
20230                      (reg:DI 27)
20231                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20232    (use (match_operand:DI 1 "register_operand" "r"))
20233    (use (match_operand:DI 2 "const_int_operand" "i"))
20234    (use (label_ref:DI (match_operand 3 "" "X")))]
20235   "TARGET_64BIT
20236    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20237    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20238   "*
20239 {
20240   int i;
20241   operands[0] = gen_rtx_MEM (Pmode,
20242                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20243   output_asm_insn (\"jmp\\t%A1\", operands);
20244   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20245     {
20246       operands[4] = adjust_address (operands[0], DImode, i*16);
20247       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20248       PUT_MODE (operands[4], TImode);
20249       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20250         output_asm_insn (\"rex\", operands);
20251       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20252     }
20253   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20254                              CODE_LABEL_NUMBER (operands[3]));
20255   RET;
20256 }
20257   "
20258   [(set_attr "type" "other")
20259    (set_attr "length_immediate" "0")
20260    (set_attr "length_address" "0")
20261    (set_attr "length" "135")
20262    (set_attr "memory" "store")
20263    (set_attr "modrm" "0")
20264    (set_attr "mode" "DI")])
20265
20266 (define_expand "prefetch"
20267   [(prefetch (match_operand 0 "address_operand" "")
20268              (match_operand:SI 1 "const_int_operand" "")
20269              (match_operand:SI 2 "const_int_operand" ""))]
20270   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20271 {
20272   int rw = INTVAL (operands[1]);
20273   int locality = INTVAL (operands[2]);
20274
20275   gcc_assert (rw == 0 || rw == 1);
20276   gcc_assert (locality >= 0 && locality <= 3);
20277   gcc_assert (GET_MODE (operands[0]) == Pmode
20278               || GET_MODE (operands[0]) == VOIDmode);
20279
20280   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20281      supported by SSE counterpart or the SSE prefetch is not available
20282      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20283      of locality.  */
20284   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20285     operands[2] = GEN_INT (3);
20286   else
20287     operands[1] = const0_rtx;
20288 })
20289
20290 (define_insn "*prefetch_sse"
20291   [(prefetch (match_operand:SI 0 "address_operand" "p")
20292              (const_int 0)
20293              (match_operand:SI 1 "const_int_operand" ""))]
20294   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20295 {
20296   static const char * const patterns[4] = {
20297    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20298   };
20299
20300   int locality = INTVAL (operands[1]);
20301   gcc_assert (locality >= 0 && locality <= 3);
20302
20303   return patterns[locality];  
20304 }
20305   [(set_attr "type" "sse")
20306    (set_attr "memory" "none")])
20307
20308 (define_insn "*prefetch_sse_rex"
20309   [(prefetch (match_operand:DI 0 "address_operand" "p")
20310              (const_int 0)
20311              (match_operand:SI 1 "const_int_operand" ""))]
20312   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20313 {
20314   static const char * const patterns[4] = {
20315    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20316   };
20317
20318   int locality = INTVAL (operands[1]);
20319   gcc_assert (locality >= 0 && locality <= 3);
20320
20321   return patterns[locality];  
20322 }
20323   [(set_attr "type" "sse")
20324    (set_attr "memory" "none")])
20325
20326 (define_insn "*prefetch_3dnow"
20327   [(prefetch (match_operand:SI 0 "address_operand" "p")
20328              (match_operand:SI 1 "const_int_operand" "n")
20329              (const_int 3))]
20330   "TARGET_3DNOW && !TARGET_64BIT"
20331 {
20332   if (INTVAL (operands[1]) == 0)
20333     return "prefetch\t%a0";
20334   else
20335     return "prefetchw\t%a0";
20336 }
20337   [(set_attr "type" "mmx")
20338    (set_attr "memory" "none")])
20339
20340 (define_insn "*prefetch_3dnow_rex"
20341   [(prefetch (match_operand:DI 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_expand "stack_protect_set"
20355   [(match_operand 0 "memory_operand" "")
20356    (match_operand 1 "memory_operand" "")]
20357   ""
20358 {
20359 #ifdef TARGET_THREAD_SSP_OFFSET
20360   if (TARGET_64BIT)
20361     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20362                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20363   else
20364     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20365                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20366 #else
20367   if (TARGET_64BIT)
20368     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20369   else
20370     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20371 #endif
20372   DONE;
20373 })
20374
20375 (define_insn "stack_protect_set_si"
20376   [(set (match_operand:SI 0 "memory_operand" "=m")
20377         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20378    (set (match_scratch:SI 2 "=&r") (const_int 0))
20379    (clobber (reg:CC FLAGS_REG))]
20380   ""
20381   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20382   [(set_attr "type" "multi")])
20383
20384 (define_insn "stack_protect_set_di"
20385   [(set (match_operand:DI 0 "memory_operand" "=m")
20386         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20387    (set (match_scratch:DI 2 "=&r") (const_int 0))
20388    (clobber (reg:CC FLAGS_REG))]
20389   "TARGET_64BIT"
20390   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20391   [(set_attr "type" "multi")])
20392
20393 (define_insn "stack_tls_protect_set_si"
20394   [(set (match_operand:SI 0 "memory_operand" "=m")
20395         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20396    (set (match_scratch:SI 2 "=&r") (const_int 0))
20397    (clobber (reg:CC FLAGS_REG))]
20398   ""
20399   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20400   [(set_attr "type" "multi")])
20401
20402 (define_insn "stack_tls_protect_set_di"
20403   [(set (match_operand:DI 0 "memory_operand" "=m")
20404         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20405    (set (match_scratch:DI 2 "=&r") (const_int 0))
20406    (clobber (reg:CC FLAGS_REG))]
20407   "TARGET_64BIT"
20408   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20409   [(set_attr "type" "multi")])
20410
20411 (define_expand "stack_protect_test"
20412   [(match_operand 0 "memory_operand" "")
20413    (match_operand 1 "memory_operand" "")
20414    (match_operand 2 "" "")]
20415   ""
20416 {
20417   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20418   ix86_compare_op0 = operands[0];
20419   ix86_compare_op1 = operands[1];
20420   ix86_compare_emitted = flags;
20421
20422 #ifdef TARGET_THREAD_SSP_OFFSET
20423   if (TARGET_64BIT)
20424     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20425                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20426   else
20427     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20428                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20429 #else
20430   if (TARGET_64BIT)
20431     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20432   else
20433     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20434 #endif
20435   emit_jump_insn (gen_beq (operands[2]));
20436   DONE;
20437 })
20438
20439 (define_insn "stack_protect_test_si"
20440   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20441         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20442                      (match_operand:SI 2 "memory_operand" "m")]
20443                     UNSPEC_SP_TEST))
20444    (clobber (match_scratch:SI 3 "=&r"))]
20445   ""
20446   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20447   [(set_attr "type" "multi")])
20448
20449 (define_insn "stack_protect_test_di"
20450   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20451         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20452                      (match_operand:DI 2 "memory_operand" "m")]
20453                     UNSPEC_SP_TEST))
20454    (clobber (match_scratch:DI 3 "=&r"))]
20455   "TARGET_64BIT"
20456   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20457   [(set_attr "type" "multi")])
20458
20459 (define_insn "stack_tls_protect_test_si"
20460   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20461         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20462                      (match_operand:SI 2 "const_int_operand" "i")]
20463                     UNSPEC_SP_TLS_TEST))
20464    (clobber (match_scratch:SI 3 "=r"))]
20465   ""
20466   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20467   [(set_attr "type" "multi")])
20468
20469 (define_insn "stack_tls_protect_test_di"
20470   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20471         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20472                      (match_operand:DI 2 "const_int_operand" "i")]
20473                     UNSPEC_SP_TLS_TEST))
20474    (clobber (match_scratch:DI 3 "=r"))]
20475   "TARGET_64BIT"
20476   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20477   [(set_attr "type" "multi")])
20478
20479 (include "sse.md")
20480 (include "mmx.md")
20481 (include "sync.md")