]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gcc/config/i386/i386.md
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156
157    ; For SSE4A support
158    (UNSPEC_EXTRQI               130)
159    (UNSPEC_EXTRQ                131)   
160    (UNSPEC_INSERTQI             132)
161    (UNSPEC_INSERTQ              133)
162   ])
163
164 (define_constants
165   [(UNSPECV_BLOCKAGE            0)
166    (UNSPECV_STACK_PROBE         1)
167    (UNSPECV_EMMS                2)
168    (UNSPECV_LDMXCSR             3)
169    (UNSPECV_STMXCSR             4)
170    (UNSPECV_FEMMS               5)
171    (UNSPECV_CLFLUSH             6)
172    (UNSPECV_ALIGN               7)
173    (UNSPECV_MONITOR             8)
174    (UNSPECV_MWAIT               9)
175    (UNSPECV_CMPXCHG_1           10)
176    (UNSPECV_CMPXCHG_2           11)
177    (UNSPECV_XCHG                12)
178    (UNSPECV_LOCK                13)
179   ])
180
181 ;; Registers by name.
182 (define_constants
183   [(BP_REG                       6)
184    (SP_REG                       7)
185    (FLAGS_REG                   17)
186    (FPSR_REG                    18)
187    (DIRFLAG_REG                 19)
188   ])
189
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191 ;; from i386.c.
192
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first.  This allows for better optimization.  For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
197
198 \f
199 ;; Processor type.  This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202                     nocona,core2,generic32,generic64,amdfam10"
203   (const (symbol_ref "ix86_tune")))
204
205 ;; A basic instruction type.  Refinements due to arguments to be
206 ;; provided in other attributes.
207 (define_attr "type"
208   "other,multi,
209    alu,alu1,negnot,imov,imovx,lea,
210    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211    icmp,test,ibr,setcc,icmov,
212    push,pop,call,callv,leave,
213    str,bitmanip,cld,
214    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215    sselog,sselog1,sseiadd,sseishft,sseimul,
216    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218   (const_string "other"))
219
220 ;; Main data type used by the insn
221 (define_attr "mode"
222   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223   (const_string "unknown"))
224
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228            (const_string "i387")
229          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
231            (const_string "sse")
232          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233            (const_string "mmx")
234          (eq_attr "type" "other")
235            (const_string "unknown")]
236          (const_string "integer")))
237
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave,
241                           bitmanip")
242            (const_int 0)
243          (eq_attr "unit" "i387,sse,mmx")
244            (const_int 0)
245          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246                           imul,icmp,push,pop")
247            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248          (eq_attr "type" "imov,test")
249            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250          (eq_attr "type" "call")
251            (if_then_else (match_operand 0 "constant_call_address_operand" "")
252              (const_int 4)
253              (const_int 0))
254          (eq_attr "type" "callv")
255            (if_then_else (match_operand 1 "constant_call_address_operand" "")
256              (const_int 4)
257              (const_int 0))
258          ;; We don't know the size before shorten_branches.  Expect
259          ;; the instruction to fit for better scheduling.
260          (eq_attr "type" "ibr")
261            (const_int 1)
262          ]
263          (symbol_ref "/* Update immediate_length and other attributes! */
264                       gcc_unreachable (),1")))
265
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
269            (const_int 0)
270          (and (eq_attr "type" "call")
271               (match_operand 0 "constant_call_address_operand" ""))
272              (const_int 0)
273          (and (eq_attr "type" "callv")
274               (match_operand 1 "constant_call_address_operand" ""))
275              (const_int 0)
276          ]
277          (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281   (if_then_else (ior (eq_attr "mode" "HI")
282                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" "" 
288   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
294   (if_then_else 
295     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296          (eq_attr "unit" "sse,mmx"))
297     (const_int 1)
298     (const_int 0)))
299
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302   (cond [(and (eq_attr "mode" "DI")
303               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304            (const_int 1)
305          (and (eq_attr "mode" "QI")
306               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307                   (const_int 0)))
308            (const_int 1)
309          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310              (const_int 0))
311            (const_int 1)
312         ]
313         (const_int 0)))
314
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317   (cond [(eq_attr "type" "str,cld,leave")
318            (const_int 0)
319          (eq_attr "unit" "i387")
320            (const_int 0)
321          (and (eq_attr "type" "incdec")
322               (ior (match_operand:SI 1 "register_operand" "")
323                    (match_operand:HI 1 "register_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "push")
326               (not (match_operand 1 "memory_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "pop")
329               (not (match_operand 0 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "imov")
332               (ior (and (match_operand 0 "register_operand" "")
333                         (match_operand 1 "immediate_operand" ""))
334                    (ior (and (match_operand 0 "ax_reg_operand" "")
335                              (match_operand 1 "memory_displacement_only_operand" ""))
336                         (and (match_operand 0 "memory_displacement_only_operand" "")
337                              (match_operand 1 "ax_reg_operand" "")))))
338            (const_int 0)
339          (and (eq_attr "type" "call")
340               (match_operand 0 "constant_call_address_operand" ""))
341              (const_int 0)
342          (and (eq_attr "type" "callv")
343               (match_operand 1 "constant_call_address_operand" ""))
344              (const_int 0)
345          ]
346          (const_int 1)))
347
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
351 ;; other insns.
352 (define_attr "length" ""
353   (cond [(eq_attr "type" "other,multi,fistp,frndint")
354            (const_int 16)
355          (eq_attr "type" "fcmp")
356            (const_int 4)
357          (eq_attr "unit" "i387")
358            (plus (const_int 2)
359                  (plus (attr "prefix_data16")
360                        (attr "length_address")))]
361          (plus (plus (attr "modrm")
362                      (plus (attr "prefix_0f")
363                            (plus (attr "prefix_rex")
364                                  (const_int 1))))
365                (plus (attr "prefix_rep")
366                      (plus (attr "prefix_data16")
367                            (plus (attr "length_immediate")
368                                  (attr "length_address")))))))
369
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
373
374 (define_attr "memory" "none,load,store,both,unknown"
375   (cond [(eq_attr "type" "other,multi,str")
376            (const_string "unknown")
377          (eq_attr "type" "lea,fcmov,fpspc,cld")
378            (const_string "none")
379          (eq_attr "type" "fistp,leave")
380            (const_string "both")
381          (eq_attr "type" "frndint")
382            (const_string "load")
383          (eq_attr "type" "push")
384            (if_then_else (match_operand 1 "memory_operand" "")
385              (const_string "both")
386              (const_string "store"))
387          (eq_attr "type" "pop")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "both")
390              (const_string "load"))
391          (eq_attr "type" "setcc")
392            (if_then_else (match_operand 0 "memory_operand" "")
393              (const_string "store")
394              (const_string "none"))
395          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396            (if_then_else (ior (match_operand 0 "memory_operand" "")
397                               (match_operand 1 "memory_operand" ""))
398              (const_string "load")
399              (const_string "none"))
400          (eq_attr "type" "ibr")
401            (if_then_else (match_operand 0 "memory_operand" "")
402              (const_string "load")
403              (const_string "none"))
404          (eq_attr "type" "call")
405            (if_then_else (match_operand 0 "constant_call_address_operand" "")
406              (const_string "none")
407              (const_string "load"))
408          (eq_attr "type" "callv")
409            (if_then_else (match_operand 1 "constant_call_address_operand" "")
410              (const_string "none")
411              (const_string "load"))
412          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413               (match_operand 1 "memory_operand" ""))
414            (const_string "both")
415          (and (match_operand 0 "memory_operand" "")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (match_operand 0 "memory_operand" "")
419            (const_string "store")
420          (match_operand 1 "memory_operand" "")
421            (const_string "load")
422          (and (eq_attr "type"
423                  "!alu1,negnot,ishift1,
424                    imov,imovx,icmp,test,bitmanip,
425                    fmov,fcmp,fsgn,
426                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427                    mmx,mmxmov,mmxcmp,mmxcvt")
428               (match_operand 2 "memory_operand" ""))
429            (const_string "load")
430          (and (eq_attr "type" "icmov")
431               (match_operand 3 "memory_operand" ""))
432            (const_string "load")
433         ]
434         (const_string "none")))
435
436 ;; Indicates if an instruction has both an immediate and a displacement.
437
438 (define_attr "imm_disp" "false,true,unknown"
439   (cond [(eq_attr "type" "other,multi")
440            (const_string "unknown")
441          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442               (and (match_operand 0 "memory_displacement_operand" "")
443                    (match_operand 1 "immediate_operand" "")))
444            (const_string "true")
445          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446               (and (match_operand 0 "memory_displacement_operand" "")
447                    (match_operand 2 "immediate_operand" "")))
448            (const_string "true")
449         ]
450         (const_string "false")))
451
452 ;; Indicates if an FP operation has an integer source.
453
454 (define_attr "fp_int_src" "false,true"
455   (const_string "false"))
456
457 ;; Defines rounding mode of an FP operation.
458
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460   (const_string "any"))
461
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464   [(set_attr "length" "128")
465    (set_attr "type" "multi")])
466
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
469  
470 ;; All integer modes handled by x87 fisttp operator.
471 (define_mode_macro X87MODEI [HI SI DI])
472
473 ;; All integer modes handled by integer x87 operators.
474 (define_mode_macro X87MODEI12 [HI SI])
475
476 ;; All SSE floating point modes
477 (define_mode_macro SSEMODEF [SF DF])
478  
479 ;; All integer modes handled by SSE cvtts?2si* operators.
480 (define_mode_macro SSEMODEI24 [SI DI])
481
482 \f
483 ;; Scheduling descriptions
484
485 (include "pentium.md")
486 (include "ppro.md")
487 (include "k6.md")
488 (include "athlon.md")
489 (include "geode.md")
490
491 \f
492 ;; Operand and operator predicates and constraints
493
494 (include "predicates.md")
495 (include "constraints.md")
496
497 \f
498 ;; Compare instructions.
499
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
503
504 (define_expand "cmpti"
505   [(set (reg:CC FLAGS_REG)
506         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507                     (match_operand:TI 1 "x86_64_general_operand" "")))]
508   "TARGET_64BIT"
509 {
510   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511     operands[0] = force_reg (TImode, operands[0]);
512   ix86_compare_op0 = operands[0];
513   ix86_compare_op1 = operands[1];
514   DONE;
515 })
516
517 (define_expand "cmpdi"
518   [(set (reg:CC FLAGS_REG)
519         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520                     (match_operand:DI 1 "x86_64_general_operand" "")))]
521   ""
522 {
523   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524     operands[0] = force_reg (DImode, operands[0]);
525   ix86_compare_op0 = operands[0];
526   ix86_compare_op1 = operands[1];
527   DONE;
528 })
529
530 (define_expand "cmpsi"
531   [(set (reg:CC FLAGS_REG)
532         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533                     (match_operand:SI 1 "general_operand" "")))]
534   ""
535 {
536   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537     operands[0] = force_reg (SImode, operands[0]);
538   ix86_compare_op0 = operands[0];
539   ix86_compare_op1 = operands[1];
540   DONE;
541 })
542
543 (define_expand "cmphi"
544   [(set (reg:CC FLAGS_REG)
545         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546                     (match_operand:HI 1 "general_operand" "")))]
547   ""
548 {
549   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550     operands[0] = force_reg (HImode, operands[0]);
551   ix86_compare_op0 = operands[0];
552   ix86_compare_op1 = operands[1];
553   DONE;
554 })
555
556 (define_expand "cmpqi"
557   [(set (reg:CC FLAGS_REG)
558         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559                     (match_operand:QI 1 "general_operand" "")))]
560   "TARGET_QIMODE_MATH"
561 {
562   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
563     operands[0] = force_reg (QImode, operands[0]);
564   ix86_compare_op0 = operands[0];
565   ix86_compare_op1 = operands[1];
566   DONE;
567 })
568
569 (define_insn "cmpdi_ccno_1_rex64"
570   [(set (reg FLAGS_REG)
571         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572                  (match_operand:DI 1 "const0_operand" "n,n")))]
573   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574   "@
575    test{q}\t{%0, %0|%0, %0}
576    cmp{q}\t{%1, %0|%0, %1}"
577   [(set_attr "type" "test,icmp")
578    (set_attr "length_immediate" "0,1")
579    (set_attr "mode" "DI")])
580
581 (define_insn "*cmpdi_minus_1_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585                  (const_int 0)))]
586   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587   "cmp{q}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "DI")])
590
591 (define_expand "cmpdi_1_rex64"
592   [(set (reg:CC FLAGS_REG)
593         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594                     (match_operand:DI 1 "general_operand" "")))]
595   "TARGET_64BIT"
596   "")
597
598 (define_insn "cmpdi_1_insn_rex64"
599   [(set (reg FLAGS_REG)
600         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603   "cmp{q}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "DI")])
606
607
608 (define_insn "*cmpsi_ccno_1"
609   [(set (reg FLAGS_REG)
610         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611                  (match_operand:SI 1 "const0_operand" "n,n")))]
612   "ix86_match_ccmode (insn, CCNOmode)"
613   "@
614    test{l}\t{%0, %0|%0, %0}
615    cmp{l}\t{%1, %0|%0, %1}"
616   [(set_attr "type" "test,icmp")
617    (set_attr "length_immediate" "0,1")
618    (set_attr "mode" "SI")])
619
620 (define_insn "*cmpsi_minus_1"
621   [(set (reg FLAGS_REG)
622         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                            (match_operand:SI 1 "general_operand" "ri,mr"))
624                  (const_int 0)))]
625   "ix86_match_ccmode (insn, CCGOCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
629
630 (define_expand "cmpsi_1"
631   [(set (reg:CC FLAGS_REG)
632         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633                     (match_operand:SI 1 "general_operand" "ri,mr")))]
634   ""
635   "")
636
637 (define_insn "*cmpsi_1_insn"
638   [(set (reg FLAGS_REG)
639         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640                  (match_operand:SI 1 "general_operand" "ri,mr")))]
641   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
642     && ix86_match_ccmode (insn, CCmode)"
643   "cmp{l}\t{%1, %0|%0, %1}"
644   [(set_attr "type" "icmp")
645    (set_attr "mode" "SI")])
646
647 (define_insn "*cmphi_ccno_1"
648   [(set (reg FLAGS_REG)
649         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650                  (match_operand:HI 1 "const0_operand" "n,n")))]
651   "ix86_match_ccmode (insn, CCNOmode)"
652   "@
653    test{w}\t{%0, %0|%0, %0}
654    cmp{w}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "test,icmp")
656    (set_attr "length_immediate" "0,1")
657    (set_attr "mode" "HI")])
658
659 (define_insn "*cmphi_minus_1"
660   [(set (reg FLAGS_REG)
661         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662                            (match_operand:HI 1 "general_operand" "ri,mr"))
663                  (const_int 0)))]
664   "ix86_match_ccmode (insn, CCGOCmode)"
665   "cmp{w}\t{%1, %0|%0, %1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "HI")])
668
669 (define_insn "*cmphi_1"
670   [(set (reg FLAGS_REG)
671         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672                  (match_operand:HI 1 "general_operand" "ri,mr")))]
673   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
674    && ix86_match_ccmode (insn, CCmode)"
675   "cmp{w}\t{%1, %0|%0, %1}"
676   [(set_attr "type" "icmp")
677    (set_attr "mode" "HI")])
678
679 (define_insn "*cmpqi_ccno_1"
680   [(set (reg FLAGS_REG)
681         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682                  (match_operand:QI 1 "const0_operand" "n,n")))]
683   "ix86_match_ccmode (insn, CCNOmode)"
684   "@
685    test{b}\t{%0, %0|%0, %0}
686    cmp{b}\t{$0, %0|%0, 0}"
687   [(set_attr "type" "test,icmp")
688    (set_attr "length_immediate" "0,1")
689    (set_attr "mode" "QI")])
690
691 (define_insn "*cmpqi_1"
692   [(set (reg FLAGS_REG)
693         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694                  (match_operand:QI 1 "general_operand" "qi,mq")))]
695   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
696     && ix86_match_ccmode (insn, CCmode)"
697   "cmp{b}\t{%1, %0|%0, %1}"
698   [(set_attr "type" "icmp")
699    (set_attr "mode" "QI")])
700
701 (define_insn "*cmpqi_minus_1"
702   [(set (reg FLAGS_REG)
703         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704                            (match_operand:QI 1 "general_operand" "qi,mq"))
705                  (const_int 0)))]
706   "ix86_match_ccmode (insn, CCGOCmode)"
707   "cmp{b}\t{%1, %0|%0, %1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "general_operand" "Qm")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_1_rex64"
726   [(set (reg FLAGS_REG)
727         (compare
728           (match_operand:QI 0 "register_operand" "Q")
729           (subreg:QI
730             (zero_extract:SI
731               (match_operand 1 "ext_register_operand" "Q")
732               (const_int 8)
733               (const_int 8)) 0)))]
734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%h1, %0|%0, %h1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_2"
740   [(set (reg FLAGS_REG)
741         (compare
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "Q")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "const0_operand" "n")))]
748   "ix86_match_ccmode (insn, CCNOmode)"
749   "test{b}\t%h0, %h0"
750   [(set_attr "type" "test")
751    (set_attr "length_immediate" "0")
752    (set_attr "mode" "QI")])
753
754 (define_expand "cmpqi_ext_3"
755   [(set (reg:CC FLAGS_REG)
756         (compare:CC
757           (subreg:QI
758             (zero_extract:SI
759               (match_operand 0 "ext_register_operand" "")
760               (const_int 8)
761               (const_int 8)) 0)
762           (match_operand:QI 1 "general_operand" "")))]
763   ""
764   "")
765
766 (define_insn "cmpqi_ext_3_insn"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "general_operand" "Qmn")))]
775   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
779
780 (define_insn "cmpqi_ext_3_insn_rex64"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790   "cmp{b}\t{%1, %h0|%h0, %1}"
791   [(set_attr "type" "icmp")
792    (set_attr "mode" "QI")])
793
794 (define_insn "*cmpqi_ext_4"
795   [(set (reg FLAGS_REG)
796         (compare
797           (subreg:QI
798             (zero_extract:SI
799               (match_operand 0 "ext_register_operand" "Q")
800               (const_int 8)
801               (const_int 8)) 0)
802           (subreg:QI
803             (zero_extract:SI
804               (match_operand 1 "ext_register_operand" "Q")
805               (const_int 8)
806               (const_int 8)) 0)))]
807   "ix86_match_ccmode (insn, CCmode)"
808   "cmp{b}\t{%h1, %h0|%h0, %h1}"
809   [(set_attr "type" "icmp")
810    (set_attr "mode" "QI")])
811
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares.  Which is what
815 ;; the old patterns did, but with many more of them.
816
817 (define_expand "cmpxf"
818   [(set (reg:CC FLAGS_REG)
819         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820                     (match_operand:XF 1 "nonmemory_operand" "")))]
821   "TARGET_80387"
822 {
823   ix86_compare_op0 = operands[0];
824   ix86_compare_op1 = operands[1];
825   DONE;
826 })
827
828 (define_expand "cmpdf"
829   [(set (reg:CC FLAGS_REG)
830         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
833 {
834   ix86_compare_op0 = operands[0];
835   ix86_compare_op1 = operands[1];
836   DONE;
837 })
838
839 (define_expand "cmpsf"
840   [(set (reg:CC FLAGS_REG)
841         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843   "TARGET_80387 || TARGET_SSE_MATH"
844 {
845   ix86_compare_op0 = operands[0];
846   ix86_compare_op1 = operands[1];
847   DONE;
848 })
849
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
852 ;;
853 ;; CCFPmode     compare with exceptions
854 ;; CCFPUmode    compare with no exceptions
855
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
858
859 (define_insn "*cmpfp_0"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand 1 "register_operand" "f")
864              (match_operand 2 "const0_operand" "X"))]
865         UNSPEC_FNSTSW))]
866   "TARGET_80387
867    && FLOAT_MODE_P (GET_MODE (operands[1]))
868    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "multi")
871    (set_attr "unit" "i387")
872    (set (attr "mode")
873      (cond [(match_operand:SF 1 "" "")
874               (const_string "SF")
875             (match_operand:DF 1 "" "")
876               (const_string "DF")
877            ]
878            (const_string "XF")))])
879
880 (define_insn "*cmpfp_sf"
881   [(set (match_operand:HI 0 "register_operand" "=a")
882         (unspec:HI
883           [(compare:CCFP
884              (match_operand:SF 1 "register_operand" "f")
885              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886           UNSPEC_FNSTSW))]
887   "TARGET_80387"
888   "* return output_fp_compare (insn, operands, 0, 0);"
889   [(set_attr "type" "multi")
890    (set_attr "unit" "i387")
891    (set_attr "mode" "SF")])
892
893 (define_insn "*cmpfp_df"
894   [(set (match_operand:HI 0 "register_operand" "=a")
895         (unspec:HI
896           [(compare:CCFP
897              (match_operand:DF 1 "register_operand" "f")
898              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899           UNSPEC_FNSTSW))]
900   "TARGET_80387"
901   "* return output_fp_compare (insn, operands, 0, 0);"
902   [(set_attr "type" "multi")
903    (set_attr "unit" "i387")
904    (set_attr "mode" "DF")])
905
906 (define_insn "*cmpfp_xf"
907   [(set (match_operand:HI 0 "register_operand" "=a")
908         (unspec:HI
909           [(compare:CCFP
910              (match_operand:XF 1 "register_operand" "f")
911              (match_operand:XF 2 "register_operand" "f"))]
912           UNSPEC_FNSTSW))]
913   "TARGET_80387"
914   "* return output_fp_compare (insn, operands, 0, 0);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set_attr "mode" "XF")])
918
919 (define_insn "*cmpfp_u"
920   [(set (match_operand:HI 0 "register_operand" "=a")
921         (unspec:HI
922           [(compare:CCFPU
923              (match_operand 1 "register_operand" "f")
924              (match_operand 2 "register_operand" "f"))]
925           UNSPEC_FNSTSW))]
926   "TARGET_80387
927    && FLOAT_MODE_P (GET_MODE (operands[1]))
928    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929   "* return output_fp_compare (insn, operands, 0, 1);"
930   [(set_attr "type" "multi")
931    (set_attr "unit" "i387")
932    (set (attr "mode")
933      (cond [(match_operand:SF 1 "" "")
934               (const_string "SF")
935             (match_operand:DF 1 "" "")
936               (const_string "DF")
937            ]
938            (const_string "XF")))])
939
940 (define_insn "*cmpfp_<mode>"
941   [(set (match_operand:HI 0 "register_operand" "=a")
942         (unspec:HI
943           [(compare:CCFP
944              (match_operand 1 "register_operand" "f")
945              (match_operator 3 "float_operator"
946                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947           UNSPEC_FNSTSW))]
948   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949    && FLOAT_MODE_P (GET_MODE (operands[1]))
950    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951   "* return output_fp_compare (insn, operands, 0, 0);"
952   [(set_attr "type" "multi")
953    (set_attr "unit" "i387")
954    (set_attr "fp_int_src" "true")
955    (set_attr "mode" "<MODE>")])
956
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
959
960 (define_insn "x86_fnstsw_1"
961   [(set (match_operand:HI 0 "register_operand" "=a")
962         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "fnstsw\t%0"
965   [(set_attr "length" "2")
966    (set_attr "mode" "SI")
967    (set_attr "unit" "i387")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC FLAGS_REG)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "amdfam10_decode" "direct")
980    (set_attr "mode" "SI")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
984 (define_insn "*cmpfp_i_mixed"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "f,x")
987                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
988   "TARGET_MIX_SSE_I387
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp,ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")
998    (set_attr "amdfam10_decode" "direct")])
999
1000 (define_insn "*cmpfp_i_sse"
1001   [(set (reg:CCFP FLAGS_REG)
1002         (compare:CCFP (match_operand 0 "register_operand" "x")
1003                       (match_operand 1 "nonimmediate_operand" "xm")))]
1004   "TARGET_SSE_MATH
1005    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "ssecomi")
1009    (set (attr "mode")
1010      (if_then_else (match_operand:SF 1 "" "")
1011         (const_string "SF")
1012         (const_string "DF")))
1013    (set_attr "athlon_decode" "vector")
1014    (set_attr "amdfam10_decode" "direct")])
1015
1016 (define_insn "*cmpfp_i_i387"
1017   [(set (reg:CCFP FLAGS_REG)
1018         (compare:CCFP (match_operand 0 "register_operand" "f")
1019                       (match_operand 1 "register_operand" "f")))]
1020   "TARGET_80387 && TARGET_CMOVE
1021    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1022    && FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024   "* return output_fp_compare (insn, operands, 1, 0);"
1025   [(set_attr "type" "fcmp")
1026    (set (attr "mode")
1027      (cond [(match_operand:SF 1 "" "")
1028               (const_string "SF")
1029             (match_operand:DF 1 "" "")
1030               (const_string "DF")
1031            ]
1032            (const_string "XF")))
1033    (set_attr "athlon_decode" "vector")
1034    (set_attr "amdfam10_decode" "direct")])
1035
1036 (define_insn "*cmpfp_iu_mixed"
1037   [(set (reg:CCFPU FLAGS_REG)
1038         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1039                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1040   "TARGET_MIX_SSE_I387
1041    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1042    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043   "* return output_fp_compare (insn, operands, 1, 1);"
1044   [(set_attr "type" "fcmp,ssecomi")
1045    (set (attr "mode")
1046      (if_then_else (match_operand:SF 1 "" "")
1047         (const_string "SF")
1048         (const_string "DF")))
1049    (set_attr "athlon_decode" "vector")
1050    (set_attr "amdfam10_decode" "direct")])
1051
1052 (define_insn "*cmpfp_iu_sse"
1053   [(set (reg:CCFPU FLAGS_REG)
1054         (compare:CCFPU (match_operand 0 "register_operand" "x")
1055                        (match_operand 1 "nonimmediate_operand" "xm")))]
1056   "TARGET_SSE_MATH
1057    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1059   "* return output_fp_compare (insn, operands, 1, 1);"
1060   [(set_attr "type" "ssecomi")
1061    (set (attr "mode")
1062      (if_then_else (match_operand:SF 1 "" "")
1063         (const_string "SF")
1064         (const_string "DF")))
1065    (set_attr "athlon_decode" "vector")
1066    (set_attr "amdfam10_decode" "direct")])
1067
1068 (define_insn "*cmpfp_iu_387"
1069   [(set (reg:CCFPU FLAGS_REG)
1070         (compare:CCFPU (match_operand 0 "register_operand" "f")
1071                        (match_operand 1 "register_operand" "f")))]
1072   "TARGET_80387 && TARGET_CMOVE
1073    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1074    && FLOAT_MODE_P (GET_MODE (operands[0]))
1075    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1076   "* return output_fp_compare (insn, operands, 1, 1);"
1077   [(set_attr "type" "fcmp")
1078    (set (attr "mode")
1079      (cond [(match_operand:SF 1 "" "")
1080               (const_string "SF")
1081             (match_operand:DF 1 "" "")
1082               (const_string "DF")
1083            ]
1084            (const_string "XF")))
1085    (set_attr "athlon_decode" "vector")
1086    (set_attr "amdfam10_decode" "direct")])
1087 \f
1088 ;; Move instructions.
1089
1090 ;; General case of fullword move.
1091
1092 (define_expand "movsi"
1093   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1094         (match_operand:SI 1 "general_operand" ""))]
1095   ""
1096   "ix86_expand_move (SImode, operands); DONE;")
1097
1098 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1099 ;; general_operand.
1100 ;;
1101 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1102 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1103 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1104 ;; targets without our curiosities, and it is just as easy to represent
1105 ;; this differently.
1106
1107 (define_insn "*pushsi2"
1108   [(set (match_operand:SI 0 "push_operand" "=<")
1109         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1110   "!TARGET_64BIT"
1111   "push{l}\t%1"
1112   [(set_attr "type" "push")
1113    (set_attr "mode" "SI")])
1114
1115 ;; For 64BIT abi we always round up to 8 bytes.
1116 (define_insn "*pushsi2_rex64"
1117   [(set (match_operand:SI 0 "push_operand" "=X")
1118         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1119   "TARGET_64BIT"
1120   "push{q}\t%q1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 (define_insn "*pushsi2_prologue"
1125   [(set (match_operand:SI 0 "push_operand" "=<")
1126         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1127    (clobber (mem:BLK (scratch)))]
1128   "!TARGET_64BIT"
1129   "push{l}\t%1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*popsi1_epilogue"
1134   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1135         (mem:SI (reg:SI SP_REG)))
1136    (set (reg:SI SP_REG)
1137         (plus:SI (reg:SI SP_REG) (const_int 4)))
1138    (clobber (mem:BLK (scratch)))]
1139   "!TARGET_64BIT"
1140   "pop{l}\t%0"
1141   [(set_attr "type" "pop")
1142    (set_attr "mode" "SI")])
1143
1144 (define_insn "popsi1"
1145   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1146         (mem:SI (reg:SI SP_REG)))
1147    (set (reg:SI SP_REG)
1148         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1149   "!TARGET_64BIT"
1150   "pop{l}\t%0"
1151   [(set_attr "type" "pop")
1152    (set_attr "mode" "SI")])
1153
1154 (define_insn "*movsi_xor"
1155   [(set (match_operand:SI 0 "register_operand" "=r")
1156         (match_operand:SI 1 "const0_operand" "i"))
1157    (clobber (reg:CC FLAGS_REG))]
1158   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1159   "xor{l}\t{%0, %0|%0, %0}"
1160   [(set_attr "type" "alu1")
1161    (set_attr "mode" "SI")
1162    (set_attr "length_immediate" "0")])
1163  
1164 (define_insn "*movsi_or"
1165   [(set (match_operand:SI 0 "register_operand" "=r")
1166         (match_operand:SI 1 "immediate_operand" "i"))
1167    (clobber (reg:CC FLAGS_REG))]
1168   "reload_completed
1169    && operands[1] == constm1_rtx
1170    && (TARGET_PENTIUM || optimize_size)"
1171 {
1172   operands[1] = constm1_rtx;
1173   return "or{l}\t{%1, %0|%0, %1}";
1174 }
1175   [(set_attr "type" "alu1")
1176    (set_attr "mode" "SI")
1177    (set_attr "length_immediate" "1")])
1178
1179 (define_insn "*movsi_1"
1180   [(set (match_operand:SI 0 "nonimmediate_operand"
1181                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1182         (match_operand:SI 1 "general_operand"
1183                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1184   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1185 {
1186   switch (get_attr_type (insn))
1187     {
1188     case TYPE_SSELOG1:
1189       if (get_attr_mode (insn) == MODE_TI)
1190         return "pxor\t%0, %0";
1191       return "xorps\t%0, %0";
1192
1193     case TYPE_SSEMOV:
1194       switch (get_attr_mode (insn))
1195         {
1196         case MODE_TI:
1197           return "movdqa\t{%1, %0|%0, %1}";
1198         case MODE_V4SF:
1199           return "movaps\t{%1, %0|%0, %1}";
1200         case MODE_SI:
1201           return "movd\t{%1, %0|%0, %1}";
1202         case MODE_SF:
1203           return "movss\t{%1, %0|%0, %1}";
1204         default:
1205           gcc_unreachable ();
1206         }
1207
1208     case TYPE_MMXADD:
1209       return "pxor\t%0, %0";
1210
1211     case TYPE_MMXMOV:
1212       if (get_attr_mode (insn) == MODE_DI)
1213         return "movq\t{%1, %0|%0, %1}";
1214       return "movd\t{%1, %0|%0, %1}";
1215
1216     case TYPE_LEA:
1217       return "lea{l}\t{%1, %0|%0, %1}";
1218
1219     default:
1220       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1221       return "mov{l}\t{%1, %0|%0, %1}";
1222     }
1223 }
1224   [(set (attr "type")
1225      (cond [(eq_attr "alternative" "2")
1226               (const_string "mmxadd")
1227             (eq_attr "alternative" "3,4,5")
1228               (const_string "mmxmov")
1229             (eq_attr "alternative" "6")
1230               (const_string "sselog1")
1231             (eq_attr "alternative" "7,8,9,10,11")
1232               (const_string "ssemov")
1233             (match_operand:DI 1 "pic_32bit_operand" "")
1234               (const_string "lea")
1235            ]
1236            (const_string "imov")))
1237    (set (attr "mode")
1238      (cond [(eq_attr "alternative" "2,3")
1239               (const_string "DI")
1240             (eq_attr "alternative" "6,7")
1241               (if_then_else
1242                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1243                 (const_string "V4SF")
1244                 (const_string "TI"))
1245             (and (eq_attr "alternative" "8,9,10,11")
1246                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1247               (const_string "SF")
1248            ]
1249            (const_string "SI")))])
1250
1251 ;; Stores and loads of ax to arbitrary constant address.
1252 ;; We fake an second form of instruction to force reload to load address
1253 ;; into register when rax is not available
1254 (define_insn "*movabssi_1_rex64"
1255   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1256         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1257   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1258   "@
1259    movabs{l}\t{%1, %P0|%P0, %1}
1260    mov{l}\t{%1, %a0|%a0, %1}"
1261   [(set_attr "type" "imov")
1262    (set_attr "modrm" "0,*")
1263    (set_attr "length_address" "8,0")
1264    (set_attr "length_immediate" "0,*")
1265    (set_attr "memory" "store")
1266    (set_attr "mode" "SI")])
1267
1268 (define_insn "*movabssi_2_rex64"
1269   [(set (match_operand:SI 0 "register_operand" "=a,r")
1270         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1271   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1272   "@
1273    movabs{l}\t{%P1, %0|%0, %P1}
1274    mov{l}\t{%a1, %0|%0, %a1}"
1275   [(set_attr "type" "imov")
1276    (set_attr "modrm" "0,*")
1277    (set_attr "length_address" "8,0")
1278    (set_attr "length_immediate" "0")
1279    (set_attr "memory" "load")
1280    (set_attr "mode" "SI")])
1281
1282 (define_insn "*swapsi"
1283   [(set (match_operand:SI 0 "register_operand" "+r")
1284         (match_operand:SI 1 "register_operand" "+r"))
1285    (set (match_dup 1)
1286         (match_dup 0))]
1287   ""
1288   "xchg{l}\t%1, %0"
1289   [(set_attr "type" "imov")
1290    (set_attr "mode" "SI")
1291    (set_attr "pent_pair" "np")
1292    (set_attr "athlon_decode" "vector")
1293    (set_attr "amdfam10_decode" "double")])   
1294
1295 (define_expand "movhi"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297         (match_operand:HI 1 "general_operand" ""))]
1298   ""
1299   "ix86_expand_move (HImode, operands); DONE;")
1300
1301 (define_insn "*pushhi2"
1302   [(set (match_operand:HI 0 "push_operand" "=X")
1303         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1304   "!TARGET_64BIT"
1305   "push{l}\t%k1"
1306   [(set_attr "type" "push")
1307    (set_attr "mode" "SI")])
1308
1309 ;; For 64BIT abi we always round up to 8 bytes.
1310 (define_insn "*pushhi2_rex64"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1313   "TARGET_64BIT"
1314   "push{q}\t%q1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "DI")])
1317
1318 (define_insn "*movhi_1"
1319   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1320         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1321   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1322 {
1323   switch (get_attr_type (insn))
1324     {
1325     case TYPE_IMOVX:
1326       /* movzwl is faster than movw on p2 due to partial word stalls,
1327          though not as fast as an aligned movl.  */
1328       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1329     default:
1330       if (get_attr_mode (insn) == MODE_SI)
1331         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1332       else
1333         return "mov{w}\t{%1, %0|%0, %1}";
1334     }
1335 }
1336   [(set (attr "type")
1337      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1338               (const_string "imov")
1339             (and (eq_attr "alternative" "0")
1340                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341                           (const_int 0))
1342                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1343                           (const_int 0))))
1344               (const_string "imov")
1345             (and (eq_attr "alternative" "1,2")
1346                  (match_operand:HI 1 "aligned_operand" ""))
1347               (const_string "imov")
1348             (and (ne (symbol_ref "TARGET_MOVX")
1349                      (const_int 0))
1350                  (eq_attr "alternative" "0,2"))
1351               (const_string "imovx")
1352            ]
1353            (const_string "imov")))
1354     (set (attr "mode")
1355       (cond [(eq_attr "type" "imovx")
1356                (const_string "SI")
1357              (and (eq_attr "alternative" "1,2")
1358                   (match_operand:HI 1 "aligned_operand" ""))
1359                (const_string "SI")
1360              (and (eq_attr "alternative" "0")
1361                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1362                            (const_int 0))
1363                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1364                            (const_int 0))))
1365                (const_string "SI")
1366             ]
1367             (const_string "HI")))])
1368
1369 ;; Stores and loads of ax to arbitrary constant address.
1370 ;; We fake an second form of instruction to force reload to load address
1371 ;; into register when rax is not available
1372 (define_insn "*movabshi_1_rex64"
1373   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1374         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1375   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1376   "@
1377    movabs{w}\t{%1, %P0|%P0, %1}
1378    mov{w}\t{%1, %a0|%a0, %1}"
1379   [(set_attr "type" "imov")
1380    (set_attr "modrm" "0,*")
1381    (set_attr "length_address" "8,0")
1382    (set_attr "length_immediate" "0,*")
1383    (set_attr "memory" "store")
1384    (set_attr "mode" "HI")])
1385
1386 (define_insn "*movabshi_2_rex64"
1387   [(set (match_operand:HI 0 "register_operand" "=a,r")
1388         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1389   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1390   "@
1391    movabs{w}\t{%P1, %0|%0, %P1}
1392    mov{w}\t{%a1, %0|%0, %a1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "modrm" "0,*")
1395    (set_attr "length_address" "8,0")
1396    (set_attr "length_immediate" "0")
1397    (set_attr "memory" "load")
1398    (set_attr "mode" "HI")])
1399
1400 (define_insn "*swaphi_1"
1401   [(set (match_operand:HI 0 "register_operand" "+r")
1402         (match_operand:HI 1 "register_operand" "+r"))
1403    (set (match_dup 1)
1404         (match_dup 0))]
1405   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1406   "xchg{l}\t%k1, %k0"
1407   [(set_attr "type" "imov")
1408    (set_attr "mode" "SI")
1409    (set_attr "pent_pair" "np")
1410    (set_attr "athlon_decode" "vector")
1411    (set_attr "amdfam10_decode" "double")])   
1412
1413 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1414 (define_insn "*swaphi_2"
1415   [(set (match_operand:HI 0 "register_operand" "+r")
1416         (match_operand:HI 1 "register_operand" "+r"))
1417    (set (match_dup 1)
1418         (match_dup 0))]
1419   "TARGET_PARTIAL_REG_STALL"
1420   "xchg{w}\t%1, %0"
1421   [(set_attr "type" "imov")
1422    (set_attr "mode" "HI")
1423    (set_attr "pent_pair" "np")
1424    (set_attr "athlon_decode" "vector")])
1425
1426 (define_expand "movstricthi"
1427   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1428         (match_operand:HI 1 "general_operand" ""))]
1429   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1430 {
1431   /* Don't generate memory->memory moves, go through a register */
1432   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1433     operands[1] = force_reg (HImode, operands[1]);
1434 })
1435
1436 (define_insn "*movstricthi_1"
1437   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1438         (match_operand:HI 1 "general_operand" "rn,m"))]
1439   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1440    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1441   "mov{w}\t{%1, %0|%0, %1}"
1442   [(set_attr "type" "imov")
1443    (set_attr "mode" "HI")])
1444
1445 (define_insn "*movstricthi_xor"
1446   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1447         (match_operand:HI 1 "const0_operand" "i"))
1448    (clobber (reg:CC FLAGS_REG))]
1449   "reload_completed
1450    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1451   "xor{w}\t{%0, %0|%0, %0}"
1452   [(set_attr "type" "alu1")
1453    (set_attr "mode" "HI")
1454    (set_attr "length_immediate" "0")])
1455
1456 (define_expand "movqi"
1457   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1458         (match_operand:QI 1 "general_operand" ""))]
1459   ""
1460   "ix86_expand_move (QImode, operands); DONE;")
1461
1462 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1463 ;; "push a byte".  But actually we use pushl, which has the effect
1464 ;; of rounding the amount pushed up to a word.
1465
1466 (define_insn "*pushqi2"
1467   [(set (match_operand:QI 0 "push_operand" "=X")
1468         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1469   "!TARGET_64BIT"
1470   "push{l}\t%k1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "SI")])
1473
1474 ;; For 64BIT abi we always round up to 8 bytes.
1475 (define_insn "*pushqi2_rex64"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1478   "TARGET_64BIT"
1479   "push{q}\t%q1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "DI")])
1482
1483 ;; Situation is quite tricky about when to choose full sized (SImode) move
1484 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1485 ;; partial register dependency machines (such as AMD Athlon), where QImode
1486 ;; moves issue extra dependency and for partial register stalls machines
1487 ;; that don't use QImode patterns (and QImode move cause stall on the next
1488 ;; instruction).
1489 ;;
1490 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1491 ;; register stall machines with, where we use QImode instructions, since
1492 ;; partial register stall can be caused there.  Then we use movzx.
1493 (define_insn "*movqi_1"
1494   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1495         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1496   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1497 {
1498   switch (get_attr_type (insn))
1499     {
1500     case TYPE_IMOVX:
1501       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1502       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1503     default:
1504       if (get_attr_mode (insn) == MODE_SI)
1505         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1506       else
1507         return "mov{b}\t{%1, %0|%0, %1}";
1508     }
1509 }
1510   [(set (attr "type")
1511      (cond [(and (eq_attr "alternative" "5")
1512                  (not (match_operand:QI 1 "aligned_operand" "")))
1513               (const_string "imovx")
1514             (ne (symbol_ref "optimize_size") (const_int 0))
1515               (const_string "imov")
1516             (and (eq_attr "alternative" "3")
1517                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518                           (const_int 0))
1519                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1520                           (const_int 0))))
1521               (const_string "imov")
1522             (eq_attr "alternative" "3,5")
1523               (const_string "imovx")
1524             (and (ne (symbol_ref "TARGET_MOVX")
1525                      (const_int 0))
1526                  (eq_attr "alternative" "2"))
1527               (const_string "imovx")
1528            ]
1529            (const_string "imov")))
1530    (set (attr "mode")
1531       (cond [(eq_attr "alternative" "3,4,5")
1532                (const_string "SI")
1533              (eq_attr "alternative" "6")
1534                (const_string "QI")
1535              (eq_attr "type" "imovx")
1536                (const_string "SI")
1537              (and (eq_attr "type" "imov")
1538                   (and (eq_attr "alternative" "0,1")
1539                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1540                                 (const_int 0))
1541                             (and (eq (symbol_ref "optimize_size")
1542                                      (const_int 0))
1543                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1544                                      (const_int 0))))))
1545                (const_string "SI")
1546              ;; Avoid partial register stalls when not using QImode arithmetic
1547              (and (eq_attr "type" "imov")
1548                   (and (eq_attr "alternative" "0,1")
1549                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1550                                 (const_int 0))
1551                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1552                                 (const_int 0)))))
1553                (const_string "SI")
1554            ]
1555            (const_string "QI")))])
1556
1557 (define_expand "reload_outqi"
1558   [(parallel [(match_operand:QI 0 "" "=m")
1559               (match_operand:QI 1 "register_operand" "r")
1560               (match_operand:QI 2 "register_operand" "=&q")])]
1561   ""
1562 {
1563   rtx op0, op1, op2;
1564   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1565
1566   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1567   if (! q_regs_operand (op1, QImode))
1568     {
1569       emit_insn (gen_movqi (op2, op1));
1570       op1 = op2;
1571     }
1572   emit_insn (gen_movqi (op0, op1));
1573   DONE;
1574 })
1575
1576 (define_insn "*swapqi_1"
1577   [(set (match_operand:QI 0 "register_operand" "+r")
1578         (match_operand:QI 1 "register_operand" "+r"))
1579    (set (match_dup 1)
1580         (match_dup 0))]
1581   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1582   "xchg{l}\t%k1, %k0"
1583   [(set_attr "type" "imov")
1584    (set_attr "mode" "SI")
1585    (set_attr "pent_pair" "np")
1586    (set_attr "athlon_decode" "vector")
1587    (set_attr "amdfam10_decode" "vector")])   
1588
1589 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1590 (define_insn "*swapqi_2"
1591   [(set (match_operand:QI 0 "register_operand" "+q")
1592         (match_operand:QI 1 "register_operand" "+q"))
1593    (set (match_dup 1)
1594         (match_dup 0))]
1595   "TARGET_PARTIAL_REG_STALL"
1596   "xchg{b}\t%1, %0"
1597   [(set_attr "type" "imov")
1598    (set_attr "mode" "QI")
1599    (set_attr "pent_pair" "np")
1600    (set_attr "athlon_decode" "vector")])
1601
1602 (define_expand "movstrictqi"
1603   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1604         (match_operand:QI 1 "general_operand" ""))]
1605   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1606 {
1607   /* Don't generate memory->memory moves, go through a register.  */
1608   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1609     operands[1] = force_reg (QImode, operands[1]);
1610 })
1611
1612 (define_insn "*movstrictqi_1"
1613   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1614         (match_operand:QI 1 "general_operand" "*qn,m"))]
1615   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1616    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1617   "mov{b}\t{%1, %0|%0, %1}"
1618   [(set_attr "type" "imov")
1619    (set_attr "mode" "QI")])
1620
1621 (define_insn "*movstrictqi_xor"
1622   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1623         (match_operand:QI 1 "const0_operand" "i"))
1624    (clobber (reg:CC FLAGS_REG))]
1625   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1626   "xor{b}\t{%0, %0|%0, %0}"
1627   [(set_attr "type" "alu1")
1628    (set_attr "mode" "QI")
1629    (set_attr "length_immediate" "0")])
1630
1631 (define_insn "*movsi_extv_1"
1632   [(set (match_operand:SI 0 "register_operand" "=R")
1633         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   ""
1637   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1638   [(set_attr "type" "imovx")
1639    (set_attr "mode" "SI")])
1640
1641 (define_insn "*movhi_extv_1"
1642   [(set (match_operand:HI 0 "register_operand" "=R")
1643         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   ""
1647   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1648   [(set_attr "type" "imovx")
1649    (set_attr "mode" "SI")])
1650
1651 (define_insn "*movqi_extv_1"
1652   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 (define_insn "*movqi_extv_1_rex64"
1679   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1680         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1681                          (const_int 8)
1682                          (const_int 8)))]
1683   "TARGET_64BIT"
1684 {
1685   switch (get_attr_type (insn))
1686     {
1687     case TYPE_IMOVX:
1688       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1689     default:
1690       return "mov{b}\t{%h1, %0|%0, %h1}";
1691     }
1692 }
1693   [(set (attr "type")
1694      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1695                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1696                              (ne (symbol_ref "TARGET_MOVX")
1697                                  (const_int 0))))
1698         (const_string "imovx")
1699         (const_string "imov")))
1700    (set (attr "mode")
1701      (if_then_else (eq_attr "type" "imovx")
1702         (const_string "SI")
1703         (const_string "QI")))])
1704
1705 ;; Stores and loads of ax to arbitrary constant address.
1706 ;; We fake an second form of instruction to force reload to load address
1707 ;; into register when rax is not available
1708 (define_insn "*movabsqi_1_rex64"
1709   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1710         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1711   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1712   "@
1713    movabs{b}\t{%1, %P0|%P0, %1}
1714    mov{b}\t{%1, %a0|%a0, %1}"
1715   [(set_attr "type" "imov")
1716    (set_attr "modrm" "0,*")
1717    (set_attr "length_address" "8,0")
1718    (set_attr "length_immediate" "0,*")
1719    (set_attr "memory" "store")
1720    (set_attr "mode" "QI")])
1721
1722 (define_insn "*movabsqi_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=a,r")
1724         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1725   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1726   "@
1727    movabs{b}\t{%P1, %0|%0, %P1}
1728    mov{b}\t{%a1, %0|%0, %a1}"
1729   [(set_attr "type" "imov")
1730    (set_attr "modrm" "0,*")
1731    (set_attr "length_address" "8,0")
1732    (set_attr "length_immediate" "0")
1733    (set_attr "memory" "load")
1734    (set_attr "mode" "QI")])
1735
1736 (define_insn "*movdi_extzv_1"
1737   [(set (match_operand:DI 0 "register_operand" "=R")
1738         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1739                          (const_int 8)
1740                          (const_int 8)))]
1741   "TARGET_64BIT"
1742   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1743   [(set_attr "type" "imovx")
1744    (set_attr "mode" "DI")])
1745
1746 (define_insn "*movsi_extzv_1"
1747   [(set (match_operand:SI 0 "register_operand" "=R")
1748         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1749                          (const_int 8)
1750                          (const_int 8)))]
1751   ""
1752   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1753   [(set_attr "type" "imovx")
1754    (set_attr "mode" "SI")])
1755
1756 (define_insn "*movqi_extzv_2"
1757   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 (and (match_operand:QI 0 "register_operand" "")
1773                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                              (ne (symbol_ref "TARGET_MOVX")
1775                                  (const_int 0))))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1782
1783 (define_insn "*movqi_extzv_2_rex64"
1784   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1785         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1786                                     (const_int 8)
1787                                     (const_int 8)) 0))]
1788   "TARGET_64BIT"
1789 {
1790   switch (get_attr_type (insn))
1791     {
1792     case TYPE_IMOVX:
1793       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1794     default:
1795       return "mov{b}\t{%h1, %0|%0, %h1}";
1796     }
1797 }
1798   [(set (attr "type")
1799      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1800                         (ne (symbol_ref "TARGET_MOVX")
1801                             (const_int 0)))
1802         (const_string "imovx")
1803         (const_string "imov")))
1804    (set (attr "mode")
1805      (if_then_else (eq_attr "type" "imovx")
1806         (const_string "SI")
1807         (const_string "QI")))])
1808
1809 (define_insn "movsi_insv_1"
1810   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811                          (const_int 8)
1812                          (const_int 8))
1813         (match_operand:SI 1 "general_operand" "Qmn"))]
1814   "!TARGET_64BIT"
1815   "mov{b}\t{%b1, %h0|%h0, %b1}"
1816   [(set_attr "type" "imov")
1817    (set_attr "mode" "QI")])
1818
1819 (define_insn "movdi_insv_1_rex64"
1820   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1821                          (const_int 8)
1822                          (const_int 8))
1823         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1824   "TARGET_64BIT"
1825   "mov{b}\t{%b1, %h0|%h0, %b1}"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "QI")])
1828
1829 (define_insn "*movqi_insv_2"
1830   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831                          (const_int 8)
1832                          (const_int 8))
1833         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1834                      (const_int 8)))]
1835   ""
1836   "mov{b}\t{%h1, %h0|%h0, %h1}"
1837   [(set_attr "type" "imov")
1838    (set_attr "mode" "QI")])
1839
1840 (define_expand "movdi"
1841   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842         (match_operand:DI 1 "general_operand" ""))]
1843   ""
1844   "ix86_expand_move (DImode, operands); DONE;")
1845
1846 (define_insn "*pushdi"
1847   [(set (match_operand:DI 0 "push_operand" "=<")
1848         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1849   "!TARGET_64BIT"
1850   "#")
1851
1852 (define_insn "*pushdi2_rex64"
1853   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1855   "TARGET_64BIT"
1856   "@
1857    push{q}\t%1
1858    #"
1859   [(set_attr "type" "push,multi")
1860    (set_attr "mode" "DI")])
1861
1862 ;; Convert impossible pushes of immediate to existing instructions.
1863 ;; First try to get scratch register and go through it.  In case this
1864 ;; fails, push sign extended lower part first and then overwrite
1865 ;; upper part by 32bit move.
1866 (define_peephole2
1867   [(match_scratch:DI 2 "r")
1868    (set (match_operand:DI 0 "push_operand" "")
1869         (match_operand:DI 1 "immediate_operand" ""))]
1870   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 2) (match_dup 1))
1873    (set (match_dup 0) (match_dup 2))]
1874   "")
1875
1876 ;; We need to define this as both peepholer and splitter for case
1877 ;; peephole2 pass is not run.
1878 ;; "&& 1" is needed to keep it from matching the previous pattern.
1879 (define_peephole2
1880   [(set (match_operand:DI 0 "push_operand" "")
1881         (match_operand:DI 1 "immediate_operand" ""))]
1882   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884   [(set (match_dup 0) (match_dup 1))
1885    (set (match_dup 2) (match_dup 3))]
1886   "split_di (operands + 1, 1, operands + 2, operands + 3);
1887    operands[1] = gen_lowpart (DImode, operands[2]);
1888    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889                                                     GEN_INT (4)));
1890   ")
1891
1892 (define_split
1893   [(set (match_operand:DI 0 "push_operand" "")
1894         (match_operand:DI 1 "immediate_operand" ""))]
1895   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896                     ? flow2_completed : reload_completed)
1897    && !symbolic_operand (operands[1], DImode)
1898    && !x86_64_immediate_operand (operands[1], DImode)"
1899   [(set (match_dup 0) (match_dup 1))
1900    (set (match_dup 2) (match_dup 3))]
1901   "split_di (operands + 1, 1, operands + 2, operands + 3);
1902    operands[1] = gen_lowpart (DImode, operands[2]);
1903    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1904                                                     GEN_INT (4)));
1905   ")
1906
1907 (define_insn "*pushdi2_prologue_rex64"
1908   [(set (match_operand:DI 0 "push_operand" "=<")
1909         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "push{q}\t%1"
1913   [(set_attr "type" "push")
1914    (set_attr "mode" "DI")])
1915
1916 (define_insn "*popdi1_epilogue_rex64"
1917   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918         (mem:DI (reg:DI SP_REG)))
1919    (set (reg:DI SP_REG)
1920         (plus:DI (reg:DI SP_REG) (const_int 8)))
1921    (clobber (mem:BLK (scratch)))]
1922   "TARGET_64BIT"
1923   "pop{q}\t%0"
1924   [(set_attr "type" "pop")
1925    (set_attr "mode" "DI")])
1926
1927 (define_insn "popdi1"
1928   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929         (mem:DI (reg:DI SP_REG)))
1930    (set (reg:DI SP_REG)
1931         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1932   "TARGET_64BIT"
1933   "pop{q}\t%0"
1934   [(set_attr "type" "pop")
1935    (set_attr "mode" "DI")])
1936
1937 (define_insn "*movdi_xor_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const0_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942    && reload_completed"
1943   "xor{l}\t{%k0, %k0|%k0, %k0}"
1944   [(set_attr "type" "alu1")
1945    (set_attr "mode" "SI")
1946    (set_attr "length_immediate" "0")])
1947
1948 (define_insn "*movdi_or_rex64"
1949   [(set (match_operand:DI 0 "register_operand" "=r")
1950         (match_operand:DI 1 "const_int_operand" "i"))
1951    (clobber (reg:CC FLAGS_REG))]
1952   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1953    && reload_completed
1954    && operands[1] == constm1_rtx"
1955 {
1956   operands[1] = constm1_rtx;
1957   return "or{q}\t{%1, %0|%0, %1}";
1958 }
1959   [(set_attr "type" "alu1")
1960    (set_attr "mode" "DI")
1961    (set_attr "length_immediate" "1")])
1962
1963 (define_insn "*movdi_2"
1964   [(set (match_operand:DI 0 "nonimmediate_operand"
1965                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966         (match_operand:DI 1 "general_operand"
1967                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969   "@
1970    #
1971    #
1972    pxor\t%0, %0
1973    movq\t{%1, %0|%0, %1}
1974    movq\t{%1, %0|%0, %1}
1975    pxor\t%0, %0
1976    movq\t{%1, %0|%0, %1}
1977    movdqa\t{%1, %0|%0, %1}
1978    movq\t{%1, %0|%0, %1}
1979    xorps\t%0, %0
1980    movlps\t{%1, %0|%0, %1}
1981    movaps\t{%1, %0|%0, %1}
1982    movlps\t{%1, %0|%0, %1}"
1983   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1985
1986 (define_split
1987   [(set (match_operand:DI 0 "push_operand" "")
1988         (match_operand:DI 1 "general_operand" ""))]
1989   "!TARGET_64BIT && reload_completed
1990    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991   [(const_int 0)]
1992   "ix86_split_long_move (operands); DONE;")
1993
1994 ;; %%% This multiword shite has got to go.
1995 (define_split
1996   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997         (match_operand:DI 1 "general_operand" ""))]
1998   "!TARGET_64BIT && reload_completed
1999    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2001   [(const_int 0)]
2002   "ix86_split_long_move (operands); DONE;")
2003
2004 (define_insn "*movdi_1_rex64"
2005   [(set (match_operand:DI 0 "nonimmediate_operand"
2006                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007         (match_operand:DI 1 "general_operand"
2008                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2010 {
2011   switch (get_attr_type (insn))
2012     {
2013     case TYPE_SSECVT:
2014       if (which_alternative == 13)
2015         return "movq2dq\t{%1, %0|%0, %1}";
2016       else
2017         return "movdq2q\t{%1, %0|%0, %1}";
2018     case TYPE_SSEMOV:
2019       if (get_attr_mode (insn) == MODE_TI)
2020           return "movdqa\t{%1, %0|%0, %1}";
2021       /* FALLTHRU */
2022     case TYPE_MMXMOV:
2023       /* Moves from and into integer register is done using movd opcode with
2024          REX prefix.  */
2025       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026           return "movd\t{%1, %0|%0, %1}";
2027       return "movq\t{%1, %0|%0, %1}";
2028     case TYPE_SSELOG1:
2029     case TYPE_MMXADD:
2030       return "pxor\t%0, %0";
2031     case TYPE_MULTI:
2032       return "#";
2033     case TYPE_LEA:
2034       return "lea{q}\t{%a1, %0|%0, %a1}";
2035     default:
2036       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037       if (get_attr_mode (insn) == MODE_SI)
2038         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039       else if (which_alternative == 2)
2040         return "movabs{q}\t{%1, %0|%0, %1}";
2041       else
2042         return "mov{q}\t{%1, %0|%0, %1}";
2043     }
2044 }
2045   [(set (attr "type")
2046      (cond [(eq_attr "alternative" "5")
2047               (const_string "mmxadd")
2048             (eq_attr "alternative" "6,7,8")
2049               (const_string "mmxmov")
2050             (eq_attr "alternative" "9")
2051               (const_string "sselog1")
2052             (eq_attr "alternative" "10,11,12")
2053               (const_string "ssemov")
2054             (eq_attr "alternative" "13,14")
2055               (const_string "ssecvt")
2056             (eq_attr "alternative" "4")
2057               (const_string "multi")
2058             (match_operand:DI 1 "pic_32bit_operand" "")
2059               (const_string "lea")
2060            ]
2061            (const_string "imov")))
2062    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2065
2066 ;; Stores and loads of ax to arbitrary constant address.
2067 ;; We fake an second form of instruction to force reload to load address
2068 ;; into register when rax is not available
2069 (define_insn "*movabsdi_1_rex64"
2070   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2073   "@
2074    movabs{q}\t{%1, %P0|%P0, %1}
2075    mov{q}\t{%1, %a0|%a0, %1}"
2076   [(set_attr "type" "imov")
2077    (set_attr "modrm" "0,*")
2078    (set_attr "length_address" "8,0")
2079    (set_attr "length_immediate" "0,*")
2080    (set_attr "memory" "store")
2081    (set_attr "mode" "DI")])
2082
2083 (define_insn "*movabsdi_2_rex64"
2084   [(set (match_operand:DI 0 "register_operand" "=a,r")
2085         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2087   "@
2088    movabs{q}\t{%P1, %0|%0, %P1}
2089    mov{q}\t{%a1, %0|%0, %a1}"
2090   [(set_attr "type" "imov")
2091    (set_attr "modrm" "0,*")
2092    (set_attr "length_address" "8,0")
2093    (set_attr "length_immediate" "0")
2094    (set_attr "memory" "load")
2095    (set_attr "mode" "DI")])
2096
2097 ;; Convert impossible stores of immediate to existing instructions.
2098 ;; First try to get scratch register and go through it.  In case this
2099 ;; fails, move by 32bit parts.
2100 (define_peephole2
2101   [(match_scratch:DI 2 "r")
2102    (set (match_operand:DI 0 "memory_operand" "")
2103         (match_operand:DI 1 "immediate_operand" ""))]
2104   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105    && !x86_64_immediate_operand (operands[1], DImode)"
2106   [(set (match_dup 2) (match_dup 1))
2107    (set (match_dup 0) (match_dup 2))]
2108   "")
2109
2110 ;; We need to define this as both peepholer and splitter for case
2111 ;; peephole2 pass is not run.
2112 ;; "&& 1" is needed to keep it from matching the previous pattern.
2113 (define_peephole2
2114   [(set (match_operand:DI 0 "memory_operand" "")
2115         (match_operand:DI 1 "immediate_operand" ""))]
2116   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2118   [(set (match_dup 2) (match_dup 3))
2119    (set (match_dup 4) (match_dup 5))]
2120   "split_di (operands, 2, operands + 2, operands + 4);")
2121
2122 (define_split
2123   [(set (match_operand:DI 0 "memory_operand" "")
2124         (match_operand:DI 1 "immediate_operand" ""))]
2125   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126                     ? flow2_completed : reload_completed)
2127    && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 3))
2130    (set (match_dup 4) (match_dup 5))]
2131   "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133 (define_insn "*swapdi_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "+r")
2135         (match_operand:DI 1 "register_operand" "+r"))
2136    (set (match_dup 1)
2137         (match_dup 0))]
2138   "TARGET_64BIT"
2139   "xchg{q}\t%1, %0"
2140   [(set_attr "type" "imov")
2141    (set_attr "mode" "DI")
2142    (set_attr "pent_pair" "np")
2143    (set_attr "athlon_decode" "vector")
2144    (set_attr "amdfam10_decode" "double")])   
2145
2146 (define_expand "movti"
2147   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2148         (match_operand:TI 1 "nonimmediate_operand" ""))]
2149   "TARGET_SSE || TARGET_64BIT"
2150 {
2151   if (TARGET_64BIT)
2152     ix86_expand_move (TImode, operands);
2153   else
2154     ix86_expand_vector_move (TImode, operands);
2155   DONE;
2156 })
2157
2158 (define_insn "*movti_internal"
2159   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2160         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2161   "TARGET_SSE && !TARGET_64BIT
2162    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163 {
2164   switch (which_alternative)
2165     {
2166     case 0:
2167       if (get_attr_mode (insn) == MODE_V4SF)
2168         return "xorps\t%0, %0";
2169       else
2170         return "pxor\t%0, %0";
2171     case 1:
2172     case 2:
2173       if (get_attr_mode (insn) == MODE_V4SF)
2174         return "movaps\t{%1, %0|%0, %1}";
2175       else
2176         return "movdqa\t{%1, %0|%0, %1}";
2177     default:
2178       gcc_unreachable ();
2179     }
2180 }
2181   [(set_attr "type" "sselog1,ssemov,ssemov")
2182    (set (attr "mode")
2183         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2184                     (ne (symbol_ref "optimize_size") (const_int 0)))
2185                  (const_string "V4SF")
2186                (and (eq_attr "alternative" "2")
2187                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2188                         (const_int 0)))
2189                  (const_string "V4SF")]
2190               (const_string "TI")))])
2191
2192 (define_insn "*movti_rex64"
2193   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2194         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2195   "TARGET_64BIT
2196    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2197 {
2198   switch (which_alternative)
2199     {
2200     case 0:
2201     case 1:
2202       return "#";
2203     case 2:
2204       if (get_attr_mode (insn) == MODE_V4SF)
2205         return "xorps\t%0, %0";
2206       else
2207         return "pxor\t%0, %0";
2208     case 3:
2209     case 4:
2210       if (get_attr_mode (insn) == MODE_V4SF)
2211         return "movaps\t{%1, %0|%0, %1}";
2212       else
2213         return "movdqa\t{%1, %0|%0, %1}";
2214     default:
2215       gcc_unreachable ();
2216     }
2217 }
2218   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2219    (set (attr "mode")
2220         (cond [(eq_attr "alternative" "2,3")
2221                  (if_then_else
2222                    (ne (symbol_ref "optimize_size")
2223                        (const_int 0))
2224                    (const_string "V4SF")
2225                    (const_string "TI"))
2226                (eq_attr "alternative" "4")
2227                  (if_then_else
2228                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2229                             (const_int 0))
2230                         (ne (symbol_ref "optimize_size")
2231                             (const_int 0)))
2232                    (const_string "V4SF")
2233                    (const_string "TI"))]
2234                (const_string "DI")))])
2235
2236 (define_split
2237   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2238         (match_operand:TI 1 "general_operand" ""))]
2239   "reload_completed && !SSE_REG_P (operands[0])
2240    && !SSE_REG_P (operands[1])"
2241   [(const_int 0)]
2242   "ix86_split_long_move (operands); DONE;")
2243
2244 (define_expand "movsf"
2245   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2246         (match_operand:SF 1 "general_operand" ""))]
2247   ""
2248   "ix86_expand_move (SFmode, operands); DONE;")
2249
2250 (define_insn "*pushsf"
2251   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2252         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2253   "!TARGET_64BIT"
2254 {
2255   /* Anything else should be already split before reg-stack.  */
2256   gcc_assert (which_alternative == 1);
2257   return "push{l}\t%1";
2258 }
2259   [(set_attr "type" "multi,push,multi")
2260    (set_attr "unit" "i387,*,*")
2261    (set_attr "mode" "SF,SI,SF")])
2262
2263 (define_insn "*pushsf_rex64"
2264   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2265         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2266   "TARGET_64BIT"
2267 {
2268   /* Anything else should be already split before reg-stack.  */
2269   gcc_assert (which_alternative == 1);
2270   return "push{q}\t%q1";
2271 }
2272   [(set_attr "type" "multi,push,multi")
2273    (set_attr "unit" "i387,*,*")
2274    (set_attr "mode" "SF,DI,SF")])
2275
2276 (define_split
2277   [(set (match_operand:SF 0 "push_operand" "")
2278         (match_operand:SF 1 "memory_operand" ""))]
2279   "reload_completed
2280    && GET_CODE (operands[1]) == MEM
2281    && constant_pool_reference_p (operands[1])"
2282   [(set (match_dup 0)
2283         (match_dup 1))]
2284   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2285
2286
2287 ;; %%% Kill this when call knows how to work this out.
2288 (define_split
2289   [(set (match_operand:SF 0 "push_operand" "")
2290         (match_operand:SF 1 "any_fp_register_operand" ""))]
2291   "!TARGET_64BIT"
2292   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2293    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2294
2295 (define_split
2296   [(set (match_operand:SF 0 "push_operand" "")
2297         (match_operand:SF 1 "any_fp_register_operand" ""))]
2298   "TARGET_64BIT"
2299   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2300    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2301
2302 (define_insn "*movsf_1"
2303   [(set (match_operand:SF 0 "nonimmediate_operand"
2304           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2305         (match_operand:SF 1 "general_operand"
2306           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2307   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2308    && (reload_in_progress || reload_completed
2309        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2310        || GET_CODE (operands[1]) != CONST_DOUBLE
2311        || memory_operand (operands[0], SFmode))" 
2312 {
2313   switch (which_alternative)
2314     {
2315     case 0:
2316       return output_387_reg_move (insn, operands);
2317
2318     case 1:
2319       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320         return "fstp%z0\t%y0";
2321       else
2322         return "fst%z0\t%y0";
2323
2324     case 2:
2325       return standard_80387_constant_opcode (operands[1]);
2326
2327     case 3:
2328     case 4:
2329       return "mov{l}\t{%1, %0|%0, %1}";
2330     case 5:
2331       if (get_attr_mode (insn) == MODE_TI)
2332         return "pxor\t%0, %0";
2333       else
2334         return "xorps\t%0, %0";
2335     case 6:
2336       if (get_attr_mode (insn) == MODE_V4SF)
2337         return "movaps\t{%1, %0|%0, %1}";
2338       else
2339         return "movss\t{%1, %0|%0, %1}";
2340     case 7:
2341     case 8:
2342       return "movss\t{%1, %0|%0, %1}";
2343
2344     case 9:
2345     case 10:
2346       return "movd\t{%1, %0|%0, %1}";
2347
2348     case 11:
2349       return "movq\t{%1, %0|%0, %1}";
2350
2351     default:
2352       gcc_unreachable ();
2353     }
2354 }
2355   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356    (set (attr "mode")
2357         (cond [(eq_attr "alternative" "3,4,9,10")
2358                  (const_string "SI")
2359                (eq_attr "alternative" "5")
2360                  (if_then_else
2361                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362                                  (const_int 0))
2363                              (ne (symbol_ref "TARGET_SSE2")
2364                                  (const_int 0)))
2365                         (eq (symbol_ref "optimize_size")
2366                             (const_int 0)))
2367                    (const_string "TI")
2368                    (const_string "V4SF"))
2369                /* For architectures resolving dependencies on
2370                   whole SSE registers use APS move to break dependency
2371                   chains, otherwise use short move to avoid extra work. 
2372
2373                   Do the same for architectures resolving dependencies on
2374                   the parts.  While in DF mode it is better to always handle
2375                   just register parts, the SF mode is different due to lack
2376                   of instructions to load just part of the register.  It is
2377                   better to maintain the whole registers in single format
2378                   to avoid problems on using packed logical operations.  */
2379                (eq_attr "alternative" "6")
2380                  (if_then_else
2381                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382                             (const_int 0))
2383                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384                             (const_int 0)))
2385                    (const_string "V4SF")
2386                    (const_string "SF"))
2387                (eq_attr "alternative" "11")
2388                  (const_string "DI")]
2389                (const_string "SF")))])
2390
2391 (define_insn "*swapsf"
2392   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393         (match_operand:SF 1 "fp_register_operand" "+f"))
2394    (set (match_dup 1)
2395         (match_dup 0))]
2396   "reload_completed || TARGET_80387"
2397 {
2398   if (STACK_TOP_P (operands[0]))
2399     return "fxch\t%1";
2400   else
2401     return "fxch\t%0";
2402 }
2403   [(set_attr "type" "fxch")
2404    (set_attr "mode" "SF")])
2405
2406 (define_expand "movdf"
2407   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408         (match_operand:DF 1 "general_operand" ""))]
2409   ""
2410   "ix86_expand_move (DFmode, operands); DONE;")
2411
2412 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2414 ;; On the average, pushdf using integers can be still shorter.  Allow this
2415 ;; pattern for optimize_size too.
2416
2417 (define_insn "*pushdf_nointeger"
2418   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421 {
2422   /* This insn should be already split before reg-stack.  */
2423   gcc_unreachable ();
2424 }
2425   [(set_attr "type" "multi")
2426    (set_attr "unit" "i387,*,*,*")
2427    (set_attr "mode" "DF,SI,SI,DF")])
2428
2429 (define_insn "*pushdf_integer"
2430   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433 {
2434   /* This insn should be already split before reg-stack.  */
2435   gcc_unreachable ();
2436 }
2437   [(set_attr "type" "multi")
2438    (set_attr "unit" "i387,*,*")
2439    (set_attr "mode" "DF,SI,DF")])
2440
2441 ;; %%% Kill this when call knows how to work this out.
2442 (define_split
2443   [(set (match_operand:DF 0 "push_operand" "")
2444         (match_operand:DF 1 "any_fp_register_operand" ""))]
2445   "!TARGET_64BIT && reload_completed"
2446   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2448   "")
2449
2450 (define_split
2451   [(set (match_operand:DF 0 "push_operand" "")
2452         (match_operand:DF 1 "any_fp_register_operand" ""))]
2453   "TARGET_64BIT && reload_completed"
2454   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2456   "")
2457
2458 (define_split
2459   [(set (match_operand:DF 0 "push_operand" "")
2460         (match_operand:DF 1 "general_operand" ""))]
2461   "reload_completed"
2462   [(const_int 0)]
2463   "ix86_split_long_move (operands); DONE;")
2464
2465 ;; Moving is usually shorter when only FP registers are used. This separate
2466 ;; movdf pattern avoids the use of integer registers for FP operations
2467 ;; when optimizing for size.
2468
2469 (define_insn "*movdf_nointeger"
2470   [(set (match_operand:DF 0 "nonimmediate_operand"
2471                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2472         (match_operand:DF 1 "general_operand"
2473                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2474   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2475    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476    && (reload_in_progress || reload_completed
2477        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478        || GET_CODE (operands[1]) != CONST_DOUBLE
2479        || memory_operand (operands[0], DFmode))" 
2480 {
2481   switch (which_alternative)
2482     {
2483     case 0:
2484       return output_387_reg_move (insn, operands);
2485
2486     case 1:
2487       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488         return "fstp%z0\t%y0";
2489       else
2490         return "fst%z0\t%y0";
2491
2492     case 2:
2493       return standard_80387_constant_opcode (operands[1]);
2494
2495     case 3:
2496     case 4:
2497       return "#";
2498     case 5:
2499       switch (get_attr_mode (insn))
2500         {
2501         case MODE_V4SF:
2502           return "xorps\t%0, %0";
2503         case MODE_V2DF:
2504           return "xorpd\t%0, %0";
2505         case MODE_TI:
2506           return "pxor\t%0, %0";
2507         default:
2508           gcc_unreachable ();
2509         }
2510     case 6:
2511     case 7:
2512     case 8:
2513       switch (get_attr_mode (insn))
2514         {
2515         case MODE_V4SF:
2516           return "movaps\t{%1, %0|%0, %1}";
2517         case MODE_V2DF:
2518           return "movapd\t{%1, %0|%0, %1}";
2519         case MODE_TI:
2520           return "movdqa\t{%1, %0|%0, %1}";
2521         case MODE_DI:
2522           return "movq\t{%1, %0|%0, %1}";
2523         case MODE_DF:
2524           return "movsd\t{%1, %0|%0, %1}";
2525         case MODE_V1DF:
2526           return "movlpd\t{%1, %0|%0, %1}";
2527         case MODE_V2SF:
2528           return "movlps\t{%1, %0|%0, %1}";
2529         default:
2530           gcc_unreachable ();
2531         }
2532
2533     default:
2534       gcc_unreachable ();
2535     }
2536 }
2537   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2538    (set (attr "mode")
2539         (cond [(eq_attr "alternative" "0,1,2")
2540                  (const_string "DF")
2541                (eq_attr "alternative" "3,4")
2542                  (const_string "SI")
2543
2544                /* For SSE1, we have many fewer alternatives.  */
2545                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2546                  (cond [(eq_attr "alternative" "5,6")
2547                           (const_string "V4SF")
2548                        ]
2549                    (const_string "V2SF"))
2550
2551                /* xorps is one byte shorter.  */
2552                (eq_attr "alternative" "5")
2553                  (cond [(ne (symbol_ref "optimize_size")
2554                             (const_int 0))
2555                           (const_string "V4SF")
2556                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2557                             (const_int 0))
2558                           (const_string "TI")
2559                        ]
2560                        (const_string "V2DF"))
2561
2562                /* For architectures resolving dependencies on
2563                   whole SSE registers use APD move to break dependency
2564                   chains, otherwise use short move to avoid extra work.
2565
2566                   movaps encodes one byte shorter.  */
2567                (eq_attr "alternative" "6")
2568                  (cond
2569                    [(ne (symbol_ref "optimize_size")
2570                         (const_int 0))
2571                       (const_string "V4SF")
2572                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2573                         (const_int 0))
2574                       (const_string "V2DF")
2575                    ]
2576                    (const_string "DF"))
2577                /* For architectures resolving dependencies on register
2578                   parts we may avoid extra work to zero out upper part
2579                   of register.  */
2580                (eq_attr "alternative" "7")
2581                  (if_then_else
2582                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2583                        (const_int 0))
2584                    (const_string "V1DF")
2585                    (const_string "DF"))
2586               ]
2587               (const_string "DF")))])
2588
2589 (define_insn "*movdf_integer"
2590   [(set (match_operand:DF 0 "nonimmediate_operand"
2591                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2592         (match_operand:DF 1 "general_operand"
2593                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2594   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2595    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2596    && (reload_in_progress || reload_completed
2597        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2598        || GET_CODE (operands[1]) != CONST_DOUBLE
2599        || memory_operand (operands[0], DFmode))" 
2600 {
2601   switch (which_alternative)
2602     {
2603     case 0:
2604       return output_387_reg_move (insn, operands);
2605
2606     case 1:
2607       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2608         return "fstp%z0\t%y0";
2609       else
2610         return "fst%z0\t%y0";
2611
2612     case 2:
2613       return standard_80387_constant_opcode (operands[1]);
2614
2615     case 3:
2616     case 4:
2617       return "#";
2618
2619     case 5:
2620       switch (get_attr_mode (insn))
2621         {
2622         case MODE_V4SF:
2623           return "xorps\t%0, %0";
2624         case MODE_V2DF:
2625           return "xorpd\t%0, %0";
2626         case MODE_TI:
2627           return "pxor\t%0, %0";
2628         default:
2629           gcc_unreachable ();
2630         }
2631     case 6:
2632     case 7:
2633     case 8:
2634       switch (get_attr_mode (insn))
2635         {
2636         case MODE_V4SF:
2637           return "movaps\t{%1, %0|%0, %1}";
2638         case MODE_V2DF:
2639           return "movapd\t{%1, %0|%0, %1}";
2640         case MODE_TI:
2641           return "movdqa\t{%1, %0|%0, %1}";
2642         case MODE_DI:
2643           return "movq\t{%1, %0|%0, %1}";
2644         case MODE_DF:
2645           return "movsd\t{%1, %0|%0, %1}";
2646         case MODE_V1DF:
2647           return "movlpd\t{%1, %0|%0, %1}";
2648         case MODE_V2SF:
2649           return "movlps\t{%1, %0|%0, %1}";
2650         default:
2651           gcc_unreachable ();
2652         }
2653
2654     default:
2655       gcc_unreachable();
2656     }
2657 }
2658   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2659    (set (attr "mode")
2660         (cond [(eq_attr "alternative" "0,1,2")
2661                  (const_string "DF")
2662                (eq_attr "alternative" "3,4")
2663                  (const_string "SI")
2664
2665                /* For SSE1, we have many fewer alternatives.  */
2666                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2667                  (cond [(eq_attr "alternative" "5,6")
2668                           (const_string "V4SF")
2669                        ]
2670                    (const_string "V2SF"))
2671
2672                /* xorps is one byte shorter.  */
2673                (eq_attr "alternative" "5")
2674                  (cond [(ne (symbol_ref "optimize_size")
2675                             (const_int 0))
2676                           (const_string "V4SF")
2677                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2678                             (const_int 0))
2679                           (const_string "TI")
2680                        ]
2681                        (const_string "V2DF"))
2682
2683                /* For architectures resolving dependencies on
2684                   whole SSE registers use APD move to break dependency
2685                   chains, otherwise use short move to avoid extra work.
2686
2687                   movaps encodes one byte shorter.  */
2688                (eq_attr "alternative" "6")
2689                  (cond
2690                    [(ne (symbol_ref "optimize_size")
2691                         (const_int 0))
2692                       (const_string "V4SF")
2693                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2694                         (const_int 0))
2695                       (const_string "V2DF")
2696                    ]
2697                    (const_string "DF"))
2698                /* For architectures resolving dependencies on register
2699                   parts we may avoid extra work to zero out upper part
2700                   of register.  */
2701                (eq_attr "alternative" "7")
2702                  (if_then_else
2703                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2704                        (const_int 0))
2705                    (const_string "V1DF")
2706                    (const_string "DF"))
2707               ]
2708               (const_string "DF")))])
2709
2710 (define_split
2711   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2712         (match_operand:DF 1 "general_operand" ""))]
2713   "reload_completed
2714    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2715    && ! (ANY_FP_REG_P (operands[0]) || 
2716          (GET_CODE (operands[0]) == SUBREG
2717           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2718    && ! (ANY_FP_REG_P (operands[1]) || 
2719          (GET_CODE (operands[1]) == SUBREG
2720           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2721   [(const_int 0)]
2722   "ix86_split_long_move (operands); DONE;")
2723
2724 (define_insn "*swapdf"
2725   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2726         (match_operand:DF 1 "fp_register_operand" "+f"))
2727    (set (match_dup 1)
2728         (match_dup 0))]
2729   "reload_completed || TARGET_80387"
2730 {
2731   if (STACK_TOP_P (operands[0]))
2732     return "fxch\t%1";
2733   else
2734     return "fxch\t%0";
2735 }
2736   [(set_attr "type" "fxch")
2737    (set_attr "mode" "DF")])
2738
2739 (define_expand "movxf"
2740   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2741         (match_operand:XF 1 "general_operand" ""))]
2742   ""
2743   "ix86_expand_move (XFmode, operands); DONE;")
2744
2745 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2746 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2747 ;; Pushing using integer instructions is longer except for constants
2748 ;; and direct memory references.
2749 ;; (assuming that any given constant is pushed only once, but this ought to be
2750 ;;  handled elsewhere).
2751
2752 (define_insn "*pushxf_nointeger"
2753   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2754         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2755   "optimize_size"
2756 {
2757   /* This insn should be already split before reg-stack.  */
2758   gcc_unreachable ();
2759 }
2760   [(set_attr "type" "multi")
2761    (set_attr "unit" "i387,*,*")
2762    (set_attr "mode" "XF,SI,SI")])
2763
2764 (define_insn "*pushxf_integer"
2765   [(set (match_operand:XF 0 "push_operand" "=<,<")
2766         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2767   "!optimize_size"
2768 {
2769   /* This insn should be already split before reg-stack.  */
2770   gcc_unreachable ();
2771 }
2772   [(set_attr "type" "multi")
2773    (set_attr "unit" "i387,*")
2774    (set_attr "mode" "XF,SI")])
2775
2776 (define_split
2777   [(set (match_operand 0 "push_operand" "")
2778         (match_operand 1 "general_operand" ""))]
2779   "reload_completed
2780    && (GET_MODE (operands[0]) == XFmode
2781        || GET_MODE (operands[0]) == DFmode)
2782    && !ANY_FP_REG_P (operands[1])"
2783   [(const_int 0)]
2784   "ix86_split_long_move (operands); DONE;")
2785
2786 (define_split
2787   [(set (match_operand:XF 0 "push_operand" "")
2788         (match_operand:XF 1 "any_fp_register_operand" ""))]
2789   "!TARGET_64BIT"
2790   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2791    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2792   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2793
2794 (define_split
2795   [(set (match_operand:XF 0 "push_operand" "")
2796         (match_operand:XF 1 "any_fp_register_operand" ""))]
2797   "TARGET_64BIT"
2798   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2799    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2800   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2801
2802 ;; Do not use integer registers when optimizing for size
2803 (define_insn "*movxf_nointeger"
2804   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2805         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2806   "optimize_size
2807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808    && (reload_in_progress || reload_completed
2809        || GET_CODE (operands[1]) != CONST_DOUBLE
2810        || memory_operand (operands[0], XFmode))" 
2811 {
2812   switch (which_alternative)
2813     {
2814     case 0:
2815       return output_387_reg_move (insn, operands);
2816
2817     case 1:
2818       /* There is no non-popping store to memory for XFmode.  So if
2819          we need one, follow the store with a load.  */
2820       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821         return "fstp%z0\t%y0\;fld%z0\t%y0";
2822       else
2823         return "fstp%z0\t%y0";
2824
2825     case 2:
2826       return standard_80387_constant_opcode (operands[1]);
2827
2828     case 3: case 4:
2829       return "#";
2830     default:
2831       gcc_unreachable ();
2832     }
2833 }
2834   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835    (set_attr "mode" "XF,XF,XF,SI,SI")])
2836
2837 (define_insn "*movxf_integer"
2838   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2839         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2840   "!optimize_size
2841    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842    && (reload_in_progress || reload_completed
2843        || GET_CODE (operands[1]) != CONST_DOUBLE
2844        || memory_operand (operands[0], XFmode))" 
2845 {
2846   switch (which_alternative)
2847     {
2848     case 0:
2849       return output_387_reg_move (insn, operands);
2850
2851     case 1:
2852       /* There is no non-popping store to memory for XFmode.  So if
2853          we need one, follow the store with a load.  */
2854       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855         return "fstp%z0\t%y0\;fld%z0\t%y0";
2856       else
2857         return "fstp%z0\t%y0";
2858
2859     case 2:
2860       return standard_80387_constant_opcode (operands[1]);
2861
2862     case 3: case 4:
2863       return "#";
2864
2865     default:
2866       gcc_unreachable ();
2867     }
2868 }
2869   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2870    (set_attr "mode" "XF,XF,XF,SI,SI")])
2871
2872 (define_split
2873   [(set (match_operand 0 "nonimmediate_operand" "")
2874         (match_operand 1 "general_operand" ""))]
2875   "reload_completed
2876    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2877    && GET_MODE (operands[0]) == XFmode
2878    && ! (ANY_FP_REG_P (operands[0]) || 
2879          (GET_CODE (operands[0]) == SUBREG
2880           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2881    && ! (ANY_FP_REG_P (operands[1]) || 
2882          (GET_CODE (operands[1]) == SUBREG
2883           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2884   [(const_int 0)]
2885   "ix86_split_long_move (operands); DONE;")
2886
2887 (define_split
2888   [(set (match_operand 0 "register_operand" "")
2889         (match_operand 1 "memory_operand" ""))]
2890   "reload_completed
2891    && GET_CODE (operands[1]) == MEM
2892    && (GET_MODE (operands[0]) == XFmode
2893        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2894    && constant_pool_reference_p (operands[1])"
2895   [(set (match_dup 0) (match_dup 1))]
2896 {
2897   rtx c = avoid_constant_pool_reference (operands[1]);
2898   rtx r = operands[0];
2899
2900   if (GET_CODE (r) == SUBREG)
2901     r = SUBREG_REG (r);
2902
2903   if (SSE_REG_P (r))
2904     {
2905       if (!standard_sse_constant_p (c))
2906         FAIL;
2907     }
2908   else if (FP_REG_P (r))
2909     {
2910       if (!standard_80387_constant_p (c))
2911         FAIL;
2912     }
2913   else if (MMX_REG_P (r))
2914     FAIL;
2915
2916   operands[1] = c;
2917 })
2918
2919 (define_insn "swapxf"
2920   [(set (match_operand:XF 0 "register_operand" "+f")
2921         (match_operand:XF 1 "register_operand" "+f"))
2922    (set (match_dup 1)
2923         (match_dup 0))]
2924   "TARGET_80387"
2925 {
2926   if (STACK_TOP_P (operands[0]))
2927     return "fxch\t%1";
2928   else
2929     return "fxch\t%0";
2930 }
2931   [(set_attr "type" "fxch")
2932    (set_attr "mode" "XF")])
2933
2934 (define_expand "movtf"
2935   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2936         (match_operand:TF 1 "nonimmediate_operand" ""))]
2937   "TARGET_64BIT"
2938 {
2939   ix86_expand_move (TFmode, operands);
2940   DONE;
2941 })
2942
2943 (define_insn "*movtf_internal"
2944   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2945         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2946   "TARGET_64BIT
2947    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2948 {
2949   switch (which_alternative)
2950     {
2951     case 0:
2952     case 1:
2953       return "#";
2954     case 2:
2955       if (get_attr_mode (insn) == MODE_V4SF)
2956         return "xorps\t%0, %0";
2957       else
2958         return "pxor\t%0, %0";
2959     case 3:
2960     case 4:
2961       if (get_attr_mode (insn) == MODE_V4SF)
2962         return "movaps\t{%1, %0|%0, %1}";
2963       else
2964         return "movdqa\t{%1, %0|%0, %1}";
2965     default:
2966       gcc_unreachable ();
2967     }
2968 }
2969   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2970    (set (attr "mode")
2971         (cond [(eq_attr "alternative" "2,3")
2972                  (if_then_else
2973                    (ne (symbol_ref "optimize_size")
2974                        (const_int 0))
2975                    (const_string "V4SF")
2976                    (const_string "TI"))
2977                (eq_attr "alternative" "4")
2978                  (if_then_else
2979                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2980                             (const_int 0))
2981                         (ne (symbol_ref "optimize_size")
2982                             (const_int 0)))
2983                    (const_string "V4SF")
2984                    (const_string "TI"))]
2985                (const_string "DI")))])
2986
2987 (define_split
2988   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2989         (match_operand:TF 1 "general_operand" ""))]
2990   "reload_completed && !SSE_REG_P (operands[0])
2991    && !SSE_REG_P (operands[1])"
2992   [(const_int 0)]
2993   "ix86_split_long_move (operands); DONE;")
2994 \f
2995 ;; Zero extension instructions
2996
2997 (define_expand "zero_extendhisi2"
2998   [(set (match_operand:SI 0 "register_operand" "")
2999      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3000   ""
3001 {
3002   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3003     {
3004       operands[1] = force_reg (HImode, operands[1]);
3005       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3006       DONE;
3007     }
3008 })
3009
3010 (define_insn "zero_extendhisi2_and"
3011   [(set (match_operand:SI 0 "register_operand" "=r")
3012      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3013    (clobber (reg:CC FLAGS_REG))]
3014   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015   "#"
3016   [(set_attr "type" "alu1")
3017    (set_attr "mode" "SI")])
3018
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3024   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3025               (clobber (reg:CC FLAGS_REG))])]
3026   "")
3027
3028 (define_insn "*zero_extendhisi2_movzwl"
3029   [(set (match_operand:SI 0 "register_operand" "=r")
3030      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3031   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032   "movz{wl|x}\t{%1, %0|%0, %1}"
3033   [(set_attr "type" "imovx")
3034    (set_attr "mode" "SI")])
3035
3036 (define_expand "zero_extendqihi2"
3037   [(parallel
3038     [(set (match_operand:HI 0 "register_operand" "")
3039        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3040      (clobber (reg:CC FLAGS_REG))])]
3041   ""
3042   "")
3043
3044 (define_insn "*zero_extendqihi2_and"
3045   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3046      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3049   "#"
3050   [(set_attr "type" "alu1")
3051    (set_attr "mode" "HI")])
3052
3053 (define_insn "*zero_extendqihi2_movzbw_and"
3054   [(set (match_operand:HI 0 "register_operand" "=r,r")
3055      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3056    (clobber (reg:CC FLAGS_REG))]
3057   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3058   "#"
3059   [(set_attr "type" "imovx,alu1")
3060    (set_attr "mode" "HI")])
3061
3062 ; zero extend to SImode here to avoid partial register stalls
3063 (define_insn "*zero_extendqihi2_movzbl"
3064   [(set (match_operand:HI 0 "register_operand" "=r")
3065      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3066   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3067   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3068   [(set_attr "type" "imovx")
3069    (set_attr "mode" "SI")])
3070
3071 ;; For the movzbw case strip only the clobber
3072 (define_split
3073   [(set (match_operand:HI 0 "register_operand" "")
3074         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3075    (clobber (reg:CC FLAGS_REG))]
3076   "reload_completed 
3077    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3078    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3079   [(set (match_operand:HI 0 "register_operand" "")
3080         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3081
3082 ;; When source and destination does not overlap, clear destination
3083 ;; first and then do the movb
3084 (define_split
3085   [(set (match_operand:HI 0 "register_operand" "")
3086         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3087    (clobber (reg:CC FLAGS_REG))]
3088   "reload_completed
3089    && ANY_QI_REG_P (operands[0])
3090    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3091    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3092   [(set (match_dup 0) (const_int 0))
3093    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3094   "operands[2] = gen_lowpart (QImode, operands[0]);")
3095
3096 ;; Rest is handled by single and.
3097 (define_split
3098   [(set (match_operand:HI 0 "register_operand" "")
3099         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "reload_completed
3102    && true_regnum (operands[0]) == true_regnum (operands[1])"
3103   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3104               (clobber (reg:CC FLAGS_REG))])]
3105   "")
3106
3107 (define_expand "zero_extendqisi2"
3108   [(parallel
3109     [(set (match_operand:SI 0 "register_operand" "")
3110        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111      (clobber (reg:CC FLAGS_REG))])]
3112   ""
3113   "")
3114
3115 (define_insn "*zero_extendqisi2_and"
3116   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3117      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3120   "#"
3121   [(set_attr "type" "alu1")
3122    (set_attr "mode" "SI")])
3123
3124 (define_insn "*zero_extendqisi2_movzbw_and"
3125   [(set (match_operand:SI 0 "register_operand" "=r,r")
3126      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3127    (clobber (reg:CC FLAGS_REG))]
3128   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3129   "#"
3130   [(set_attr "type" "imovx,alu1")
3131    (set_attr "mode" "SI")])
3132
3133 (define_insn "*zero_extendqisi2_movzbw"
3134   [(set (match_operand:SI 0 "register_operand" "=r")
3135      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3136   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3137   "movz{bl|x}\t{%1, %0|%0, %1}"
3138   [(set_attr "type" "imovx")
3139    (set_attr "mode" "SI")])
3140
3141 ;; For the movzbl case strip only the clobber
3142 (define_split
3143   [(set (match_operand:SI 0 "register_operand" "")
3144         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3145    (clobber (reg:CC FLAGS_REG))]
3146   "reload_completed 
3147    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3148    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3149   [(set (match_dup 0)
3150         (zero_extend:SI (match_dup 1)))])
3151
3152 ;; When source and destination does not overlap, clear destination
3153 ;; first and then do the movb
3154 (define_split
3155   [(set (match_operand:SI 0 "register_operand" "")
3156         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3157    (clobber (reg:CC FLAGS_REG))]
3158   "reload_completed
3159    && ANY_QI_REG_P (operands[0])
3160    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3161    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3162    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3163   [(set (match_dup 0) (const_int 0))
3164    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3165   "operands[2] = gen_lowpart (QImode, operands[0]);")
3166
3167 ;; Rest is handled by single and.
3168 (define_split
3169   [(set (match_operand:SI 0 "register_operand" "")
3170         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "reload_completed
3173    && true_regnum (operands[0]) == true_regnum (operands[1])"
3174   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3175               (clobber (reg:CC FLAGS_REG))])]
3176   "")
3177
3178 ;; %%% Kill me once multi-word ops are sane.
3179 (define_expand "zero_extendsidi2"
3180   [(set (match_operand:DI 0 "register_operand" "=r")
3181      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3182   ""
3183   "if (!TARGET_64BIT)
3184      {
3185        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3186        DONE;
3187      }
3188   ")
3189
3190 (define_insn "zero_extendsidi2_32"
3191   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3192         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3193    (clobber (reg:CC FLAGS_REG))]
3194   "!TARGET_64BIT"
3195   "@
3196    #
3197    #
3198    #
3199    movd\t{%1, %0|%0, %1}
3200    movd\t{%1, %0|%0, %1}"
3201   [(set_attr "mode" "SI,SI,SI,DI,TI")
3202    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3203
3204 (define_insn "zero_extendsidi2_rex64"
3205   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3206      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3207   "TARGET_64BIT"
3208   "@
3209    mov\t{%k1, %k0|%k0, %k1}
3210    #
3211    movd\t{%1, %0|%0, %1}
3212    movd\t{%1, %0|%0, %1}"
3213   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3214    (set_attr "mode" "SI,DI,SI,SI")])
3215
3216 (define_split
3217   [(set (match_operand:DI 0 "memory_operand" "")
3218      (zero_extend:DI (match_dup 0)))]
3219   "TARGET_64BIT"
3220   [(set (match_dup 4) (const_int 0))]
3221   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3222
3223 (define_split 
3224   [(set (match_operand:DI 0 "register_operand" "")
3225         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3226    (clobber (reg:CC FLAGS_REG))]
3227   "!TARGET_64BIT && reload_completed
3228    && true_regnum (operands[0]) == true_regnum (operands[1])"
3229   [(set (match_dup 4) (const_int 0))]
3230   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3231
3232 (define_split 
3233   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3234         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3235    (clobber (reg:CC FLAGS_REG))]
3236   "!TARGET_64BIT && reload_completed
3237    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3238   [(set (match_dup 3) (match_dup 1))
3239    (set (match_dup 4) (const_int 0))]
3240   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3241
3242 (define_insn "zero_extendhidi2"
3243   [(set (match_operand:DI 0 "register_operand" "=r")
3244      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3245   "TARGET_64BIT"
3246   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3247   [(set_attr "type" "imovx")
3248    (set_attr "mode" "DI")])
3249
3250 (define_insn "zero_extendqidi2"
3251   [(set (match_operand:DI 0 "register_operand" "=r")
3252      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3253   "TARGET_64BIT"
3254   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3255   [(set_attr "type" "imovx")
3256    (set_attr "mode" "DI")])
3257 \f
3258 ;; Sign extension instructions
3259
3260 (define_expand "extendsidi2"
3261   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3262                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263               (clobber (reg:CC FLAGS_REG))
3264               (clobber (match_scratch:SI 2 ""))])]
3265   ""
3266 {
3267   if (TARGET_64BIT)
3268     {
3269       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3270       DONE;
3271     }
3272 })
3273
3274 (define_insn "*extendsidi2_1"
3275   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3276         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3277    (clobber (reg:CC FLAGS_REG))
3278    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3279   "!TARGET_64BIT"
3280   "#")
3281
3282 (define_insn "extendsidi2_rex64"
3283   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3284         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3285   "TARGET_64BIT"
3286   "@
3287    {cltq|cdqe}
3288    movs{lq|x}\t{%1,%0|%0, %1}"
3289   [(set_attr "type" "imovx")
3290    (set_attr "mode" "DI")
3291    (set_attr "prefix_0f" "0")
3292    (set_attr "modrm" "0,1")])
3293
3294 (define_insn "extendhidi2"
3295   [(set (match_operand:DI 0 "register_operand" "=r")
3296         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3297   "TARGET_64BIT"
3298   "movs{wq|x}\t{%1,%0|%0, %1}"
3299   [(set_attr "type" "imovx")
3300    (set_attr "mode" "DI")])
3301
3302 (define_insn "extendqidi2"
3303   [(set (match_operand:DI 0 "register_operand" "=r")
3304         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3305   "TARGET_64BIT"
3306   "movs{bq|x}\t{%1,%0|%0, %1}"
3307    [(set_attr "type" "imovx")
3308     (set_attr "mode" "DI")])
3309
3310 ;; Extend to memory case when source register does die.
3311 (define_split 
3312   [(set (match_operand:DI 0 "memory_operand" "")
3313         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3314    (clobber (reg:CC FLAGS_REG))
3315    (clobber (match_operand:SI 2 "register_operand" ""))]
3316   "(reload_completed
3317     && dead_or_set_p (insn, operands[1])
3318     && !reg_mentioned_p (operands[1], operands[0]))"
3319   [(set (match_dup 3) (match_dup 1))
3320    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3321               (clobber (reg:CC FLAGS_REG))])
3322    (set (match_dup 4) (match_dup 1))]
3323   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3324
3325 ;; Extend to memory case when source register does not die.
3326 (define_split 
3327   [(set (match_operand:DI 0 "memory_operand" "")
3328         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329    (clobber (reg:CC FLAGS_REG))
3330    (clobber (match_operand:SI 2 "register_operand" ""))]
3331   "reload_completed"
3332   [(const_int 0)]
3333 {
3334   split_di (&operands[0], 1, &operands[3], &operands[4]);
3335
3336   emit_move_insn (operands[3], operands[1]);
3337
3338   /* Generate a cltd if possible and doing so it profitable.  */
3339   if (true_regnum (operands[1]) == 0
3340       && true_regnum (operands[2]) == 1
3341       && (optimize_size || TARGET_USE_CLTD))
3342     {
3343       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3344     }
3345   else
3346     {
3347       emit_move_insn (operands[2], operands[1]);
3348       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3349     }
3350   emit_move_insn (operands[4], operands[2]);
3351   DONE;
3352 })
3353
3354 ;; Extend to register case.  Optimize case where source and destination
3355 ;; registers match and cases where we can use cltd.
3356 (define_split 
3357   [(set (match_operand:DI 0 "register_operand" "")
3358         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3359    (clobber (reg:CC FLAGS_REG))
3360    (clobber (match_scratch:SI 2 ""))]
3361   "reload_completed"
3362   [(const_int 0)]
3363 {
3364   split_di (&operands[0], 1, &operands[3], &operands[4]);
3365
3366   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3367     emit_move_insn (operands[3], operands[1]);
3368
3369   /* Generate a cltd if possible and doing so it profitable.  */
3370   if (true_regnum (operands[3]) == 0
3371       && (optimize_size || TARGET_USE_CLTD))
3372     {
3373       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3374       DONE;
3375     }
3376
3377   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3378     emit_move_insn (operands[4], operands[1]);
3379
3380   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3381   DONE;
3382 })
3383
3384 (define_insn "extendhisi2"
3385   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3386         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3387   ""
3388 {
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cwtl|cwde}";
3393     default:
3394       return "movs{wl|x}\t{%1,%0|%0, %1}";
3395     }
3396 }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "SI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3409
3410 (define_insn "*extendhisi2_zext"
3411   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3412         (zero_extend:DI
3413           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3414   "TARGET_64BIT"
3415 {
3416   switch (get_attr_prefix_0f (insn))
3417     {
3418     case 0:
3419       return "{cwtl|cwde}";
3420     default:
3421       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3422     }
3423 }
3424   [(set_attr "type" "imovx")
3425    (set_attr "mode" "SI")
3426    (set (attr "prefix_0f")
3427      ;; movsx is short decodable while cwtl is vector decoded.
3428      (if_then_else (and (eq_attr "cpu" "!k6")
3429                         (eq_attr "alternative" "0"))
3430         (const_string "0")
3431         (const_string "1")))
3432    (set (attr "modrm")
3433      (if_then_else (eq_attr "prefix_0f" "0")
3434         (const_string "0")
3435         (const_string "1")))])
3436
3437 (define_insn "extendqihi2"
3438   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3439         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3440   ""
3441 {
3442   switch (get_attr_prefix_0f (insn))
3443     {
3444     case 0:
3445       return "{cbtw|cbw}";
3446     default:
3447       return "movs{bw|x}\t{%1,%0|%0, %1}";
3448     }
3449 }
3450   [(set_attr "type" "imovx")
3451    (set_attr "mode" "HI")
3452    (set (attr "prefix_0f")
3453      ;; movsx is short decodable while cwtl is vector decoded.
3454      (if_then_else (and (eq_attr "cpu" "!k6")
3455                         (eq_attr "alternative" "0"))
3456         (const_string "0")
3457         (const_string "1")))
3458    (set (attr "modrm")
3459      (if_then_else (eq_attr "prefix_0f" "0")
3460         (const_string "0")
3461         (const_string "1")))])
3462
3463 (define_insn "extendqisi2"
3464   [(set (match_operand:SI 0 "register_operand" "=r")
3465         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3466   ""
3467   "movs{bl|x}\t{%1,%0|%0, %1}"
3468    [(set_attr "type" "imovx")
3469     (set_attr "mode" "SI")])
3470
3471 (define_insn "*extendqisi2_zext"
3472   [(set (match_operand:DI 0 "register_operand" "=r")
3473         (zero_extend:DI
3474           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3475   "TARGET_64BIT"
3476   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3477    [(set_attr "type" "imovx")
3478     (set_attr "mode" "SI")])
3479 \f
3480 ;; Conversions between float and double.
3481
3482 ;; These are all no-ops in the model used for the 80387.  So just
3483 ;; emit moves.
3484
3485 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3486 (define_insn "*dummy_extendsfdf2"
3487   [(set (match_operand:DF 0 "push_operand" "=<")
3488         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3489   "0"
3490   "#")
3491
3492 (define_split
3493   [(set (match_operand:DF 0 "push_operand" "")
3494         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3495   "!TARGET_64BIT"
3496   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3497    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3498
3499 (define_split
3500   [(set (match_operand:DF 0 "push_operand" "")
3501         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3502   "TARGET_64BIT"
3503   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3504    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3505
3506 (define_insn "*dummy_extendsfxf2"
3507   [(set (match_operand:XF 0 "push_operand" "=<")
3508         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3509   "0"
3510   "#")
3511
3512 (define_split
3513   [(set (match_operand:XF 0 "push_operand" "")
3514         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3515   ""
3516   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3517    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3518   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3519
3520 (define_split
3521   [(set (match_operand:XF 0 "push_operand" "")
3522         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3523   "TARGET_64BIT"
3524   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3525    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3526   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3527
3528 (define_split
3529   [(set (match_operand:XF 0 "push_operand" "")
3530         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3531   ""
3532   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3533    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3534   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3535
3536 (define_split
3537   [(set (match_operand:XF 0 "push_operand" "")
3538         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3539   "TARGET_64BIT"
3540   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3541    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3542   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3543
3544 (define_expand "extendsfdf2"
3545   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3546         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3547   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3548 {
3549   /* ??? Needed for compress_float_constant since all fp constants
3550      are LEGITIMATE_CONSTANT_P.  */
3551   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3552     {
3553       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3554           && standard_80387_constant_p (operands[1]) > 0)
3555         {
3556           operands[1] = simplify_const_unary_operation
3557             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3558           emit_move_insn_1 (operands[0], operands[1]);
3559           DONE;
3560         }
3561       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3562     }
3563   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3564     operands[1] = force_reg (SFmode, operands[1]);
3565 })
3566
3567 (define_insn "*extendsfdf2_mixed"
3568   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3570   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572 {
3573   switch (which_alternative)
3574     {
3575     case 0:
3576       return output_387_reg_move (insn, operands);
3577
3578     case 1:
3579       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580         return "fstp%z0\t%y0";
3581       else
3582         return "fst%z0\t%y0";
3583
3584     case 2:
3585       return "cvtss2sd\t{%1, %0|%0, %1}";
3586
3587     default:
3588       gcc_unreachable ();
3589     }
3590 }
3591   [(set_attr "type" "fmov,fmov,ssecvt")
3592    (set_attr "mode" "SF,XF,DF")])
3593
3594 (define_insn "*extendsfdf2_sse"
3595   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597   "TARGET_SSE2 && TARGET_SSE_MATH
3598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3599   "cvtss2sd\t{%1, %0|%0, %1}"
3600   [(set_attr "type" "ssecvt")
3601    (set_attr "mode" "DF")])
3602
3603 (define_insn "*extendsfdf2_i387"
3604   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3605         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3606   "TARGET_80387
3607    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608 {
3609   switch (which_alternative)
3610     {
3611     case 0:
3612       return output_387_reg_move (insn, operands);
3613
3614     case 1:
3615       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3616         return "fstp%z0\t%y0";
3617       else
3618         return "fst%z0\t%y0";
3619
3620     default:
3621       gcc_unreachable ();
3622     }
3623 }
3624   [(set_attr "type" "fmov")
3625    (set_attr "mode" "SF,XF")])
3626
3627 (define_expand "extendsfxf2"
3628   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3629         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3630   "TARGET_80387"
3631 {
3632   /* ??? Needed for compress_float_constant since all fp constants
3633      are LEGITIMATE_CONSTANT_P.  */
3634   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3635     {
3636       if (standard_80387_constant_p (operands[1]) > 0)
3637         {
3638           operands[1] = simplify_const_unary_operation
3639             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3640           emit_move_insn_1 (operands[0], operands[1]);
3641           DONE;
3642         }
3643       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3644     }
3645   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3646     operands[1] = force_reg (SFmode, operands[1]);
3647 })
3648
3649 (define_insn "*extendsfxf2_i387"
3650   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3651         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3652   "TARGET_80387
3653    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3654 {
3655   switch (which_alternative)
3656     {
3657     case 0:
3658       return output_387_reg_move (insn, operands);
3659
3660     case 1:
3661       /* There is no non-popping store to memory for XFmode.  So if
3662          we need one, follow the store with a load.  */
3663       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3664         return "fstp%z0\t%y0";
3665       else
3666         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3667
3668     default:
3669       gcc_unreachable ();
3670     }
3671 }
3672   [(set_attr "type" "fmov")
3673    (set_attr "mode" "SF,XF")])
3674
3675 (define_expand "extenddfxf2"
3676   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3677         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3678   "TARGET_80387"
3679 {
3680   /* ??? Needed for compress_float_constant since all fp constants
3681      are LEGITIMATE_CONSTANT_P.  */
3682   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3683     {
3684       if (standard_80387_constant_p (operands[1]) > 0)
3685         {
3686           operands[1] = simplify_const_unary_operation
3687             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3688           emit_move_insn_1 (operands[0], operands[1]);
3689           DONE;
3690         }
3691       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3692     }
3693   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3694     operands[1] = force_reg (DFmode, operands[1]);
3695 })
3696
3697 (define_insn "*extenddfxf2_i387"
3698   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3699         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3700   "TARGET_80387
3701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3702 {
3703   switch (which_alternative)
3704     {
3705     case 0:
3706       return output_387_reg_move (insn, operands);
3707
3708     case 1:
3709       /* There is no non-popping store to memory for XFmode.  So if
3710          we need one, follow the store with a load.  */
3711       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3713       else
3714         return "fstp%z0\t%y0";
3715
3716     default:
3717       gcc_unreachable ();
3718     }
3719 }
3720   [(set_attr "type" "fmov")
3721    (set_attr "mode" "DF,XF")])
3722
3723 ;; %%% This seems bad bad news.
3724 ;; This cannot output into an f-reg because there is no way to be sure
3725 ;; of truncating in that case.  Otherwise this is just like a simple move
3726 ;; insn.  So we pretend we can output to a reg in order to get better
3727 ;; register preferencing, but we really use a stack slot.
3728
3729 ;; Conversion from DFmode to SFmode.
3730
3731 (define_expand "truncdfsf2"
3732   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "")))]
3735   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3736 {
3737   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3738     operands[1] = force_reg (DFmode, operands[1]);
3739
3740   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3741     ;
3742   else if (flag_unsafe_math_optimizations)
3743     ;
3744   else
3745     {
3746       rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3747       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3748       DONE;
3749     }
3750 })
3751
3752 (define_expand "truncdfsf2_with_temp"
3753   [(parallel [(set (match_operand:SF 0 "" "")
3754                    (float_truncate:SF (match_operand:DF 1 "" "")))
3755               (clobber (match_operand:SF 2 "" ""))])]
3756   "")
3757
3758 (define_insn "*truncdfsf_fast_mixed"
3759   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3760         (float_truncate:SF
3761           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3762   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3763 {
3764   switch (which_alternative)
3765     {
3766     case 0:
3767       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768         return "fstp%z0\t%y0";
3769       else
3770         return "fst%z0\t%y0";
3771     case 1:
3772       return output_387_reg_move (insn, operands);
3773     case 2:
3774       return "cvtsd2ss\t{%1, %0|%0, %1}";
3775     default:
3776       gcc_unreachable ();
3777     }
3778 }
3779   [(set_attr "type" "fmov,fmov,ssecvt")
3780    (set_attr "mode" "SF")])
3781
3782 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3783 ;; because nothing we do here is unsafe.
3784 (define_insn "*truncdfsf_fast_sse"
3785   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3786         (float_truncate:SF
3787           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3788   "TARGET_SSE2 && TARGET_SSE_MATH"
3789   "cvtsd2ss\t{%1, %0|%0, %1}"
3790   [(set_attr "type" "ssecvt")
3791    (set_attr "mode" "SF")])
3792
3793 (define_insn "*truncdfsf_fast_i387"
3794   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3795         (float_truncate:SF
3796           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797   "TARGET_80387 && flag_unsafe_math_optimizations"
3798   "* return output_387_reg_move (insn, operands);"
3799   [(set_attr "type" "fmov")
3800    (set_attr "mode" "SF")])
3801
3802 (define_insn "*truncdfsf_mixed"
3803   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3804         (float_truncate:SF
3805           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3806    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3807   "TARGET_MIX_SSE_I387"
3808 {
3809   switch (which_alternative)
3810     {
3811     case 0:
3812       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813         return "fstp%z0\t%y0";
3814       else
3815         return "fst%z0\t%y0";
3816     case 1:
3817       return "#";
3818     case 2:
3819       return "cvtsd2ss\t{%1, %0|%0, %1}";
3820     default:
3821       gcc_unreachable ();
3822     }
3823 }
3824   [(set_attr "type" "fmov,multi,ssecvt")
3825    (set_attr "unit" "*,i387,*")
3826    (set_attr "mode" "SF")])
3827
3828 (define_insn "*truncdfsf_i387"
3829   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3830         (float_truncate:SF
3831           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3832    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3833   "TARGET_80387"
3834 {
3835   switch (which_alternative)
3836     {
3837     case 0:
3838       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3839         return "fstp%z0\t%y0";
3840       else
3841         return "fst%z0\t%y0";
3842     case 1:
3843       return "#";
3844     default:
3845       gcc_unreachable ();
3846     }
3847 }
3848   [(set_attr "type" "fmov,multi")
3849    (set_attr "unit" "*,i387")
3850    (set_attr "mode" "SF")])
3851
3852 (define_insn "*truncdfsf2_i387_1"
3853   [(set (match_operand:SF 0 "memory_operand" "=m")
3854         (float_truncate:SF
3855           (match_operand:DF 1 "register_operand" "f")))]
3856   "TARGET_80387
3857    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3858    && !TARGET_MIX_SSE_I387"
3859 {
3860   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3861     return "fstp%z0\t%y0";
3862   else
3863     return "fst%z0\t%y0";
3864 }
3865   [(set_attr "type" "fmov")
3866    (set_attr "mode" "SF")])
3867
3868 (define_split
3869   [(set (match_operand:SF 0 "register_operand" "")
3870         (float_truncate:SF
3871          (match_operand:DF 1 "fp_register_operand" "")))
3872    (clobber (match_operand 2 "" ""))]
3873   "reload_completed"
3874   [(set (match_dup 2) (match_dup 1))
3875    (set (match_dup 0) (match_dup 2))]
3876 {
3877   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3878 })
3879
3880 ;; Conversion from XFmode to SFmode.
3881
3882 (define_expand "truncxfsf2"
3883   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3884                    (float_truncate:SF
3885                     (match_operand:XF 1 "register_operand" "")))
3886               (clobber (match_dup 2))])]
3887   "TARGET_80387"
3888 {
3889   if (flag_unsafe_math_optimizations)
3890     {
3891       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3892       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3893       if (reg != operands[0])
3894         emit_move_insn (operands[0], reg);
3895       DONE;
3896     }
3897   else
3898     operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3899 })
3900
3901 (define_insn "*truncxfsf2_mixed"
3902   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3903         (float_truncate:SF
3904          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3905    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3906   "TARGET_MIX_SSE_I387"
3907 {
3908   gcc_assert (!which_alternative);
3909   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910     return "fstp%z0\t%y0";
3911   else
3912     return "fst%z0\t%y0";
3913 }
3914   [(set_attr "type" "fmov,multi,multi,multi")
3915    (set_attr "unit" "*,i387,i387,i387")
3916    (set_attr "mode" "SF")])
3917
3918 (define_insn "truncxfsf2_i387_noop"
3919   [(set (match_operand:SF 0 "register_operand" "=f")
3920         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387 && flag_unsafe_math_optimizations"
3922 {
3923   return output_387_reg_move (insn, operands);
3924 }
3925   [(set_attr "type" "fmov")
3926    (set_attr "mode" "SF")])
3927
3928 (define_insn "*truncxfsf2_i387"
3929   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3930         (float_truncate:SF
3931          (match_operand:XF 1 "register_operand" "f,f,f")))
3932    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3933   "TARGET_80387"
3934 {
3935   gcc_assert (!which_alternative);
3936   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3937     return "fstp%z0\t%y0";
3938    else
3939      return "fst%z0\t%y0";
3940 }
3941   [(set_attr "type" "fmov,multi,multi")
3942    (set_attr "unit" "*,i387,i387")
3943    (set_attr "mode" "SF")])
3944
3945 (define_insn "*truncxfsf2_i387_1"
3946   [(set (match_operand:SF 0 "memory_operand" "=m")
3947         (float_truncate:SF
3948          (match_operand:XF 1 "register_operand" "f")))]
3949   "TARGET_80387"
3950 {
3951   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952     return "fstp%z0\t%y0";
3953   else
3954     return "fst%z0\t%y0";
3955 }
3956   [(set_attr "type" "fmov")
3957    (set_attr "mode" "SF")])
3958
3959 (define_split
3960   [(set (match_operand:SF 0 "register_operand" "")
3961         (float_truncate:SF
3962          (match_operand:XF 1 "register_operand" "")))
3963    (clobber (match_operand:SF 2 "memory_operand" ""))]
3964   "TARGET_80387 && reload_completed"
3965   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3966    (set (match_dup 0) (match_dup 2))]
3967   "")
3968
3969 (define_split
3970   [(set (match_operand:SF 0 "memory_operand" "")
3971         (float_truncate:SF
3972          (match_operand:XF 1 "register_operand" "")))
3973    (clobber (match_operand:SF 2 "memory_operand" ""))]
3974   "TARGET_80387"
3975   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3976   "")
3977
3978 ;; Conversion from XFmode to DFmode.
3979
3980 (define_expand "truncxfdf2"
3981   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3982                    (float_truncate:DF
3983                     (match_operand:XF 1 "register_operand" "")))
3984               (clobber (match_dup 2))])]
3985   "TARGET_80387"
3986 {
3987   if (flag_unsafe_math_optimizations)
3988     {
3989       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3990       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3991       if (reg != operands[0])
3992         emit_move_insn (operands[0], reg);
3993       DONE;
3994     }
3995   else
3996     operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3997 })
3998
3999 (define_insn "*truncxfdf2_mixed"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4001         (float_truncate:DF
4002          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4003    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4004   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4005 {
4006   gcc_assert (!which_alternative);
4007   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008     return "fstp%z0\t%y0";
4009   else
4010     return "fst%z0\t%y0";
4011 }
4012   [(set_attr "type" "fmov,multi,multi,multi")
4013    (set_attr "unit" "*,i387,i387,i387")
4014    (set_attr "mode" "DF")])
4015
4016 (define_insn "truncxfdf2_i387_noop"
4017   [(set (match_operand:DF 0 "register_operand" "=f")
4018         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4019   "TARGET_80387 && flag_unsafe_math_optimizations"
4020 {
4021   return output_387_reg_move (insn, operands);
4022 }
4023   [(set_attr "type" "fmov")
4024    (set_attr "mode" "DF")])
4025
4026 (define_insn "*truncxfdf2_i387"
4027   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4028         (float_truncate:DF
4029          (match_operand:XF 1 "register_operand" "f,f,f")))
4030    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4031   "TARGET_80387"
4032 {
4033   gcc_assert (!which_alternative);
4034   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035     return "fstp%z0\t%y0";
4036   else
4037     return "fst%z0\t%y0";
4038 }
4039   [(set_attr "type" "fmov,multi,multi")
4040    (set_attr "unit" "*,i387,i387")
4041    (set_attr "mode" "DF")])
4042
4043 (define_insn "*truncxfdf2_i387_1"
4044   [(set (match_operand:DF 0 "memory_operand" "=m")
4045         (float_truncate:DF
4046           (match_operand:XF 1 "register_operand" "f")))]
4047   "TARGET_80387"
4048 {
4049   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4050     return "fstp%z0\t%y0";
4051   else
4052     return "fst%z0\t%y0";
4053 }
4054   [(set_attr "type" "fmov")
4055    (set_attr "mode" "DF")])
4056
4057 (define_split
4058   [(set (match_operand:DF 0 "register_operand" "")
4059         (float_truncate:DF
4060          (match_operand:XF 1 "register_operand" "")))
4061    (clobber (match_operand:DF 2 "memory_operand" ""))]
4062   "TARGET_80387 && reload_completed"
4063   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4064    (set (match_dup 0) (match_dup 2))]
4065   "")
4066
4067 (define_split
4068   [(set (match_operand:DF 0 "memory_operand" "")
4069         (float_truncate:DF
4070          (match_operand:XF 1 "register_operand" "")))
4071    (clobber (match_operand:DF 2 "memory_operand" ""))]
4072   "TARGET_80387"
4073   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4074   "")
4075 \f
4076 ;; Signed conversion to DImode.
4077
4078 (define_expand "fix_truncxfdi2"
4079   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4081               (clobber (reg:CC FLAGS_REG))])]
4082   "TARGET_80387"
4083 {
4084   if (TARGET_FISTTP)
4085    {
4086      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4087      DONE;
4088    }
4089 })
4090
4091 (define_expand "fix_trunc<mode>di2"
4092   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4093                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4094               (clobber (reg:CC FLAGS_REG))])]
4095   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4096 {
4097   if (TARGET_FISTTP
4098       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4099    {
4100      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4101      DONE;
4102    }
4103   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4104    {
4105      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4106      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4107      if (out != operands[0])
4108         emit_move_insn (operands[0], out);
4109      DONE;
4110    }
4111 })
4112
4113 ;; Signed conversion to SImode.
4114
4115 (define_expand "fix_truncxfsi2"
4116   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4118               (clobber (reg:CC FLAGS_REG))])]
4119   "TARGET_80387"
4120 {
4121   if (TARGET_FISTTP)
4122    {
4123      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4124      DONE;
4125    }
4126 })
4127
4128 (define_expand "fix_trunc<mode>si2"
4129   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4130                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4131               (clobber (reg:CC FLAGS_REG))])]
4132   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4133 {
4134   if (TARGET_FISTTP
4135       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4136    {
4137      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4138      DONE;
4139    }
4140   if (SSE_FLOAT_MODE_P (<MODE>mode))
4141    {
4142      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4143      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4144      if (out != operands[0])
4145         emit_move_insn (operands[0], out);
4146      DONE;
4147    }
4148 })
4149
4150 ;; Signed conversion to HImode.
4151
4152 (define_expand "fix_trunc<mode>hi2"
4153   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4154                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4155               (clobber (reg:CC FLAGS_REG))])]
4156   "TARGET_80387
4157    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4158 {
4159   if (TARGET_FISTTP)
4160    {
4161      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4162      DONE;
4163    }
4164 })
4165
4166 ;; When SSE is available, it is always faster to use it!
4167 (define_insn "fix_truncsfdi_sse"
4168   [(set (match_operand:DI 0 "register_operand" "=r,r")
4169         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4170   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171   "cvttss2si{q}\t{%1, %0|%0, %1}"
4172   [(set_attr "type" "sseicvt")
4173    (set_attr "mode" "SF")
4174    (set_attr "athlon_decode" "double,vector")
4175    (set_attr "amdfam10_decode" "double,double")])
4176
4177 (define_insn "fix_truncdfdi_sse"
4178   [(set (match_operand:DI 0 "register_operand" "=r,r")
4179         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4180   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4182   [(set_attr "type" "sseicvt")
4183    (set_attr "mode" "DF")
4184    (set_attr "athlon_decode" "double,vector")
4185    (set_attr "amdfam10_decode" "double,double")])
4186
4187 (define_insn "fix_truncsfsi_sse"
4188   [(set (match_operand:SI 0 "register_operand" "=r,r")
4189         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4190   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4191   "cvttss2si\t{%1, %0|%0, %1}"
4192   [(set_attr "type" "sseicvt")
4193    (set_attr "mode" "DF")
4194    (set_attr "athlon_decode" "double,vector")
4195    (set_attr "amdfam10_decode" "double,double")])
4196
4197 (define_insn "fix_truncdfsi_sse"
4198   [(set (match_operand:SI 0 "register_operand" "=r,r")
4199         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4200   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4201   "cvttsd2si\t{%1, %0|%0, %1}"
4202   [(set_attr "type" "sseicvt")
4203    (set_attr "mode" "DF")
4204    (set_attr "athlon_decode" "double,vector")
4205    (set_attr "amdfam10_decode" "double,double")])
4206
4207 ;; Avoid vector decoded forms of the instruction.
4208 (define_peephole2
4209   [(match_scratch:DF 2 "Y")
4210    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4211         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4212   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4213   [(set (match_dup 2) (match_dup 1))
4214    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4215   "")
4216
4217 (define_peephole2
4218   [(match_scratch:SF 2 "x")
4219    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4221   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4222   [(set (match_dup 2) (match_dup 1))
4223    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4224   "")
4225
4226 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4227   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4228         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4229   "TARGET_FISTTP
4230    && FLOAT_MODE_P (GET_MODE (operands[1]))
4231    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4232          && (TARGET_64BIT || <MODE>mode != DImode))
4233         && TARGET_SSE_MATH)
4234    && !(reload_completed || reload_in_progress)"
4235   "#"
4236   "&& 1"
4237   [(const_int 0)]
4238 {
4239   if (memory_operand (operands[0], VOIDmode))
4240     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4241   else
4242     {
4243       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4245                                                             operands[1],
4246                                                             operands[2]));
4247     }
4248   DONE;
4249 }
4250   [(set_attr "type" "fisttp")
4251    (set_attr "mode" "<MODE>")])
4252
4253 (define_insn "fix_trunc<mode>_i387_fisttp"
4254   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4255         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4256    (clobber (match_scratch:XF 2 "=&1f"))]
4257   "TARGET_FISTTP
4258    && FLOAT_MODE_P (GET_MODE (operands[1]))
4259    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4260          && (TARGET_64BIT || <MODE>mode != DImode))
4261         && TARGET_SSE_MATH)"
4262   "* return output_fix_trunc (insn, operands, 1);"
4263   [(set_attr "type" "fisttp")
4264    (set_attr "mode" "<MODE>")])
4265
4266 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4267   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4268         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4269    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4270    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4271   "TARGET_FISTTP
4272    && FLOAT_MODE_P (GET_MODE (operands[1]))
4273    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4274         && (TARGET_64BIT || <MODE>mode != DImode))
4275         && TARGET_SSE_MATH)"
4276   "#"
4277   [(set_attr "type" "fisttp")
4278    (set_attr "mode" "<MODE>")])
4279
4280 (define_split
4281   [(set (match_operand:X87MODEI 0 "register_operand" "")
4282         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4283    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4284    (clobber (match_scratch 3 ""))]
4285   "reload_completed"
4286   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4287               (clobber (match_dup 3))])
4288    (set (match_dup 0) (match_dup 2))]
4289   "")
4290
4291 (define_split
4292   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4293         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4294    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4295    (clobber (match_scratch 3 ""))]
4296   "reload_completed"
4297   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4298               (clobber (match_dup 3))])]
4299   "")
4300
4301 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4302 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4303 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4304 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4305 ;; function in i386.c.
4306 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4307   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4308         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4309    (clobber (reg:CC FLAGS_REG))]
4310   "TARGET_80387 && !TARGET_FISTTP
4311    && FLOAT_MODE_P (GET_MODE (operands[1]))
4312    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4313          && (TARGET_64BIT || <MODE>mode != DImode))
4314    && !(reload_completed || reload_in_progress)"
4315   "#"
4316   "&& 1"
4317   [(const_int 0)]
4318 {
4319   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4320
4321   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4322   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4323   if (memory_operand (operands[0], VOIDmode))
4324     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4325                                          operands[2], operands[3]));
4326   else
4327     {
4328       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4329       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4330                                                      operands[2], operands[3],
4331                                                      operands[4]));
4332     }
4333   DONE;
4334 }
4335   [(set_attr "type" "fistp")
4336    (set_attr "i387_cw" "trunc")
4337    (set_attr "mode" "<MODE>")])
4338
4339 (define_insn "fix_truncdi_i387"
4340   [(set (match_operand:DI 0 "memory_operand" "=m")
4341         (fix:DI (match_operand 1 "register_operand" "f")))
4342    (use (match_operand:HI 2 "memory_operand" "m"))
4343    (use (match_operand:HI 3 "memory_operand" "m"))
4344    (clobber (match_scratch:XF 4 "=&1f"))]
4345   "TARGET_80387 && !TARGET_FISTTP
4346    && FLOAT_MODE_P (GET_MODE (operands[1]))
4347    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4348   "* return output_fix_trunc (insn, operands, 0);"
4349   [(set_attr "type" "fistp")
4350    (set_attr "i387_cw" "trunc")
4351    (set_attr "mode" "DI")])
4352
4353 (define_insn "fix_truncdi_i387_with_temp"
4354   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4355         (fix:DI (match_operand 1 "register_operand" "f,f")))
4356    (use (match_operand:HI 2 "memory_operand" "m,m"))
4357    (use (match_operand:HI 3 "memory_operand" "m,m"))
4358    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4359    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4360   "TARGET_80387 && !TARGET_FISTTP
4361    && FLOAT_MODE_P (GET_MODE (operands[1]))
4362    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4363   "#"
4364   [(set_attr "type" "fistp")
4365    (set_attr "i387_cw" "trunc")
4366    (set_attr "mode" "DI")])
4367
4368 (define_split 
4369   [(set (match_operand:DI 0 "register_operand" "")
4370         (fix:DI (match_operand 1 "register_operand" "")))
4371    (use (match_operand:HI 2 "memory_operand" ""))
4372    (use (match_operand:HI 3 "memory_operand" ""))
4373    (clobber (match_operand:DI 4 "memory_operand" ""))
4374    (clobber (match_scratch 5 ""))]
4375   "reload_completed"
4376   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4377               (use (match_dup 2))
4378               (use (match_dup 3))
4379               (clobber (match_dup 5))])
4380    (set (match_dup 0) (match_dup 4))]
4381   "")
4382
4383 (define_split 
4384   [(set (match_operand:DI 0 "memory_operand" "")
4385         (fix:DI (match_operand 1 "register_operand" "")))
4386    (use (match_operand:HI 2 "memory_operand" ""))
4387    (use (match_operand:HI 3 "memory_operand" ""))
4388    (clobber (match_operand:DI 4 "memory_operand" ""))
4389    (clobber (match_scratch 5 ""))]
4390   "reload_completed"
4391   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4392               (use (match_dup 2))
4393               (use (match_dup 3))
4394               (clobber (match_dup 5))])]
4395   "")
4396
4397 (define_insn "fix_trunc<mode>_i387"
4398   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4399         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4400    (use (match_operand:HI 2 "memory_operand" "m"))
4401    (use (match_operand:HI 3 "memory_operand" "m"))]
4402   "TARGET_80387 && !TARGET_FISTTP
4403    && FLOAT_MODE_P (GET_MODE (operands[1]))
4404    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4405   "* return output_fix_trunc (insn, operands, 0);"
4406   [(set_attr "type" "fistp")
4407    (set_attr "i387_cw" "trunc")
4408    (set_attr "mode" "<MODE>")])
4409
4410 (define_insn "fix_trunc<mode>_i387_with_temp"
4411   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4412         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4413    (use (match_operand:HI 2 "memory_operand" "m,m"))
4414    (use (match_operand:HI 3 "memory_operand" "m,m"))
4415    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4416   "TARGET_80387 && !TARGET_FISTTP
4417    && FLOAT_MODE_P (GET_MODE (operands[1]))
4418    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4419   "#"
4420   [(set_attr "type" "fistp")
4421    (set_attr "i387_cw" "trunc")
4422    (set_attr "mode" "<MODE>")])
4423
4424 (define_split 
4425   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4426         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4427    (use (match_operand:HI 2 "memory_operand" ""))
4428    (use (match_operand:HI 3 "memory_operand" ""))
4429    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4430   "reload_completed"
4431   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4432               (use (match_dup 2))
4433               (use (match_dup 3))])
4434    (set (match_dup 0) (match_dup 4))]
4435   "")
4436
4437 (define_split 
4438   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4439         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4440    (use (match_operand:HI 2 "memory_operand" ""))
4441    (use (match_operand:HI 3 "memory_operand" ""))
4442    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4443   "reload_completed"
4444   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4445               (use (match_dup 2))
4446               (use (match_dup 3))])]
4447   "")
4448
4449 (define_insn "x86_fnstcw_1"
4450   [(set (match_operand:HI 0 "memory_operand" "=m")
4451         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4452   "TARGET_80387"
4453   "fnstcw\t%0"
4454   [(set_attr "length" "2")
4455    (set_attr "mode" "HI")
4456    (set_attr "unit" "i387")])
4457
4458 (define_insn "x86_fldcw_1"
4459   [(set (reg:HI FPSR_REG)
4460         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4461   "TARGET_80387"
4462   "fldcw\t%0"
4463   [(set_attr "length" "2")
4464    (set_attr "mode" "HI")
4465    (set_attr "unit" "i387")
4466    (set_attr "athlon_decode" "vector")
4467    (set_attr "amdfam10_decode" "vector")])   
4468 \f
4469 ;; Conversion between fixed point and floating point.
4470
4471 ;; Even though we only accept memory inputs, the backend _really_
4472 ;; wants to be able to do this between registers.
4473
4474 (define_expand "floathisf2"
4475   [(set (match_operand:SF 0 "register_operand" "")
4476         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4477   "TARGET_80387 || TARGET_SSE_MATH"
4478 {
4479   if (TARGET_SSE_MATH)
4480     {
4481       emit_insn (gen_floatsisf2 (operands[0],
4482                                  convert_to_mode (SImode, operands[1], 0)));
4483       DONE;
4484     }
4485 })
4486
4487 (define_insn "*floathisf2_i387"
4488   [(set (match_operand:SF 0 "register_operand" "=f,f")
4489         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4490   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4491   "@
4492    fild%z1\t%1
4493    #"
4494   [(set_attr "type" "fmov,multi")
4495    (set_attr "mode" "SF")
4496    (set_attr "unit" "*,i387")
4497    (set_attr "fp_int_src" "true")])
4498
4499 (define_expand "floatsisf2"
4500   [(set (match_operand:SF 0 "register_operand" "")
4501         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4502   "TARGET_80387 || TARGET_SSE_MATH"
4503   "")
4504
4505 (define_insn "*floatsisf2_mixed"
4506   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4507         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4508   "TARGET_MIX_SSE_I387"
4509   "@
4510    fild%z1\t%1
4511    #
4512    cvtsi2ss\t{%1, %0|%0, %1}
4513    cvtsi2ss\t{%1, %0|%0, %1}"
4514   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4515    (set_attr "mode" "SF")
4516    (set_attr "unit" "*,i387,*,*")
4517    (set_attr "athlon_decode" "*,*,vector,double")
4518    (set_attr "amdfam10_decode" "*,*,vector,double")
4519    (set_attr "fp_int_src" "true")])
4520
4521 (define_insn "*floatsisf2_sse"
4522   [(set (match_operand:SF 0 "register_operand" "=x,x")
4523         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4524   "TARGET_SSE_MATH"
4525   "cvtsi2ss\t{%1, %0|%0, %1}"
4526   [(set_attr "type" "sseicvt")
4527    (set_attr "mode" "SF")
4528    (set_attr "athlon_decode" "vector,double")
4529    (set_attr "amdfam10_decode" "vector,double")
4530    (set_attr "fp_int_src" "true")])
4531
4532 (define_insn "*floatsisf2_i387"
4533   [(set (match_operand:SF 0 "register_operand" "=f,f")
4534         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4535   "TARGET_80387"
4536   "@
4537    fild%z1\t%1
4538    #"
4539   [(set_attr "type" "fmov,multi")
4540    (set_attr "mode" "SF")
4541    (set_attr "unit" "*,i387")
4542    (set_attr "fp_int_src" "true")])
4543
4544 (define_expand "floatdisf2"
4545   [(set (match_operand:SF 0 "register_operand" "")
4546         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4547   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4548   "")
4549
4550 (define_insn "*floatdisf2_mixed"
4551   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4552         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4554   "@
4555    fild%z1\t%1
4556    #
4557    cvtsi2ss{q}\t{%1, %0|%0, %1}
4558    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560    (set_attr "mode" "SF")
4561    (set_attr "unit" "*,i387,*,*")
4562    (set_attr "athlon_decode" "*,*,vector,double")
4563    (set_attr "amdfam10_decode" "*,*,vector,double")
4564    (set_attr "fp_int_src" "true")])
4565
4566 (define_insn "*floatdisf2_sse"
4567   [(set (match_operand:SF 0 "register_operand" "=x,x")
4568         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4569   "TARGET_64BIT && TARGET_SSE_MATH"
4570   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "mode" "SF")
4573    (set_attr "athlon_decode" "vector,double")
4574    (set_attr "amdfam10_decode" "vector,double")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_insn "*floatdisf2_i387"
4578   [(set (match_operand:SF 0 "register_operand" "=f,f")
4579         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4580   "TARGET_80387"
4581   "@
4582    fild%z1\t%1
4583    #"
4584   [(set_attr "type" "fmov,multi")
4585    (set_attr "mode" "SF")
4586    (set_attr "unit" "*,i387")
4587    (set_attr "fp_int_src" "true")])
4588
4589 (define_expand "floathidf2"
4590   [(set (match_operand:DF 0 "register_operand" "")
4591         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4593 {
4594   if (TARGET_SSE2 && TARGET_SSE_MATH)
4595     {
4596       emit_insn (gen_floatsidf2 (operands[0],
4597                                  convert_to_mode (SImode, operands[1], 0)));
4598       DONE;
4599     }
4600 })
4601
4602 (define_insn "*floathidf2_i387"
4603   [(set (match_operand:DF 0 "register_operand" "=f,f")
4604         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4605   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4606   "@
4607    fild%z1\t%1
4608    #"
4609   [(set_attr "type" "fmov,multi")
4610    (set_attr "mode" "DF")
4611    (set_attr "unit" "*,i387")
4612    (set_attr "fp_int_src" "true")])
4613
4614 (define_expand "floatsidf2"
4615   [(set (match_operand:DF 0 "register_operand" "")
4616         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4617   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4618   "")
4619
4620 (define_insn "*floatsidf2_mixed"
4621   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4622         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4623   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4624   "@
4625    fild%z1\t%1
4626    #
4627    cvtsi2sd\t{%1, %0|%0, %1}
4628    cvtsi2sd\t{%1, %0|%0, %1}"
4629   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4630    (set_attr "mode" "DF")
4631    (set_attr "unit" "*,i387,*,*")
4632    (set_attr "athlon_decode" "*,*,double,direct")
4633    (set_attr "amdfam10_decode" "*,*,vector,double")
4634    (set_attr "fp_int_src" "true")])
4635
4636 (define_insn "*floatsidf2_sse"
4637   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639   "TARGET_SSE2 && TARGET_SSE_MATH"
4640   "cvtsi2sd\t{%1, %0|%0, %1}"
4641   [(set_attr "type" "sseicvt")
4642    (set_attr "mode" "DF")
4643    (set_attr "athlon_decode" "double,direct")
4644    (set_attr "amdfam10_decode" "vector,double")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "*floatsidf2_i387"
4648   [(set (match_operand:DF 0 "register_operand" "=f,f")
4649         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650   "TARGET_80387"
4651   "@
4652    fild%z1\t%1
4653    #"
4654   [(set_attr "type" "fmov,multi")
4655    (set_attr "mode" "DF")
4656    (set_attr "unit" "*,i387")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_expand "floatdidf2"
4660   [(set (match_operand:DF 0 "register_operand" "")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4662   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4663   "")
4664
4665 (define_insn "*floatdidf2_mixed"
4666   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4667         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4668   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4669   "@
4670    fild%z1\t%1
4671    #
4672    cvtsi2sd{q}\t{%1, %0|%0, %1}
4673    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4674   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4675    (set_attr "mode" "DF")
4676    (set_attr "unit" "*,i387,*,*")
4677    (set_attr "athlon_decode" "*,*,double,direct")
4678    (set_attr "amdfam10_decode" "*,*,vector,double")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "*floatdidf2_sse"
4682   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4683         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4684   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4685   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4686   [(set_attr "type" "sseicvt")
4687    (set_attr "mode" "DF")
4688    (set_attr "athlon_decode" "double,direct")
4689    (set_attr "amdfam10_decode" "vector,double")
4690    (set_attr "fp_int_src" "true")])
4691
4692 (define_insn "*floatdidf2_i387"
4693   [(set (match_operand:DF 0 "register_operand" "=f,f")
4694         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695   "TARGET_80387"
4696   "@
4697    fild%z1\t%1
4698    #"
4699   [(set_attr "type" "fmov,multi")
4700    (set_attr "mode" "DF")
4701    (set_attr "unit" "*,i387")
4702    (set_attr "fp_int_src" "true")])
4703
4704 (define_insn "floathixf2"
4705   [(set (match_operand:XF 0 "register_operand" "=f,f")
4706         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4707   "TARGET_80387"
4708   "@
4709    fild%z1\t%1
4710    #"
4711   [(set_attr "type" "fmov,multi")
4712    (set_attr "mode" "XF")
4713    (set_attr "unit" "*,i387")
4714    (set_attr "fp_int_src" "true")])
4715
4716 (define_insn "floatsixf2"
4717   [(set (match_operand:XF 0 "register_operand" "=f,f")
4718         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4719   "TARGET_80387"
4720   "@
4721    fild%z1\t%1
4722    #"
4723   [(set_attr "type" "fmov,multi")
4724    (set_attr "mode" "XF")
4725    (set_attr "unit" "*,i387")
4726    (set_attr "fp_int_src" "true")])
4727
4728 (define_insn "floatdixf2"
4729   [(set (match_operand:XF 0 "register_operand" "=f,f")
4730         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4731   "TARGET_80387"
4732   "@
4733    fild%z1\t%1
4734    #"
4735   [(set_attr "type" "fmov,multi")
4736    (set_attr "mode" "XF")
4737    (set_attr "unit" "*,i387")
4738    (set_attr "fp_int_src" "true")])
4739
4740 ;; %%% Kill these when reload knows how to do it.
4741 (define_split
4742   [(set (match_operand 0 "fp_register_operand" "")
4743         (float (match_operand 1 "register_operand" "")))]
4744   "reload_completed
4745    && TARGET_80387
4746    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4747   [(const_int 0)]
4748 {
4749   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4750   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4751   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4752   ix86_free_from_memory (GET_MODE (operands[1]));
4753   DONE;
4754 })
4755
4756 (define_expand "floatunssisf2"
4757   [(use (match_operand:SF 0 "register_operand" ""))
4758    (use (match_operand:SI 1 "register_operand" ""))]
4759   "!TARGET_64BIT && TARGET_SSE_MATH"
4760   "x86_emit_floatuns (operands); DONE;")
4761
4762 (define_expand "floatunsdisf2"
4763   [(use (match_operand:SF 0 "register_operand" ""))
4764    (use (match_operand:DI 1 "register_operand" ""))]
4765   "TARGET_64BIT && TARGET_SSE_MATH"
4766   "x86_emit_floatuns (operands); DONE;")
4767
4768 (define_expand "floatunsdidf2"
4769   [(use (match_operand:DF 0 "register_operand" ""))
4770    (use (match_operand:DI 1 "register_operand" ""))]
4771   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4772   "x86_emit_floatuns (operands); DONE;")
4773 \f
4774 ;; SSE extract/set expanders
4775
4776 \f
4777 ;; Add instructions
4778
4779 ;; %%% splits for addditi3
4780
4781 (define_expand "addti3"
4782   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4783         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4784                  (match_operand:TI 2 "x86_64_general_operand" "")))
4785    (clobber (reg:CC FLAGS_REG))]
4786   "TARGET_64BIT"
4787   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4788
4789 (define_insn "*addti3_1"
4790   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4791         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4792                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4793    (clobber (reg:CC FLAGS_REG))]
4794   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4795   "#")
4796
4797 (define_split
4798   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800                  (match_operand:TI 2 "x86_64_general_operand" "")))
4801    (clobber (reg:CC FLAGS_REG))]
4802   "TARGET_64BIT && reload_completed"
4803   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804                                           UNSPEC_ADD_CARRY))
4805               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4806    (parallel [(set (match_dup 3)
4807                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4808                                      (match_dup 4))
4809                             (match_dup 5)))
4810               (clobber (reg:CC FLAGS_REG))])]
4811   "split_ti (operands+0, 1, operands+0, operands+3);
4812    split_ti (operands+1, 1, operands+1, operands+4);
4813    split_ti (operands+2, 1, operands+2, operands+5);")
4814
4815 ;; %%% splits for addsidi3
4816 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4818 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4819
4820 (define_expand "adddi3"
4821   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4822         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4823                  (match_operand:DI 2 "x86_64_general_operand" "")))
4824    (clobber (reg:CC FLAGS_REG))]
4825   ""
4826   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4827
4828 (define_insn "*adddi3_1"
4829   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4830         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4831                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4832    (clobber (reg:CC FLAGS_REG))]
4833   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834   "#")
4835
4836 (define_split
4837   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839                  (match_operand:DI 2 "general_operand" "")))
4840    (clobber (reg:CC FLAGS_REG))]
4841   "!TARGET_64BIT && reload_completed"
4842   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4843                                           UNSPEC_ADD_CARRY))
4844               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4845    (parallel [(set (match_dup 3)
4846                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4847                                      (match_dup 4))
4848                             (match_dup 5)))
4849               (clobber (reg:CC FLAGS_REG))])]
4850   "split_di (operands+0, 1, operands+0, operands+3);
4851    split_di (operands+1, 1, operands+1, operands+4);
4852    split_di (operands+2, 1, operands+2, operands+5);")
4853
4854 (define_insn "adddi3_carry_rex64"
4855   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4856           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4857                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4858                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4859    (clobber (reg:CC FLAGS_REG))]
4860   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4861   "adc{q}\t{%2, %0|%0, %2}"
4862   [(set_attr "type" "alu")
4863    (set_attr "pent_pair" "pu")
4864    (set_attr "mode" "DI")])
4865
4866 (define_insn "*adddi3_cc_rex64"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872         (plus:DI (match_dup 1) (match_dup 2)))]
4873   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874   "add{q}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "DI")])
4877
4878 (define_insn "addqi3_carry"
4879   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4881                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4882                    (match_operand:QI 2 "general_operand" "qi,qm")))
4883    (clobber (reg:CC FLAGS_REG))]
4884   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4885   "adc{b}\t{%2, %0|%0, %2}"
4886   [(set_attr "type" "alu")
4887    (set_attr "pent_pair" "pu")
4888    (set_attr "mode" "QI")])
4889
4890 (define_insn "addhi3_carry"
4891   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4892           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4893                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4894                    (match_operand:HI 2 "general_operand" "ri,rm")))
4895    (clobber (reg:CC FLAGS_REG))]
4896   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4897   "adc{w}\t{%2, %0|%0, %2}"
4898   [(set_attr "type" "alu")
4899    (set_attr "pent_pair" "pu")
4900    (set_attr "mode" "HI")])
4901
4902 (define_insn "addsi3_carry"
4903   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4904           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4905                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4906                    (match_operand:SI 2 "general_operand" "ri,rm")))
4907    (clobber (reg:CC FLAGS_REG))]
4908   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909   "adc{l}\t{%2, %0|%0, %2}"
4910   [(set_attr "type" "alu")
4911    (set_attr "pent_pair" "pu")
4912    (set_attr "mode" "SI")])
4913
4914 (define_insn "*addsi3_carry_zext"
4915   [(set (match_operand:DI 0 "register_operand" "=r")
4916           (zero_extend:DI 
4917             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4919                      (match_operand:SI 2 "general_operand" "rim"))))
4920    (clobber (reg:CC FLAGS_REG))]
4921   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4922   "adc{l}\t{%2, %k0|%k0, %2}"
4923   [(set_attr "type" "alu")
4924    (set_attr "pent_pair" "pu")
4925    (set_attr "mode" "SI")])
4926
4927 (define_insn "*addsi3_cc"
4928   [(set (reg:CC FLAGS_REG)
4929         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4930                     (match_operand:SI 2 "general_operand" "ri,rm")]
4931                    UNSPEC_ADD_CARRY))
4932    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4933         (plus:SI (match_dup 1) (match_dup 2)))]
4934   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4935   "add{l}\t{%2, %0|%0, %2}"
4936   [(set_attr "type" "alu")
4937    (set_attr "mode" "SI")])
4938
4939 (define_insn "addqi3_cc"
4940   [(set (reg:CC FLAGS_REG)
4941         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4942                     (match_operand:QI 2 "general_operand" "qi,qm")]
4943                    UNSPEC_ADD_CARRY))
4944    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4945         (plus:QI (match_dup 1) (match_dup 2)))]
4946   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4947   "add{b}\t{%2, %0|%0, %2}"
4948   [(set_attr "type" "alu")
4949    (set_attr "mode" "QI")])
4950
4951 (define_expand "addsi3"
4952   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4953                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4954                             (match_operand:SI 2 "general_operand" "")))
4955               (clobber (reg:CC FLAGS_REG))])]
4956   ""
4957   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4958
4959 (define_insn "*lea_1"
4960   [(set (match_operand:SI 0 "register_operand" "=r")
4961         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4962   "!TARGET_64BIT"
4963   "lea{l}\t{%a1, %0|%0, %a1}"
4964   [(set_attr "type" "lea")
4965    (set_attr "mode" "SI")])
4966
4967 (define_insn "*lea_1_rex64"
4968   [(set (match_operand:SI 0 "register_operand" "=r")
4969         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4970   "TARGET_64BIT"
4971   "lea{l}\t{%a1, %0|%0, %a1}"
4972   [(set_attr "type" "lea")
4973    (set_attr "mode" "SI")])
4974
4975 (define_insn "*lea_1_zext"
4976   [(set (match_operand:DI 0 "register_operand" "=r")
4977         (zero_extend:DI
4978          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4979   "TARGET_64BIT"
4980   "lea{l}\t{%a1, %k0|%k0, %a1}"
4981   [(set_attr "type" "lea")
4982    (set_attr "mode" "SI")])
4983
4984 (define_insn "*lea_2_rex64"
4985   [(set (match_operand:DI 0 "register_operand" "=r")
4986         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4987   "TARGET_64BIT"
4988   "lea{q}\t{%a1, %0|%0, %a1}"
4989   [(set_attr "type" "lea")
4990    (set_attr "mode" "DI")])
4991
4992 ;; The lea patterns for non-Pmodes needs to be matched by several
4993 ;; insns converted to real lea by splitters.
4994
4995 (define_insn_and_split "*lea_general_1"
4996   [(set (match_operand 0 "register_operand" "=r")
4997         (plus (plus (match_operand 1 "index_register_operand" "l")
4998                     (match_operand 2 "register_operand" "r"))
4999               (match_operand 3 "immediate_operand" "i")))]
5000   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5001     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5002    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5003    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5004    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5005    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5006        || GET_MODE (operands[3]) == VOIDmode)"
5007   "#"
5008   "&& reload_completed"
5009   [(const_int 0)]
5010 {
5011   rtx pat;
5012   operands[0] = gen_lowpart (SImode, operands[0]);
5013   operands[1] = gen_lowpart (Pmode, operands[1]);
5014   operands[2] = gen_lowpart (Pmode, operands[2]);
5015   operands[3] = gen_lowpart (Pmode, operands[3]);
5016   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5017                       operands[3]);
5018   if (Pmode != SImode)
5019     pat = gen_rtx_SUBREG (SImode, pat, 0);
5020   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5021   DONE;
5022 }
5023   [(set_attr "type" "lea")
5024    (set_attr "mode" "SI")])
5025
5026 (define_insn_and_split "*lea_general_1_zext"
5027   [(set (match_operand:DI 0 "register_operand" "=r")
5028         (zero_extend:DI
5029           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5030                             (match_operand:SI 2 "register_operand" "r"))
5031                    (match_operand:SI 3 "immediate_operand" "i"))))]
5032   "TARGET_64BIT"
5033   "#"
5034   "&& reload_completed"
5035   [(set (match_dup 0)
5036         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5037                                                      (match_dup 2))
5038                                             (match_dup 3)) 0)))]
5039 {
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[2] = gen_lowpart (Pmode, operands[2]);
5042   operands[3] = gen_lowpart (Pmode, operands[3]);
5043 }
5044   [(set_attr "type" "lea")
5045    (set_attr "mode" "SI")])
5046
5047 (define_insn_and_split "*lea_general_2"
5048   [(set (match_operand 0 "register_operand" "=r")
5049         (plus (mult (match_operand 1 "index_register_operand" "l")
5050                     (match_operand 2 "const248_operand" "i"))
5051               (match_operand 3 "nonmemory_operand" "ri")))]
5052   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5053     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5054    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5055    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5056    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5057        || GET_MODE (operands[3]) == VOIDmode)"
5058   "#"
5059   "&& reload_completed"
5060   [(const_int 0)]
5061 {
5062   rtx pat;
5063   operands[0] = gen_lowpart (SImode, operands[0]);
5064   operands[1] = gen_lowpart (Pmode, operands[1]);
5065   operands[3] = gen_lowpart (Pmode, operands[3]);
5066   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5067                       operands[3]);
5068   if (Pmode != SImode)
5069     pat = gen_rtx_SUBREG (SImode, pat, 0);
5070   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5071   DONE;
5072 }
5073   [(set_attr "type" "lea")
5074    (set_attr "mode" "SI")])
5075
5076 (define_insn_and_split "*lea_general_2_zext"
5077   [(set (match_operand:DI 0 "register_operand" "=r")
5078         (zero_extend:DI
5079           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5080                             (match_operand:SI 2 "const248_operand" "n"))
5081                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5082   "TARGET_64BIT"
5083   "#"
5084   "&& reload_completed"
5085   [(set (match_dup 0)
5086         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5087                                                      (match_dup 2))
5088                                             (match_dup 3)) 0)))]
5089 {
5090   operands[1] = gen_lowpart (Pmode, operands[1]);
5091   operands[3] = gen_lowpart (Pmode, operands[3]);
5092 }
5093   [(set_attr "type" "lea")
5094    (set_attr "mode" "SI")])
5095
5096 (define_insn_and_split "*lea_general_3"
5097   [(set (match_operand 0 "register_operand" "=r")
5098         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5099                           (match_operand 2 "const248_operand" "i"))
5100                     (match_operand 3 "register_operand" "r"))
5101               (match_operand 4 "immediate_operand" "i")))]
5102   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5107   "#"
5108   "&& reload_completed"
5109   [(const_int 0)]
5110 {
5111   rtx pat;
5112   operands[0] = gen_lowpart (SImode, operands[0]);
5113   operands[1] = gen_lowpart (Pmode, operands[1]);
5114   operands[3] = gen_lowpart (Pmode, operands[3]);
5115   operands[4] = gen_lowpart (Pmode, operands[4]);
5116   pat = gen_rtx_PLUS (Pmode,
5117                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5118                                                          operands[2]),
5119                                     operands[3]),
5120                       operands[4]);
5121   if (Pmode != SImode)
5122     pat = gen_rtx_SUBREG (SImode, pat, 0);
5123   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5124   DONE;
5125 }
5126   [(set_attr "type" "lea")
5127    (set_attr "mode" "SI")])
5128
5129 (define_insn_and_split "*lea_general_3_zext"
5130   [(set (match_operand:DI 0 "register_operand" "=r")
5131         (zero_extend:DI
5132           (plus:SI (plus:SI (mult:SI
5133                               (match_operand:SI 1 "index_register_operand" "l")
5134                               (match_operand:SI 2 "const248_operand" "n"))
5135                             (match_operand:SI 3 "register_operand" "r"))
5136                    (match_operand:SI 4 "immediate_operand" "i"))))]
5137   "TARGET_64BIT"
5138   "#"
5139   "&& reload_completed"
5140   [(set (match_dup 0)
5141         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5142                                                               (match_dup 2))
5143                                                      (match_dup 3))
5144                                             (match_dup 4)) 0)))]
5145 {
5146   operands[1] = gen_lowpart (Pmode, operands[1]);
5147   operands[3] = gen_lowpart (Pmode, operands[3]);
5148   operands[4] = gen_lowpart (Pmode, operands[4]);
5149 }
5150   [(set_attr "type" "lea")
5151    (set_attr "mode" "SI")])
5152
5153 (define_insn "*adddi_1_rex64"
5154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5155         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5156                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5157    (clobber (reg:CC FLAGS_REG))]
5158   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5159 {
5160   switch (get_attr_type (insn))
5161     {
5162     case TYPE_LEA:
5163       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5164       return "lea{q}\t{%a2, %0|%0, %a2}";
5165
5166     case TYPE_INCDEC:
5167       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168       if (operands[2] == const1_rtx)
5169         return "inc{q}\t%0";
5170       else
5171         {
5172           gcc_assert (operands[2] == constm1_rtx);
5173           return "dec{q}\t%0";
5174         }
5175
5176     default:
5177       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5178
5179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5181       if (GET_CODE (operands[2]) == CONST_INT
5182           /* Avoid overflows.  */
5183           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184           && (INTVAL (operands[2]) == 128
5185               || (INTVAL (operands[2]) < 0
5186                   && INTVAL (operands[2]) != -128)))
5187         {
5188           operands[2] = GEN_INT (-INTVAL (operands[2]));
5189           return "sub{q}\t{%2, %0|%0, %2}";
5190         }
5191       return "add{q}\t{%2, %0|%0, %2}";
5192     }
5193 }
5194   [(set (attr "type")
5195      (cond [(eq_attr "alternative" "2")
5196               (const_string "lea")
5197             ; Current assemblers are broken and do not allow @GOTOFF in
5198             ; ought but a memory context.
5199             (match_operand:DI 2 "pic_symbolic_operand" "")
5200               (const_string "lea")
5201             (match_operand:DI 2 "incdec_operand" "")
5202               (const_string "incdec")
5203            ]
5204            (const_string "alu")))
5205    (set_attr "mode" "DI")])
5206
5207 ;; Convert lea to the lea pattern to avoid flags dependency.
5208 (define_split
5209   [(set (match_operand:DI 0 "register_operand" "")
5210         (plus:DI (match_operand:DI 1 "register_operand" "")
5211                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5212    (clobber (reg:CC FLAGS_REG))]
5213   "TARGET_64BIT && reload_completed
5214    && true_regnum (operands[0]) != true_regnum (operands[1])"
5215   [(set (match_dup 0)
5216         (plus:DI (match_dup 1)
5217                  (match_dup 2)))]
5218   "")
5219
5220 (define_insn "*adddi_2_rex64"
5221   [(set (reg FLAGS_REG)
5222         (compare
5223           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5224                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5225           (const_int 0)))                       
5226    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5227         (plus:DI (match_dup 1) (match_dup 2)))]
5228   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5229    && ix86_binary_operator_ok (PLUS, DImode, operands)
5230    /* Current assemblers are broken and do not allow @GOTOFF in
5231       ought but a memory context.  */
5232    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5233 {
5234   switch (get_attr_type (insn))
5235     {
5236     case TYPE_INCDEC:
5237       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238       if (operands[2] == const1_rtx)
5239         return "inc{q}\t%0";
5240       else
5241         {
5242           gcc_assert (operands[2] == constm1_rtx);
5243           return "dec{q}\t%0";
5244         }
5245
5246     default:
5247       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248       /* ???? We ought to handle there the 32bit case too
5249          - do we need new constraint?  */
5250       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5251          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5252       if (GET_CODE (operands[2]) == CONST_INT
5253           /* Avoid overflows.  */
5254           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5255           && (INTVAL (operands[2]) == 128
5256               || (INTVAL (operands[2]) < 0
5257                   && INTVAL (operands[2]) != -128)))
5258         {
5259           operands[2] = GEN_INT (-INTVAL (operands[2]));
5260           return "sub{q}\t{%2, %0|%0, %2}";
5261         }
5262       return "add{q}\t{%2, %0|%0, %2}";
5263     }
5264 }
5265   [(set (attr "type")
5266      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5267         (const_string "incdec")
5268         (const_string "alu")))
5269    (set_attr "mode" "DI")])
5270
5271 (define_insn "*adddi_3_rex64"
5272   [(set (reg FLAGS_REG)
5273         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5274                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5275    (clobber (match_scratch:DI 0 "=r"))]
5276   "TARGET_64BIT
5277    && ix86_match_ccmode (insn, CCZmode)
5278    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5279    /* Current assemblers are broken and do not allow @GOTOFF in
5280       ought but a memory context.  */
5281    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5282 {
5283   switch (get_attr_type (insn))
5284     {
5285     case TYPE_INCDEC:
5286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287       if (operands[2] == const1_rtx)
5288         return "inc{q}\t%0";
5289       else
5290         {
5291           gcc_assert (operands[2] == constm1_rtx);
5292           return "dec{q}\t%0";
5293         }
5294
5295     default:
5296       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5297       /* ???? We ought to handle there the 32bit case too
5298          - do we need new constraint?  */
5299       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5300          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5301       if (GET_CODE (operands[2]) == CONST_INT
5302           /* Avoid overflows.  */
5303           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5304           && (INTVAL (operands[2]) == 128
5305               || (INTVAL (operands[2]) < 0
5306                   && INTVAL (operands[2]) != -128)))
5307         {
5308           operands[2] = GEN_INT (-INTVAL (operands[2]));
5309           return "sub{q}\t{%2, %0|%0, %2}";
5310         }
5311       return "add{q}\t{%2, %0|%0, %2}";
5312     }
5313 }
5314   [(set (attr "type")
5315      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5316         (const_string "incdec")
5317         (const_string "alu")))
5318    (set_attr "mode" "DI")])
5319
5320 ; For comparisons against 1, -1 and 128, we may generate better code
5321 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5322 ; is matched then.  We can't accept general immediate, because for
5323 ; case of overflows,  the result is messed up.
5324 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5325 ; when negated.
5326 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5327 ; only for comparisons not depending on it.
5328 (define_insn "*adddi_4_rex64"
5329   [(set (reg FLAGS_REG)
5330         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5331                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5332    (clobber (match_scratch:DI 0 "=rm"))]
5333   "TARGET_64BIT
5334    &&  ix86_match_ccmode (insn, CCGCmode)"
5335 {
5336   switch (get_attr_type (insn))
5337     {
5338     case TYPE_INCDEC:
5339       if (operands[2] == constm1_rtx)
5340         return "inc{q}\t%0";
5341       else
5342         {
5343           gcc_assert (operands[2] == const1_rtx);
5344           return "dec{q}\t%0";
5345         }
5346
5347     default:
5348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5351       if ((INTVAL (operands[2]) == -128
5352            || (INTVAL (operands[2]) > 0
5353                && INTVAL (operands[2]) != 128))
5354           /* Avoid overflows.  */
5355           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5356         return "sub{q}\t{%2, %0|%0, %2}";
5357       operands[2] = GEN_INT (-INTVAL (operands[2]));
5358       return "add{q}\t{%2, %0|%0, %2}";
5359     }
5360 }
5361   [(set (attr "type")
5362      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5363         (const_string "incdec")
5364         (const_string "alu")))
5365    (set_attr "mode" "DI")])
5366
5367 (define_insn "*adddi_5_rex64"
5368   [(set (reg FLAGS_REG)
5369         (compare
5370           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5371                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5372           (const_int 0)))                       
5373    (clobber (match_scratch:DI 0 "=r"))]
5374   "TARGET_64BIT
5375    && ix86_match_ccmode (insn, CCGOCmode)
5376    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5377    /* Current assemblers are broken and do not allow @GOTOFF in
5378       ought but a memory context.  */
5379    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5380 {
5381   switch (get_attr_type (insn))
5382     {
5383     case TYPE_INCDEC:
5384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5385       if (operands[2] == const1_rtx)
5386         return "inc{q}\t%0";
5387       else
5388         {
5389           gcc_assert (operands[2] == constm1_rtx);
5390           return "dec{q}\t%0";
5391         }
5392
5393     default:
5394       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5395       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5397       if (GET_CODE (operands[2]) == CONST_INT
5398           /* Avoid overflows.  */
5399           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400           && (INTVAL (operands[2]) == 128
5401               || (INTVAL (operands[2]) < 0
5402                   && INTVAL (operands[2]) != -128)))
5403         {
5404           operands[2] = GEN_INT (-INTVAL (operands[2]));
5405           return "sub{q}\t{%2, %0|%0, %2}";
5406         }
5407       return "add{q}\t{%2, %0|%0, %2}";
5408     }
5409 }
5410   [(set (attr "type")
5411      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412         (const_string "incdec")
5413         (const_string "alu")))
5414    (set_attr "mode" "DI")])
5415
5416
5417 (define_insn "*addsi_1"
5418   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5419         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5420                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5421    (clobber (reg:CC FLAGS_REG))]
5422   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5423 {
5424   switch (get_attr_type (insn))
5425     {
5426     case TYPE_LEA:
5427       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5428       return "lea{l}\t{%a2, %0|%0, %a2}";
5429
5430     case TYPE_INCDEC:
5431       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432       if (operands[2] == const1_rtx)
5433         return "inc{l}\t%0";
5434       else
5435         {
5436           gcc_assert (operands[2] == constm1_rtx);
5437           return "dec{l}\t%0";
5438         }
5439
5440     default:
5441       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5442
5443       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5445       if (GET_CODE (operands[2]) == CONST_INT
5446           && (INTVAL (operands[2]) == 128
5447               || (INTVAL (operands[2]) < 0
5448                   && INTVAL (operands[2]) != -128)))
5449         {
5450           operands[2] = GEN_INT (-INTVAL (operands[2]));
5451           return "sub{l}\t{%2, %0|%0, %2}";
5452         }
5453       return "add{l}\t{%2, %0|%0, %2}";
5454     }
5455 }
5456   [(set (attr "type")
5457      (cond [(eq_attr "alternative" "2")
5458               (const_string "lea")
5459             ; Current assemblers are broken and do not allow @GOTOFF in
5460             ; ought but a memory context.
5461             (match_operand:SI 2 "pic_symbolic_operand" "")
5462               (const_string "lea")
5463             (match_operand:SI 2 "incdec_operand" "")
5464               (const_string "incdec")
5465            ]
5466            (const_string "alu")))
5467    (set_attr "mode" "SI")])
5468
5469 ;; Convert lea to the lea pattern to avoid flags dependency.
5470 (define_split
5471   [(set (match_operand 0 "register_operand" "")
5472         (plus (match_operand 1 "register_operand" "")
5473               (match_operand 2 "nonmemory_operand" "")))
5474    (clobber (reg:CC FLAGS_REG))]
5475   "reload_completed
5476    && true_regnum (operands[0]) != true_regnum (operands[1])"
5477   [(const_int 0)]
5478 {
5479   rtx pat;
5480   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5481      may confuse gen_lowpart.  */
5482   if (GET_MODE (operands[0]) != Pmode)
5483     {
5484       operands[1] = gen_lowpart (Pmode, operands[1]);
5485       operands[2] = gen_lowpart (Pmode, operands[2]);
5486     }
5487   operands[0] = gen_lowpart (SImode, operands[0]);
5488   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5489   if (Pmode != SImode)
5490     pat = gen_rtx_SUBREG (SImode, pat, 0);
5491   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5492   DONE;
5493 })
5494
5495 ;; It may seem that nonimmediate operand is proper one for operand 1.
5496 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5497 ;; we take care in ix86_binary_operator_ok to not allow two memory
5498 ;; operands so proper swapping will be done in reload.  This allow
5499 ;; patterns constructed from addsi_1 to match.
5500 (define_insn "addsi_1_zext"
5501   [(set (match_operand:DI 0 "register_operand" "=r,r")
5502         (zero_extend:DI
5503           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5504                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5505    (clobber (reg:CC FLAGS_REG))]
5506   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5507 {
5508   switch (get_attr_type (insn))
5509     {
5510     case TYPE_LEA:
5511       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5512       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5513
5514     case TYPE_INCDEC:
5515       if (operands[2] == const1_rtx)
5516         return "inc{l}\t%k0";
5517       else
5518         {
5519           gcc_assert (operands[2] == constm1_rtx);
5520           return "dec{l}\t%k0";
5521         }
5522
5523     default:
5524       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5526       if (GET_CODE (operands[2]) == CONST_INT
5527           && (INTVAL (operands[2]) == 128
5528               || (INTVAL (operands[2]) < 0
5529                   && INTVAL (operands[2]) != -128)))
5530         {
5531           operands[2] = GEN_INT (-INTVAL (operands[2]));
5532           return "sub{l}\t{%2, %k0|%k0, %2}";
5533         }
5534       return "add{l}\t{%2, %k0|%k0, %2}";
5535     }
5536 }
5537   [(set (attr "type")
5538      (cond [(eq_attr "alternative" "1")
5539               (const_string "lea")
5540             ; Current assemblers are broken and do not allow @GOTOFF in
5541             ; ought but a memory context.
5542             (match_operand:SI 2 "pic_symbolic_operand" "")
5543               (const_string "lea")
5544             (match_operand:SI 2 "incdec_operand" "")
5545               (const_string "incdec")
5546            ]
5547            (const_string "alu")))
5548    (set_attr "mode" "SI")])
5549
5550 ;; Convert lea to the lea pattern to avoid flags dependency.
5551 (define_split
5552   [(set (match_operand:DI 0 "register_operand" "")
5553         (zero_extend:DI
5554           (plus:SI (match_operand:SI 1 "register_operand" "")
5555                    (match_operand:SI 2 "nonmemory_operand" ""))))
5556    (clobber (reg:CC FLAGS_REG))]
5557   "TARGET_64BIT && reload_completed
5558    && true_regnum (operands[0]) != true_regnum (operands[1])"
5559   [(set (match_dup 0)
5560         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5561 {
5562   operands[1] = gen_lowpart (Pmode, operands[1]);
5563   operands[2] = gen_lowpart (Pmode, operands[2]);
5564 })
5565
5566 (define_insn "*addsi_2"
5567   [(set (reg FLAGS_REG)
5568         (compare
5569           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5570                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5571           (const_int 0)))                       
5572    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5573         (plus:SI (match_dup 1) (match_dup 2)))]
5574   "ix86_match_ccmode (insn, CCGOCmode)
5575    && ix86_binary_operator_ok (PLUS, SImode, operands)
5576    /* Current assemblers are broken and do not allow @GOTOFF in
5577       ought but a memory context.  */
5578    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5579 {
5580   switch (get_attr_type (insn))
5581     {
5582     case TYPE_INCDEC:
5583       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584       if (operands[2] == const1_rtx)
5585         return "inc{l}\t%0";
5586       else
5587         {
5588           gcc_assert (operands[2] == constm1_rtx);
5589           return "dec{l}\t%0";
5590         }
5591
5592     default:
5593       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5595          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5596       if (GET_CODE (operands[2]) == CONST_INT
5597           && (INTVAL (operands[2]) == 128
5598               || (INTVAL (operands[2]) < 0
5599                   && INTVAL (operands[2]) != -128)))
5600         {
5601           operands[2] = GEN_INT (-INTVAL (operands[2]));
5602           return "sub{l}\t{%2, %0|%0, %2}";
5603         }
5604       return "add{l}\t{%2, %0|%0, %2}";
5605     }
5606 }
5607   [(set (attr "type")
5608      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5609         (const_string "incdec")
5610         (const_string "alu")))
5611    (set_attr "mode" "SI")])
5612
5613 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5614 (define_insn "*addsi_2_zext"
5615   [(set (reg FLAGS_REG)
5616         (compare
5617           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5618                    (match_operand:SI 2 "general_operand" "rmni"))
5619           (const_int 0)))                       
5620    (set (match_operand:DI 0 "register_operand" "=r")
5621         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5622   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5623    && ix86_binary_operator_ok (PLUS, SImode, operands)
5624    /* Current assemblers are broken and do not allow @GOTOFF in
5625       ought but a memory context.  */
5626    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627 {
5628   switch (get_attr_type (insn))
5629     {
5630     case TYPE_INCDEC:
5631       if (operands[2] == const1_rtx)
5632         return "inc{l}\t%k0";
5633       else
5634         {
5635           gcc_assert (operands[2] == constm1_rtx);
5636           return "dec{l}\t%k0";
5637         }
5638
5639     default:
5640       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5641          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5642       if (GET_CODE (operands[2]) == CONST_INT
5643           && (INTVAL (operands[2]) == 128
5644               || (INTVAL (operands[2]) < 0
5645                   && INTVAL (operands[2]) != -128)))
5646         {
5647           operands[2] = GEN_INT (-INTVAL (operands[2]));
5648           return "sub{l}\t{%2, %k0|%k0, %2}";
5649         }
5650       return "add{l}\t{%2, %k0|%k0, %2}";
5651     }
5652 }
5653   [(set (attr "type")
5654      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5655         (const_string "incdec")
5656         (const_string "alu")))
5657    (set_attr "mode" "SI")])
5658
5659 (define_insn "*addsi_3"
5660   [(set (reg FLAGS_REG)
5661         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5662                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5663    (clobber (match_scratch:SI 0 "=r"))]
5664   "ix86_match_ccmode (insn, CCZmode)
5665    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5666    /* Current assemblers are broken and do not allow @GOTOFF in
5667       ought but a memory context.  */
5668    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5669 {
5670   switch (get_attr_type (insn))
5671     {
5672     case TYPE_INCDEC:
5673       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5674       if (operands[2] == const1_rtx)
5675         return "inc{l}\t%0";
5676       else
5677         {
5678           gcc_assert (operands[2] == constm1_rtx);
5679           return "dec{l}\t%0";
5680         }
5681
5682     default:
5683       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5686       if (GET_CODE (operands[2]) == CONST_INT
5687           && (INTVAL (operands[2]) == 128
5688               || (INTVAL (operands[2]) < 0
5689                   && INTVAL (operands[2]) != -128)))
5690         {
5691           operands[2] = GEN_INT (-INTVAL (operands[2]));
5692           return "sub{l}\t{%2, %0|%0, %2}";
5693         }
5694       return "add{l}\t{%2, %0|%0, %2}";
5695     }
5696 }
5697   [(set (attr "type")
5698      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5699         (const_string "incdec")
5700         (const_string "alu")))
5701    (set_attr "mode" "SI")])
5702
5703 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5704 (define_insn "*addsi_3_zext"
5705   [(set (reg FLAGS_REG)
5706         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5707                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5708    (set (match_operand:DI 0 "register_operand" "=r")
5709         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5711    && ix86_binary_operator_ok (PLUS, SImode, operands)
5712    /* Current assemblers are broken and do not allow @GOTOFF in
5713       ought but a memory context.  */
5714    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715 {
5716   switch (get_attr_type (insn))
5717     {
5718     case TYPE_INCDEC:
5719       if (operands[2] == const1_rtx)
5720         return "inc{l}\t%k0";
5721       else
5722         {
5723           gcc_assert (operands[2] == constm1_rtx);
5724           return "dec{l}\t%k0";
5725         }
5726
5727     default:
5728       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5730       if (GET_CODE (operands[2]) == CONST_INT
5731           && (INTVAL (operands[2]) == 128
5732               || (INTVAL (operands[2]) < 0
5733                   && INTVAL (operands[2]) != -128)))
5734         {
5735           operands[2] = GEN_INT (-INTVAL (operands[2]));
5736           return "sub{l}\t{%2, %k0|%k0, %2}";
5737         }
5738       return "add{l}\t{%2, %k0|%k0, %2}";
5739     }
5740 }
5741   [(set (attr "type")
5742      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5743         (const_string "incdec")
5744         (const_string "alu")))
5745    (set_attr "mode" "SI")])
5746
5747 ; For comparisons against 1, -1 and 128, we may generate better code
5748 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5749 ; is matched then.  We can't accept general immediate, because for
5750 ; case of overflows,  the result is messed up.
5751 ; This pattern also don't hold of 0x80000000, since the value overflows
5752 ; when negated.
5753 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5754 ; only for comparisons not depending on it.
5755 (define_insn "*addsi_4"
5756   [(set (reg FLAGS_REG)
5757         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5758                  (match_operand:SI 2 "const_int_operand" "n")))
5759    (clobber (match_scratch:SI 0 "=rm"))]
5760   "ix86_match_ccmode (insn, CCGCmode)
5761    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5762 {
5763   switch (get_attr_type (insn))
5764     {
5765     case TYPE_INCDEC:
5766       if (operands[2] == constm1_rtx)
5767         return "inc{l}\t%0";
5768       else
5769         {
5770           gcc_assert (operands[2] == const1_rtx);
5771           return "dec{l}\t%0";
5772         }
5773
5774     default:
5775       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5778       if ((INTVAL (operands[2]) == -128
5779            || (INTVAL (operands[2]) > 0
5780                && INTVAL (operands[2]) != 128)))
5781         return "sub{l}\t{%2, %0|%0, %2}";
5782       operands[2] = GEN_INT (-INTVAL (operands[2]));
5783       return "add{l}\t{%2, %0|%0, %2}";
5784     }
5785 }
5786   [(set (attr "type")
5787      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5788         (const_string "incdec")
5789         (const_string "alu")))
5790    (set_attr "mode" "SI")])
5791
5792 (define_insn "*addsi_5"
5793   [(set (reg FLAGS_REG)
5794         (compare
5795           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5796                    (match_operand:SI 2 "general_operand" "rmni"))
5797           (const_int 0)))                       
5798    (clobber (match_scratch:SI 0 "=r"))]
5799   "ix86_match_ccmode (insn, CCGOCmode)
5800    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5801    /* Current assemblers are broken and do not allow @GOTOFF in
5802       ought but a memory context.  */
5803    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5804 {
5805   switch (get_attr_type (insn))
5806     {
5807     case TYPE_INCDEC:
5808       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809       if (operands[2] == const1_rtx)
5810         return "inc{l}\t%0";
5811       else
5812         {
5813           gcc_assert (operands[2] == constm1_rtx);
5814           return "dec{l}\t%0";
5815         }
5816
5817     default:
5818       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5820          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5821       if (GET_CODE (operands[2]) == CONST_INT
5822           && (INTVAL (operands[2]) == 128
5823               || (INTVAL (operands[2]) < 0
5824                   && INTVAL (operands[2]) != -128)))
5825         {
5826           operands[2] = GEN_INT (-INTVAL (operands[2]));
5827           return "sub{l}\t{%2, %0|%0, %2}";
5828         }
5829       return "add{l}\t{%2, %0|%0, %2}";
5830     }
5831 }
5832   [(set (attr "type")
5833      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5834         (const_string "incdec")
5835         (const_string "alu")))
5836    (set_attr "mode" "SI")])
5837
5838 (define_expand "addhi3"
5839   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5840                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5841                             (match_operand:HI 2 "general_operand" "")))
5842               (clobber (reg:CC FLAGS_REG))])]
5843   "TARGET_HIMODE_MATH"
5844   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5845
5846 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5847 ;; type optimizations enabled by define-splits.  This is not important
5848 ;; for PII, and in fact harmful because of partial register stalls.
5849
5850 (define_insn "*addhi_1_lea"
5851   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5852         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5853                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5854    (clobber (reg:CC FLAGS_REG))]
5855   "!TARGET_PARTIAL_REG_STALL
5856    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5857 {
5858   switch (get_attr_type (insn))
5859     {
5860     case TYPE_LEA:
5861       return "#";
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 (eq_attr "alternative" "2")
5887         (const_string "lea")
5888         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5889            (const_string "incdec")
5890            (const_string "alu"))))
5891    (set_attr "mode" "HI,HI,SI")])
5892
5893 (define_insn "*addhi_1"
5894   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5895         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896                  (match_operand:HI 2 "general_operand" "ri,rm")))
5897    (clobber (reg:CC FLAGS_REG))]
5898   "TARGET_PARTIAL_REG_STALL
5899    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{w}\t%0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{w}\t%0";
5910         }
5911
5912     default:
5913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915       if (GET_CODE (operands[2]) == CONST_INT
5916           && (INTVAL (operands[2]) == 128
5917               || (INTVAL (operands[2]) < 0
5918                   && INTVAL (operands[2]) != -128)))
5919         {
5920           operands[2] = GEN_INT (-INTVAL (operands[2]));
5921           return "sub{w}\t{%2, %0|%0, %2}";
5922         }
5923       return "add{w}\t{%2, %0|%0, %2}";
5924     }
5925 }
5926   [(set (attr "type")
5927      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928         (const_string "incdec")
5929         (const_string "alu")))
5930    (set_attr "mode" "HI")])
5931
5932 (define_insn "*addhi_2"
5933   [(set (reg FLAGS_REG)
5934         (compare
5935           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5936                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5937           (const_int 0)))                       
5938    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5939         (plus:HI (match_dup 1) (match_dup 2)))]
5940   "ix86_match_ccmode (insn, CCGOCmode)
5941    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5942 {
5943   switch (get_attr_type (insn))
5944     {
5945     case TYPE_INCDEC:
5946       if (operands[2] == const1_rtx)
5947         return "inc{w}\t%0";
5948       else
5949         {
5950           gcc_assert (operands[2] == constm1_rtx);
5951           return "dec{w}\t%0";
5952         }
5953
5954     default:
5955       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5957       if (GET_CODE (operands[2]) == CONST_INT
5958           && (INTVAL (operands[2]) == 128
5959               || (INTVAL (operands[2]) < 0
5960                   && INTVAL (operands[2]) != -128)))
5961         {
5962           operands[2] = GEN_INT (-INTVAL (operands[2]));
5963           return "sub{w}\t{%2, %0|%0, %2}";
5964         }
5965       return "add{w}\t{%2, %0|%0, %2}";
5966     }
5967 }
5968   [(set (attr "type")
5969      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970         (const_string "incdec")
5971         (const_string "alu")))
5972    (set_attr "mode" "HI")])
5973
5974 (define_insn "*addhi_3"
5975   [(set (reg FLAGS_REG)
5976         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5977                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5978    (clobber (match_scratch:HI 0 "=r"))]
5979   "ix86_match_ccmode (insn, CCZmode)
5980    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5981 {
5982   switch (get_attr_type (insn))
5983     {
5984     case TYPE_INCDEC:
5985       if (operands[2] == const1_rtx)
5986         return "inc{w}\t%0";
5987       else
5988         {
5989           gcc_assert (operands[2] == constm1_rtx);
5990           return "dec{w}\t%0";
5991         }
5992
5993     default:
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 (GET_CODE (operands[2]) == CONST_INT
5997           && (INTVAL (operands[2]) == 128
5998               || (INTVAL (operands[2]) < 0
5999                   && INTVAL (operands[2]) != -128)))
6000         {
6001           operands[2] = GEN_INT (-INTVAL (operands[2]));
6002           return "sub{w}\t{%2, %0|%0, %2}";
6003         }
6004       return "add{w}\t{%2, %0|%0, %2}";
6005     }
6006 }
6007   [(set (attr "type")
6008      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6009         (const_string "incdec")
6010         (const_string "alu")))
6011    (set_attr "mode" "HI")])
6012
6013 ; See comments above addsi_4 for details.
6014 (define_insn "*addhi_4"
6015   [(set (reg FLAGS_REG)
6016         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6017                  (match_operand:HI 2 "const_int_operand" "n")))
6018    (clobber (match_scratch:HI 0 "=rm"))]
6019   "ix86_match_ccmode (insn, CCGCmode)
6020    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == constm1_rtx)
6026         return "inc{w}\t%0";
6027       else
6028         {
6029           gcc_assert (operands[2] == const1_rtx);
6030           return "dec{w}\t%0";
6031         }
6032
6033     default:
6034       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6037       if ((INTVAL (operands[2]) == -128
6038            || (INTVAL (operands[2]) > 0
6039                && INTVAL (operands[2]) != 128)))
6040         return "sub{w}\t{%2, %0|%0, %2}";
6041       operands[2] = GEN_INT (-INTVAL (operands[2]));
6042       return "add{w}\t{%2, %0|%0, %2}";
6043     }
6044 }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "SI")])
6050
6051
6052 (define_insn "*addhi_5"
6053   [(set (reg FLAGS_REG)
6054         (compare
6055           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6056                    (match_operand:HI 2 "general_operand" "rmni"))
6057           (const_int 0)))                       
6058    (clobber (match_scratch:HI 0 "=r"))]
6059   "ix86_match_ccmode (insn, CCGOCmode)
6060    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6061 {
6062   switch (get_attr_type (insn))
6063     {
6064     case TYPE_INCDEC:
6065       if (operands[2] == const1_rtx)
6066         return "inc{w}\t%0";
6067       else
6068         {
6069           gcc_assert (operands[2] == constm1_rtx);
6070           return "dec{w}\t%0";
6071         }
6072
6073     default:
6074       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6076       if (GET_CODE (operands[2]) == CONST_INT
6077           && (INTVAL (operands[2]) == 128
6078               || (INTVAL (operands[2]) < 0
6079                   && INTVAL (operands[2]) != -128)))
6080         {
6081           operands[2] = GEN_INT (-INTVAL (operands[2]));
6082           return "sub{w}\t{%2, %0|%0, %2}";
6083         }
6084       return "add{w}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set_attr "mode" "HI")])
6092
6093 (define_expand "addqi3"
6094   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6095                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6096                             (match_operand:QI 2 "general_operand" "")))
6097               (clobber (reg:CC FLAGS_REG))])]
6098   "TARGET_QIMODE_MATH"
6099   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6100
6101 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6102 (define_insn "*addqi_1_lea"
6103   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6104         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6105                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6106    (clobber (reg:CC FLAGS_REG))]
6107   "!TARGET_PARTIAL_REG_STALL
6108    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6109 {
6110   int widen = (which_alternative == 2);
6111   switch (get_attr_type (insn))
6112     {
6113     case TYPE_LEA:
6114       return "#";
6115     case TYPE_INCDEC:
6116       if (operands[2] == const1_rtx)
6117         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6118       else
6119         {
6120           gcc_assert (operands[2] == constm1_rtx);
6121           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6122         }
6123
6124     default:
6125       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6127       if (GET_CODE (operands[2]) == CONST_INT
6128           && (INTVAL (operands[2]) == 128
6129               || (INTVAL (operands[2]) < 0
6130                   && INTVAL (operands[2]) != -128)))
6131         {
6132           operands[2] = GEN_INT (-INTVAL (operands[2]));
6133           if (widen)
6134             return "sub{l}\t{%2, %k0|%k0, %2}";
6135           else
6136             return "sub{b}\t{%2, %0|%0, %2}";
6137         }
6138       if (widen)
6139         return "add{l}\t{%k2, %k0|%k0, %k2}";
6140       else
6141         return "add{b}\t{%2, %0|%0, %2}";
6142     }
6143 }
6144   [(set (attr "type")
6145      (if_then_else (eq_attr "alternative" "3")
6146         (const_string "lea")
6147         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148            (const_string "incdec")
6149            (const_string "alu"))))
6150    (set_attr "mode" "QI,QI,SI,SI")])
6151
6152 (define_insn "*addqi_1"
6153   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6154         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6155                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6156    (clobber (reg:CC FLAGS_REG))]
6157   "TARGET_PARTIAL_REG_STALL
6158    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6159 {
6160   int widen = (which_alternative == 2);
6161   switch (get_attr_type (insn))
6162     {
6163     case TYPE_INCDEC:
6164       if (operands[2] == const1_rtx)
6165         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6166       else
6167         {
6168           gcc_assert (operands[2] == constm1_rtx);
6169           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6170         }
6171
6172     default:
6173       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6175       if (GET_CODE (operands[2]) == CONST_INT
6176           && (INTVAL (operands[2]) == 128
6177               || (INTVAL (operands[2]) < 0
6178                   && INTVAL (operands[2]) != -128)))
6179         {
6180           operands[2] = GEN_INT (-INTVAL (operands[2]));
6181           if (widen)
6182             return "sub{l}\t{%2, %k0|%k0, %2}";
6183           else
6184             return "sub{b}\t{%2, %0|%0, %2}";
6185         }
6186       if (widen)
6187         return "add{l}\t{%k2, %k0|%k0, %k2}";
6188       else
6189         return "add{b}\t{%2, %0|%0, %2}";
6190     }
6191 }
6192   [(set (attr "type")
6193      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194         (const_string "incdec")
6195         (const_string "alu")))
6196    (set_attr "mode" "QI,QI,SI")])
6197
6198 (define_insn "*addqi_1_slp"
6199   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6200         (plus:QI (match_dup 0)
6201                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6202    (clobber (reg:CC FLAGS_REG))]
6203   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6204    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6205 {
6206   switch (get_attr_type (insn))
6207     {
6208     case TYPE_INCDEC:
6209       if (operands[1] == const1_rtx)
6210         return "inc{b}\t%0";
6211       else
6212         {
6213           gcc_assert (operands[1] == constm1_rtx);
6214           return "dec{b}\t%0";
6215         }
6216
6217     default:
6218       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6219       if (GET_CODE (operands[1]) == CONST_INT
6220           && INTVAL (operands[1]) < 0)
6221         {
6222           operands[1] = GEN_INT (-INTVAL (operands[1]));
6223           return "sub{b}\t{%1, %0|%0, %1}";
6224         }
6225       return "add{b}\t{%1, %0|%0, %1}";
6226     }
6227 }
6228   [(set (attr "type")
6229      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6230         (const_string "incdec")
6231         (const_string "alu1")))
6232    (set (attr "memory")
6233      (if_then_else (match_operand 1 "memory_operand" "")
6234         (const_string "load")
6235         (const_string "none")))
6236    (set_attr "mode" "QI")])
6237
6238 (define_insn "*addqi_2"
6239   [(set (reg FLAGS_REG)
6240         (compare
6241           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6242                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6243           (const_int 0)))
6244    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6245         (plus:QI (match_dup 1) (match_dup 2)))]
6246   "ix86_match_ccmode (insn, CCGOCmode)
6247    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6248 {
6249   switch (get_attr_type (insn))
6250     {
6251     case TYPE_INCDEC:
6252       if (operands[2] == const1_rtx)
6253         return "inc{b}\t%0";
6254       else
6255         {
6256           gcc_assert (operands[2] == constm1_rtx
6257                       || (GET_CODE (operands[2]) == CONST_INT
6258                           && INTVAL (operands[2]) == 255));
6259           return "dec{b}\t%0";
6260         }
6261
6262     default:
6263       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6264       if (GET_CODE (operands[2]) == CONST_INT
6265           && INTVAL (operands[2]) < 0)
6266         {
6267           operands[2] = GEN_INT (-INTVAL (operands[2]));
6268           return "sub{b}\t{%2, %0|%0, %2}";
6269         }
6270       return "add{b}\t{%2, %0|%0, %2}";
6271     }
6272 }
6273   [(set (attr "type")
6274      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275         (const_string "incdec")
6276         (const_string "alu")))
6277    (set_attr "mode" "QI")])
6278
6279 (define_insn "*addqi_3"
6280   [(set (reg FLAGS_REG)
6281         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6282                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6283    (clobber (match_scratch:QI 0 "=q"))]
6284   "ix86_match_ccmode (insn, CCZmode)
6285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6286 {
6287   switch (get_attr_type (insn))
6288     {
6289     case TYPE_INCDEC:
6290       if (operands[2] == const1_rtx)
6291         return "inc{b}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == constm1_rtx
6295                       || (GET_CODE (operands[2]) == CONST_INT
6296                           && INTVAL (operands[2]) == 255));
6297           return "dec{b}\t%0";
6298         }
6299
6300     default:
6301       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6302       if (GET_CODE (operands[2]) == CONST_INT
6303           && INTVAL (operands[2]) < 0)
6304         {
6305           operands[2] = GEN_INT (-INTVAL (operands[2]));
6306           return "sub{b}\t{%2, %0|%0, %2}";
6307         }
6308       return "add{b}\t{%2, %0|%0, %2}";
6309     }
6310 }
6311   [(set (attr "type")
6312      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6313         (const_string "incdec")
6314         (const_string "alu")))
6315    (set_attr "mode" "QI")])
6316
6317 ; See comments above addsi_4 for details.
6318 (define_insn "*addqi_4"
6319   [(set (reg FLAGS_REG)
6320         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6321                  (match_operand:QI 2 "const_int_operand" "n")))
6322    (clobber (match_scratch:QI 0 "=qm"))]
6323   "ix86_match_ccmode (insn, CCGCmode)
6324    && (INTVAL (operands[2]) & 0xff) != 0x80"
6325 {
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == constm1_rtx
6330           || (GET_CODE (operands[2]) == CONST_INT
6331               && INTVAL (operands[2]) == 255))
6332         return "inc{b}\t%0";
6333       else
6334         {
6335           gcc_assert (operands[2] == const1_rtx);
6336           return "dec{b}\t%0";
6337         }
6338
6339     default:
6340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341       if (INTVAL (operands[2]) < 0)
6342         {
6343           operands[2] = GEN_INT (-INTVAL (operands[2]));
6344           return "add{b}\t{%2, %0|%0, %2}";
6345         }
6346       return "sub{b}\t{%2, %0|%0, %2}";
6347     }
6348 }
6349   [(set (attr "type")
6350      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351         (const_string "incdec")
6352         (const_string "alu")))
6353    (set_attr "mode" "QI")])
6354
6355
6356 (define_insn "*addqi_5"
6357   [(set (reg FLAGS_REG)
6358         (compare
6359           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6360                    (match_operand:QI 2 "general_operand" "qmni"))
6361           (const_int 0)))
6362    (clobber (match_scratch:QI 0 "=q"))]
6363   "ix86_match_ccmode (insn, CCGOCmode)
6364    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6365 {
6366   switch (get_attr_type (insn))
6367     {
6368     case TYPE_INCDEC:
6369       if (operands[2] == const1_rtx)
6370         return "inc{b}\t%0";
6371       else
6372         {
6373           gcc_assert (operands[2] == constm1_rtx
6374                       || (GET_CODE (operands[2]) == CONST_INT
6375                           && INTVAL (operands[2]) == 255));
6376           return "dec{b}\t%0";
6377         }
6378
6379     default:
6380       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6381       if (GET_CODE (operands[2]) == CONST_INT
6382           && INTVAL (operands[2]) < 0)
6383         {
6384           operands[2] = GEN_INT (-INTVAL (operands[2]));
6385           return "sub{b}\t{%2, %0|%0, %2}";
6386         }
6387       return "add{b}\t{%2, %0|%0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6395
6396
6397 (define_insn "addqi_ext_1"
6398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399                          (const_int 8)
6400                          (const_int 8))
6401         (plus:SI
6402           (zero_extract:SI
6403             (match_operand 1 "ext_register_operand" "0")
6404             (const_int 8)
6405             (const_int 8))
6406           (match_operand:QI 2 "general_operand" "Qmn")))
6407    (clobber (reg:CC FLAGS_REG))]
6408   "!TARGET_64BIT"
6409 {
6410   switch (get_attr_type (insn))
6411     {
6412     case TYPE_INCDEC:
6413       if (operands[2] == const1_rtx)
6414         return "inc{b}\t%h0";
6415       else
6416         {
6417           gcc_assert (operands[2] == constm1_rtx
6418                       || (GET_CODE (operands[2]) == CONST_INT
6419                           && INTVAL (operands[2]) == 255));
6420           return "dec{b}\t%h0";
6421         }
6422
6423     default:
6424       return "add{b}\t{%2, %h0|%h0, %2}";
6425     }
6426 }
6427   [(set (attr "type")
6428      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429         (const_string "incdec")
6430         (const_string "alu")))
6431    (set_attr "mode" "QI")])
6432
6433 (define_insn "*addqi_ext_1_rex64"
6434   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435                          (const_int 8)
6436                          (const_int 8))
6437         (plus:SI
6438           (zero_extract:SI
6439             (match_operand 1 "ext_register_operand" "0")
6440             (const_int 8)
6441             (const_int 8))
6442           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6443    (clobber (reg:CC FLAGS_REG))]
6444   "TARGET_64BIT"
6445 {
6446   switch (get_attr_type (insn))
6447     {
6448     case TYPE_INCDEC:
6449       if (operands[2] == const1_rtx)
6450         return "inc{b}\t%h0";
6451       else
6452         {
6453           gcc_assert (operands[2] == constm1_rtx
6454                       || (GET_CODE (operands[2]) == CONST_INT
6455                           && INTVAL (operands[2]) == 255));
6456           return "dec{b}\t%h0";
6457         }
6458
6459     default:
6460       return "add{b}\t{%2, %h0|%h0, %2}";
6461     }
6462 }
6463   [(set (attr "type")
6464      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465         (const_string "incdec")
6466         (const_string "alu")))
6467    (set_attr "mode" "QI")])
6468
6469 (define_insn "*addqi_ext_2"
6470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6471                          (const_int 8)
6472                          (const_int 8))
6473         (plus:SI
6474           (zero_extract:SI
6475             (match_operand 1 "ext_register_operand" "%0")
6476             (const_int 8)
6477             (const_int 8))
6478           (zero_extract:SI
6479             (match_operand 2 "ext_register_operand" "Q")
6480             (const_int 8)
6481             (const_int 8))))
6482    (clobber (reg:CC FLAGS_REG))]
6483   ""
6484   "add{b}\t{%h2, %h0|%h0, %h2}"
6485   [(set_attr "type" "alu")
6486    (set_attr "mode" "QI")])
6487
6488 ;; The patterns that match these are at the end of this file.
6489
6490 (define_expand "addxf3"
6491   [(set (match_operand:XF 0 "register_operand" "")
6492         (plus:XF (match_operand:XF 1 "register_operand" "")
6493                  (match_operand:XF 2 "register_operand" "")))]
6494   "TARGET_80387"
6495   "")
6496
6497 (define_expand "adddf3"
6498   [(set (match_operand:DF 0 "register_operand" "")
6499         (plus:DF (match_operand:DF 1 "register_operand" "")
6500                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6501   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6502   "")
6503
6504 (define_expand "addsf3"
6505   [(set (match_operand:SF 0 "register_operand" "")
6506         (plus:SF (match_operand:SF 1 "register_operand" "")
6507                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6508   "TARGET_80387 || TARGET_SSE_MATH"
6509   "")
6510 \f
6511 ;; Subtract instructions
6512
6513 ;; %%% splits for subditi3
6514
6515 (define_expand "subti3"
6516   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6517                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6518                              (match_operand:TI 2 "x86_64_general_operand" "")))
6519               (clobber (reg:CC FLAGS_REG))])]
6520   "TARGET_64BIT"
6521   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6522
6523 (define_insn "*subti3_1"
6524   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6525         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6526                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6529   "#")
6530
6531 (define_split
6532   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534                   (match_operand:TI 2 "x86_64_general_operand" "")))
6535    (clobber (reg:CC FLAGS_REG))]
6536   "TARGET_64BIT && reload_completed"
6537   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6538               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6539    (parallel [(set (match_dup 3)
6540                    (minus:DI (match_dup 4)
6541                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6542                                       (match_dup 5))))
6543               (clobber (reg:CC FLAGS_REG))])]
6544   "split_ti (operands+0, 1, operands+0, operands+3);
6545    split_ti (operands+1, 1, operands+1, operands+4);
6546    split_ti (operands+2, 1, operands+2, operands+5);")
6547
6548 ;; %%% splits for subsidi3
6549
6550 (define_expand "subdi3"
6551   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6552                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6553                              (match_operand:DI 2 "x86_64_general_operand" "")))
6554               (clobber (reg:CC FLAGS_REG))])]
6555   ""
6556   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6557
6558 (define_insn "*subdi3_1"
6559   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6560         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564   "#")
6565
6566 (define_split
6567   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569                   (match_operand:DI 2 "general_operand" "")))
6570    (clobber (reg:CC FLAGS_REG))]
6571   "!TARGET_64BIT && reload_completed"
6572   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6573               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6574    (parallel [(set (match_dup 3)
6575                    (minus:SI (match_dup 4)
6576                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6577                                       (match_dup 5))))
6578               (clobber (reg:CC FLAGS_REG))])]
6579   "split_di (operands+0, 1, operands+0, operands+3);
6580    split_di (operands+1, 1, operands+1, operands+4);
6581    split_di (operands+2, 1, operands+2, operands+5);")
6582
6583 (define_insn "subdi3_carry_rex64"
6584   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6586             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6587                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590   "sbb{q}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "pent_pair" "pu")
6593    (set_attr "mode" "DI")])
6594
6595 (define_insn "*subdi_1_rex64"
6596   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6599    (clobber (reg:CC FLAGS_REG))]
6600   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601   "sub{q}\t{%2, %0|%0, %2}"
6602   [(set_attr "type" "alu")
6603    (set_attr "mode" "DI")])
6604
6605 (define_insn "*subdi_2_rex64"
6606   [(set (reg FLAGS_REG)
6607         (compare
6608           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6610           (const_int 0)))
6611    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:DI (match_dup 1) (match_dup 2)))]
6613   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6614    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615   "sub{q}\t{%2, %0|%0, %2}"
6616   [(set_attr "type" "alu")
6617    (set_attr "mode" "DI")])
6618
6619 (define_insn "*subdi_3_rex63"
6620   [(set (reg FLAGS_REG)
6621         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6623    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624         (minus:DI (match_dup 1) (match_dup 2)))]
6625   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6626    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627   "sub{q}\t{%2, %0|%0, %2}"
6628   [(set_attr "type" "alu")
6629    (set_attr "mode" "DI")])
6630
6631 (define_insn "subqi3_carry"
6632   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6633           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6634             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6635                (match_operand:QI 2 "general_operand" "qi,qm"))))
6636    (clobber (reg:CC FLAGS_REG))]
6637   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6638   "sbb{b}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "pent_pair" "pu")
6641    (set_attr "mode" "QI")])
6642
6643 (define_insn "subhi3_carry"
6644   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6645           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6646             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6647                (match_operand:HI 2 "general_operand" "ri,rm"))))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650   "sbb{w}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "pent_pair" "pu")
6653    (set_attr "mode" "HI")])
6654
6655 (define_insn "subsi3_carry"
6656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6659                (match_operand:SI 2 "general_operand" "ri,rm"))))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sbb{l}\t{%2, %0|%0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "pent_pair" "pu")
6665    (set_attr "mode" "SI")])
6666
6667 (define_insn "subsi3_carry_zext"
6668   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6669           (zero_extend:DI
6670             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6671               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6673    (clobber (reg:CC FLAGS_REG))]
6674   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675   "sbb{l}\t{%2, %k0|%k0, %2}"
6676   [(set_attr "type" "alu")
6677    (set_attr "pent_pair" "pu")
6678    (set_attr "mode" "SI")])
6679
6680 (define_expand "subsi3"
6681   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6682                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6683                              (match_operand:SI 2 "general_operand" "")))
6684               (clobber (reg:CC FLAGS_REG))])]
6685   ""
6686   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6687
6688 (define_insn "*subsi_1"
6689   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6691                   (match_operand:SI 2 "general_operand" "ri,rm")))
6692    (clobber (reg:CC FLAGS_REG))]
6693   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sub{l}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "SI")])
6697
6698 (define_insn "*subsi_1_zext"
6699   [(set (match_operand:DI 0 "register_operand" "=r")
6700         (zero_extend:DI
6701           (minus:SI (match_operand:SI 1 "register_operand" "0")
6702                     (match_operand:SI 2 "general_operand" "rim"))))
6703    (clobber (reg:CC FLAGS_REG))]
6704   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705   "sub{l}\t{%2, %k0|%k0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "SI")])
6708
6709 (define_insn "*subsi_2"
6710   [(set (reg FLAGS_REG)
6711         (compare
6712           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713                     (match_operand:SI 2 "general_operand" "ri,rm"))
6714           (const_int 0)))
6715    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716         (minus:SI (match_dup 1) (match_dup 2)))]
6717   "ix86_match_ccmode (insn, CCGOCmode)
6718    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719   "sub{l}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "SI")])
6722
6723 (define_insn "*subsi_2_zext"
6724   [(set (reg FLAGS_REG)
6725         (compare
6726           (minus:SI (match_operand:SI 1 "register_operand" "0")
6727                     (match_operand:SI 2 "general_operand" "rim"))
6728           (const_int 0)))
6729    (set (match_operand:DI 0 "register_operand" "=r")
6730         (zero_extend:DI
6731           (minus:SI (match_dup 1)
6732                     (match_dup 2))))]
6733   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6734    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735   "sub{l}\t{%2, %k0|%k0, %2}"
6736   [(set_attr "type" "alu")
6737    (set_attr "mode" "SI")])
6738
6739 (define_insn "*subsi_3"
6740   [(set (reg FLAGS_REG)
6741         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6742                  (match_operand:SI 2 "general_operand" "ri,rm")))
6743    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744         (minus:SI (match_dup 1) (match_dup 2)))]
6745   "ix86_match_ccmode (insn, CCmode)
6746    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747   "sub{l}\t{%2, %0|%0, %2}"
6748   [(set_attr "type" "alu")
6749    (set_attr "mode" "SI")])
6750
6751 (define_insn "*subsi_3_zext"
6752   [(set (reg FLAGS_REG)
6753         (compare (match_operand:SI 1 "register_operand" "0")
6754                  (match_operand:SI 2 "general_operand" "rim")))
6755    (set (match_operand:DI 0 "register_operand" "=r")
6756         (zero_extend:DI
6757           (minus:SI (match_dup 1)
6758                     (match_dup 2))))]
6759   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6760    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761   "sub{l}\t{%2, %1|%1, %2}"
6762   [(set_attr "type" "alu")
6763    (set_attr "mode" "DI")])
6764
6765 (define_expand "subhi3"
6766   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6767                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6768                              (match_operand:HI 2 "general_operand" "")))
6769               (clobber (reg:CC FLAGS_REG))])]
6770   "TARGET_HIMODE_MATH"
6771   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6772
6773 (define_insn "*subhi_1"
6774   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776                   (match_operand:HI 2 "general_operand" "ri,rm")))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6779   "sub{w}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "HI")])
6782
6783 (define_insn "*subhi_2"
6784   [(set (reg FLAGS_REG)
6785         (compare
6786           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6787                     (match_operand:HI 2 "general_operand" "ri,rm"))
6788           (const_int 0)))
6789    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790         (minus:HI (match_dup 1) (match_dup 2)))]
6791   "ix86_match_ccmode (insn, CCGOCmode)
6792    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6793   "sub{w}\t{%2, %0|%0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "HI")])
6796
6797 (define_insn "*subhi_3"
6798   [(set (reg FLAGS_REG)
6799         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800                  (match_operand:HI 2 "general_operand" "ri,rm")))
6801    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:HI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCmode)
6804    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805   "sub{w}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "HI")])
6808
6809 (define_expand "subqi3"
6810   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6811                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6812                              (match_operand:QI 2 "general_operand" "")))
6813               (clobber (reg:CC FLAGS_REG))])]
6814   "TARGET_QIMODE_MATH"
6815   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6816
6817 (define_insn "*subqi_1"
6818   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6819         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6820                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6821    (clobber (reg:CC FLAGS_REG))]
6822   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6823   "sub{b}\t{%2, %0|%0, %2}"
6824   [(set_attr "type" "alu")
6825    (set_attr "mode" "QI")])
6826
6827 (define_insn "*subqi_1_slp"
6828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6829         (minus:QI (match_dup 0)
6830                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6831    (clobber (reg:CC FLAGS_REG))]
6832   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6833    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6834   "sub{b}\t{%1, %0|%0, %1}"
6835   [(set_attr "type" "alu1")
6836    (set_attr "mode" "QI")])
6837
6838 (define_insn "*subqi_2"
6839   [(set (reg FLAGS_REG)
6840         (compare
6841           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842                     (match_operand:QI 2 "general_operand" "qi,qm"))
6843           (const_int 0)))
6844    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6845         (minus:HI (match_dup 1) (match_dup 2)))]
6846   "ix86_match_ccmode (insn, CCGOCmode)
6847    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6848   "sub{b}\t{%2, %0|%0, %2}"
6849   [(set_attr "type" "alu")
6850    (set_attr "mode" "QI")])
6851
6852 (define_insn "*subqi_3"
6853   [(set (reg FLAGS_REG)
6854         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855                  (match_operand:QI 2 "general_operand" "qi,qm")))
6856    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857         (minus:HI (match_dup 1) (match_dup 2)))]
6858   "ix86_match_ccmode (insn, CCmode)
6859    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860   "sub{b}\t{%2, %0|%0, %2}"
6861   [(set_attr "type" "alu")
6862    (set_attr "mode" "QI")])
6863
6864 ;; The patterns that match these are at the end of this file.
6865
6866 (define_expand "subxf3"
6867   [(set (match_operand:XF 0 "register_operand" "")
6868         (minus:XF (match_operand:XF 1 "register_operand" "")
6869                   (match_operand:XF 2 "register_operand" "")))]
6870   "TARGET_80387"
6871   "")
6872
6873 (define_expand "subdf3"
6874   [(set (match_operand:DF 0 "register_operand" "")
6875         (minus:DF (match_operand:DF 1 "register_operand" "")
6876                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6877   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6878   "")
6879
6880 (define_expand "subsf3"
6881   [(set (match_operand:SF 0 "register_operand" "")
6882         (minus:SF (match_operand:SF 1 "register_operand" "")
6883                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6884   "TARGET_80387 || TARGET_SSE_MATH"
6885   "")
6886 \f
6887 ;; Multiply instructions
6888
6889 (define_expand "muldi3"
6890   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6891                    (mult:DI (match_operand:DI 1 "register_operand" "")
6892                             (match_operand:DI 2 "x86_64_general_operand" "")))
6893               (clobber (reg:CC FLAGS_REG))])]
6894   "TARGET_64BIT"
6895   "")
6896
6897 ;; On AMDFAM10 
6898 ;; IMUL reg64, reg64, imm8      Direct
6899 ;; IMUL reg64, mem64, imm8      VectorPath
6900 ;; IMUL reg64, reg64, imm32     Direct
6901 ;; IMUL reg64, mem64, imm32     VectorPath 
6902 ;; IMUL reg64, reg64            Direct
6903 ;; IMUL reg64, mem64            Direct
6904
6905 (define_insn "*muldi3_1_rex64"
6906   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6907         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6908                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6909    (clobber (reg:CC FLAGS_REG))]
6910   "TARGET_64BIT
6911    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6912   "@
6913    imul{q}\t{%2, %1, %0|%0, %1, %2}
6914    imul{q}\t{%2, %1, %0|%0, %1, %2}
6915    imul{q}\t{%2, %0|%0, %2}"
6916   [(set_attr "type" "imul")
6917    (set_attr "prefix_0f" "0,0,1")
6918    (set (attr "athlon_decode")
6919         (cond [(eq_attr "cpu" "athlon")
6920                   (const_string "vector")
6921                (eq_attr "alternative" "1")
6922                   (const_string "vector")
6923                (and (eq_attr "alternative" "2")
6924                     (match_operand 1 "memory_operand" ""))
6925                   (const_string "vector")]
6926               (const_string "direct")))
6927    (set (attr "amdfam10_decode")
6928         (cond [(and (eq_attr "alternative" "0,1")
6929                     (match_operand 1 "memory_operand" ""))
6930                   (const_string "vector")]
6931               (const_string "direct")))       
6932    (set_attr "mode" "DI")])
6933
6934 (define_expand "mulsi3"
6935   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936                    (mult:SI (match_operand:SI 1 "register_operand" "")
6937                             (match_operand:SI 2 "general_operand" "")))
6938               (clobber (reg:CC FLAGS_REG))])]
6939   ""
6940   "")
6941
6942 ;; On AMDFAM10 
6943 ;; IMUL reg32, reg32, imm8      Direct
6944 ;; IMUL reg32, mem32, imm8      VectorPath
6945 ;; IMUL reg32, reg32, imm32     Direct
6946 ;; IMUL reg32, mem32, imm32     VectorPath
6947 ;; IMUL reg32, reg32            Direct
6948 ;; IMUL reg32, mem32            Direct
6949
6950 (define_insn "*mulsi3_1"
6951   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6952         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6954    (clobber (reg:CC FLAGS_REG))]
6955   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6956   "@
6957    imul{l}\t{%2, %1, %0|%0, %1, %2}
6958    imul{l}\t{%2, %1, %0|%0, %1, %2}
6959    imul{l}\t{%2, %0|%0, %2}"
6960   [(set_attr "type" "imul")
6961    (set_attr "prefix_0f" "0,0,1")
6962    (set (attr "athlon_decode")
6963         (cond [(eq_attr "cpu" "athlon")
6964                   (const_string "vector")
6965                (eq_attr "alternative" "1")
6966                   (const_string "vector")
6967                (and (eq_attr "alternative" "2")
6968                     (match_operand 1 "memory_operand" ""))
6969                   (const_string "vector")]
6970               (const_string "direct")))
6971    (set (attr "amdfam10_decode")
6972         (cond [(and (eq_attr "alternative" "0,1")
6973                     (match_operand 1 "memory_operand" ""))
6974                   (const_string "vector")]
6975               (const_string "direct")))       
6976    (set_attr "mode" "SI")])
6977
6978 (define_insn "*mulsi3_1_zext"
6979   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6980         (zero_extend:DI
6981           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6982                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6983    (clobber (reg:CC FLAGS_REG))]
6984   "TARGET_64BIT
6985    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986   "@
6987    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6988    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6989    imul{l}\t{%2, %k0|%k0, %2}"
6990   [(set_attr "type" "imul")
6991    (set_attr "prefix_0f" "0,0,1")
6992    (set (attr "athlon_decode")
6993         (cond [(eq_attr "cpu" "athlon")
6994                   (const_string "vector")
6995                (eq_attr "alternative" "1")
6996                   (const_string "vector")
6997                (and (eq_attr "alternative" "2")
6998                     (match_operand 1 "memory_operand" ""))
6999                   (const_string "vector")]
7000               (const_string "direct")))
7001    (set (attr "amdfam10_decode")
7002         (cond [(and (eq_attr "alternative" "0,1")
7003                     (match_operand 1 "memory_operand" ""))
7004                   (const_string "vector")]
7005               (const_string "direct")))       
7006    (set_attr "mode" "SI")])
7007
7008 (define_expand "mulhi3"
7009   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010                    (mult:HI (match_operand:HI 1 "register_operand" "")
7011                             (match_operand:HI 2 "general_operand" "")))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   "TARGET_HIMODE_MATH"
7014   "")
7015
7016 ;; On AMDFAM10
7017 ;; IMUL reg16, reg16, imm8      VectorPath
7018 ;; IMUL reg16, mem16, imm8      VectorPath
7019 ;; IMUL reg16, reg16, imm16     VectorPath
7020 ;; IMUL reg16, mem16, imm16     VectorPath
7021 ;; IMUL reg16, reg16            Direct
7022 ;; IMUL reg16, mem16            Direct
7023 (define_insn "*mulhi3_1"
7024   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7025         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7026                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7027    (clobber (reg:CC FLAGS_REG))]
7028   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7029   "@
7030    imul{w}\t{%2, %1, %0|%0, %1, %2}
7031    imul{w}\t{%2, %1, %0|%0, %1, %2}
7032    imul{w}\t{%2, %0|%0, %2}"
7033   [(set_attr "type" "imul")
7034    (set_attr "prefix_0f" "0,0,1")
7035    (set (attr "athlon_decode")
7036         (cond [(eq_attr "cpu" "athlon")
7037                   (const_string "vector")
7038                (eq_attr "alternative" "1,2")
7039                   (const_string "vector")]
7040               (const_string "direct")))
7041    (set (attr "amdfam10_decode")
7042         (cond [(eq_attr "alternative" "0,1")
7043                   (const_string "vector")]
7044               (const_string "direct")))
7045    (set_attr "mode" "HI")])
7046
7047 (define_expand "mulqi3"
7048   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7049                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7050                             (match_operand:QI 2 "register_operand" "")))
7051               (clobber (reg:CC FLAGS_REG))])]
7052   "TARGET_QIMODE_MATH"
7053   "")
7054
7055 ;;On AMDFAM10
7056 ;; MUL reg8     Direct
7057 ;; MUL mem8     Direct
7058
7059 (define_insn "*mulqi3_1"
7060   [(set (match_operand:QI 0 "register_operand" "=a")
7061         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7062                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7063    (clobber (reg:CC FLAGS_REG))]
7064   "TARGET_QIMODE_MATH
7065    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7066   "mul{b}\t%2"
7067   [(set_attr "type" "imul")
7068    (set_attr "length_immediate" "0")
7069    (set (attr "athlon_decode")
7070      (if_then_else (eq_attr "cpu" "athlon")
7071         (const_string "vector")
7072         (const_string "direct")))
7073    (set_attr "amdfam10_decode" "direct")        
7074    (set_attr "mode" "QI")])
7075
7076 (define_expand "umulqihi3"
7077   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7078                    (mult:HI (zero_extend:HI
7079                               (match_operand:QI 1 "nonimmediate_operand" ""))
7080                             (zero_extend:HI
7081                               (match_operand:QI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_QIMODE_MATH"
7084   "")
7085
7086 (define_insn "*umulqihi3_1"
7087   [(set (match_operand:HI 0 "register_operand" "=a")
7088         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_QIMODE_MATH
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "mul{b}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "direct")))
7100    (set_attr "amdfam10_decode" "direct")        
7101    (set_attr "mode" "QI")])
7102
7103 (define_expand "mulqihi3"
7104   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7105                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7106                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7107               (clobber (reg:CC FLAGS_REG))])]
7108   "TARGET_QIMODE_MATH"
7109   "")
7110
7111 (define_insn "*mulqihi3_insn"
7112   [(set (match_operand:HI 0 "register_operand" "=a")
7113         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7114                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "TARGET_QIMODE_MATH
7117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7118   "imul{b}\t%2"
7119   [(set_attr "type" "imul")
7120    (set_attr "length_immediate" "0")
7121    (set (attr "athlon_decode")
7122      (if_then_else (eq_attr "cpu" "athlon")
7123         (const_string "vector")
7124         (const_string "direct")))
7125    (set_attr "amdfam10_decode" "direct")        
7126    (set_attr "mode" "QI")])
7127
7128 (define_expand "umulditi3"
7129   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130                    (mult:TI (zero_extend:TI
7131                               (match_operand:DI 1 "nonimmediate_operand" ""))
7132                             (zero_extend:TI
7133                               (match_operand:DI 2 "register_operand" ""))))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "TARGET_64BIT"
7136   "")
7137
7138 (define_insn "*umulditi3_insn"
7139   [(set (match_operand:TI 0 "register_operand" "=A")
7140         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "mul{q}\t%2"
7146   [(set_attr "type" "imul")
7147    (set_attr "length_immediate" "0")
7148    (set (attr "athlon_decode")
7149      (if_then_else (eq_attr "cpu" "athlon")
7150         (const_string "vector")
7151         (const_string "double")))
7152    (set_attr "amdfam10_decode" "double")        
7153    (set_attr "mode" "DI")])
7154
7155 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7156 (define_expand "umulsidi3"
7157   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7158                    (mult:DI (zero_extend:DI
7159                               (match_operand:SI 1 "nonimmediate_operand" ""))
7160                             (zero_extend:DI
7161                               (match_operand:SI 2 "register_operand" ""))))
7162               (clobber (reg:CC FLAGS_REG))])]
7163   "!TARGET_64BIT"
7164   "")
7165
7166 (define_insn "*umulsidi3_insn"
7167   [(set (match_operand:DI 0 "register_operand" "=A")
7168         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7169                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7170    (clobber (reg:CC FLAGS_REG))]
7171   "!TARGET_64BIT
7172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7173   "mul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set_attr "length_immediate" "0")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "amdfam10_decode" "double")        
7181    (set_attr "mode" "SI")])
7182
7183 (define_expand "mulditi3"
7184   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7185                    (mult:TI (sign_extend:TI
7186                               (match_operand:DI 1 "nonimmediate_operand" ""))
7187                             (sign_extend:TI
7188                               (match_operand:DI 2 "register_operand" ""))))
7189               (clobber (reg:CC FLAGS_REG))])]
7190   "TARGET_64BIT"
7191   "")
7192
7193 (define_insn "*mulditi3_insn"
7194   [(set (match_operand:TI 0 "register_operand" "=A")
7195         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7196                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7197    (clobber (reg:CC FLAGS_REG))]
7198   "TARGET_64BIT
7199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200   "imul{q}\t%2"
7201   [(set_attr "type" "imul")
7202    (set_attr "length_immediate" "0")
7203    (set (attr "athlon_decode")
7204      (if_then_else (eq_attr "cpu" "athlon")
7205         (const_string "vector")
7206         (const_string "double")))
7207    (set_attr "amdfam10_decode" "double")
7208    (set_attr "mode" "DI")])
7209
7210 (define_expand "mulsidi3"
7211   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7212                    (mult:DI (sign_extend:DI
7213                               (match_operand:SI 1 "nonimmediate_operand" ""))
7214                             (sign_extend:DI
7215                               (match_operand:SI 2 "register_operand" ""))))
7216               (clobber (reg:CC FLAGS_REG))])]
7217   "!TARGET_64BIT"
7218   "")
7219
7220 (define_insn "*mulsidi3_insn"
7221   [(set (match_operand:DI 0 "register_operand" "=A")
7222         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7223                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7224    (clobber (reg:CC FLAGS_REG))]
7225   "!TARGET_64BIT
7226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227   "imul{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 "amdfam10_decode" "double")        
7235    (set_attr "mode" "SI")])
7236
7237 (define_expand "umuldi3_highpart"
7238   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7239                    (truncate:DI
7240                      (lshiftrt:TI
7241                        (mult:TI (zero_extend:TI
7242                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7243                                 (zero_extend:TI
7244                                   (match_operand:DI 2 "register_operand" "")))
7245                        (const_int 64))))
7246               (clobber (match_scratch:DI 3 ""))
7247               (clobber (reg:CC FLAGS_REG))])]
7248   "TARGET_64BIT"
7249   "")
7250
7251 (define_insn "*umuldi3_highpart_rex64"
7252   [(set (match_operand:DI 0 "register_operand" "=d")
7253         (truncate:DI
7254           (lshiftrt:TI
7255             (mult:TI (zero_extend:TI
7256                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257                      (zero_extend:TI
7258                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259             (const_int 64))))
7260    (clobber (match_scratch:DI 3 "=1"))
7261    (clobber (reg:CC FLAGS_REG))]
7262   "TARGET_64BIT
7263    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264   "mul{q}\t%2"
7265   [(set_attr "type" "imul")
7266    (set_attr "length_immediate" "0")
7267    (set (attr "athlon_decode")
7268      (if_then_else (eq_attr "cpu" "athlon")
7269         (const_string "vector")
7270         (const_string "double")))
7271    (set_attr "amdfam10_decode" "double")        
7272    (set_attr "mode" "DI")])
7273
7274 (define_expand "umulsi3_highpart"
7275   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7276                    (truncate:SI
7277                      (lshiftrt:DI
7278                        (mult:DI (zero_extend:DI
7279                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7280                                 (zero_extend:DI
7281                                   (match_operand:SI 2 "register_operand" "")))
7282                        (const_int 32))))
7283               (clobber (match_scratch:SI 3 ""))
7284               (clobber (reg:CC FLAGS_REG))])]
7285   ""
7286   "")
7287
7288 (define_insn "*umulsi3_highpart_insn"
7289   [(set (match_operand:SI 0 "register_operand" "=d")
7290         (truncate:SI
7291           (lshiftrt:DI
7292             (mult:DI (zero_extend:DI
7293                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7294                      (zero_extend:DI
7295                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7296             (const_int 32))))
7297    (clobber (match_scratch:SI 3 "=1"))
7298    (clobber (reg:CC FLAGS_REG))]
7299   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7300   "mul{l}\t%2"
7301   [(set_attr "type" "imul")
7302    (set_attr "length_immediate" "0")
7303    (set (attr "athlon_decode")
7304      (if_then_else (eq_attr "cpu" "athlon")
7305         (const_string "vector")
7306         (const_string "double")))
7307    (set_attr "amdfam10_decode" "double")
7308    (set_attr "mode" "SI")])
7309
7310 (define_insn "*umulsi3_highpart_zext"
7311   [(set (match_operand:DI 0 "register_operand" "=d")
7312         (zero_extend:DI (truncate:SI
7313           (lshiftrt:DI
7314             (mult:DI (zero_extend:DI
7315                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7316                      (zero_extend:DI
7317                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7318             (const_int 32)))))
7319    (clobber (match_scratch:SI 3 "=1"))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "TARGET_64BIT
7322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7323   "mul{l}\t%2"
7324   [(set_attr "type" "imul")
7325    (set_attr "length_immediate" "0")
7326    (set (attr "athlon_decode")
7327      (if_then_else (eq_attr "cpu" "athlon")
7328         (const_string "vector")
7329         (const_string "double")))
7330    (set_attr "amdfam10_decode" "double")
7331    (set_attr "mode" "SI")])
7332
7333 (define_expand "smuldi3_highpart"
7334   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7335                    (truncate:DI
7336                      (lshiftrt:TI
7337                        (mult:TI (sign_extend:TI
7338                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7339                                 (sign_extend:TI
7340                                   (match_operand:DI 2 "register_operand" "")))
7341                        (const_int 64))))
7342               (clobber (match_scratch:DI 3 ""))
7343               (clobber (reg:CC FLAGS_REG))])]
7344   "TARGET_64BIT"
7345   "")
7346
7347 (define_insn "*smuldi3_highpart_rex64"
7348   [(set (match_operand:DI 0 "register_operand" "=d")
7349         (truncate:DI
7350           (lshiftrt:TI
7351             (mult:TI (sign_extend:TI
7352                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7353                      (sign_extend:TI
7354                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7355             (const_int 64))))
7356    (clobber (match_scratch:DI 3 "=1"))
7357    (clobber (reg:CC FLAGS_REG))]
7358   "TARGET_64BIT
7359    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7360   "imul{q}\t%2"
7361   [(set_attr "type" "imul")
7362    (set (attr "athlon_decode")
7363      (if_then_else (eq_attr "cpu" "athlon")
7364         (const_string "vector")
7365         (const_string "double")))
7366    (set_attr "amdfam10_decode" "double")
7367    (set_attr "mode" "DI")])
7368
7369 (define_expand "smulsi3_highpart"
7370   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7371                    (truncate:SI
7372                      (lshiftrt:DI
7373                        (mult:DI (sign_extend:DI
7374                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7375                                 (sign_extend:DI
7376                                   (match_operand:SI 2 "register_operand" "")))
7377                        (const_int 32))))
7378               (clobber (match_scratch:SI 3 ""))
7379               (clobber (reg:CC FLAGS_REG))])]
7380   ""
7381   "")
7382
7383 (define_insn "*smulsi3_highpart_insn"
7384   [(set (match_operand:SI 0 "register_operand" "=d")
7385         (truncate:SI
7386           (lshiftrt:DI
7387             (mult:DI (sign_extend:DI
7388                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389                      (sign_extend:DI
7390                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391             (const_int 32))))
7392    (clobber (match_scratch:SI 3 "=1"))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7395   "imul{l}\t%2"
7396   [(set_attr "type" "imul")
7397    (set (attr "athlon_decode")
7398      (if_then_else (eq_attr "cpu" "athlon")
7399         (const_string "vector")
7400         (const_string "double")))
7401    (set_attr "amdfam10_decode" "double")
7402    (set_attr "mode" "SI")])
7403
7404 (define_insn "*smulsi3_highpart_zext"
7405   [(set (match_operand:DI 0 "register_operand" "=d")
7406         (zero_extend:DI (truncate:SI
7407           (lshiftrt:DI
7408             (mult:DI (sign_extend:DI
7409                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410                      (sign_extend:DI
7411                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412             (const_int 32)))))
7413    (clobber (match_scratch:SI 3 "=1"))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT
7416    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417   "imul{l}\t%2"
7418   [(set_attr "type" "imul")
7419    (set (attr "athlon_decode")
7420      (if_then_else (eq_attr "cpu" "athlon")
7421         (const_string "vector")
7422         (const_string "double")))
7423    (set_attr "amdfam10_decode" "double")
7424    (set_attr "mode" "SI")])
7425
7426 ;; The patterns that match these are at the end of this file.
7427
7428 (define_expand "mulxf3"
7429   [(set (match_operand:XF 0 "register_operand" "")
7430         (mult:XF (match_operand:XF 1 "register_operand" "")
7431                  (match_operand:XF 2 "register_operand" "")))]
7432   "TARGET_80387"
7433   "")
7434
7435 (define_expand "muldf3"
7436   [(set (match_operand:DF 0 "register_operand" "")
7437         (mult:DF (match_operand:DF 1 "register_operand" "")
7438                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7439   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7440   "")
7441
7442 (define_expand "mulsf3"
7443   [(set (match_operand:SF 0 "register_operand" "")
7444         (mult:SF (match_operand:SF 1 "register_operand" "")
7445                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7446   "TARGET_80387 || TARGET_SSE_MATH"
7447   "")
7448 \f
7449 ;; Divide instructions
7450
7451 (define_insn "divqi3"
7452   [(set (match_operand:QI 0 "register_operand" "=a")
7453         (div:QI (match_operand:HI 1 "register_operand" "0")
7454                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455    (clobber (reg:CC FLAGS_REG))]
7456   "TARGET_QIMODE_MATH"
7457   "idiv{b}\t%2"
7458   [(set_attr "type" "idiv")
7459    (set_attr "mode" "QI")])
7460
7461 (define_insn "udivqi3"
7462   [(set (match_operand:QI 0 "register_operand" "=a")
7463         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7464                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7465    (clobber (reg:CC FLAGS_REG))]
7466   "TARGET_QIMODE_MATH"
7467   "div{b}\t%2"
7468   [(set_attr "type" "idiv")
7469    (set_attr "mode" "QI")])
7470
7471 ;; The patterns that match these are at the end of this file.
7472
7473 (define_expand "divxf3"
7474   [(set (match_operand:XF 0 "register_operand" "")
7475         (div:XF (match_operand:XF 1 "register_operand" "")
7476                 (match_operand:XF 2 "register_operand" "")))]
7477   "TARGET_80387"
7478   "")
7479
7480 (define_expand "divdf3"
7481   [(set (match_operand:DF 0 "register_operand" "")
7482         (div:DF (match_operand:DF 1 "register_operand" "")
7483                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7484    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7485    "")
7486  
7487 (define_expand "divsf3"
7488   [(set (match_operand:SF 0 "register_operand" "")
7489         (div:SF (match_operand:SF 1 "register_operand" "")
7490                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7491   "TARGET_80387 || TARGET_SSE_MATH"
7492   "")
7493 \f
7494 ;; Remainder instructions.
7495
7496 (define_expand "divmoddi4"
7497   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7498                    (div:DI (match_operand:DI 1 "register_operand" "")
7499                            (match_operand:DI 2 "nonimmediate_operand" "")))
7500               (set (match_operand:DI 3 "register_operand" "")
7501                    (mod:DI (match_dup 1) (match_dup 2)))
7502               (clobber (reg:CC FLAGS_REG))])]
7503   "TARGET_64BIT"
7504   "")
7505
7506 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7507 ;; Penalize eax case slightly because it results in worse scheduling
7508 ;; of code.
7509 (define_insn "*divmoddi4_nocltd_rex64"
7510   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7511         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7512                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7513    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7514         (mod:DI (match_dup 2) (match_dup 3)))
7515    (clobber (reg:CC FLAGS_REG))]
7516   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7517   "#"
7518   [(set_attr "type" "multi")])
7519
7520 (define_insn "*divmoddi4_cltd_rex64"
7521   [(set (match_operand:DI 0 "register_operand" "=a")
7522         (div:DI (match_operand:DI 2 "register_operand" "a")
7523                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7524    (set (match_operand:DI 1 "register_operand" "=&d")
7525         (mod:DI (match_dup 2) (match_dup 3)))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7528   "#"
7529   [(set_attr "type" "multi")])
7530
7531 (define_insn "*divmoddi_noext_rex64"
7532   [(set (match_operand:DI 0 "register_operand" "=a")
7533         (div:DI (match_operand:DI 1 "register_operand" "0")
7534                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7535    (set (match_operand:DI 3 "register_operand" "=d")
7536         (mod:DI (match_dup 1) (match_dup 2)))
7537    (use (match_operand:DI 4 "register_operand" "3"))
7538    (clobber (reg:CC FLAGS_REG))]
7539   "TARGET_64BIT"
7540   "idiv{q}\t%2"
7541   [(set_attr "type" "idiv")
7542    (set_attr "mode" "DI")])
7543
7544 (define_split
7545   [(set (match_operand:DI 0 "register_operand" "")
7546         (div:DI (match_operand:DI 1 "register_operand" "")
7547                 (match_operand:DI 2 "nonimmediate_operand" "")))
7548    (set (match_operand:DI 3 "register_operand" "")
7549         (mod:DI (match_dup 1) (match_dup 2)))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "TARGET_64BIT && reload_completed"
7552   [(parallel [(set (match_dup 3)
7553                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7554               (clobber (reg:CC FLAGS_REG))])
7555    (parallel [(set (match_dup 0)
7556                    (div:DI (reg:DI 0) (match_dup 2)))
7557               (set (match_dup 3)
7558                    (mod:DI (reg:DI 0) (match_dup 2)))
7559               (use (match_dup 3))
7560               (clobber (reg:CC FLAGS_REG))])]
7561 {
7562   /* Avoid use of cltd in favor of a mov+shift.  */
7563   if (!TARGET_USE_CLTD && !optimize_size)
7564     {
7565       if (true_regnum (operands[1]))
7566         emit_move_insn (operands[0], operands[1]);
7567       else
7568         emit_move_insn (operands[3], operands[1]);
7569       operands[4] = operands[3];
7570     }
7571   else
7572     {
7573       gcc_assert (!true_regnum (operands[1]));
7574       operands[4] = operands[1];
7575     }
7576 })
7577
7578
7579 (define_expand "divmodsi4"
7580   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581                    (div:SI (match_operand:SI 1 "register_operand" "")
7582                            (match_operand:SI 2 "nonimmediate_operand" "")))
7583               (set (match_operand:SI 3 "register_operand" "")
7584                    (mod:SI (match_dup 1) (match_dup 2)))
7585               (clobber (reg:CC FLAGS_REG))])]
7586   ""
7587   "")
7588
7589 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7590 ;; Penalize eax case slightly because it results in worse scheduling
7591 ;; of code.
7592 (define_insn "*divmodsi4_nocltd"
7593   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597         (mod:SI (match_dup 2) (match_dup 3)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "!optimize_size && !TARGET_USE_CLTD"
7600   "#"
7601   [(set_attr "type" "multi")])
7602
7603 (define_insn "*divmodsi4_cltd"
7604   [(set (match_operand:SI 0 "register_operand" "=a")
7605         (div:SI (match_operand:SI 2 "register_operand" "a")
7606                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607    (set (match_operand:SI 1 "register_operand" "=&d")
7608         (mod:SI (match_dup 2) (match_dup 3)))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "optimize_size || TARGET_USE_CLTD"
7611   "#"
7612   [(set_attr "type" "multi")])
7613
7614 (define_insn "*divmodsi_noext"
7615   [(set (match_operand:SI 0 "register_operand" "=a")
7616         (div:SI (match_operand:SI 1 "register_operand" "0")
7617                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618    (set (match_operand:SI 3 "register_operand" "=d")
7619         (mod:SI (match_dup 1) (match_dup 2)))
7620    (use (match_operand:SI 4 "register_operand" "3"))
7621    (clobber (reg:CC FLAGS_REG))]
7622   ""
7623   "idiv{l}\t%2"
7624   [(set_attr "type" "idiv")
7625    (set_attr "mode" "SI")])
7626
7627 (define_split
7628   [(set (match_operand:SI 0 "register_operand" "")
7629         (div:SI (match_operand:SI 1 "register_operand" "")
7630                 (match_operand:SI 2 "nonimmediate_operand" "")))
7631    (set (match_operand:SI 3 "register_operand" "")
7632         (mod:SI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "reload_completed"
7635   [(parallel [(set (match_dup 3)
7636                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7637               (clobber (reg:CC FLAGS_REG))])
7638    (parallel [(set (match_dup 0)
7639                    (div:SI (reg:SI 0) (match_dup 2)))
7640               (set (match_dup 3)
7641                    (mod:SI (reg:SI 0) (match_dup 2)))
7642               (use (match_dup 3))
7643               (clobber (reg:CC FLAGS_REG))])]
7644 {
7645   /* Avoid use of cltd in favor of a mov+shift.  */
7646   if (!TARGET_USE_CLTD && !optimize_size)
7647     {
7648       if (true_regnum (operands[1]))
7649         emit_move_insn (operands[0], operands[1]);
7650       else
7651         emit_move_insn (operands[3], operands[1]);
7652       operands[4] = operands[3];
7653     }
7654   else
7655     {
7656       gcc_assert (!true_regnum (operands[1]));
7657       operands[4] = operands[1];
7658     }
7659 })
7660 ;; %%% Split me.
7661 (define_insn "divmodhi4"
7662   [(set (match_operand:HI 0 "register_operand" "=a")
7663         (div:HI (match_operand:HI 1 "register_operand" "0")
7664                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7665    (set (match_operand:HI 3 "register_operand" "=&d")
7666         (mod:HI (match_dup 1) (match_dup 2)))
7667    (clobber (reg:CC FLAGS_REG))]
7668   "TARGET_HIMODE_MATH"
7669   "cwtd\;idiv{w}\t%2"
7670   [(set_attr "type" "multi")
7671    (set_attr "length_immediate" "0")
7672    (set_attr "mode" "SI")])
7673
7674 (define_insn "udivmoddi4"
7675   [(set (match_operand:DI 0 "register_operand" "=a")
7676         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7677                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7678    (set (match_operand:DI 3 "register_operand" "=&d")
7679         (umod:DI (match_dup 1) (match_dup 2)))
7680    (clobber (reg:CC FLAGS_REG))]
7681   "TARGET_64BIT"
7682   "xor{q}\t%3, %3\;div{q}\t%2"
7683   [(set_attr "type" "multi")
7684    (set_attr "length_immediate" "0")
7685    (set_attr "mode" "DI")])
7686
7687 (define_insn "*udivmoddi4_noext"
7688   [(set (match_operand:DI 0 "register_operand" "=a")
7689         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7690                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691    (set (match_operand:DI 3 "register_operand" "=d")
7692         (umod:DI (match_dup 1) (match_dup 2)))
7693    (use (match_dup 3))
7694    (clobber (reg:CC FLAGS_REG))]
7695   "TARGET_64BIT"
7696   "div{q}\t%2"
7697   [(set_attr "type" "idiv")
7698    (set_attr "mode" "DI")])
7699
7700 (define_split
7701   [(set (match_operand:DI 0 "register_operand" "")
7702         (udiv:DI (match_operand:DI 1 "register_operand" "")
7703                  (match_operand:DI 2 "nonimmediate_operand" "")))
7704    (set (match_operand:DI 3 "register_operand" "")
7705         (umod:DI (match_dup 1) (match_dup 2)))
7706    (clobber (reg:CC FLAGS_REG))]
7707   "TARGET_64BIT && reload_completed"
7708   [(set (match_dup 3) (const_int 0))
7709    (parallel [(set (match_dup 0)
7710                    (udiv:DI (match_dup 1) (match_dup 2)))
7711               (set (match_dup 3)
7712                    (umod:DI (match_dup 1) (match_dup 2)))
7713               (use (match_dup 3))
7714               (clobber (reg:CC FLAGS_REG))])]
7715   "")
7716
7717 (define_insn "udivmodsi4"
7718   [(set (match_operand:SI 0 "register_operand" "=a")
7719         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7720                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721    (set (match_operand:SI 3 "register_operand" "=&d")
7722         (umod:SI (match_dup 1) (match_dup 2)))
7723    (clobber (reg:CC FLAGS_REG))]
7724   ""
7725   "xor{l}\t%3, %3\;div{l}\t%2"
7726   [(set_attr "type" "multi")
7727    (set_attr "length_immediate" "0")
7728    (set_attr "mode" "SI")])
7729
7730 (define_insn "*udivmodsi4_noext"
7731   [(set (match_operand:SI 0 "register_operand" "=a")
7732         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7733                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734    (set (match_operand:SI 3 "register_operand" "=d")
7735         (umod:SI (match_dup 1) (match_dup 2)))
7736    (use (match_dup 3))
7737    (clobber (reg:CC FLAGS_REG))]
7738   ""
7739   "div{l}\t%2"
7740   [(set_attr "type" "idiv")
7741    (set_attr "mode" "SI")])
7742
7743 (define_split
7744   [(set (match_operand:SI 0 "register_operand" "")
7745         (udiv:SI (match_operand:SI 1 "register_operand" "")
7746                  (match_operand:SI 2 "nonimmediate_operand" "")))
7747    (set (match_operand:SI 3 "register_operand" "")
7748         (umod:SI (match_dup 1) (match_dup 2)))
7749    (clobber (reg:CC FLAGS_REG))]
7750   "reload_completed"
7751   [(set (match_dup 3) (const_int 0))
7752    (parallel [(set (match_dup 0)
7753                    (udiv:SI (match_dup 1) (match_dup 2)))
7754               (set (match_dup 3)
7755                    (umod:SI (match_dup 1) (match_dup 2)))
7756               (use (match_dup 3))
7757               (clobber (reg:CC FLAGS_REG))])]
7758   "")
7759
7760 (define_expand "udivmodhi4"
7761   [(set (match_dup 4) (const_int 0))
7762    (parallel [(set (match_operand:HI 0 "register_operand" "")
7763                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7764                             (match_operand:HI 2 "nonimmediate_operand" "")))
7765               (set (match_operand:HI 3 "register_operand" "")
7766                    (umod:HI (match_dup 1) (match_dup 2)))
7767               (use (match_dup 4))
7768               (clobber (reg:CC FLAGS_REG))])]
7769   "TARGET_HIMODE_MATH"
7770   "operands[4] = gen_reg_rtx (HImode);")
7771
7772 (define_insn "*udivmodhi_noext"
7773   [(set (match_operand:HI 0 "register_operand" "=a")
7774         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7775                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7776    (set (match_operand:HI 3 "register_operand" "=d")
7777         (umod:HI (match_dup 1) (match_dup 2)))
7778    (use (match_operand:HI 4 "register_operand" "3"))
7779    (clobber (reg:CC FLAGS_REG))]
7780   ""
7781   "div{w}\t%2"
7782   [(set_attr "type" "idiv")
7783    (set_attr "mode" "HI")])
7784
7785 ;; We cannot use div/idiv for double division, because it causes
7786 ;; "division by zero" on the overflow and that's not what we expect
7787 ;; from truncate.  Because true (non truncating) double division is
7788 ;; never generated, we can't create this insn anyway.
7789 ;
7790 ;(define_insn ""
7791 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7792 ;       (truncate:SI
7793 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7794 ;                  (zero_extend:DI
7795 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7796 ;   (set (match_operand:SI 3 "register_operand" "=d")
7797 ;       (truncate:SI
7798 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7799 ;   (clobber (reg:CC FLAGS_REG))]
7800 ;  ""
7801 ;  "div{l}\t{%2, %0|%0, %2}"
7802 ;  [(set_attr "type" "idiv")])
7803 \f
7804 ;;- Logical AND instructions
7805
7806 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7807 ;; Note that this excludes ah.
7808
7809 (define_insn "*testdi_1_rex64"
7810   [(set (reg FLAGS_REG)
7811         (compare
7812           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7813                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7814           (const_int 0)))]
7815   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7816    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7817   "@
7818    test{l}\t{%k1, %k0|%k0, %k1}
7819    test{l}\t{%k1, %k0|%k0, %k1}
7820    test{q}\t{%1, %0|%0, %1}
7821    test{q}\t{%1, %0|%0, %1}
7822    test{q}\t{%1, %0|%0, %1}"
7823   [(set_attr "type" "test")
7824    (set_attr "modrm" "0,1,0,1,1")
7825    (set_attr "mode" "SI,SI,DI,DI,DI")
7826    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7827
7828 (define_insn "testsi_1"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7832                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7833           (const_int 0)))]
7834   "ix86_match_ccmode (insn, CCNOmode)
7835    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836   "test{l}\t{%1, %0|%0, %1}"
7837   [(set_attr "type" "test")
7838    (set_attr "modrm" "0,1,1")
7839    (set_attr "mode" "SI")
7840    (set_attr "pent_pair" "uv,np,uv")])
7841
7842 (define_expand "testsi_ccno_1"
7843   [(set (reg:CCNO FLAGS_REG)
7844         (compare:CCNO
7845           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7846                   (match_operand:SI 1 "nonmemory_operand" ""))
7847           (const_int 0)))]
7848   ""
7849   "")
7850
7851 (define_insn "*testhi_1"
7852   [(set (reg FLAGS_REG)
7853         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7854                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7855                  (const_int 0)))]
7856   "ix86_match_ccmode (insn, CCNOmode)
7857    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7858   "test{w}\t{%1, %0|%0, %1}"
7859   [(set_attr "type" "test")
7860    (set_attr "modrm" "0,1,1")
7861    (set_attr "mode" "HI")
7862    (set_attr "pent_pair" "uv,np,uv")])
7863
7864 (define_expand "testqi_ccz_1"
7865   [(set (reg:CCZ FLAGS_REG)
7866         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7867                              (match_operand:QI 1 "nonmemory_operand" ""))
7868                  (const_int 0)))]
7869   ""
7870   "")
7871
7872 (define_insn "*testqi_1_maybe_si"
7873   [(set (reg FLAGS_REG)
7874         (compare
7875           (and:QI
7876             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7877             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7878           (const_int 0)))]
7879    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7880     && ix86_match_ccmode (insn,
7881                          GET_CODE (operands[1]) == CONST_INT
7882                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7883 {
7884   if (which_alternative == 3)
7885     {
7886       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7887         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888       return "test{l}\t{%1, %k0|%k0, %1}";
7889     }
7890   return "test{b}\t{%1, %0|%0, %1}";
7891 }
7892   [(set_attr "type" "test")
7893    (set_attr "modrm" "0,1,1,1")
7894    (set_attr "mode" "QI,QI,QI,SI")
7895    (set_attr "pent_pair" "uv,np,uv,np")])
7896
7897 (define_insn "*testqi_1"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:QI
7901             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7902             (match_operand:QI 1 "general_operand" "n,n,qn"))
7903           (const_int 0)))]
7904   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7905    && ix86_match_ccmode (insn, CCNOmode)"
7906   "test{b}\t{%1, %0|%0, %1}"
7907   [(set_attr "type" "test")
7908    (set_attr "modrm" "0,1,1")
7909    (set_attr "mode" "QI")
7910    (set_attr "pent_pair" "uv,np,uv")])
7911
7912 (define_expand "testqi_ext_ccno_0"
7913   [(set (reg:CCNO FLAGS_REG)
7914         (compare:CCNO
7915           (and:SI
7916             (zero_extract:SI
7917               (match_operand 0 "ext_register_operand" "")
7918               (const_int 8)
7919               (const_int 8))
7920             (match_operand 1 "const_int_operand" ""))
7921           (const_int 0)))]
7922   ""
7923   "")
7924
7925 (define_insn "*testqi_ext_0"
7926   [(set (reg FLAGS_REG)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (match_operand 1 "const_int_operand" "n"))
7934           (const_int 0)))]
7935   "ix86_match_ccmode (insn, CCNOmode)"
7936   "test{b}\t{%1, %h0|%h0, %1}"
7937   [(set_attr "type" "test")
7938    (set_attr "mode" "QI")
7939    (set_attr "length_immediate" "1")
7940    (set_attr "pent_pair" "np")])
7941
7942 (define_insn "*testqi_ext_1"
7943   [(set (reg FLAGS_REG)
7944         (compare
7945           (and:SI
7946             (zero_extract:SI
7947               (match_operand 0 "ext_register_operand" "Q")
7948               (const_int 8)
7949               (const_int 8))
7950             (zero_extend:SI
7951               (match_operand:QI 1 "general_operand" "Qm")))
7952           (const_int 0)))]
7953   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7954    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7955   "test{b}\t{%1, %h0|%h0, %1}"
7956   [(set_attr "type" "test")
7957    (set_attr "mode" "QI")])
7958
7959 (define_insn "*testqi_ext_1_rex64"
7960   [(set (reg FLAGS_REG)
7961         (compare
7962           (and:SI
7963             (zero_extract:SI
7964               (match_operand 0 "ext_register_operand" "Q")
7965               (const_int 8)
7966               (const_int 8))
7967             (zero_extend:SI
7968               (match_operand:QI 1 "register_operand" "Q")))
7969           (const_int 0)))]
7970   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7971   "test{b}\t{%1, %h0|%h0, %1}"
7972   [(set_attr "type" "test")
7973    (set_attr "mode" "QI")])
7974
7975 (define_insn "*testqi_ext_2"
7976   [(set (reg FLAGS_REG)
7977         (compare
7978           (and:SI
7979             (zero_extract:SI
7980               (match_operand 0 "ext_register_operand" "Q")
7981               (const_int 8)
7982               (const_int 8))
7983             (zero_extract:SI
7984               (match_operand 1 "ext_register_operand" "Q")
7985               (const_int 8)
7986               (const_int 8)))
7987           (const_int 0)))]
7988   "ix86_match_ccmode (insn, CCNOmode)"
7989   "test{b}\t{%h1, %h0|%h0, %h1}"
7990   [(set_attr "type" "test")
7991    (set_attr "mode" "QI")])
7992
7993 ;; Combine likes to form bit extractions for some tests.  Humor it.
7994 (define_insn "*testqi_ext_3"
7995   [(set (reg FLAGS_REG)
7996         (compare (zero_extract:SI
7997                    (match_operand 0 "nonimmediate_operand" "rm")
7998                    (match_operand:SI 1 "const_int_operand" "")
7999                    (match_operand:SI 2 "const_int_operand" ""))
8000                  (const_int 0)))]
8001   "ix86_match_ccmode (insn, CCNOmode)
8002    && INTVAL (operands[1]) > 0
8003    && INTVAL (operands[2]) >= 0
8004    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8005    && (GET_MODE (operands[0]) == SImode
8006        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8007        || GET_MODE (operands[0]) == HImode
8008        || GET_MODE (operands[0]) == QImode)"
8009   "#")
8010
8011 (define_insn "*testqi_ext_3_rex64"
8012   [(set (reg FLAGS_REG)
8013         (compare (zero_extract:DI
8014                    (match_operand 0 "nonimmediate_operand" "rm")
8015                    (match_operand:DI 1 "const_int_operand" "")
8016                    (match_operand:DI 2 "const_int_operand" ""))
8017                  (const_int 0)))]
8018   "TARGET_64BIT
8019    && ix86_match_ccmode (insn, CCNOmode)
8020    && INTVAL (operands[1]) > 0
8021    && INTVAL (operands[2]) >= 0
8022    /* Ensure that resulting mask is zero or sign extended operand.  */
8023    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8024        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8025            && INTVAL (operands[1]) > 32))
8026    && (GET_MODE (operands[0]) == SImode
8027        || GET_MODE (operands[0]) == DImode
8028        || GET_MODE (operands[0]) == HImode
8029        || GET_MODE (operands[0]) == QImode)"
8030   "#")
8031
8032 (define_split
8033   [(set (match_operand 0 "flags_reg_operand" "")
8034         (match_operator 1 "compare_operator"
8035           [(zero_extract
8036              (match_operand 2 "nonimmediate_operand" "")
8037              (match_operand 3 "const_int_operand" "")
8038              (match_operand 4 "const_int_operand" ""))
8039            (const_int 0)]))]
8040   "ix86_match_ccmode (insn, CCNOmode)"
8041   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8042 {
8043   rtx val = operands[2];
8044   HOST_WIDE_INT len = INTVAL (operands[3]);
8045   HOST_WIDE_INT pos = INTVAL (operands[4]);
8046   HOST_WIDE_INT mask;
8047   enum machine_mode mode, submode;
8048
8049   mode = GET_MODE (val);
8050   if (GET_CODE (val) == MEM)
8051     {
8052       /* ??? Combine likes to put non-volatile mem extractions in QImode
8053          no matter the size of the test.  So find a mode that works.  */
8054       if (! MEM_VOLATILE_P (val))
8055         {
8056           mode = smallest_mode_for_size (pos + len, MODE_INT);
8057           val = adjust_address (val, mode, 0);
8058         }
8059     }
8060   else if (GET_CODE (val) == SUBREG
8061            && (submode = GET_MODE (SUBREG_REG (val)),
8062                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8063            && pos + len <= GET_MODE_BITSIZE (submode))
8064     {
8065       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8066       mode = submode;
8067       val = SUBREG_REG (val);
8068     }
8069   else if (mode == HImode && pos + len <= 8)
8070     {
8071       /* Small HImode tests can be converted to QImode.  */
8072       mode = QImode;
8073       val = gen_lowpart (QImode, val);
8074     }
8075
8076   if (len == HOST_BITS_PER_WIDE_INT)
8077     mask = -1;
8078   else
8079     mask = ((HOST_WIDE_INT)1 << len) - 1;
8080   mask <<= pos;
8081
8082   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8083 })
8084
8085 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8086 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8087 ;; this is relatively important trick.
8088 ;; Do the conversion only post-reload to avoid limiting of the register class
8089 ;; to QI regs.
8090 (define_split
8091   [(set (match_operand 0 "flags_reg_operand" "")
8092         (match_operator 1 "compare_operator"
8093           [(and (match_operand 2 "register_operand" "")
8094                 (match_operand 3 "const_int_operand" ""))
8095            (const_int 0)]))]
8096    "reload_completed
8097     && QI_REG_P (operands[2])
8098     && GET_MODE (operands[2]) != QImode
8099     && ((ix86_match_ccmode (insn, CCZmode)
8100          && !(INTVAL (operands[3]) & ~(255 << 8)))
8101         || (ix86_match_ccmode (insn, CCNOmode)
8102             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8103   [(set (match_dup 0)
8104         (match_op_dup 1
8105           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8106                    (match_dup 3))
8107            (const_int 0)]))]
8108   "operands[2] = gen_lowpart (SImode, operands[2]);
8109    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8110
8111 (define_split
8112   [(set (match_operand 0 "flags_reg_operand" "")
8113         (match_operator 1 "compare_operator"
8114           [(and (match_operand 2 "nonimmediate_operand" "")
8115                 (match_operand 3 "const_int_operand" ""))
8116            (const_int 0)]))]
8117    "reload_completed
8118     && GET_MODE (operands[2]) != QImode
8119     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8120     && ((ix86_match_ccmode (insn, CCZmode)
8121          && !(INTVAL (operands[3]) & ~255))
8122         || (ix86_match_ccmode (insn, CCNOmode)
8123             && !(INTVAL (operands[3]) & ~127)))"
8124   [(set (match_dup 0)
8125         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8126                          (const_int 0)]))]
8127   "operands[2] = gen_lowpart (QImode, operands[2]);
8128    operands[3] = gen_lowpart (QImode, operands[3]);")
8129
8130
8131 ;; %%% This used to optimize known byte-wide and operations to memory,
8132 ;; and sometimes to QImode registers.  If this is considered useful,
8133 ;; it should be done with splitters.
8134
8135 (define_expand "anddi3"
8136   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8137         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8138                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "TARGET_64BIT"
8141   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8142
8143 (define_insn "*anddi_1_rex64"
8144   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8145         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8146                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8147    (clobber (reg:CC FLAGS_REG))]
8148   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8149 {
8150   switch (get_attr_type (insn))
8151     {
8152     case TYPE_IMOVX:
8153       {
8154         enum machine_mode mode;
8155
8156         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8157         if (INTVAL (operands[2]) == 0xff)
8158           mode = QImode;
8159         else
8160           {
8161             gcc_assert (INTVAL (operands[2]) == 0xffff);
8162             mode = HImode;
8163           }
8164         
8165         operands[1] = gen_lowpart (mode, operands[1]);
8166         if (mode == QImode)
8167           return "movz{bq|x}\t{%1,%0|%0, %1}";
8168         else
8169           return "movz{wq|x}\t{%1,%0|%0, %1}";
8170       }
8171
8172     default:
8173       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8174       if (get_attr_mode (insn) == MODE_SI)
8175         return "and{l}\t{%k2, %k0|%k0, %k2}";
8176       else
8177         return "and{q}\t{%2, %0|%0, %2}";
8178     }
8179 }
8180   [(set_attr "type" "alu,alu,alu,imovx")
8181    (set_attr "length_immediate" "*,*,*,0")
8182    (set_attr "mode" "SI,DI,DI,DI")])
8183
8184 (define_insn "*anddi_2"
8185   [(set (reg FLAGS_REG)
8186         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8187                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8188                  (const_int 0)))
8189    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8190         (and:DI (match_dup 1) (match_dup 2)))]
8191   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192    && ix86_binary_operator_ok (AND, DImode, operands)"
8193   "@
8194    and{l}\t{%k2, %k0|%k0, %k2}
8195    and{q}\t{%2, %0|%0, %2}
8196    and{q}\t{%2, %0|%0, %2}"
8197   [(set_attr "type" "alu")
8198    (set_attr "mode" "SI,DI,DI")])
8199
8200 (define_expand "andsi3"
8201   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8202         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8203                 (match_operand:SI 2 "general_operand" "")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   ""
8206   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8207
8208 (define_insn "*andsi_1"
8209   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8210         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8211                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "ix86_binary_operator_ok (AND, SImode, operands)"
8214 {
8215   switch (get_attr_type (insn))
8216     {
8217     case TYPE_IMOVX:
8218       {
8219         enum machine_mode mode;
8220
8221         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8222         if (INTVAL (operands[2]) == 0xff)
8223           mode = QImode;
8224         else
8225           {
8226             gcc_assert (INTVAL (operands[2]) == 0xffff);
8227             mode = HImode;
8228           }
8229         
8230         operands[1] = gen_lowpart (mode, operands[1]);
8231         if (mode == QImode)
8232           return "movz{bl|x}\t{%1,%0|%0, %1}";
8233         else
8234           return "movz{wl|x}\t{%1,%0|%0, %1}";
8235       }
8236
8237     default:
8238       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8239       return "and{l}\t{%2, %0|%0, %2}";
8240     }
8241 }
8242   [(set_attr "type" "alu,alu,imovx")
8243    (set_attr "length_immediate" "*,*,0")
8244    (set_attr "mode" "SI")])
8245
8246 (define_split
8247   [(set (match_operand 0 "register_operand" "")
8248         (and (match_dup 0)
8249              (const_int -65536)))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8252   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8253   "operands[1] = gen_lowpart (HImode, operands[0]);")
8254
8255 (define_split
8256   [(set (match_operand 0 "ext_register_operand" "")
8257         (and (match_dup 0)
8258              (const_int -256)))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8261   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8262   "operands[1] = gen_lowpart (QImode, operands[0]);")
8263
8264 (define_split
8265   [(set (match_operand 0 "ext_register_operand" "")
8266         (and (match_dup 0)
8267              (const_int -65281)))
8268    (clobber (reg:CC FLAGS_REG))]
8269   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8270   [(parallel [(set (zero_extract:SI (match_dup 0)
8271                                     (const_int 8)
8272                                     (const_int 8))
8273                    (xor:SI 
8274                      (zero_extract:SI (match_dup 0)
8275                                       (const_int 8)
8276                                       (const_int 8))
8277                      (zero_extract:SI (match_dup 0)
8278                                       (const_int 8)
8279                                       (const_int 8))))
8280               (clobber (reg:CC FLAGS_REG))])]
8281   "operands[0] = gen_lowpart (SImode, operands[0]);")
8282
8283 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8284 (define_insn "*andsi_1_zext"
8285   [(set (match_operand:DI 0 "register_operand" "=r")
8286         (zero_extend:DI
8287           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288                   (match_operand:SI 2 "general_operand" "rim"))))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8291   "and{l}\t{%2, %k0|%k0, %2}"
8292   [(set_attr "type" "alu")
8293    (set_attr "mode" "SI")])
8294
8295 (define_insn "*andsi_2"
8296   [(set (reg FLAGS_REG)
8297         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8298                          (match_operand:SI 2 "general_operand" "rim,ri"))
8299                  (const_int 0)))
8300    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8301         (and:SI (match_dup 1) (match_dup 2)))]
8302   "ix86_match_ccmode (insn, CCNOmode)
8303    && ix86_binary_operator_ok (AND, SImode, operands)"
8304   "and{l}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "SI")])
8307
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*andsi_2_zext"
8310   [(set (reg FLAGS_REG)
8311         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312                          (match_operand:SI 2 "general_operand" "rim"))
8313                  (const_int 0)))
8314    (set (match_operand:DI 0 "register_operand" "=r")
8315         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8316   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8317    && ix86_binary_operator_ok (AND, SImode, operands)"
8318   "and{l}\t{%2, %k0|%k0, %2}"
8319   [(set_attr "type" "alu")
8320    (set_attr "mode" "SI")])
8321
8322 (define_expand "andhi3"
8323   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325                 (match_operand:HI 2 "general_operand" "")))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "TARGET_HIMODE_MATH"
8328   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8329
8330 (define_insn "*andhi_1"
8331   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8332         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8333                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "ix86_binary_operator_ok (AND, HImode, operands)"
8336 {
8337   switch (get_attr_type (insn))
8338     {
8339     case TYPE_IMOVX:
8340       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8341       gcc_assert (INTVAL (operands[2]) == 0xff);
8342       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8343
8344     default:
8345       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8346
8347       return "and{w}\t{%2, %0|%0, %2}";
8348     }
8349 }
8350   [(set_attr "type" "alu,alu,imovx")
8351    (set_attr "length_immediate" "*,*,0")
8352    (set_attr "mode" "HI,HI,SI")])
8353
8354 (define_insn "*andhi_2"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357                          (match_operand:HI 2 "general_operand" "rim,ri"))
8358                  (const_int 0)))
8359    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360         (and:HI (match_dup 1) (match_dup 2)))]
8361   "ix86_match_ccmode (insn, CCNOmode)
8362    && ix86_binary_operator_ok (AND, HImode, operands)"
8363   "and{w}\t{%2, %0|%0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "mode" "HI")])
8366
8367 (define_expand "andqi3"
8368   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370                 (match_operand:QI 2 "general_operand" "")))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "TARGET_QIMODE_MATH"
8373   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8376 (define_insn "*andqi_1"
8377   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "ix86_binary_operator_ok (AND, QImode, operands)"
8382   "@
8383    and{b}\t{%2, %0|%0, %2}
8384    and{b}\t{%2, %0|%0, %2}
8385    and{l}\t{%k2, %k0|%k0, %k2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_1_slp"
8390   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391         (and:QI (match_dup 0)
8392                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396   "and{b}\t{%1, %0|%0, %1}"
8397   [(set_attr "type" "alu1")
8398    (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_2_maybe_si"
8401   [(set (reg FLAGS_REG)
8402         (compare (and:QI
8403                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405                  (const_int 0)))
8406    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407         (and:QI (match_dup 1) (match_dup 2)))]
8408   "ix86_binary_operator_ok (AND, QImode, operands)
8409    && ix86_match_ccmode (insn,
8410                          GET_CODE (operands[2]) == CONST_INT
8411                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8412 {
8413   if (which_alternative == 2)
8414     {
8415       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8416         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8417       return "and{l}\t{%2, %k0|%k0, %2}";
8418     }
8419   return "and{b}\t{%2, %0|%0, %2}";
8420 }
8421   [(set_attr "type" "alu")
8422    (set_attr "mode" "QI,QI,SI")])
8423
8424 (define_insn "*andqi_2"
8425   [(set (reg FLAGS_REG)
8426         (compare (and:QI
8427                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8428                    (match_operand:QI 2 "general_operand" "qim,qi"))
8429                  (const_int 0)))
8430    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8431         (and:QI (match_dup 1) (match_dup 2)))]
8432   "ix86_match_ccmode (insn, CCNOmode)
8433    && ix86_binary_operator_ok (AND, QImode, operands)"
8434   "and{b}\t{%2, %0|%0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "mode" "QI")])
8437
8438 (define_insn "*andqi_2_slp"
8439   [(set (reg FLAGS_REG)
8440         (compare (and:QI
8441                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8442                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8443                  (const_int 0)))
8444    (set (strict_low_part (match_dup 0))
8445         (and:QI (match_dup 0) (match_dup 1)))]
8446   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8447    && ix86_match_ccmode (insn, CCNOmode)
8448    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8449   "and{b}\t{%1, %0|%0, %1}"
8450   [(set_attr "type" "alu1")
8451    (set_attr "mode" "QI")])
8452
8453 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8454 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8455 ;; for a QImode operand, which of course failed.
8456
8457 (define_insn "andqi_ext_0"
8458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459                          (const_int 8)
8460                          (const_int 8))
8461         (and:SI 
8462           (zero_extract:SI
8463             (match_operand 1 "ext_register_operand" "0")
8464             (const_int 8)
8465             (const_int 8))
8466           (match_operand 2 "const_int_operand" "n")))
8467    (clobber (reg:CC FLAGS_REG))]
8468   ""
8469   "and{b}\t{%2, %h0|%h0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "1")
8472    (set_attr "mode" "QI")])
8473
8474 ;; Generated by peephole translating test to and.  This shows up
8475 ;; often in fp comparisons.
8476
8477 (define_insn "*andqi_ext_0_cc"
8478   [(set (reg FLAGS_REG)
8479         (compare
8480           (and:SI
8481             (zero_extract:SI
8482               (match_operand 1 "ext_register_operand" "0")
8483               (const_int 8)
8484               (const_int 8))
8485             (match_operand 2 "const_int_operand" "n"))
8486           (const_int 0)))
8487    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8488                          (const_int 8)
8489                          (const_int 8))
8490         (and:SI 
8491           (zero_extract:SI
8492             (match_dup 1)
8493             (const_int 8)
8494             (const_int 8))
8495           (match_dup 2)))]
8496   "ix86_match_ccmode (insn, CCNOmode)"
8497   "and{b}\t{%2, %h0|%h0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "length_immediate" "1")
8500    (set_attr "mode" "QI")])
8501
8502 (define_insn "*andqi_ext_1"
8503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504                          (const_int 8)
8505                          (const_int 8))
8506         (and:SI 
8507           (zero_extract:SI
8508             (match_operand 1 "ext_register_operand" "0")
8509             (const_int 8)
8510             (const_int 8))
8511           (zero_extend:SI
8512             (match_operand:QI 2 "general_operand" "Qm"))))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "!TARGET_64BIT"
8515   "and{b}\t{%2, %h0|%h0, %2}"
8516   [(set_attr "type" "alu")
8517    (set_attr "length_immediate" "0")
8518    (set_attr "mode" "QI")])
8519
8520 (define_insn "*andqi_ext_1_rex64"
8521   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522                          (const_int 8)
8523                          (const_int 8))
8524         (and:SI 
8525           (zero_extract:SI
8526             (match_operand 1 "ext_register_operand" "0")
8527             (const_int 8)
8528             (const_int 8))
8529           (zero_extend:SI
8530             (match_operand 2 "ext_register_operand" "Q"))))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "TARGET_64BIT"
8533   "and{b}\t{%2, %h0|%h0, %2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "length_immediate" "0")
8536    (set_attr "mode" "QI")])
8537
8538 (define_insn "*andqi_ext_2"
8539   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8540                          (const_int 8)
8541                          (const_int 8))
8542         (and:SI
8543           (zero_extract:SI
8544             (match_operand 1 "ext_register_operand" "%0")
8545             (const_int 8)
8546             (const_int 8))
8547           (zero_extract:SI
8548             (match_operand 2 "ext_register_operand" "Q")
8549             (const_int 8)
8550             (const_int 8))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   ""
8553   "and{b}\t{%h2, %h0|%h0, %h2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "length_immediate" "0")
8556    (set_attr "mode" "QI")])
8557
8558 ;; Convert wide AND instructions with immediate operand to shorter QImode
8559 ;; equivalents when possible.
8560 ;; Don't do the splitting with memory operands, since it introduces risk
8561 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8562 ;; for size, but that can (should?) be handled by generic code instead.
8563 (define_split
8564   [(set (match_operand 0 "register_operand" "")
8565         (and (match_operand 1 "register_operand" "")
8566              (match_operand 2 "const_int_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568    "reload_completed
8569     && QI_REG_P (operands[0])
8570     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571     && !(~INTVAL (operands[2]) & ~(255 << 8))
8572     && GET_MODE (operands[0]) != QImode"
8573   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8574                    (and:SI (zero_extract:SI (match_dup 1)
8575                                             (const_int 8) (const_int 8))
8576                            (match_dup 2)))
8577               (clobber (reg:CC FLAGS_REG))])]
8578   "operands[0] = gen_lowpart (SImode, operands[0]);
8579    operands[1] = gen_lowpart (SImode, operands[1]);
8580    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8581
8582 ;; Since AND can be encoded with sign extended immediate, this is only
8583 ;; profitable when 7th bit is not set.
8584 (define_split
8585   [(set (match_operand 0 "register_operand" "")
8586         (and (match_operand 1 "general_operand" "")
8587              (match_operand 2 "const_int_operand" "")))
8588    (clobber (reg:CC FLAGS_REG))]
8589    "reload_completed
8590     && ANY_QI_REG_P (operands[0])
8591     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8592     && !(~INTVAL (operands[2]) & ~255)
8593     && !(INTVAL (operands[2]) & 128)
8594     && GET_MODE (operands[0]) != QImode"
8595   [(parallel [(set (strict_low_part (match_dup 0))
8596                    (and:QI (match_dup 1)
8597                            (match_dup 2)))
8598               (clobber (reg:CC FLAGS_REG))])]
8599   "operands[0] = gen_lowpart (QImode, operands[0]);
8600    operands[1] = gen_lowpart (QImode, operands[1]);
8601    operands[2] = gen_lowpart (QImode, operands[2]);")
8602 \f
8603 ;; Logical inclusive OR instructions
8604
8605 ;; %%% This used to optimize known byte-wide and operations to memory.
8606 ;; If this is considered useful, it should be done with splitters.
8607
8608 (define_expand "iordi3"
8609   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8610         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8611                 (match_operand:DI 2 "x86_64_general_operand" "")))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "TARGET_64BIT"
8614   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8615
8616 (define_insn "*iordi_1_rex64"
8617   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8618         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8619                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "TARGET_64BIT
8622    && ix86_binary_operator_ok (IOR, DImode, operands)"
8623   "or{q}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "DI")])
8626
8627 (define_insn "*iordi_2_rex64"
8628   [(set (reg FLAGS_REG)
8629         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8630                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8631                  (const_int 0)))
8632    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8633         (ior:DI (match_dup 1) (match_dup 2)))]
8634   "TARGET_64BIT
8635    && ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (IOR, DImode, operands)"
8637   "or{q}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "DI")])
8640
8641 (define_insn "*iordi_3_rex64"
8642   [(set (reg FLAGS_REG)
8643         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8644                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8645                  (const_int 0)))
8646    (clobber (match_scratch:DI 0 "=r"))]
8647   "TARGET_64BIT
8648    && ix86_match_ccmode (insn, CCNOmode)
8649    && ix86_binary_operator_ok (IOR, DImode, operands)"
8650   "or{q}\t{%2, %0|%0, %2}"
8651   [(set_attr "type" "alu")
8652    (set_attr "mode" "DI")])
8653
8654
8655 (define_expand "iorsi3"
8656   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8657         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8658                 (match_operand:SI 2 "general_operand" "")))
8659    (clobber (reg:CC FLAGS_REG))]
8660   ""
8661   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8662
8663 (define_insn "*iorsi_1"
8664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8665         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8666                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "ix86_binary_operator_ok (IOR, SImode, operands)"
8669   "or{l}\t{%2, %0|%0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "SI")])
8672
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 (define_insn "*iorsi_1_zext"
8675   [(set (match_operand:DI 0 "register_operand" "=rm")
8676         (zero_extend:DI
8677           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678                   (match_operand:SI 2 "general_operand" "rim"))))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8681   "or{l}\t{%2, %k0|%k0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "mode" "SI")])
8684
8685 (define_insn "*iorsi_1_zext_imm"
8686   [(set (match_operand:DI 0 "register_operand" "=rm")
8687         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "TARGET_64BIT"
8691   "or{l}\t{%2, %k0|%k0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "mode" "SI")])
8694
8695 (define_insn "*iorsi_2"
8696   [(set (reg FLAGS_REG)
8697         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8698                          (match_operand:SI 2 "general_operand" "rim,ri"))
8699                  (const_int 0)))
8700    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8701         (ior:SI (match_dup 1) (match_dup 2)))]
8702   "ix86_match_ccmode (insn, CCNOmode)
8703    && ix86_binary_operator_ok (IOR, SImode, operands)"
8704   "or{l}\t{%2, %0|%0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "mode" "SI")])
8707
8708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8709 ;; ??? Special case for immediate operand is missing - it is tricky.
8710 (define_insn "*iorsi_2_zext"
8711   [(set (reg FLAGS_REG)
8712         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713                          (match_operand:SI 2 "general_operand" "rim"))
8714                  (const_int 0)))
8715    (set (match_operand:DI 0 "register_operand" "=r")
8716         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8717   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8718    && ix86_binary_operator_ok (IOR, SImode, operands)"
8719   "or{l}\t{%2, %k0|%k0, %2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "mode" "SI")])
8722
8723 (define_insn "*iorsi_2_zext_imm"
8724   [(set (reg FLAGS_REG)
8725         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8726                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8727                  (const_int 0)))
8728    (set (match_operand:DI 0 "register_operand" "=r")
8729         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8730   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8731    && ix86_binary_operator_ok (IOR, SImode, operands)"
8732   "or{l}\t{%2, %k0|%k0, %2}"
8733   [(set_attr "type" "alu")
8734    (set_attr "mode" "SI")])
8735
8736 (define_insn "*iorsi_3"
8737   [(set (reg FLAGS_REG)
8738         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8739                          (match_operand:SI 2 "general_operand" "rim"))
8740                  (const_int 0)))
8741    (clobber (match_scratch:SI 0 "=r"))]
8742   "ix86_match_ccmode (insn, CCNOmode)
8743    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8744   "or{l}\t{%2, %0|%0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "mode" "SI")])
8747
8748 (define_expand "iorhi3"
8749   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8750         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8751                 (match_operand:HI 2 "general_operand" "")))
8752    (clobber (reg:CC FLAGS_REG))]
8753   "TARGET_HIMODE_MATH"
8754   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8755
8756 (define_insn "*iorhi_1"
8757   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8758         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, HImode, operands)"
8762   "or{w}\t{%2, %0|%0, %2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "mode" "HI")])
8765
8766 (define_insn "*iorhi_2"
8767   [(set (reg FLAGS_REG)
8768         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8769                          (match_operand:HI 2 "general_operand" "rim,ri"))
8770                  (const_int 0)))
8771    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8772         (ior:HI (match_dup 1) (match_dup 2)))]
8773   "ix86_match_ccmode (insn, CCNOmode)
8774    && ix86_binary_operator_ok (IOR, HImode, operands)"
8775   "or{w}\t{%2, %0|%0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "HI")])
8778
8779 (define_insn "*iorhi_3"
8780   [(set (reg FLAGS_REG)
8781         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8782                          (match_operand:HI 2 "general_operand" "rim"))
8783                  (const_int 0)))
8784    (clobber (match_scratch:HI 0 "=r"))]
8785   "ix86_match_ccmode (insn, CCNOmode)
8786    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8787   "or{w}\t{%2, %0|%0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "HI")])
8790
8791 (define_expand "iorqi3"
8792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8793         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8794                 (match_operand:QI 2 "general_operand" "")))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "TARGET_QIMODE_MATH"
8797   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8798
8799 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8800 (define_insn "*iorqi_1"
8801   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8802         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8803                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "ix86_binary_operator_ok (IOR, QImode, operands)"
8806   "@
8807    or{b}\t{%2, %0|%0, %2}
8808    or{b}\t{%2, %0|%0, %2}
8809    or{l}\t{%k2, %k0|%k0, %k2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "mode" "QI,QI,SI")])
8812
8813 (define_insn "*iorqi_1_slp"
8814   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8815         (ior:QI (match_dup 0)
8816                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820   "or{b}\t{%1, %0|%0, %1}"
8821   [(set_attr "type" "alu1")
8822    (set_attr "mode" "QI")])
8823
8824 (define_insn "*iorqi_2"
8825   [(set (reg FLAGS_REG)
8826         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8827                          (match_operand:QI 2 "general_operand" "qim,qi"))
8828                  (const_int 0)))
8829    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8830         (ior:QI (match_dup 1) (match_dup 2)))]
8831   "ix86_match_ccmode (insn, CCNOmode)
8832    && ix86_binary_operator_ok (IOR, QImode, operands)"
8833   "or{b}\t{%2, %0|%0, %2}"
8834   [(set_attr "type" "alu")
8835    (set_attr "mode" "QI")])
8836
8837 (define_insn "*iorqi_2_slp"
8838   [(set (reg FLAGS_REG)
8839         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8840                          (match_operand:QI 1 "general_operand" "qim,qi"))
8841                  (const_int 0)))
8842    (set (strict_low_part (match_dup 0))
8843         (ior:QI (match_dup 0) (match_dup 1)))]
8844   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8845    && ix86_match_ccmode (insn, CCNOmode)
8846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8847   "or{b}\t{%1, %0|%0, %1}"
8848   [(set_attr "type" "alu1")
8849    (set_attr "mode" "QI")])
8850
8851 (define_insn "*iorqi_3"
8852   [(set (reg FLAGS_REG)
8853         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8854                          (match_operand:QI 2 "general_operand" "qim"))
8855                  (const_int 0)))
8856    (clobber (match_scratch:QI 0 "=q"))]
8857   "ix86_match_ccmode (insn, CCNOmode)
8858    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859   "or{b}\t{%2, %0|%0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "mode" "QI")])
8862
8863 (define_insn "iorqi_ext_0"
8864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865                          (const_int 8)
8866                          (const_int 8))
8867         (ior:SI 
8868           (zero_extract:SI
8869             (match_operand 1 "ext_register_operand" "0")
8870             (const_int 8)
8871             (const_int 8))
8872           (match_operand 2 "const_int_operand" "n")))
8873    (clobber (reg:CC FLAGS_REG))]
8874   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8875   "or{b}\t{%2, %h0|%h0, %2}"
8876   [(set_attr "type" "alu")
8877    (set_attr "length_immediate" "1")
8878    (set_attr "mode" "QI")])
8879
8880 (define_insn "*iorqi_ext_1"
8881   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8882                          (const_int 8)
8883                          (const_int 8))
8884         (ior:SI 
8885           (zero_extract:SI
8886             (match_operand 1 "ext_register_operand" "0")
8887             (const_int 8)
8888             (const_int 8))
8889           (zero_extend:SI
8890             (match_operand:QI 2 "general_operand" "Qm"))))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "!TARGET_64BIT
8893    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8894   "or{b}\t{%2, %h0|%h0, %2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "length_immediate" "0")
8897    (set_attr "mode" "QI")])
8898
8899 (define_insn "*iorqi_ext_1_rex64"
8900   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8901                          (const_int 8)
8902                          (const_int 8))
8903         (ior:SI 
8904           (zero_extract:SI
8905             (match_operand 1 "ext_register_operand" "0")
8906             (const_int 8)
8907             (const_int 8))
8908           (zero_extend:SI
8909             (match_operand 2 "ext_register_operand" "Q"))))
8910    (clobber (reg:CC FLAGS_REG))]
8911   "TARGET_64BIT
8912    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8913   "or{b}\t{%2, %h0|%h0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "length_immediate" "0")
8916    (set_attr "mode" "QI")])
8917
8918 (define_insn "*iorqi_ext_2"
8919   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8920                          (const_int 8)
8921                          (const_int 8))
8922         (ior:SI 
8923           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8924                            (const_int 8)
8925                            (const_int 8))
8926           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8927                            (const_int 8)
8928                            (const_int 8))))
8929    (clobber (reg:CC FLAGS_REG))]
8930   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8931   "ior{b}\t{%h2, %h0|%h0, %h2}"
8932   [(set_attr "type" "alu")
8933    (set_attr "length_immediate" "0")
8934    (set_attr "mode" "QI")])
8935
8936 (define_split
8937   [(set (match_operand 0 "register_operand" "")
8938         (ior (match_operand 1 "register_operand" "")
8939              (match_operand 2 "const_int_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941    "reload_completed
8942     && QI_REG_P (operands[0])
8943     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944     && !(INTVAL (operands[2]) & ~(255 << 8))
8945     && GET_MODE (operands[0]) != QImode"
8946   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8947                    (ior:SI (zero_extract:SI (match_dup 1)
8948                                             (const_int 8) (const_int 8))
8949                            (match_dup 2)))
8950               (clobber (reg:CC FLAGS_REG))])]
8951   "operands[0] = gen_lowpart (SImode, operands[0]);
8952    operands[1] = gen_lowpart (SImode, operands[1]);
8953    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8954
8955 ;; Since OR can be encoded with sign extended immediate, this is only
8956 ;; profitable when 7th bit is set.
8957 (define_split
8958   [(set (match_operand 0 "register_operand" "")
8959         (ior (match_operand 1 "general_operand" "")
8960              (match_operand 2 "const_int_operand" "")))
8961    (clobber (reg:CC FLAGS_REG))]
8962    "reload_completed
8963     && ANY_QI_REG_P (operands[0])
8964     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8965     && !(INTVAL (operands[2]) & ~255)
8966     && (INTVAL (operands[2]) & 128)
8967     && GET_MODE (operands[0]) != QImode"
8968   [(parallel [(set (strict_low_part (match_dup 0))
8969                    (ior:QI (match_dup 1)
8970                            (match_dup 2)))
8971               (clobber (reg:CC FLAGS_REG))])]
8972   "operands[0] = gen_lowpart (QImode, operands[0]);
8973    operands[1] = gen_lowpart (QImode, operands[1]);
8974    operands[2] = gen_lowpart (QImode, operands[2]);")
8975 \f
8976 ;; Logical XOR instructions
8977
8978 ;; %%% This used to optimize known byte-wide and operations to memory.
8979 ;; If this is considered useful, it should be done with splitters.
8980
8981 (define_expand "xordi3"
8982   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8983         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8984                 (match_operand:DI 2 "x86_64_general_operand" "")))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_64BIT"
8987   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8988
8989 (define_insn "*xordi_1_rex64"
8990   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8991         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8992                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "TARGET_64BIT
8995    && ix86_binary_operator_ok (XOR, DImode, operands)"
8996   "@
8997    xor{q}\t{%2, %0|%0, %2}
8998    xor{q}\t{%2, %0|%0, %2}"
8999   [(set_attr "type" "alu")
9000    (set_attr "mode" "DI,DI")])
9001
9002 (define_insn "*xordi_2_rex64"
9003   [(set (reg FLAGS_REG)
9004         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9005                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9006                  (const_int 0)))
9007    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9008         (xor:DI (match_dup 1) (match_dup 2)))]
9009   "TARGET_64BIT
9010    && ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, DImode, operands)"
9012   "@
9013    xor{q}\t{%2, %0|%0, %2}
9014    xor{q}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "DI,DI")])
9017
9018 (define_insn "*xordi_3_rex64"
9019   [(set (reg FLAGS_REG)
9020         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9021                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9022                  (const_int 0)))
9023    (clobber (match_scratch:DI 0 "=r"))]
9024   "TARGET_64BIT
9025    && ix86_match_ccmode (insn, CCNOmode)
9026    && ix86_binary_operator_ok (XOR, DImode, operands)"
9027   "xor{q}\t{%2, %0|%0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "mode" "DI")])
9030
9031 (define_expand "xorsi3"
9032   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9033         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9034                 (match_operand:SI 2 "general_operand" "")))
9035    (clobber (reg:CC FLAGS_REG))]
9036   ""
9037   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9038
9039 (define_insn "*xorsi_1"
9040   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9041         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042                 (match_operand:SI 2 "general_operand" "ri,rm")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "ix86_binary_operator_ok (XOR, SImode, operands)"
9045   "xor{l}\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "SI")])
9048
9049 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050 ;; Add speccase for immediates
9051 (define_insn "*xorsi_1_zext"
9052   [(set (match_operand:DI 0 "register_operand" "=r")
9053         (zero_extend:DI
9054           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055                   (match_operand:SI 2 "general_operand" "rim"))))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058   "xor{l}\t{%2, %k0|%k0, %2}"
9059   [(set_attr "type" "alu")
9060    (set_attr "mode" "SI")])
9061
9062 (define_insn "*xorsi_1_zext_imm"
9063   [(set (match_operand:DI 0 "register_operand" "=r")
9064         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9065                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9066    (clobber (reg:CC FLAGS_REG))]
9067   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9068   "xor{l}\t{%2, %k0|%k0, %2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "mode" "SI")])
9071
9072 (define_insn "*xorsi_2"
9073   [(set (reg FLAGS_REG)
9074         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9075                          (match_operand:SI 2 "general_operand" "rim,ri"))
9076                  (const_int 0)))
9077    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9078         (xor:SI (match_dup 1) (match_dup 2)))]
9079   "ix86_match_ccmode (insn, CCNOmode)
9080    && ix86_binary_operator_ok (XOR, SImode, operands)"
9081   "xor{l}\t{%2, %0|%0, %2}"
9082   [(set_attr "type" "alu")
9083    (set_attr "mode" "SI")])
9084
9085 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9086 ;; ??? Special case for immediate operand is missing - it is tricky.
9087 (define_insn "*xorsi_2_zext"
9088   [(set (reg FLAGS_REG)
9089         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090                          (match_operand:SI 2 "general_operand" "rim"))
9091                  (const_int 0)))
9092    (set (match_operand:DI 0 "register_operand" "=r")
9093         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9094   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9095    && ix86_binary_operator_ok (XOR, SImode, operands)"
9096   "xor{l}\t{%2, %k0|%k0, %2}"
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "SI")])
9099
9100 (define_insn "*xorsi_2_zext_imm"
9101   [(set (reg FLAGS_REG)
9102         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9103                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9104                  (const_int 0)))
9105    (set (match_operand:DI 0 "register_operand" "=r")
9106         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9108    && ix86_binary_operator_ok (XOR, SImode, operands)"
9109   "xor{l}\t{%2, %k0|%k0, %2}"
9110   [(set_attr "type" "alu")
9111    (set_attr "mode" "SI")])
9112
9113 (define_insn "*xorsi_3"
9114   [(set (reg FLAGS_REG)
9115         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116                          (match_operand:SI 2 "general_operand" "rim"))
9117                  (const_int 0)))
9118    (clobber (match_scratch:SI 0 "=r"))]
9119   "ix86_match_ccmode (insn, CCNOmode)
9120    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9121   "xor{l}\t{%2, %0|%0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "mode" "SI")])
9124
9125 (define_expand "xorhi3"
9126   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9127         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9128                 (match_operand:HI 2 "general_operand" "")))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "TARGET_HIMODE_MATH"
9131   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9132
9133 (define_insn "*xorhi_1"
9134   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9135         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, HImode, operands)"
9139   "xor{w}\t{%2, %0|%0, %2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "mode" "HI")])
9142
9143 (define_insn "*xorhi_2"
9144   [(set (reg FLAGS_REG)
9145         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9146                          (match_operand:HI 2 "general_operand" "rim,ri"))
9147                  (const_int 0)))
9148    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9149         (xor:HI (match_dup 1) (match_dup 2)))]
9150   "ix86_match_ccmode (insn, CCNOmode)
9151    && ix86_binary_operator_ok (XOR, HImode, operands)"
9152   "xor{w}\t{%2, %0|%0, %2}"
9153   [(set_attr "type" "alu")
9154    (set_attr "mode" "HI")])
9155
9156 (define_insn "*xorhi_3"
9157   [(set (reg FLAGS_REG)
9158         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9159                          (match_operand:HI 2 "general_operand" "rim"))
9160                  (const_int 0)))
9161    (clobber (match_scratch:HI 0 "=r"))]
9162   "ix86_match_ccmode (insn, CCNOmode)
9163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9164   "xor{w}\t{%2, %0|%0, %2}"
9165   [(set_attr "type" "alu")
9166    (set_attr "mode" "HI")])
9167
9168 (define_expand "xorqi3"
9169   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9170         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9171                 (match_operand:QI 2 "general_operand" "")))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "TARGET_QIMODE_MATH"
9174   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9175
9176 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9177 (define_insn "*xorqi_1"
9178   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9179         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9180                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9181    (clobber (reg:CC FLAGS_REG))]
9182   "ix86_binary_operator_ok (XOR, QImode, operands)"
9183   "@
9184    xor{b}\t{%2, %0|%0, %2}
9185    xor{b}\t{%2, %0|%0, %2}
9186    xor{l}\t{%k2, %k0|%k0, %k2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "mode" "QI,QI,SI")])
9189
9190 (define_insn "*xorqi_1_slp"
9191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9192         (xor:QI (match_dup 0)
9193                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197   "xor{b}\t{%1, %0|%0, %1}"
9198   [(set_attr "type" "alu1")
9199    (set_attr "mode" "QI")])
9200
9201 (define_insn "xorqi_ext_0"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (xor:SI 
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (match_operand 2 "const_int_operand" "n")))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9213   "xor{b}\t{%2, %h0|%h0, %2}"
9214   [(set_attr "type" "alu")
9215    (set_attr "length_immediate" "1")
9216    (set_attr "mode" "QI")])
9217
9218 (define_insn "*xorqi_ext_1"
9219   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9220                          (const_int 8)
9221                          (const_int 8))
9222         (xor:SI 
9223           (zero_extract:SI
9224             (match_operand 1 "ext_register_operand" "0")
9225             (const_int 8)
9226             (const_int 8))
9227           (zero_extend:SI
9228             (match_operand:QI 2 "general_operand" "Qm"))))
9229    (clobber (reg:CC FLAGS_REG))]
9230   "!TARGET_64BIT
9231    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9232   "xor{b}\t{%2, %h0|%h0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "length_immediate" "0")
9235    (set_attr "mode" "QI")])
9236
9237 (define_insn "*xorqi_ext_1_rex64"
9238   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9239                          (const_int 8)
9240                          (const_int 8))
9241         (xor:SI 
9242           (zero_extract:SI
9243             (match_operand 1 "ext_register_operand" "0")
9244             (const_int 8)
9245             (const_int 8))
9246           (zero_extend:SI
9247             (match_operand 2 "ext_register_operand" "Q"))))
9248    (clobber (reg:CC FLAGS_REG))]
9249   "TARGET_64BIT
9250    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9251   "xor{b}\t{%2, %h0|%h0, %2}"
9252   [(set_attr "type" "alu")
9253    (set_attr "length_immediate" "0")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*xorqi_ext_2"
9257   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258                          (const_int 8)
9259                          (const_int 8))
9260         (xor:SI 
9261           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9262                            (const_int 8)
9263                            (const_int 8))
9264           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9265                            (const_int 8)
9266                            (const_int 8))))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9269   "xor{b}\t{%h2, %h0|%h0, %h2}"
9270   [(set_attr "type" "alu")
9271    (set_attr "length_immediate" "0")
9272    (set_attr "mode" "QI")])
9273
9274 (define_insn "*xorqi_cc_1"
9275   [(set (reg FLAGS_REG)
9276         (compare
9277           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9278                   (match_operand:QI 2 "general_operand" "qim,qi"))
9279           (const_int 0)))
9280    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9281         (xor:QI (match_dup 1) (match_dup 2)))]
9282   "ix86_match_ccmode (insn, CCNOmode)
9283    && ix86_binary_operator_ok (XOR, QImode, operands)"
9284   "xor{b}\t{%2, %0|%0, %2}"
9285   [(set_attr "type" "alu")
9286    (set_attr "mode" "QI")])
9287
9288 (define_insn "*xorqi_2_slp"
9289   [(set (reg FLAGS_REG)
9290         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9291                          (match_operand:QI 1 "general_operand" "qim,qi"))
9292                  (const_int 0)))
9293    (set (strict_low_part (match_dup 0))
9294         (xor:QI (match_dup 0) (match_dup 1)))]
9295   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9296    && ix86_match_ccmode (insn, CCNOmode)
9297    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9298   "xor{b}\t{%1, %0|%0, %1}"
9299   [(set_attr "type" "alu1")
9300    (set_attr "mode" "QI")])
9301
9302 (define_insn "*xorqi_cc_2"
9303   [(set (reg FLAGS_REG)
9304         (compare
9305           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9306                   (match_operand:QI 2 "general_operand" "qim"))
9307           (const_int 0)))
9308    (clobber (match_scratch:QI 0 "=q"))]
9309   "ix86_match_ccmode (insn, CCNOmode)
9310    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9311   "xor{b}\t{%2, %0|%0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "QI")])
9314
9315 (define_insn "*xorqi_cc_ext_1"
9316   [(set (reg FLAGS_REG)
9317         (compare
9318           (xor:SI
9319             (zero_extract:SI
9320               (match_operand 1 "ext_register_operand" "0")
9321               (const_int 8)
9322               (const_int 8))
9323             (match_operand:QI 2 "general_operand" "qmn"))
9324           (const_int 0)))
9325    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9326                          (const_int 8)
9327                          (const_int 8))
9328         (xor:SI 
9329           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330           (match_dup 2)))]
9331   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332   "xor{b}\t{%2, %h0|%h0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "mode" "QI")])
9335
9336 (define_insn "*xorqi_cc_ext_1_rex64"
9337   [(set (reg FLAGS_REG)
9338         (compare
9339           (xor:SI
9340             (zero_extract:SI
9341               (match_operand 1 "ext_register_operand" "0")
9342               (const_int 8)
9343               (const_int 8))
9344             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9345           (const_int 0)))
9346    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9347                          (const_int 8)
9348                          (const_int 8))
9349         (xor:SI 
9350           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351           (match_dup 2)))]
9352   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9353   "xor{b}\t{%2, %h0|%h0, %2}"
9354   [(set_attr "type" "alu")
9355    (set_attr "mode" "QI")])
9356
9357 (define_expand "xorqi_cc_ext_1"
9358   [(parallel [
9359      (set (reg:CCNO FLAGS_REG)
9360           (compare:CCNO
9361             (xor:SI
9362               (zero_extract:SI
9363                 (match_operand 1 "ext_register_operand" "")
9364                 (const_int 8)
9365                 (const_int 8))
9366               (match_operand:QI 2 "general_operand" ""))
9367             (const_int 0)))
9368      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9369                            (const_int 8)
9370                            (const_int 8))
9371           (xor:SI 
9372             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9373             (match_dup 2)))])]
9374   ""
9375   "")
9376
9377 (define_split
9378   [(set (match_operand 0 "register_operand" "")
9379         (xor (match_operand 1 "register_operand" "")
9380              (match_operand 2 "const_int_operand" "")))
9381    (clobber (reg:CC FLAGS_REG))]
9382    "reload_completed
9383     && QI_REG_P (operands[0])
9384     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385     && !(INTVAL (operands[2]) & ~(255 << 8))
9386     && GET_MODE (operands[0]) != QImode"
9387   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9388                    (xor:SI (zero_extract:SI (match_dup 1)
9389                                             (const_int 8) (const_int 8))
9390                            (match_dup 2)))
9391               (clobber (reg:CC FLAGS_REG))])]
9392   "operands[0] = gen_lowpart (SImode, operands[0]);
9393    operands[1] = gen_lowpart (SImode, operands[1]);
9394    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9395
9396 ;; Since XOR can be encoded with sign extended immediate, this is only
9397 ;; profitable when 7th bit is set.
9398 (define_split
9399   [(set (match_operand 0 "register_operand" "")
9400         (xor (match_operand 1 "general_operand" "")
9401              (match_operand 2 "const_int_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403    "reload_completed
9404     && ANY_QI_REG_P (operands[0])
9405     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9406     && !(INTVAL (operands[2]) & ~255)
9407     && (INTVAL (operands[2]) & 128)
9408     && GET_MODE (operands[0]) != QImode"
9409   [(parallel [(set (strict_low_part (match_dup 0))
9410                    (xor:QI (match_dup 1)
9411                            (match_dup 2)))
9412               (clobber (reg:CC FLAGS_REG))])]
9413   "operands[0] = gen_lowpart (QImode, operands[0]);
9414    operands[1] = gen_lowpart (QImode, operands[1]);
9415    operands[2] = gen_lowpart (QImode, operands[2]);")
9416 \f
9417 ;; Negation instructions
9418
9419 (define_expand "negti2"
9420   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9421                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9422               (clobber (reg:CC FLAGS_REG))])]
9423   "TARGET_64BIT"
9424   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9425
9426 (define_insn "*negti2_1"
9427   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9428         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "TARGET_64BIT
9431    && ix86_unary_operator_ok (NEG, TImode, operands)"
9432   "#")
9433
9434 (define_split
9435   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9436         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT && reload_completed"
9439   [(parallel
9440     [(set (reg:CCZ FLAGS_REG)
9441           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9442      (set (match_dup 0) (neg:DI (match_dup 2)))])
9443    (parallel
9444     [(set (match_dup 1)
9445           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9446                             (match_dup 3))
9447                    (const_int 0)))
9448      (clobber (reg:CC FLAGS_REG))])
9449    (parallel
9450     [(set (match_dup 1)
9451           (neg:DI (match_dup 1)))
9452      (clobber (reg:CC FLAGS_REG))])]
9453   "split_ti (operands+1, 1, operands+2, operands+3);
9454    split_ti (operands+0, 1, operands+0, operands+1);")
9455
9456 (define_expand "negdi2"
9457   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9458                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9459               (clobber (reg:CC FLAGS_REG))])]
9460   ""
9461   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9462
9463 (define_insn "*negdi2_1"
9464   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9465         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "!TARGET_64BIT
9468    && ix86_unary_operator_ok (NEG, DImode, operands)"
9469   "#")
9470
9471 (define_split
9472   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9473         (neg:DI (match_operand:DI 1 "general_operand" "")))
9474    (clobber (reg:CC FLAGS_REG))]
9475   "!TARGET_64BIT && reload_completed"
9476   [(parallel
9477     [(set (reg:CCZ FLAGS_REG)
9478           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9479      (set (match_dup 0) (neg:SI (match_dup 2)))])
9480    (parallel
9481     [(set (match_dup 1)
9482           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9483                             (match_dup 3))
9484                    (const_int 0)))
9485      (clobber (reg:CC FLAGS_REG))])
9486    (parallel
9487     [(set (match_dup 1)
9488           (neg:SI (match_dup 1)))
9489      (clobber (reg:CC FLAGS_REG))])]
9490   "split_di (operands+1, 1, operands+2, operands+3);
9491    split_di (operands+0, 1, operands+0, operands+1);")
9492
9493 (define_insn "*negdi2_1_rex64"
9494   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9495         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9498   "neg{q}\t%0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "DI")])
9501
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9505
9506 (define_insn "*negdi2_cmpz_rex64"
9507   [(set (reg:CCZ FLAGS_REG)
9508         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9509                      (const_int 0)))
9510    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9511         (neg:DI (match_dup 1)))]
9512   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9513   "neg{q}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "DI")])
9516
9517
9518 (define_expand "negsi2"
9519   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9520                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9521               (clobber (reg:CC FLAGS_REG))])]
9522   ""
9523   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9524
9525 (define_insn "*negsi2_1"
9526   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9527         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9528    (clobber (reg:CC FLAGS_REG))]
9529   "ix86_unary_operator_ok (NEG, SImode, operands)"
9530   "neg{l}\t%0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "SI")])
9533
9534 ;; Combine is quite creative about this pattern.
9535 (define_insn "*negsi2_1_zext"
9536   [(set (match_operand:DI 0 "register_operand" "=r")
9537         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9538                                         (const_int 32)))
9539                      (const_int 32)))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9542   "neg{l}\t%k0"
9543   [(set_attr "type" "negnot")
9544    (set_attr "mode" "SI")])
9545
9546 ;; The problem with neg is that it does not perform (compare x 0),
9547 ;; it really performs (compare 0 x), which leaves us with the zero
9548 ;; flag being the only useful item.
9549
9550 (define_insn "*negsi2_cmpz"
9551   [(set (reg:CCZ FLAGS_REG)
9552         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9553                      (const_int 0)))
9554    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9555         (neg:SI (match_dup 1)))]
9556   "ix86_unary_operator_ok (NEG, SImode, operands)"
9557   "neg{l}\t%0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "SI")])
9560
9561 (define_insn "*negsi2_cmpz_zext"
9562   [(set (reg:CCZ FLAGS_REG)
9563         (compare:CCZ (lshiftrt:DI
9564                        (neg:DI (ashift:DI
9565                                  (match_operand:DI 1 "register_operand" "0")
9566                                  (const_int 32)))
9567                        (const_int 32))
9568                      (const_int 0)))
9569    (set (match_operand:DI 0 "register_operand" "=r")
9570         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9571                                         (const_int 32)))
9572                      (const_int 32)))]
9573   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9574   "neg{l}\t%k0"
9575   [(set_attr "type" "negnot")
9576    (set_attr "mode" "SI")])
9577
9578 (define_expand "neghi2"
9579   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9580                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9581               (clobber (reg:CC FLAGS_REG))])]
9582   "TARGET_HIMODE_MATH"
9583   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9584
9585 (define_insn "*neghi2_1"
9586   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9587         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "ix86_unary_operator_ok (NEG, HImode, operands)"
9590   "neg{w}\t%0"
9591   [(set_attr "type" "negnot")
9592    (set_attr "mode" "HI")])
9593
9594 (define_insn "*neghi2_cmpz"
9595   [(set (reg:CCZ FLAGS_REG)
9596         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9597                      (const_int 0)))
9598    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9599         (neg:HI (match_dup 1)))]
9600   "ix86_unary_operator_ok (NEG, HImode, operands)"
9601   "neg{w}\t%0"
9602   [(set_attr "type" "negnot")
9603    (set_attr "mode" "HI")])
9604
9605 (define_expand "negqi2"
9606   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9607                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9608               (clobber (reg:CC FLAGS_REG))])]
9609   "TARGET_QIMODE_MATH"
9610   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9611
9612 (define_insn "*negqi2_1"
9613   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9614         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9615    (clobber (reg:CC FLAGS_REG))]
9616   "ix86_unary_operator_ok (NEG, QImode, operands)"
9617   "neg{b}\t%0"
9618   [(set_attr "type" "negnot")
9619    (set_attr "mode" "QI")])
9620
9621 (define_insn "*negqi2_cmpz"
9622   [(set (reg:CCZ FLAGS_REG)
9623         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9624                      (const_int 0)))
9625    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9626         (neg:QI (match_dup 1)))]
9627   "ix86_unary_operator_ok (NEG, QImode, operands)"
9628   "neg{b}\t%0"
9629   [(set_attr "type" "negnot")
9630    (set_attr "mode" "QI")])
9631
9632 ;; Changing of sign for FP values is doable using integer unit too.
9633
9634 (define_expand "negsf2"
9635   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9636         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9637   "TARGET_80387 || TARGET_SSE_MATH"
9638   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9639
9640 (define_expand "abssf2"
9641   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9642         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9643   "TARGET_80387 || TARGET_SSE_MATH"
9644   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9645
9646 (define_insn "*absnegsf2_mixed"
9647   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9648         (match_operator:SF 3 "absneg_operator"
9649           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9650    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9651    (clobber (reg:CC FLAGS_REG))]
9652   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9653    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9654   "#")
9655
9656 (define_insn "*absnegsf2_sse"
9657   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9658         (match_operator:SF 3 "absneg_operator"
9659           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9660    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9661    (clobber (reg:CC FLAGS_REG))]
9662   "TARGET_SSE_MATH
9663    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9664   "#")
9665
9666 (define_insn "*absnegsf2_i387"
9667   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9668         (match_operator:SF 3 "absneg_operator"
9669           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9670    (use (match_operand 2 "" ""))
9671    (clobber (reg:CC FLAGS_REG))]
9672   "TARGET_80387 && !TARGET_SSE_MATH
9673    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9674   "#")
9675
9676 (define_expand "copysignsf3"
9677   [(match_operand:SF 0 "register_operand" "")
9678    (match_operand:SF 1 "nonmemory_operand" "")
9679    (match_operand:SF 2 "register_operand" "")]
9680   "TARGET_SSE_MATH"
9681 {
9682   ix86_expand_copysign (operands);
9683   DONE;
9684 })
9685
9686 (define_insn_and_split "copysignsf3_const"
9687   [(set (match_operand:SF 0 "register_operand"          "=x")
9688         (unspec:SF
9689           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9690            (match_operand:SF 2 "register_operand"       "0")
9691            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9692           UNSPEC_COPYSIGN))]
9693   "TARGET_SSE_MATH"
9694   "#"
9695   "&& reload_completed"
9696   [(const_int 0)]
9697 {
9698   ix86_split_copysign_const (operands);
9699   DONE;
9700 })
9701
9702 (define_insn "copysignsf3_var"
9703   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9704         (unspec:SF
9705           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9706            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9707            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9708            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9709           UNSPEC_COPYSIGN))
9710    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9711   "TARGET_SSE_MATH"
9712   "#")
9713
9714 (define_split
9715   [(set (match_operand:SF 0 "register_operand" "")
9716         (unspec:SF
9717           [(match_operand:SF 2 "register_operand" "")
9718            (match_operand:SF 3 "register_operand" "")
9719            (match_operand:V4SF 4 "" "")
9720            (match_operand:V4SF 5 "" "")]
9721           UNSPEC_COPYSIGN))
9722    (clobber (match_scratch:V4SF 1 ""))]
9723   "TARGET_SSE_MATH && reload_completed"
9724   [(const_int 0)]
9725 {
9726   ix86_split_copysign_var (operands);
9727   DONE;
9728 })
9729
9730 (define_expand "negdf2"
9731   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9732         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9733   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9734   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9735
9736 (define_expand "absdf2"
9737   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9738         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9739   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9740   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9741
9742 (define_insn "*absnegdf2_mixed"
9743   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9744         (match_operator:DF 3 "absneg_operator"
9745           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9746    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9749    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9750   "#")
9751
9752 (define_insn "*absnegdf2_sse"
9753   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9754         (match_operator:DF 3 "absneg_operator"
9755           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9756    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9757    (clobber (reg:CC FLAGS_REG))]
9758   "TARGET_SSE2 && TARGET_SSE_MATH
9759    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9760   "#")
9761
9762 (define_insn "*absnegdf2_i387"
9763   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9764         (match_operator:DF 3 "absneg_operator"
9765           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9766    (use (match_operand 2 "" ""))
9767    (clobber (reg:CC FLAGS_REG))]
9768   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9769    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9770   "#")
9771
9772 (define_expand "copysigndf3"
9773   [(match_operand:DF 0 "register_operand" "")
9774    (match_operand:DF 1 "nonmemory_operand" "")
9775    (match_operand:DF 2 "register_operand" "")]
9776   "TARGET_SSE2 && TARGET_SSE_MATH"
9777 {
9778   ix86_expand_copysign (operands);
9779   DONE;
9780 })
9781
9782 (define_insn_and_split "copysigndf3_const"
9783   [(set (match_operand:DF 0 "register_operand"          "=x")
9784         (unspec:DF
9785           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9786            (match_operand:DF 2 "register_operand"       "0")
9787            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9788           UNSPEC_COPYSIGN))]
9789   "TARGET_SSE2 && TARGET_SSE_MATH"
9790   "#"
9791   "&& reload_completed"
9792   [(const_int 0)]
9793 {
9794   ix86_split_copysign_const (operands);
9795   DONE;
9796 })
9797
9798 (define_insn "copysigndf3_var"
9799   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9800         (unspec:DF
9801           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9802            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9803            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9804            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9805           UNSPEC_COPYSIGN))
9806    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9807   "TARGET_SSE2 && TARGET_SSE_MATH"
9808   "#")
9809
9810 (define_split
9811   [(set (match_operand:DF 0 "register_operand" "")
9812         (unspec:DF
9813           [(match_operand:DF 2 "register_operand" "")
9814            (match_operand:DF 3 "register_operand" "")
9815            (match_operand:V2DF 4 "" "")
9816            (match_operand:V2DF 5 "" "")]
9817           UNSPEC_COPYSIGN))
9818    (clobber (match_scratch:V2DF 1 ""))]
9819   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9820   [(const_int 0)]
9821 {
9822   ix86_split_copysign_var (operands);
9823   DONE;
9824 })
9825
9826 (define_expand "negxf2"
9827   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9828         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9829   "TARGET_80387"
9830   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9831
9832 (define_expand "absxf2"
9833   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9834         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9835   "TARGET_80387"
9836   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9837
9838 (define_insn "*absnegxf2_i387"
9839   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9840         (match_operator:XF 3 "absneg_operator"
9841           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9842    (use (match_operand 2 "" ""))
9843    (clobber (reg:CC FLAGS_REG))]
9844   "TARGET_80387
9845    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9846   "#")
9847
9848 ;; Splitters for fp abs and neg.
9849
9850 (define_split
9851   [(set (match_operand 0 "fp_register_operand" "")
9852         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9853    (use (match_operand 2 "" ""))
9854    (clobber (reg:CC FLAGS_REG))]
9855   "reload_completed"
9856   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9857
9858 (define_split
9859   [(set (match_operand 0 "register_operand" "")
9860         (match_operator 3 "absneg_operator"
9861           [(match_operand 1 "register_operand" "")]))
9862    (use (match_operand 2 "nonimmediate_operand" ""))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "reload_completed && SSE_REG_P (operands[0])"
9865   [(set (match_dup 0) (match_dup 3))]
9866 {
9867   enum machine_mode mode = GET_MODE (operands[0]);
9868   enum machine_mode vmode = GET_MODE (operands[2]);
9869   rtx tmp;
9870   
9871   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9872   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9873   if (operands_match_p (operands[0], operands[2]))
9874     {
9875       tmp = operands[1];
9876       operands[1] = operands[2];
9877       operands[2] = tmp;
9878     }
9879   if (GET_CODE (operands[3]) == ABS)
9880     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9881   else
9882     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9883   operands[3] = tmp;
9884 })
9885
9886 (define_split
9887   [(set (match_operand:SF 0 "register_operand" "")
9888         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9889    (use (match_operand:V4SF 2 "" ""))
9890    (clobber (reg:CC FLAGS_REG))]
9891   "reload_completed"
9892   [(parallel [(set (match_dup 0) (match_dup 1))
9893               (clobber (reg:CC FLAGS_REG))])]
9894
9895   rtx tmp;
9896   operands[0] = gen_lowpart (SImode, operands[0]);
9897   if (GET_CODE (operands[1]) == ABS)
9898     {
9899       tmp = gen_int_mode (0x7fffffff, SImode);
9900       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9901     }
9902   else
9903     {
9904       tmp = gen_int_mode (0x80000000, SImode);
9905       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9906     }
9907   operands[1] = tmp;
9908 })
9909
9910 (define_split
9911   [(set (match_operand:DF 0 "register_operand" "")
9912         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9913    (use (match_operand 2 "" ""))
9914    (clobber (reg:CC FLAGS_REG))]
9915   "reload_completed"
9916   [(parallel [(set (match_dup 0) (match_dup 1))
9917               (clobber (reg:CC FLAGS_REG))])]
9918 {
9919   rtx tmp;
9920   if (TARGET_64BIT)
9921     {
9922       tmp = gen_lowpart (DImode, operands[0]);
9923       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9924       operands[0] = tmp;
9925
9926       if (GET_CODE (operands[1]) == ABS)
9927         tmp = const0_rtx;
9928       else
9929         tmp = gen_rtx_NOT (DImode, tmp);
9930     }
9931   else
9932     {
9933       operands[0] = gen_highpart (SImode, operands[0]);
9934       if (GET_CODE (operands[1]) == ABS)
9935         {
9936           tmp = gen_int_mode (0x7fffffff, SImode);
9937           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9938         }
9939       else
9940         {
9941           tmp = gen_int_mode (0x80000000, SImode);
9942           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9943         }
9944     }
9945   operands[1] = tmp;
9946 })
9947
9948 (define_split
9949   [(set (match_operand:XF 0 "register_operand" "")
9950         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9951    (use (match_operand 2 "" ""))
9952    (clobber (reg:CC FLAGS_REG))]
9953   "reload_completed"
9954   [(parallel [(set (match_dup 0) (match_dup 1))
9955               (clobber (reg:CC FLAGS_REG))])]
9956 {
9957   rtx tmp;
9958   operands[0] = gen_rtx_REG (SImode,
9959                              true_regnum (operands[0])
9960                              + (TARGET_64BIT ? 1 : 2));
9961   if (GET_CODE (operands[1]) == ABS)
9962     {
9963       tmp = GEN_INT (0x7fff);
9964       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9965     }
9966   else
9967     {
9968       tmp = GEN_INT (0x8000);
9969       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9970     }
9971   operands[1] = tmp;
9972 })
9973
9974 (define_split
9975   [(set (match_operand 0 "memory_operand" "")
9976         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9977    (use (match_operand 2 "" ""))
9978    (clobber (reg:CC FLAGS_REG))]
9979   "reload_completed"
9980   [(parallel [(set (match_dup 0) (match_dup 1))
9981               (clobber (reg:CC FLAGS_REG))])]
9982 {
9983   enum machine_mode mode = GET_MODE (operands[0]);
9984   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9985   rtx tmp;
9986
9987   operands[0] = adjust_address (operands[0], QImode, size - 1);
9988   if (GET_CODE (operands[1]) == ABS)
9989     {
9990       tmp = gen_int_mode (0x7f, QImode);
9991       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9992     }
9993   else
9994     {
9995       tmp = gen_int_mode (0x80, QImode);
9996       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9997     }
9998   operands[1] = tmp;
9999 })
10000
10001 ;; Conditionalize these after reload. If they match before reload, we 
10002 ;; lose the clobber and ability to use integer instructions.
10003
10004 (define_insn "*negsf2_1"
10005   [(set (match_operand:SF 0 "register_operand" "=f")
10006         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10007   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10008   "fchs"
10009   [(set_attr "type" "fsgn")
10010    (set_attr "mode" "SF")])
10011
10012 (define_insn "*negdf2_1"
10013   [(set (match_operand:DF 0 "register_operand" "=f")
10014         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10015   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10016   "fchs"
10017   [(set_attr "type" "fsgn")
10018    (set_attr "mode" "DF")])
10019
10020 (define_insn "*negxf2_1"
10021   [(set (match_operand:XF 0 "register_operand" "=f")
10022         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10023   "TARGET_80387"
10024   "fchs"
10025   [(set_attr "type" "fsgn")
10026    (set_attr "mode" "XF")])
10027
10028 (define_insn "*abssf2_1"
10029   [(set (match_operand:SF 0 "register_operand" "=f")
10030         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10031   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10032   "fabs"
10033   [(set_attr "type" "fsgn")
10034    (set_attr "mode" "SF")])
10035
10036 (define_insn "*absdf2_1"
10037   [(set (match_operand:DF 0 "register_operand" "=f")
10038         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10039   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10040   "fabs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "DF")])
10043
10044 (define_insn "*absxf2_1"
10045   [(set (match_operand:XF 0 "register_operand" "=f")
10046         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10047   "TARGET_80387"
10048   "fabs"
10049   [(set_attr "type" "fsgn")
10050    (set_attr "mode" "DF")])
10051
10052 (define_insn "*negextendsfdf2"
10053   [(set (match_operand:DF 0 "register_operand" "=f")
10054         (neg:DF (float_extend:DF
10055                   (match_operand:SF 1 "register_operand" "0"))))]
10056   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10057   "fchs"
10058   [(set_attr "type" "fsgn")
10059    (set_attr "mode" "DF")])
10060
10061 (define_insn "*negextenddfxf2"
10062   [(set (match_operand:XF 0 "register_operand" "=f")
10063         (neg:XF (float_extend:XF
10064                   (match_operand:DF 1 "register_operand" "0"))))]
10065   "TARGET_80387"
10066   "fchs"
10067   [(set_attr "type" "fsgn")
10068    (set_attr "mode" "XF")])
10069
10070 (define_insn "*negextendsfxf2"
10071   [(set (match_operand:XF 0 "register_operand" "=f")
10072         (neg:XF (float_extend:XF
10073                   (match_operand:SF 1 "register_operand" "0"))))]
10074   "TARGET_80387"
10075   "fchs"
10076   [(set_attr "type" "fsgn")
10077    (set_attr "mode" "XF")])
10078
10079 (define_insn "*absextendsfdf2"
10080   [(set (match_operand:DF 0 "register_operand" "=f")
10081         (abs:DF (float_extend:DF
10082                   (match_operand:SF 1 "register_operand" "0"))))]
10083   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10084   "fabs"
10085   [(set_attr "type" "fsgn")
10086    (set_attr "mode" "DF")])
10087
10088 (define_insn "*absextenddfxf2"
10089   [(set (match_operand:XF 0 "register_operand" "=f")
10090         (abs:XF (float_extend:XF
10091           (match_operand:DF 1 "register_operand" "0"))))]
10092   "TARGET_80387"
10093   "fabs"
10094   [(set_attr "type" "fsgn")
10095    (set_attr "mode" "XF")])
10096
10097 (define_insn "*absextendsfxf2"
10098   [(set (match_operand:XF 0 "register_operand" "=f")
10099         (abs:XF (float_extend:XF
10100           (match_operand:SF 1 "register_operand" "0"))))]
10101   "TARGET_80387"
10102   "fabs"
10103   [(set_attr "type" "fsgn")
10104    (set_attr "mode" "XF")])
10105 \f
10106 ;; One complement instructions
10107
10108 (define_expand "one_cmpldi2"
10109   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10110         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10111   "TARGET_64BIT"
10112   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10113
10114 (define_insn "*one_cmpldi2_1_rex64"
10115   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10116         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10117   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10118   "not{q}\t%0"
10119   [(set_attr "type" "negnot")
10120    (set_attr "mode" "DI")])
10121
10122 (define_insn "*one_cmpldi2_2_rex64"
10123   [(set (reg FLAGS_REG)
10124         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10125                  (const_int 0)))
10126    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10127         (not:DI (match_dup 1)))]
10128   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10129    && ix86_unary_operator_ok (NOT, DImode, operands)"
10130   "#"
10131   [(set_attr "type" "alu1")
10132    (set_attr "mode" "DI")])
10133
10134 (define_split
10135   [(set (match_operand 0 "flags_reg_operand" "")
10136         (match_operator 2 "compare_operator"
10137           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10138            (const_int 0)]))
10139    (set (match_operand:DI 1 "nonimmediate_operand" "")
10140         (not:DI (match_dup 3)))]
10141   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10142   [(parallel [(set (match_dup 0)
10143                    (match_op_dup 2
10144                      [(xor:DI (match_dup 3) (const_int -1))
10145                       (const_int 0)]))
10146               (set (match_dup 1)
10147                    (xor:DI (match_dup 3) (const_int -1)))])]
10148   "")
10149
10150 (define_expand "one_cmplsi2"
10151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10152         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10153   ""
10154   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10155
10156 (define_insn "*one_cmplsi2_1"
10157   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10158         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10159   "ix86_unary_operator_ok (NOT, SImode, operands)"
10160   "not{l}\t%0"
10161   [(set_attr "type" "negnot")
10162    (set_attr "mode" "SI")])
10163
10164 ;; ??? Currently never generated - xor is used instead.
10165 (define_insn "*one_cmplsi2_1_zext"
10166   [(set (match_operand:DI 0 "register_operand" "=r")
10167         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10168   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10169   "not{l}\t%k0"
10170   [(set_attr "type" "negnot")
10171    (set_attr "mode" "SI")])
10172
10173 (define_insn "*one_cmplsi2_2"
10174   [(set (reg FLAGS_REG)
10175         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10176                  (const_int 0)))
10177    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10178         (not:SI (match_dup 1)))]
10179   "ix86_match_ccmode (insn, CCNOmode)
10180    && ix86_unary_operator_ok (NOT, SImode, operands)"
10181   "#"
10182   [(set_attr "type" "alu1")
10183    (set_attr "mode" "SI")])
10184
10185 (define_split
10186   [(set (match_operand 0 "flags_reg_operand" "")
10187         (match_operator 2 "compare_operator"
10188           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10189            (const_int 0)]))
10190    (set (match_operand:SI 1 "nonimmediate_operand" "")
10191         (not:SI (match_dup 3)))]
10192   "ix86_match_ccmode (insn, CCNOmode)"
10193   [(parallel [(set (match_dup 0)
10194                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10195                                     (const_int 0)]))
10196               (set (match_dup 1)
10197                    (xor:SI (match_dup 3) (const_int -1)))])]
10198   "")
10199
10200 ;; ??? Currently never generated - xor is used instead.
10201 (define_insn "*one_cmplsi2_2_zext"
10202   [(set (reg FLAGS_REG)
10203         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10204                  (const_int 0)))
10205    (set (match_operand:DI 0 "register_operand" "=r")
10206         (zero_extend:DI (not:SI (match_dup 1))))]
10207   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10208    && ix86_unary_operator_ok (NOT, SImode, operands)"
10209   "#"
10210   [(set_attr "type" "alu1")
10211    (set_attr "mode" "SI")])
10212
10213 (define_split
10214   [(set (match_operand 0 "flags_reg_operand" "")
10215         (match_operator 2 "compare_operator"
10216           [(not:SI (match_operand:SI 3 "register_operand" ""))
10217            (const_int 0)]))
10218    (set (match_operand:DI 1 "register_operand" "")
10219         (zero_extend:DI (not:SI (match_dup 3))))]
10220   "ix86_match_ccmode (insn, CCNOmode)"
10221   [(parallel [(set (match_dup 0)
10222                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10223                                     (const_int 0)]))
10224               (set (match_dup 1)
10225                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10226   "")
10227
10228 (define_expand "one_cmplhi2"
10229   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10230         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10231   "TARGET_HIMODE_MATH"
10232   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10233
10234 (define_insn "*one_cmplhi2_1"
10235   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10236         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10237   "ix86_unary_operator_ok (NOT, HImode, operands)"
10238   "not{w}\t%0"
10239   [(set_attr "type" "negnot")
10240    (set_attr "mode" "HI")])
10241
10242 (define_insn "*one_cmplhi2_2"
10243   [(set (reg FLAGS_REG)
10244         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10245                  (const_int 0)))
10246    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10247         (not:HI (match_dup 1)))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && ix86_unary_operator_ok (NEG, HImode, operands)"
10250   "#"
10251   [(set_attr "type" "alu1")
10252    (set_attr "mode" "HI")])
10253
10254 (define_split
10255   [(set (match_operand 0 "flags_reg_operand" "")
10256         (match_operator 2 "compare_operator"
10257           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10258            (const_int 0)]))
10259    (set (match_operand:HI 1 "nonimmediate_operand" "")
10260         (not:HI (match_dup 3)))]
10261   "ix86_match_ccmode (insn, CCNOmode)"
10262   [(parallel [(set (match_dup 0)
10263                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10264                                     (const_int 0)]))
10265               (set (match_dup 1)
10266                    (xor:HI (match_dup 3) (const_int -1)))])]
10267   "")
10268
10269 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10270 (define_expand "one_cmplqi2"
10271   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10272         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10273   "TARGET_QIMODE_MATH"
10274   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10275
10276 (define_insn "*one_cmplqi2_1"
10277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10278         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10279   "ix86_unary_operator_ok (NOT, QImode, operands)"
10280   "@
10281    not{b}\t%0
10282    not{l}\t%k0"
10283   [(set_attr "type" "negnot")
10284    (set_attr "mode" "QI,SI")])
10285
10286 (define_insn "*one_cmplqi2_2"
10287   [(set (reg FLAGS_REG)
10288         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10289                  (const_int 0)))
10290    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10291         (not:QI (match_dup 1)))]
10292   "ix86_match_ccmode (insn, CCNOmode)
10293    && ix86_unary_operator_ok (NOT, QImode, operands)"
10294   "#"
10295   [(set_attr "type" "alu1")
10296    (set_attr "mode" "QI")])
10297
10298 (define_split
10299   [(set (match_operand 0 "flags_reg_operand" "")
10300         (match_operator 2 "compare_operator"
10301           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10302            (const_int 0)]))
10303    (set (match_operand:QI 1 "nonimmediate_operand" "")
10304         (not:QI (match_dup 3)))]
10305   "ix86_match_ccmode (insn, CCNOmode)"
10306   [(parallel [(set (match_dup 0)
10307                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10308                                     (const_int 0)]))
10309               (set (match_dup 1)
10310                    (xor:QI (match_dup 3) (const_int -1)))])]
10311   "")
10312 \f
10313 ;; Arithmetic shift instructions
10314
10315 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10316 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10317 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10318 ;; from the assembler input.
10319 ;;
10320 ;; This instruction shifts the target reg/mem as usual, but instead of
10321 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10322 ;; is a left shift double, bits are taken from the high order bits of
10323 ;; reg, else if the insn is a shift right double, bits are taken from the
10324 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10325 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10326 ;;
10327 ;; Since sh[lr]d does not change the `reg' operand, that is done
10328 ;; separately, making all shifts emit pairs of shift double and normal
10329 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10330 ;; support a 63 bit shift, each shift where the count is in a reg expands
10331 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10332 ;;
10333 ;; If the shift count is a constant, we need never emit more than one
10334 ;; shift pair, instead using moves and sign extension for counts greater
10335 ;; than 31.
10336
10337 (define_expand "ashlti3"
10338   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10339                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10340                               (match_operand:QI 2 "nonmemory_operand" "")))
10341               (clobber (reg:CC FLAGS_REG))])]
10342   "TARGET_64BIT"
10343 {
10344   if (! immediate_operand (operands[2], QImode))
10345     {
10346       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10347       DONE;
10348     }
10349   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10350   DONE;
10351 })
10352
10353 (define_insn "ashlti3_1"
10354   [(set (match_operand:TI 0 "register_operand" "=r")
10355         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10356                    (match_operand:QI 2 "register_operand" "c")))
10357    (clobber (match_scratch:DI 3 "=&r"))
10358    (clobber (reg:CC FLAGS_REG))]
10359   "TARGET_64BIT"
10360   "#"
10361   [(set_attr "type" "multi")])
10362
10363 (define_insn "*ashlti3_2"
10364   [(set (match_operand:TI 0 "register_operand" "=r")
10365         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10366                    (match_operand:QI 2 "immediate_operand" "O")))
10367    (clobber (reg:CC FLAGS_REG))]
10368   "TARGET_64BIT"
10369   "#"
10370   [(set_attr "type" "multi")])
10371
10372 (define_split
10373   [(set (match_operand:TI 0 "register_operand" "")
10374         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10375                    (match_operand:QI 2 "register_operand" "")))
10376    (clobber (match_scratch:DI 3 ""))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "TARGET_64BIT && reload_completed"
10379   [(const_int 0)]
10380   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10381
10382 (define_split
10383   [(set (match_operand:TI 0 "register_operand" "")
10384         (ashift:TI (match_operand:TI 1 "register_operand" "")
10385                    (match_operand:QI 2 "immediate_operand" "")))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "TARGET_64BIT && reload_completed"
10388   [(const_int 0)]
10389   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10390
10391 (define_insn "x86_64_shld"
10392   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10393         (ior:DI (ashift:DI (match_dup 0)
10394                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10395                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10396                   (minus:QI (const_int 64) (match_dup 2)))))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "TARGET_64BIT"
10399   "@
10400    shld{q}\t{%2, %1, %0|%0, %1, %2}
10401    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10402   [(set_attr "type" "ishift")
10403    (set_attr "prefix_0f" "1")
10404    (set_attr "mode" "DI")
10405    (set_attr "athlon_decode" "vector")
10406    (set_attr "amdfam10_decode" "vector")])   
10407
10408 (define_expand "x86_64_shift_adj"
10409   [(set (reg:CCZ FLAGS_REG)
10410         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10411                              (const_int 64))
10412                      (const_int 0)))
10413    (set (match_operand:DI 0 "register_operand" "")
10414         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10415                          (match_operand:DI 1 "register_operand" "")
10416                          (match_dup 0)))
10417    (set (match_dup 1)
10418         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10419                          (match_operand:DI 3 "register_operand" "r")
10420                          (match_dup 1)))]
10421   "TARGET_64BIT"
10422   "")
10423
10424 (define_expand "ashldi3"
10425   [(set (match_operand:DI 0 "shiftdi_operand" "")
10426         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10427                    (match_operand:QI 2 "nonmemory_operand" "")))]
10428   ""
10429   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10430
10431 (define_insn "*ashldi3_1_rex64"
10432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10433         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10434                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10437 {
10438   switch (get_attr_type (insn))
10439     {
10440     case TYPE_ALU:
10441       gcc_assert (operands[2] == const1_rtx);
10442       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10443       return "add{q}\t{%0, %0|%0, %0}";
10444
10445     case TYPE_LEA:
10446       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10447       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10448       operands[1] = gen_rtx_MULT (DImode, operands[1],
10449                                   GEN_INT (1 << INTVAL (operands[2])));
10450       return "lea{q}\t{%a1, %0|%0, %a1}";
10451
10452     default:
10453       if (REG_P (operands[2]))
10454         return "sal{q}\t{%b2, %0|%0, %b2}";
10455       else if (operands[2] == const1_rtx
10456                && (TARGET_SHIFT1 || optimize_size))
10457         return "sal{q}\t%0";
10458       else
10459         return "sal{q}\t{%2, %0|%0, %2}";
10460     }
10461 }
10462   [(set (attr "type")
10463      (cond [(eq_attr "alternative" "1")
10464               (const_string "lea")
10465             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10466                           (const_int 0))
10467                       (match_operand 0 "register_operand" ""))
10468                  (match_operand 2 "const1_operand" ""))
10469               (const_string "alu")
10470            ]
10471            (const_string "ishift")))
10472    (set_attr "mode" "DI")])
10473
10474 ;; Convert lea to the lea pattern to avoid flags dependency.
10475 (define_split
10476   [(set (match_operand:DI 0 "register_operand" "")
10477         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10478                    (match_operand:QI 2 "immediate_operand" "")))
10479    (clobber (reg:CC FLAGS_REG))]
10480   "TARGET_64BIT && reload_completed
10481    && true_regnum (operands[0]) != true_regnum (operands[1])"
10482   [(set (match_dup 0)
10483         (mult:DI (match_dup 1)
10484                  (match_dup 2)))]
10485   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10486
10487 ;; This pattern can't accept a variable shift count, since shifts by
10488 ;; zero don't affect the flags.  We assume that shifts by constant
10489 ;; zero are optimized away.
10490 (define_insn "*ashldi3_cmp_rex64"
10491   [(set (reg FLAGS_REG)
10492         (compare
10493           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10494                      (match_operand:QI 2 "immediate_operand" "e"))
10495           (const_int 0)))
10496    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10497         (ashift:DI (match_dup 1) (match_dup 2)))]
10498   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10499    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10500    && (optimize_size
10501        || !TARGET_PARTIAL_FLAG_REG_STALL
10502        || (operands[2] == const1_rtx
10503            && (TARGET_SHIFT1
10504                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10505 {
10506   switch (get_attr_type (insn))
10507     {
10508     case TYPE_ALU:
10509       gcc_assert (operands[2] == const1_rtx);
10510       return "add{q}\t{%0, %0|%0, %0}";
10511
10512     default:
10513       if (REG_P (operands[2]))
10514         return "sal{q}\t{%b2, %0|%0, %b2}";
10515       else if (operands[2] == const1_rtx
10516                && (TARGET_SHIFT1 || optimize_size))
10517         return "sal{q}\t%0";
10518       else
10519         return "sal{q}\t{%2, %0|%0, %2}";
10520     }
10521 }
10522   [(set (attr "type")
10523      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524                           (const_int 0))
10525                       (match_operand 0 "register_operand" ""))
10526                  (match_operand 2 "const1_operand" ""))
10527               (const_string "alu")
10528            ]
10529            (const_string "ishift")))
10530    (set_attr "mode" "DI")])
10531
10532 (define_insn "*ashldi3_cconly_rex64"
10533   [(set (reg FLAGS_REG)
10534         (compare
10535           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10536                      (match_operand:QI 2 "immediate_operand" "e"))
10537           (const_int 0)))
10538    (clobber (match_scratch:DI 0 "=r"))]
10539   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10540    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10541    && (optimize_size
10542        || !TARGET_PARTIAL_FLAG_REG_STALL
10543        || (operands[2] == const1_rtx
10544            && (TARGET_SHIFT1
10545                || TARGET_DOUBLE_WITH_ADD)))"
10546 {
10547   switch (get_attr_type (insn))
10548     {
10549     case TYPE_ALU:
10550       gcc_assert (operands[2] == const1_rtx);
10551       return "add{q}\t{%0, %0|%0, %0}";
10552
10553     default:
10554       if (REG_P (operands[2]))
10555         return "sal{q}\t{%b2, %0|%0, %b2}";
10556       else if (operands[2] == const1_rtx
10557                && (TARGET_SHIFT1 || optimize_size))
10558         return "sal{q}\t%0";
10559       else
10560         return "sal{q}\t{%2, %0|%0, %2}";
10561     }
10562 }
10563   [(set (attr "type")
10564      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10565                           (const_int 0))
10566                       (match_operand 0 "register_operand" ""))
10567                  (match_operand 2 "const1_operand" ""))
10568               (const_string "alu")
10569            ]
10570            (const_string "ishift")))
10571    (set_attr "mode" "DI")])
10572
10573 (define_insn "*ashldi3_1"
10574   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10575         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10576                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10577    (clobber (reg:CC FLAGS_REG))]
10578   "!TARGET_64BIT"
10579   "#"
10580   [(set_attr "type" "multi")])
10581
10582 ;; By default we don't ask for a scratch register, because when DImode
10583 ;; values are manipulated, registers are already at a premium.  But if
10584 ;; we have one handy, we won't turn it away.
10585 (define_peephole2
10586   [(match_scratch:SI 3 "r")
10587    (parallel [(set (match_operand:DI 0 "register_operand" "")
10588                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10589                               (match_operand:QI 2 "nonmemory_operand" "")))
10590               (clobber (reg:CC FLAGS_REG))])
10591    (match_dup 3)]
10592   "!TARGET_64BIT && TARGET_CMOVE"
10593   [(const_int 0)]
10594   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10595
10596 (define_split
10597   [(set (match_operand:DI 0 "register_operand" "")
10598         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10599                    (match_operand:QI 2 "nonmemory_operand" "")))
10600    (clobber (reg:CC FLAGS_REG))]
10601   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10602                      ? flow2_completed : reload_completed)"
10603   [(const_int 0)]
10604   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10605
10606 (define_insn "x86_shld_1"
10607   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10608         (ior:SI (ashift:SI (match_dup 0)
10609                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10610                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10611                   (minus:QI (const_int 32) (match_dup 2)))))
10612    (clobber (reg:CC FLAGS_REG))]
10613   ""
10614   "@
10615    shld{l}\t{%2, %1, %0|%0, %1, %2}
10616    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10617   [(set_attr "type" "ishift")
10618    (set_attr "prefix_0f" "1")
10619    (set_attr "mode" "SI")
10620    (set_attr "pent_pair" "np")
10621    (set_attr "athlon_decode" "vector")
10622    (set_attr "amdfam10_decode" "vector")])   
10623
10624 (define_expand "x86_shift_adj_1"
10625   [(set (reg:CCZ FLAGS_REG)
10626         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10627                              (const_int 32))
10628                      (const_int 0)))
10629    (set (match_operand:SI 0 "register_operand" "")
10630         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10631                          (match_operand:SI 1 "register_operand" "")
10632                          (match_dup 0)))
10633    (set (match_dup 1)
10634         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10635                          (match_operand:SI 3 "register_operand" "r")
10636                          (match_dup 1)))]
10637   "TARGET_CMOVE"
10638   "")
10639
10640 (define_expand "x86_shift_adj_2"
10641   [(use (match_operand:SI 0 "register_operand" ""))
10642    (use (match_operand:SI 1 "register_operand" ""))
10643    (use (match_operand:QI 2 "register_operand" ""))]
10644   ""
10645 {
10646   rtx label = gen_label_rtx ();
10647   rtx tmp;
10648
10649   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10650
10651   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10652   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10653   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10654                               gen_rtx_LABEL_REF (VOIDmode, label),
10655                               pc_rtx);
10656   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10657   JUMP_LABEL (tmp) = label;
10658
10659   emit_move_insn (operands[0], operands[1]);
10660   ix86_expand_clear (operands[1]);
10661
10662   emit_label (label);
10663   LABEL_NUSES (label) = 1;
10664
10665   DONE;
10666 })
10667
10668 (define_expand "ashlsi3"
10669   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10670         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10671                    (match_operand:QI 2 "nonmemory_operand" "")))
10672    (clobber (reg:CC FLAGS_REG))]
10673   ""
10674   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10675
10676 (define_insn "*ashlsi3_1"
10677   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10678         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10679                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 {
10683   switch (get_attr_type (insn))
10684     {
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688       return "add{l}\t{%0, %0|%0, %0}";
10689
10690     case TYPE_LEA:
10691       return "#";
10692
10693     default:
10694       if (REG_P (operands[2]))
10695         return "sal{l}\t{%b2, %0|%0, %b2}";
10696       else if (operands[2] == const1_rtx
10697                && (TARGET_SHIFT1 || optimize_size))
10698         return "sal{l}\t%0";
10699       else
10700         return "sal{l}\t{%2, %0|%0, %2}";
10701     }
10702 }
10703   [(set (attr "type")
10704      (cond [(eq_attr "alternative" "1")
10705               (const_string "lea")
10706             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707                           (const_int 0))
10708                       (match_operand 0 "register_operand" ""))
10709                  (match_operand 2 "const1_operand" ""))
10710               (const_string "alu")
10711            ]
10712            (const_string "ishift")))
10713    (set_attr "mode" "SI")])
10714
10715 ;; Convert lea to the lea pattern to avoid flags dependency.
10716 (define_split
10717   [(set (match_operand 0 "register_operand" "")
10718         (ashift (match_operand 1 "index_register_operand" "")
10719                 (match_operand:QI 2 "const_int_operand" "")))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "reload_completed
10722    && true_regnum (operands[0]) != true_regnum (operands[1])
10723    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10724   [(const_int 0)]
10725 {
10726   rtx pat;
10727   enum machine_mode mode = GET_MODE (operands[0]);
10728
10729   if (GET_MODE_SIZE (mode) < 4)
10730     operands[0] = gen_lowpart (SImode, operands[0]);
10731   if (mode != Pmode)
10732     operands[1] = gen_lowpart (Pmode, operands[1]);
10733   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10734
10735   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10736   if (Pmode != SImode)
10737     pat = gen_rtx_SUBREG (SImode, pat, 0);
10738   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10739   DONE;
10740 })
10741
10742 ;; Rare case of shifting RSP is handled by generating move and shift
10743 (define_split
10744   [(set (match_operand 0 "register_operand" "")
10745         (ashift (match_operand 1 "register_operand" "")
10746                 (match_operand:QI 2 "const_int_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "reload_completed
10749    && true_regnum (operands[0]) != true_regnum (operands[1])"
10750   [(const_int 0)]
10751 {
10752   rtx pat, clob;
10753   emit_move_insn (operands[0], operands[1]);
10754   pat = gen_rtx_SET (VOIDmode, operands[0],
10755                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10756                                      operands[0], operands[2]));
10757   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10758   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10759   DONE;
10760 })
10761
10762 (define_insn "*ashlsi3_1_zext"
10763   [(set (match_operand:DI 0 "register_operand" "=r,r")
10764         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10765                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10766    (clobber (reg:CC FLAGS_REG))]
10767   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10768 {
10769   switch (get_attr_type (insn))
10770     {
10771     case TYPE_ALU:
10772       gcc_assert (operands[2] == const1_rtx);
10773       return "add{l}\t{%k0, %k0|%k0, %k0}";
10774
10775     case TYPE_LEA:
10776       return "#";
10777
10778     default:
10779       if (REG_P (operands[2]))
10780         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10781       else if (operands[2] == const1_rtx
10782                && (TARGET_SHIFT1 || optimize_size))
10783         return "sal{l}\t%k0";
10784       else
10785         return "sal{l}\t{%2, %k0|%k0, %2}";
10786     }
10787 }
10788   [(set (attr "type")
10789      (cond [(eq_attr "alternative" "1")
10790               (const_string "lea")
10791             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792                      (const_int 0))
10793                  (match_operand 2 "const1_operand" ""))
10794               (const_string "alu")
10795            ]
10796            (const_string "ishift")))
10797    (set_attr "mode" "SI")])
10798
10799 ;; Convert lea to the lea pattern to avoid flags dependency.
10800 (define_split
10801   [(set (match_operand:DI 0 "register_operand" "")
10802         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10803                                 (match_operand:QI 2 "const_int_operand" ""))))
10804    (clobber (reg:CC FLAGS_REG))]
10805   "TARGET_64BIT && reload_completed
10806    && true_regnum (operands[0]) != true_regnum (operands[1])"
10807   [(set (match_dup 0) (zero_extend:DI
10808                         (subreg:SI (mult:SI (match_dup 1)
10809                                             (match_dup 2)) 0)))]
10810 {
10811   operands[1] = gen_lowpart (Pmode, operands[1]);
10812   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10813 })
10814
10815 ;; This pattern can't accept a variable shift count, since shifts by
10816 ;; zero don't affect the flags.  We assume that shifts by constant
10817 ;; zero are optimized away.
10818 (define_insn "*ashlsi3_cmp"
10819   [(set (reg FLAGS_REG)
10820         (compare
10821           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10822                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10823           (const_int 0)))
10824    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10825         (ashift:SI (match_dup 1) (match_dup 2)))]
10826   "ix86_match_ccmode (insn, CCGOCmode)
10827    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10828    && (optimize_size
10829        || !TARGET_PARTIAL_FLAG_REG_STALL
10830        || (operands[2] == const1_rtx
10831            && (TARGET_SHIFT1
10832                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10833 {
10834   switch (get_attr_type (insn))
10835     {
10836     case TYPE_ALU:
10837       gcc_assert (operands[2] == const1_rtx);
10838       return "add{l}\t{%0, %0|%0, %0}";
10839
10840     default:
10841       if (REG_P (operands[2]))
10842         return "sal{l}\t{%b2, %0|%0, %b2}";
10843       else if (operands[2] == const1_rtx
10844                && (TARGET_SHIFT1 || optimize_size))
10845         return "sal{l}\t%0";
10846       else
10847         return "sal{l}\t{%2, %0|%0, %2}";
10848     }
10849 }
10850   [(set (attr "type")
10851      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10852                           (const_int 0))
10853                       (match_operand 0 "register_operand" ""))
10854                  (match_operand 2 "const1_operand" ""))
10855               (const_string "alu")
10856            ]
10857            (const_string "ishift")))
10858    (set_attr "mode" "SI")])
10859
10860 (define_insn "*ashlsi3_cconly"
10861   [(set (reg FLAGS_REG)
10862         (compare
10863           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10864                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10865           (const_int 0)))
10866    (clobber (match_scratch:SI 0 "=r"))]
10867   "ix86_match_ccmode (insn, CCGOCmode)
10868    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10869    && (optimize_size
10870        || !TARGET_PARTIAL_FLAG_REG_STALL
10871        || (operands[2] == const1_rtx
10872            && (TARGET_SHIFT1
10873                || TARGET_DOUBLE_WITH_ADD)))"
10874 {
10875   switch (get_attr_type (insn))
10876     {
10877     case TYPE_ALU:
10878       gcc_assert (operands[2] == const1_rtx);
10879       return "add{l}\t{%0, %0|%0, %0}";
10880
10881     default:
10882       if (REG_P (operands[2]))
10883         return "sal{l}\t{%b2, %0|%0, %b2}";
10884       else if (operands[2] == const1_rtx
10885                && (TARGET_SHIFT1 || optimize_size))
10886         return "sal{l}\t%0";
10887       else
10888         return "sal{l}\t{%2, %0|%0, %2}";
10889     }
10890 }
10891   [(set (attr "type")
10892      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893                           (const_int 0))
10894                       (match_operand 0 "register_operand" ""))
10895                  (match_operand 2 "const1_operand" ""))
10896               (const_string "alu")
10897            ]
10898            (const_string "ishift")))
10899    (set_attr "mode" "SI")])
10900
10901 (define_insn "*ashlsi3_cmp_zext"
10902   [(set (reg FLAGS_REG)
10903         (compare
10904           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10905                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10906           (const_int 0)))
10907    (set (match_operand:DI 0 "register_operand" "=r")
10908         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10909   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10910    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10911    && (optimize_size
10912        || !TARGET_PARTIAL_FLAG_REG_STALL
10913        || (operands[2] == const1_rtx
10914            && (TARGET_SHIFT1
10915                || TARGET_DOUBLE_WITH_ADD)))"
10916 {
10917   switch (get_attr_type (insn))
10918     {
10919     case TYPE_ALU:
10920       gcc_assert (operands[2] == const1_rtx);
10921       return "add{l}\t{%k0, %k0|%k0, %k0}";
10922
10923     default:
10924       if (REG_P (operands[2]))
10925         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10926       else if (operands[2] == const1_rtx
10927                && (TARGET_SHIFT1 || optimize_size))
10928         return "sal{l}\t%k0";
10929       else
10930         return "sal{l}\t{%2, %k0|%k0, %2}";
10931     }
10932 }
10933   [(set (attr "type")
10934      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935                      (const_int 0))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "SI")])
10941
10942 (define_expand "ashlhi3"
10943   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10944         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10945                    (match_operand:QI 2 "nonmemory_operand" "")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_HIMODE_MATH"
10948   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10949
10950 (define_insn "*ashlhi3_1_lea"
10951   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10952         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10953                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10954    (clobber (reg:CC FLAGS_REG))]
10955   "!TARGET_PARTIAL_REG_STALL
10956    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10957 {
10958   switch (get_attr_type (insn))
10959     {
10960     case TYPE_LEA:
10961       return "#";
10962     case TYPE_ALU:
10963       gcc_assert (operands[2] == const1_rtx);
10964       return "add{w}\t{%0, %0|%0, %0}";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{w}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{w}\t%0";
10972       else
10973         return "sal{w}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(eq_attr "alternative" "1")
10978               (const_string "lea")
10979             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "HI,SI")])
10987
10988 (define_insn "*ashlhi3_1"
10989   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10990         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10991                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10992    (clobber (reg:CC FLAGS_REG))]
10993   "TARGET_PARTIAL_REG_STALL
10994    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10995 {
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{w}\t{%0, %0|%0, %0}";
11001
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{w}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{w}\t%0";
11008       else
11009         return "sal{w}\t{%2, %0|%0, %2}";
11010     }
11011 }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "HI")])
11021
11022 ;; This pattern can't accept a variable shift count, since shifts by
11023 ;; zero don't affect the flags.  We assume that shifts by constant
11024 ;; zero are optimized away.
11025 (define_insn "*ashlhi3_cmp"
11026   [(set (reg FLAGS_REG)
11027         (compare
11028           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11029                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11030           (const_int 0)))
11031    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11032         (ashift:HI (match_dup 1) (match_dup 2)))]
11033   "ix86_match_ccmode (insn, CCGOCmode)
11034    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11035    && (optimize_size
11036        || !TARGET_PARTIAL_FLAG_REG_STALL
11037        || (operands[2] == const1_rtx
11038            && (TARGET_SHIFT1
11039                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11040 {
11041   switch (get_attr_type (insn))
11042     {
11043     case TYPE_ALU:
11044       gcc_assert (operands[2] == const1_rtx);
11045       return "add{w}\t{%0, %0|%0, %0}";
11046
11047     default:
11048       if (REG_P (operands[2]))
11049         return "sal{w}\t{%b2, %0|%0, %b2}";
11050       else if (operands[2] == const1_rtx
11051                && (TARGET_SHIFT1 || optimize_size))
11052         return "sal{w}\t%0";
11053       else
11054         return "sal{w}\t{%2, %0|%0, %2}";
11055     }
11056 }
11057   [(set (attr "type")
11058      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059                           (const_int 0))
11060                       (match_operand 0 "register_operand" ""))
11061                  (match_operand 2 "const1_operand" ""))
11062               (const_string "alu")
11063            ]
11064            (const_string "ishift")))
11065    (set_attr "mode" "HI")])
11066
11067 (define_insn "*ashlhi3_cconly"
11068   [(set (reg FLAGS_REG)
11069         (compare
11070           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11072           (const_int 0)))
11073    (clobber (match_scratch:HI 0 "=r"))]
11074   "ix86_match_ccmode (insn, CCGOCmode)
11075    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11076    && (optimize_size
11077        || !TARGET_PARTIAL_FLAG_REG_STALL
11078        || (operands[2] == const1_rtx
11079            && (TARGET_SHIFT1
11080                || TARGET_DOUBLE_WITH_ADD)))"
11081 {
11082   switch (get_attr_type (insn))
11083     {
11084     case TYPE_ALU:
11085       gcc_assert (operands[2] == const1_rtx);
11086       return "add{w}\t{%0, %0|%0, %0}";
11087
11088     default:
11089       if (REG_P (operands[2]))
11090         return "sal{w}\t{%b2, %0|%0, %b2}";
11091       else if (operands[2] == const1_rtx
11092                && (TARGET_SHIFT1 || optimize_size))
11093         return "sal{w}\t%0";
11094       else
11095         return "sal{w}\t{%2, %0|%0, %2}";
11096     }
11097 }
11098   [(set (attr "type")
11099      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11100                           (const_int 0))
11101                       (match_operand 0 "register_operand" ""))
11102                  (match_operand 2 "const1_operand" ""))
11103               (const_string "alu")
11104            ]
11105            (const_string "ishift")))
11106    (set_attr "mode" "HI")])
11107
11108 (define_expand "ashlqi3"
11109   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11110         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11111                    (match_operand:QI 2 "nonmemory_operand" "")))
11112    (clobber (reg:CC FLAGS_REG))]
11113   "TARGET_QIMODE_MATH"
11114   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11115
11116 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11117
11118 (define_insn "*ashlqi3_1_lea"
11119   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11120         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11121                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "!TARGET_PARTIAL_REG_STALL
11124    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11125 {
11126   switch (get_attr_type (insn))
11127     {
11128     case TYPE_LEA:
11129       return "#";
11130     case TYPE_ALU:
11131       gcc_assert (operands[2] == const1_rtx);
11132       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11133         return "add{l}\t{%k0, %k0|%k0, %k0}";
11134       else
11135         return "add{b}\t{%0, %0|%0, %0}";
11136
11137     default:
11138       if (REG_P (operands[2]))
11139         {
11140           if (get_attr_mode (insn) == MODE_SI)
11141             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11142           else
11143             return "sal{b}\t{%b2, %0|%0, %b2}";
11144         }
11145       else if (operands[2] == const1_rtx
11146                && (TARGET_SHIFT1 || optimize_size))
11147         {
11148           if (get_attr_mode (insn) == MODE_SI)
11149             return "sal{l}\t%0";
11150           else
11151             return "sal{b}\t%0";
11152         }
11153       else
11154         {
11155           if (get_attr_mode (insn) == MODE_SI)
11156             return "sal{l}\t{%2, %k0|%k0, %2}";
11157           else
11158             return "sal{b}\t{%2, %0|%0, %2}";
11159         }
11160     }
11161 }
11162   [(set (attr "type")
11163      (cond [(eq_attr "alternative" "2")
11164               (const_string "lea")
11165             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166                           (const_int 0))
11167                       (match_operand 0 "register_operand" ""))
11168                  (match_operand 2 "const1_operand" ""))
11169               (const_string "alu")
11170            ]
11171            (const_string "ishift")))
11172    (set_attr "mode" "QI,SI,SI")])
11173
11174 (define_insn "*ashlqi3_1"
11175   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11176         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11177                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11178    (clobber (reg:CC FLAGS_REG))]
11179   "TARGET_PARTIAL_REG_STALL
11180    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11181 {
11182   switch (get_attr_type (insn))
11183     {
11184     case TYPE_ALU:
11185       gcc_assert (operands[2] == const1_rtx);
11186       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11187         return "add{l}\t{%k0, %k0|%k0, %k0}";
11188       else
11189         return "add{b}\t{%0, %0|%0, %0}";
11190
11191     default:
11192       if (REG_P (operands[2]))
11193         {
11194           if (get_attr_mode (insn) == MODE_SI)
11195             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196           else
11197             return "sal{b}\t{%b2, %0|%0, %b2}";
11198         }
11199       else if (operands[2] == const1_rtx
11200                && (TARGET_SHIFT1 || optimize_size))
11201         {
11202           if (get_attr_mode (insn) == MODE_SI)
11203             return "sal{l}\t%0";
11204           else
11205             return "sal{b}\t%0";
11206         }
11207       else
11208         {
11209           if (get_attr_mode (insn) == MODE_SI)
11210             return "sal{l}\t{%2, %k0|%k0, %2}";
11211           else
11212             return "sal{b}\t{%2, %0|%0, %2}";
11213         }
11214     }
11215 }
11216   [(set (attr "type")
11217      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218                           (const_int 0))
11219                       (match_operand 0 "register_operand" ""))
11220                  (match_operand 2 "const1_operand" ""))
11221               (const_string "alu")
11222            ]
11223            (const_string "ishift")))
11224    (set_attr "mode" "QI,SI")])
11225
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags.  We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashlqi3_cmp"
11230   [(set (reg FLAGS_REG)
11231         (compare
11232           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11233                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11234           (const_int 0)))
11235    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11236         (ashift:QI (match_dup 1) (match_dup 2)))]
11237   "ix86_match_ccmode (insn, CCGOCmode)
11238    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11239    && (optimize_size
11240        || !TARGET_PARTIAL_FLAG_REG_STALL
11241        || (operands[2] == const1_rtx
11242            && (TARGET_SHIFT1
11243                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11244 {
11245   switch (get_attr_type (insn))
11246     {
11247     case TYPE_ALU:
11248       gcc_assert (operands[2] == const1_rtx);
11249       return "add{b}\t{%0, %0|%0, %0}";
11250
11251     default:
11252       if (REG_P (operands[2]))
11253         return "sal{b}\t{%b2, %0|%0, %b2}";
11254       else if (operands[2] == const1_rtx
11255                && (TARGET_SHIFT1 || optimize_size))
11256         return "sal{b}\t%0";
11257       else
11258         return "sal{b}\t{%2, %0|%0, %2}";
11259     }
11260 }
11261   [(set (attr "type")
11262      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263                           (const_int 0))
11264                       (match_operand 0 "register_operand" ""))
11265                  (match_operand 2 "const1_operand" ""))
11266               (const_string "alu")
11267            ]
11268            (const_string "ishift")))
11269    (set_attr "mode" "QI")])
11270
11271 (define_insn "*ashlqi3_cconly"
11272   [(set (reg FLAGS_REG)
11273         (compare
11274           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276           (const_int 0)))
11277    (clobber (match_scratch:QI 0 "=q"))]
11278   "ix86_match_ccmode (insn, CCGOCmode)
11279    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11280    && (optimize_size
11281        || !TARGET_PARTIAL_FLAG_REG_STALL
11282        || (operands[2] == const1_rtx
11283            && (TARGET_SHIFT1
11284                || TARGET_DOUBLE_WITH_ADD)))"
11285 {
11286   switch (get_attr_type (insn))
11287     {
11288     case TYPE_ALU:
11289       gcc_assert (operands[2] == const1_rtx);
11290       return "add{b}\t{%0, %0|%0, %0}";
11291
11292     default:
11293       if (REG_P (operands[2]))
11294         return "sal{b}\t{%b2, %0|%0, %b2}";
11295       else if (operands[2] == const1_rtx
11296                && (TARGET_SHIFT1 || optimize_size))
11297         return "sal{b}\t%0";
11298       else
11299         return "sal{b}\t{%2, %0|%0, %2}";
11300     }
11301 }
11302   [(set (attr "type")
11303      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11304                           (const_int 0))
11305                       (match_operand 0 "register_operand" ""))
11306                  (match_operand 2 "const1_operand" ""))
11307               (const_string "alu")
11308            ]
11309            (const_string "ishift")))
11310    (set_attr "mode" "QI")])
11311
11312 ;; See comment above `ashldi3' about how this works.
11313
11314 (define_expand "ashrti3"
11315   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11316                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317                                 (match_operand:QI 2 "nonmemory_operand" "")))
11318               (clobber (reg:CC FLAGS_REG))])]
11319   "TARGET_64BIT"
11320 {
11321   if (! immediate_operand (operands[2], QImode))
11322     {
11323       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11324       DONE;
11325     }
11326   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11327   DONE;
11328 })
11329
11330 (define_insn "ashrti3_1"
11331   [(set (match_operand:TI 0 "register_operand" "=r")
11332         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11333                      (match_operand:QI 2 "register_operand" "c")))
11334    (clobber (match_scratch:DI 3 "=&r"))
11335    (clobber (reg:CC FLAGS_REG))]
11336   "TARGET_64BIT"
11337   "#"
11338   [(set_attr "type" "multi")])
11339
11340 (define_insn "*ashrti3_2"
11341   [(set (match_operand:TI 0 "register_operand" "=r")
11342         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11343                      (match_operand:QI 2 "immediate_operand" "O")))
11344    (clobber (reg:CC FLAGS_REG))]
11345   "TARGET_64BIT"
11346   "#"
11347   [(set_attr "type" "multi")])
11348
11349 (define_split
11350   [(set (match_operand:TI 0 "register_operand" "")
11351         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11352                      (match_operand:QI 2 "register_operand" "")))
11353    (clobber (match_scratch:DI 3 ""))
11354    (clobber (reg:CC FLAGS_REG))]
11355   "TARGET_64BIT && reload_completed"
11356   [(const_int 0)]
11357   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11358
11359 (define_split
11360   [(set (match_operand:TI 0 "register_operand" "")
11361         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11362                      (match_operand:QI 2 "immediate_operand" "")))
11363    (clobber (reg:CC FLAGS_REG))]
11364   "TARGET_64BIT && reload_completed"
11365   [(const_int 0)]
11366   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11367
11368 (define_insn "x86_64_shrd"
11369   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11370         (ior:DI (ashiftrt:DI (match_dup 0)
11371                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11372                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11373                   (minus:QI (const_int 64) (match_dup 2)))))
11374    (clobber (reg:CC FLAGS_REG))]
11375   "TARGET_64BIT"
11376   "@
11377    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11378    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11379   [(set_attr "type" "ishift")
11380    (set_attr "prefix_0f" "1")
11381    (set_attr "mode" "DI")
11382    (set_attr "athlon_decode" "vector")
11383    (set_attr "amdfam10_decode" "vector")])   
11384
11385 (define_expand "ashrdi3"
11386   [(set (match_operand:DI 0 "shiftdi_operand" "")
11387         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11388                      (match_operand:QI 2 "nonmemory_operand" "")))]
11389   ""
11390   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11391
11392 (define_insn "*ashrdi3_63_rex64"
11393   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11394         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11395                      (match_operand:DI 2 "const_int_operand" "i,i")))
11396    (clobber (reg:CC FLAGS_REG))]
11397   "TARGET_64BIT && INTVAL (operands[2]) == 63
11398    && (TARGET_USE_CLTD || optimize_size)
11399    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400   "@
11401    {cqto|cqo}
11402    sar{q}\t{%2, %0|%0, %2}"
11403   [(set_attr "type" "imovx,ishift")
11404    (set_attr "prefix_0f" "0,*")
11405    (set_attr "length_immediate" "0,*")
11406    (set_attr "modrm" "0,1")
11407    (set_attr "mode" "DI")])
11408
11409 (define_insn "*ashrdi3_1_one_bit_rex64"
11410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412                      (match_operand:QI 2 "const1_operand" "")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11415    && (TARGET_SHIFT1 || optimize_size)"
11416   "sar{q}\t%0"
11417   [(set_attr "type" "ishift")
11418    (set (attr "length") 
11419      (if_then_else (match_operand:DI 0 "register_operand" "") 
11420         (const_string "2")
11421         (const_string "*")))])
11422
11423 (define_insn "*ashrdi3_1_rex64"
11424   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11425         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11426                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11427    (clobber (reg:CC FLAGS_REG))]
11428   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11429   "@
11430    sar{q}\t{%2, %0|%0, %2}
11431    sar{q}\t{%b2, %0|%0, %b2}"
11432   [(set_attr "type" "ishift")
11433    (set_attr "mode" "DI")])
11434
11435 ;; This pattern can't accept a variable shift count, since shifts by
11436 ;; zero don't affect the flags.  We assume that shifts by constant
11437 ;; zero are optimized away.
11438 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11439   [(set (reg FLAGS_REG)
11440         (compare
11441           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442                        (match_operand:QI 2 "const1_operand" ""))
11443           (const_int 0)))
11444    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11445         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11446   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11447    && (TARGET_SHIFT1 || optimize_size)
11448    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11449   "sar{q}\t%0"
11450   [(set_attr "type" "ishift")
11451    (set (attr "length") 
11452      (if_then_else (match_operand:DI 0 "register_operand" "") 
11453         (const_string "2")
11454         (const_string "*")))])
11455
11456 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11457   [(set (reg FLAGS_REG)
11458         (compare
11459           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11460                        (match_operand:QI 2 "const1_operand" ""))
11461           (const_int 0)))
11462    (clobber (match_scratch:DI 0 "=r"))]
11463   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11464    && (TARGET_SHIFT1 || optimize_size)
11465    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11466   "sar{q}\t%0"
11467   [(set_attr "type" "ishift")
11468    (set_attr "length" "2")])
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 "*ashrdi3_cmp_rex64"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477                        (match_operand:QI 2 "const_int_operand" "n"))
11478           (const_int 0)))
11479    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11480         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11481   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11482    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11483    && (optimize_size
11484        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11485   "sar{q}\t{%2, %0|%0, %2}"
11486   [(set_attr "type" "ishift")
11487    (set_attr "mode" "DI")])
11488
11489 (define_insn "*ashrdi3_cconly_rex64"
11490   [(set (reg FLAGS_REG)
11491         (compare
11492           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11493                        (match_operand:QI 2 "const_int_operand" "n"))
11494           (const_int 0)))
11495    (clobber (match_scratch:DI 0 "=r"))]
11496   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11498    && (optimize_size
11499        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11500   "sar{q}\t{%2, %0|%0, %2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "mode" "DI")])
11503
11504 (define_insn "*ashrdi3_1"
11505   [(set (match_operand:DI 0 "register_operand" "=r")
11506         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11507                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "!TARGET_64BIT"
11510   "#"
11511   [(set_attr "type" "multi")])
11512
11513 ;; By default we don't ask for a scratch register, because when DImode
11514 ;; values are manipulated, registers are already at a premium.  But if
11515 ;; we have one handy, we won't turn it away.
11516 (define_peephole2
11517   [(match_scratch:SI 3 "r")
11518    (parallel [(set (match_operand:DI 0 "register_operand" "")
11519                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11520                                 (match_operand:QI 2 "nonmemory_operand" "")))
11521               (clobber (reg:CC FLAGS_REG))])
11522    (match_dup 3)]
11523   "!TARGET_64BIT && TARGET_CMOVE"
11524   [(const_int 0)]
11525   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11526
11527 (define_split
11528   [(set (match_operand:DI 0 "register_operand" "")
11529         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11530                      (match_operand:QI 2 "nonmemory_operand" "")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11533                      ? flow2_completed : reload_completed)"
11534   [(const_int 0)]
11535   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11536
11537 (define_insn "x86_shrd_1"
11538   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11539         (ior:SI (ashiftrt:SI (match_dup 0)
11540                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11541                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11542                   (minus:QI (const_int 32) (match_dup 2)))))
11543    (clobber (reg:CC FLAGS_REG))]
11544   ""
11545   "@
11546    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11547    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "prefix_0f" "1")
11550    (set_attr "pent_pair" "np")
11551    (set_attr "mode" "SI")])
11552
11553 (define_expand "x86_shift_adj_3"
11554   [(use (match_operand:SI 0 "register_operand" ""))
11555    (use (match_operand:SI 1 "register_operand" ""))
11556    (use (match_operand:QI 2 "register_operand" ""))]
11557   ""
11558 {
11559   rtx label = gen_label_rtx ();
11560   rtx tmp;
11561
11562   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11563
11564   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11565   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11566   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11567                               gen_rtx_LABEL_REF (VOIDmode, label),
11568                               pc_rtx);
11569   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11570   JUMP_LABEL (tmp) = label;
11571
11572   emit_move_insn (operands[0], operands[1]);
11573   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11574
11575   emit_label (label);
11576   LABEL_NUSES (label) = 1;
11577
11578   DONE;
11579 })
11580
11581 (define_insn "ashrsi3_31"
11582   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11583         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11584                      (match_operand:SI 2 "const_int_operand" "i,i")))
11585    (clobber (reg:CC FLAGS_REG))]
11586   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11587    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11588   "@
11589    {cltd|cdq}
11590    sar{l}\t{%2, %0|%0, %2}"
11591   [(set_attr "type" "imovx,ishift")
11592    (set_attr "prefix_0f" "0,*")
11593    (set_attr "length_immediate" "0,*")
11594    (set_attr "modrm" "0,1")
11595    (set_attr "mode" "SI")])
11596
11597 (define_insn "*ashrsi3_31_zext"
11598   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11599         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11600                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11603    && INTVAL (operands[2]) == 31
11604    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605   "@
11606    {cltd|cdq}
11607    sar{l}\t{%2, %k0|%k0, %2}"
11608   [(set_attr "type" "imovx,ishift")
11609    (set_attr "prefix_0f" "0,*")
11610    (set_attr "length_immediate" "0,*")
11611    (set_attr "modrm" "0,1")
11612    (set_attr "mode" "SI")])
11613
11614 (define_expand "ashrsi3"
11615   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11616         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11617                      (match_operand:QI 2 "nonmemory_operand" "")))
11618    (clobber (reg:CC FLAGS_REG))]
11619   ""
11620   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11621
11622 (define_insn "*ashrsi3_1_one_bit"
11623   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11624         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11625                      (match_operand:QI 2 "const1_operand" "")))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11628    && (TARGET_SHIFT1 || optimize_size)"
11629   "sar{l}\t%0"
11630   [(set_attr "type" "ishift")
11631    (set (attr "length") 
11632      (if_then_else (match_operand:SI 0 "register_operand" "") 
11633         (const_string "2")
11634         (const_string "*")))])
11635
11636 (define_insn "*ashrsi3_1_one_bit_zext"
11637   [(set (match_operand:DI 0 "register_operand" "=r")
11638         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11639                                      (match_operand:QI 2 "const1_operand" ""))))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11642    && (TARGET_SHIFT1 || optimize_size)"
11643   "sar{l}\t%k0"
11644   [(set_attr "type" "ishift")
11645    (set_attr "length" "2")])
11646
11647 (define_insn "*ashrsi3_1"
11648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11649         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11650                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11651    (clobber (reg:CC FLAGS_REG))]
11652   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653   "@
11654    sar{l}\t{%2, %0|%0, %2}
11655    sar{l}\t{%b2, %0|%0, %b2}"
11656   [(set_attr "type" "ishift")
11657    (set_attr "mode" "SI")])
11658
11659 (define_insn "*ashrsi3_1_zext"
11660   [(set (match_operand:DI 0 "register_operand" "=r,r")
11661         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11662                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11663    (clobber (reg:CC FLAGS_REG))]
11664   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11665   "@
11666    sar{l}\t{%2, %k0|%k0, %2}
11667    sar{l}\t{%b2, %k0|%k0, %b2}"
11668   [(set_attr "type" "ishift")
11669    (set_attr "mode" "SI")])
11670
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags.  We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*ashrsi3_one_bit_cmp"
11675   [(set (reg FLAGS_REG)
11676         (compare
11677           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11678                        (match_operand:QI 2 "const1_operand" ""))
11679           (const_int 0)))
11680    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11681         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11682   "ix86_match_ccmode (insn, CCGOCmode)
11683    && (TARGET_SHIFT1 || optimize_size)
11684    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11685   "sar{l}\t%0"
11686   [(set_attr "type" "ishift")
11687    (set (attr "length") 
11688      (if_then_else (match_operand:SI 0 "register_operand" "") 
11689         (const_string "2")
11690         (const_string "*")))])
11691
11692 (define_insn "*ashrsi3_one_bit_cconly"
11693   [(set (reg FLAGS_REG)
11694         (compare
11695           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696                        (match_operand:QI 2 "const1_operand" ""))
11697           (const_int 0)))
11698    (clobber (match_scratch:SI 0 "=r"))]
11699   "ix86_match_ccmode (insn, CCGOCmode)
11700    && (TARGET_SHIFT1 || optimize_size)
11701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702   "sar{l}\t%0"
11703   [(set_attr "type" "ishift")
11704    (set_attr "length" "2")])
11705
11706 (define_insn "*ashrsi3_one_bit_cmp_zext"
11707   [(set (reg FLAGS_REG)
11708         (compare
11709           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710                        (match_operand:QI 2 "const1_operand" ""))
11711           (const_int 0)))
11712    (set (match_operand:DI 0 "register_operand" "=r")
11713         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11715    && (TARGET_SHIFT1 || optimize_size)
11716    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11717   "sar{l}\t%k0"
11718   [(set_attr "type" "ishift")
11719    (set_attr "length" "2")])
11720
11721 ;; This pattern can't accept a variable shift count, since shifts by
11722 ;; zero don't affect the flags.  We assume that shifts by constant
11723 ;; zero are optimized away.
11724 (define_insn "*ashrsi3_cmp"
11725   [(set (reg FLAGS_REG)
11726         (compare
11727           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11729           (const_int 0)))
11730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732   "ix86_match_ccmode (insn, CCGOCmode)
11733    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11734    && (optimize_size
11735        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11736   "sar{l}\t{%2, %0|%0, %2}"
11737   [(set_attr "type" "ishift")
11738    (set_attr "mode" "SI")])
11739
11740 (define_insn "*ashrsi3_cconly"
11741   [(set (reg FLAGS_REG)
11742         (compare
11743           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11744                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11745           (const_int 0)))
11746    (clobber (match_scratch:SI 0 "=r"))]
11747   "ix86_match_ccmode (insn, CCGOCmode)
11748    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11749    && (optimize_size
11750        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11751   "sar{l}\t{%2, %0|%0, %2}"
11752   [(set_attr "type" "ishift")
11753    (set_attr "mode" "SI")])
11754
11755 (define_insn "*ashrsi3_cmp_zext"
11756   [(set (reg FLAGS_REG)
11757         (compare
11758           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11759                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11760           (const_int 0)))
11761    (set (match_operand:DI 0 "register_operand" "=r")
11762         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11763   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11764    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11765    && (optimize_size
11766        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11767   "sar{l}\t{%2, %k0|%k0, %2}"
11768   [(set_attr "type" "ishift")
11769    (set_attr "mode" "SI")])
11770
11771 (define_expand "ashrhi3"
11772   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11773         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11774                      (match_operand:QI 2 "nonmemory_operand" "")))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "TARGET_HIMODE_MATH"
11777   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11778
11779 (define_insn "*ashrhi3_1_one_bit"
11780   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11781         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782                      (match_operand:QI 2 "const1_operand" "")))
11783    (clobber (reg:CC FLAGS_REG))]
11784   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11785    && (TARGET_SHIFT1 || optimize_size)"
11786   "sar{w}\t%0"
11787   [(set_attr "type" "ishift")
11788    (set (attr "length") 
11789      (if_then_else (match_operand 0 "register_operand" "") 
11790         (const_string "2")
11791         (const_string "*")))])
11792
11793 (define_insn "*ashrhi3_1"
11794   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11795         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11796                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11799   "@
11800    sar{w}\t{%2, %0|%0, %2}
11801    sar{w}\t{%b2, %0|%0, %b2}"
11802   [(set_attr "type" "ishift")
11803    (set_attr "mode" "HI")])
11804
11805 ;; This pattern can't accept a variable shift count, since shifts by
11806 ;; zero don't affect the flags.  We assume that shifts by constant
11807 ;; zero are optimized away.
11808 (define_insn "*ashrhi3_one_bit_cmp"
11809   [(set (reg FLAGS_REG)
11810         (compare
11811           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812                        (match_operand:QI 2 "const1_operand" ""))
11813           (const_int 0)))
11814    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11816   "ix86_match_ccmode (insn, CCGOCmode)
11817    && (TARGET_SHIFT1 || optimize_size)
11818    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11819   "sar{w}\t%0"
11820   [(set_attr "type" "ishift")
11821    (set (attr "length") 
11822      (if_then_else (match_operand 0 "register_operand" "") 
11823         (const_string "2")
11824         (const_string "*")))])
11825
11826 (define_insn "*ashrhi3_one_bit_cconly"
11827   [(set (reg FLAGS_REG)
11828         (compare
11829           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11830                        (match_operand:QI 2 "const1_operand" ""))
11831           (const_int 0)))
11832    (clobber (match_scratch:HI 0 "=r"))]
11833   "ix86_match_ccmode (insn, CCGOCmode)
11834    && (TARGET_SHIFT1 || optimize_size)
11835    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11836   "sar{w}\t%0"
11837   [(set_attr "type" "ishift")
11838    (set_attr "length" "2")])
11839
11840 ;; This pattern can't accept a variable shift count, since shifts by
11841 ;; zero don't affect the flags.  We assume that shifts by constant
11842 ;; zero are optimized away.
11843 (define_insn "*ashrhi3_cmp"
11844   [(set (reg FLAGS_REG)
11845         (compare
11846           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11848           (const_int 0)))
11849    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11851   "ix86_match_ccmode (insn, CCGOCmode)
11852    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11853    && (optimize_size
11854        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11855   "sar{w}\t{%2, %0|%0, %2}"
11856   [(set_attr "type" "ishift")
11857    (set_attr "mode" "HI")])
11858
11859 (define_insn "*ashrhi3_cconly"
11860   [(set (reg FLAGS_REG)
11861         (compare
11862           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11864           (const_int 0)))
11865    (clobber (match_scratch:HI 0 "=r"))]
11866   "ix86_match_ccmode (insn, CCGOCmode)
11867    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11868    && (optimize_size
11869        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870   "sar{w}\t{%2, %0|%0, %2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "HI")])
11873
11874 (define_expand "ashrqi3"
11875   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11876         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11877                      (match_operand:QI 2 "nonmemory_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_QIMODE_MATH"
11880   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11881
11882 (define_insn "*ashrqi3_1_one_bit"
11883   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11885                      (match_operand:QI 2 "const1_operand" "")))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "sar{b}\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 "*ashrqi3_1_one_bit_slp"
11897   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11898         (ashiftrt:QI (match_dup 0)
11899                      (match_operand:QI 1 "const1_operand" "")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11902    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11903    && (TARGET_SHIFT1 || optimize_size)"
11904   "sar{b}\t%0"
11905   [(set_attr "type" "ishift1")
11906    (set (attr "length") 
11907      (if_then_else (match_operand 0 "register_operand" "") 
11908         (const_string "2")
11909         (const_string "*")))])
11910
11911 (define_insn "*ashrqi3_1"
11912   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11913         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11914                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11915    (clobber (reg:CC FLAGS_REG))]
11916   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11917   "@
11918    sar{b}\t{%2, %0|%0, %2}
11919    sar{b}\t{%b2, %0|%0, %b2}"
11920   [(set_attr "type" "ishift")
11921    (set_attr "mode" "QI")])
11922
11923 (define_insn "*ashrqi3_1_slp"
11924   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11925         (ashiftrt:QI (match_dup 0)
11926                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11929    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11930   "@
11931    sar{b}\t{%1, %0|%0, %1}
11932    sar{b}\t{%b1, %0|%0, %b1}"
11933   [(set_attr "type" "ishift1")
11934    (set_attr "mode" "QI")])
11935
11936 ;; This pattern can't accept a variable shift count, since shifts by
11937 ;; zero don't affect the flags.  We assume that shifts by constant
11938 ;; zero are optimized away.
11939 (define_insn "*ashrqi3_one_bit_cmp"
11940   [(set (reg FLAGS_REG)
11941         (compare
11942           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11943                        (match_operand:QI 2 "const1_operand" "I"))
11944           (const_int 0)))
11945    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11947   "ix86_match_ccmode (insn, CCGOCmode)
11948    && (TARGET_SHIFT1 || optimize_size)
11949    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11950   "sar{b}\t%0"
11951   [(set_attr "type" "ishift")
11952    (set (attr "length") 
11953      (if_then_else (match_operand 0 "register_operand" "") 
11954         (const_string "2")
11955         (const_string "*")))])
11956
11957 (define_insn "*ashrqi3_one_bit_cconly"
11958   [(set (reg FLAGS_REG)
11959         (compare
11960           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11961                        (match_operand:QI 2 "const1_operand" "I"))
11962           (const_int 0)))
11963    (clobber (match_scratch:QI 0 "=q"))]
11964   "ix86_match_ccmode (insn, CCGOCmode)
11965    && (TARGET_SHIFT1 || optimize_size)
11966    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11967   "sar{b}\t%0"
11968   [(set_attr "type" "ishift")
11969    (set_attr "length" "2")])
11970
11971 ;; This pattern can't accept a variable shift count, since shifts by
11972 ;; zero don't affect the flags.  We assume that shifts by constant
11973 ;; zero are optimized away.
11974 (define_insn "*ashrqi3_cmp"
11975   [(set (reg FLAGS_REG)
11976         (compare
11977           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11978                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11979           (const_int 0)))
11980    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11981         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11982   "ix86_match_ccmode (insn, CCGOCmode)
11983    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11984    && (optimize_size
11985        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11986   "sar{b}\t{%2, %0|%0, %2}"
11987   [(set_attr "type" "ishift")
11988    (set_attr "mode" "QI")])
11989
11990 (define_insn "*ashrqi3_cconly"
11991   [(set (reg FLAGS_REG)
11992         (compare
11993           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995           (const_int 0)))
11996    (clobber (match_scratch:QI 0 "=q"))]
11997   "ix86_match_ccmode (insn, CCGOCmode)
11998    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11999    && (optimize_size
12000        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12001   "sar{b}\t{%2, %0|%0, %2}"
12002   [(set_attr "type" "ishift")
12003    (set_attr "mode" "QI")])
12004
12005 \f
12006 ;; Logical shift instructions
12007
12008 ;; See comment above `ashldi3' about how this works.
12009
12010 (define_expand "lshrti3"
12011   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12012                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12013                                 (match_operand:QI 2 "nonmemory_operand" "")))
12014               (clobber (reg:CC FLAGS_REG))])]
12015   "TARGET_64BIT"
12016 {
12017   if (! immediate_operand (operands[2], QImode))
12018     {
12019       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12020       DONE;
12021     }
12022   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12023   DONE;
12024 })
12025
12026 (define_insn "lshrti3_1"
12027   [(set (match_operand:TI 0 "register_operand" "=r")
12028         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12029                      (match_operand:QI 2 "register_operand" "c")))
12030    (clobber (match_scratch:DI 3 "=&r"))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "TARGET_64BIT"
12033   "#"
12034   [(set_attr "type" "multi")])
12035
12036 (define_insn "*lshrti3_2"
12037   [(set (match_operand:TI 0 "register_operand" "=r")
12038         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12039                      (match_operand:QI 2 "immediate_operand" "O")))
12040    (clobber (reg:CC FLAGS_REG))]
12041   "TARGET_64BIT"
12042   "#"
12043   [(set_attr "type" "multi")])
12044
12045 (define_split 
12046   [(set (match_operand:TI 0 "register_operand" "")
12047         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12048                      (match_operand:QI 2 "register_operand" "")))
12049    (clobber (match_scratch:DI 3 ""))
12050    (clobber (reg:CC FLAGS_REG))]
12051   "TARGET_64BIT && reload_completed"
12052   [(const_int 0)]
12053   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12054
12055 (define_split 
12056   [(set (match_operand:TI 0 "register_operand" "")
12057         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12058                      (match_operand:QI 2 "immediate_operand" "")))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "TARGET_64BIT && reload_completed"
12061   [(const_int 0)]
12062   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12063
12064 (define_expand "lshrdi3"
12065   [(set (match_operand:DI 0 "shiftdi_operand" "")
12066         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12067                      (match_operand:QI 2 "nonmemory_operand" "")))]
12068   ""
12069   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12070
12071 (define_insn "*lshrdi3_1_one_bit_rex64"
12072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074                      (match_operand:QI 2 "const1_operand" "")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12077    && (TARGET_SHIFT1 || optimize_size)"
12078   "shr{q}\t%0"
12079   [(set_attr "type" "ishift")
12080    (set (attr "length") 
12081      (if_then_else (match_operand:DI 0 "register_operand" "") 
12082         (const_string "2")
12083         (const_string "*")))])
12084
12085 (define_insn "*lshrdi3_1_rex64"
12086   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12087         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12088                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091   "@
12092    shr{q}\t{%2, %0|%0, %2}
12093    shr{q}\t{%b2, %0|%0, %b2}"
12094   [(set_attr "type" "ishift")
12095    (set_attr "mode" "DI")])
12096
12097 ;; This pattern can't accept a variable shift count, since shifts by
12098 ;; zero don't affect the flags.  We assume that shifts by constant
12099 ;; zero are optimized away.
12100 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12101   [(set (reg FLAGS_REG)
12102         (compare
12103           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12104                        (match_operand:QI 2 "const1_operand" ""))
12105           (const_int 0)))
12106    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12107         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12108   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12109    && (TARGET_SHIFT1 || optimize_size)
12110    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12111   "shr{q}\t%0"
12112   [(set_attr "type" "ishift")
12113    (set (attr "length") 
12114      (if_then_else (match_operand:DI 0 "register_operand" "") 
12115         (const_string "2")
12116         (const_string "*")))])
12117
12118 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12119   [(set (reg FLAGS_REG)
12120         (compare
12121           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12122                        (match_operand:QI 2 "const1_operand" ""))
12123           (const_int 0)))
12124    (clobber (match_scratch:DI 0 "=r"))]
12125   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12126    && (TARGET_SHIFT1 || optimize_size)
12127    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12128   "shr{q}\t%0"
12129   [(set_attr "type" "ishift")
12130    (set_attr "length" "2")])
12131
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags.  We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*lshrdi3_cmp_rex64"
12136   [(set (reg FLAGS_REG)
12137         (compare
12138           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12139                        (match_operand:QI 2 "const_int_operand" "e"))
12140           (const_int 0)))
12141    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12143   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12144    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12145    && (optimize_size
12146        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12147   "shr{q}\t{%2, %0|%0, %2}"
12148   [(set_attr "type" "ishift")
12149    (set_attr "mode" "DI")])
12150
12151 (define_insn "*lshrdi3_cconly_rex64"
12152   [(set (reg FLAGS_REG)
12153         (compare
12154           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12155                        (match_operand:QI 2 "const_int_operand" "e"))
12156           (const_int 0)))
12157    (clobber (match_scratch:DI 0 "=r"))]
12158   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12160    && (optimize_size
12161        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12162   "shr{q}\t{%2, %0|%0, %2}"
12163   [(set_attr "type" "ishift")
12164    (set_attr "mode" "DI")])
12165
12166 (define_insn "*lshrdi3_1"
12167   [(set (match_operand:DI 0 "register_operand" "=r")
12168         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12169                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12170    (clobber (reg:CC FLAGS_REG))]
12171   "!TARGET_64BIT"
12172   "#"
12173   [(set_attr "type" "multi")])
12174
12175 ;; By default we don't ask for a scratch register, because when DImode
12176 ;; values are manipulated, registers are already at a premium.  But if
12177 ;; we have one handy, we won't turn it away.
12178 (define_peephole2
12179   [(match_scratch:SI 3 "r")
12180    (parallel [(set (match_operand:DI 0 "register_operand" "")
12181                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12182                                 (match_operand:QI 2 "nonmemory_operand" "")))
12183               (clobber (reg:CC FLAGS_REG))])
12184    (match_dup 3)]
12185   "!TARGET_64BIT && TARGET_CMOVE"
12186   [(const_int 0)]
12187   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12188
12189 (define_split 
12190   [(set (match_operand:DI 0 "register_operand" "")
12191         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12192                      (match_operand:QI 2 "nonmemory_operand" "")))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12195                      ? flow2_completed : reload_completed)"
12196   [(const_int 0)]
12197   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12198
12199 (define_expand "lshrsi3"
12200   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12201         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12202                      (match_operand:QI 2 "nonmemory_operand" "")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   ""
12205   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12206
12207 (define_insn "*lshrsi3_1_one_bit"
12208   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12210                      (match_operand:QI 2 "const1_operand" "")))
12211    (clobber (reg:CC FLAGS_REG))]
12212   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12213    && (TARGET_SHIFT1 || optimize_size)"
12214   "shr{l}\t%0"
12215   [(set_attr "type" "ishift")
12216    (set (attr "length") 
12217      (if_then_else (match_operand:SI 0 "register_operand" "") 
12218         (const_string "2")
12219         (const_string "*")))])
12220
12221 (define_insn "*lshrsi3_1_one_bit_zext"
12222   [(set (match_operand:DI 0 "register_operand" "=r")
12223         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12224                      (match_operand:QI 2 "const1_operand" "")))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12227    && (TARGET_SHIFT1 || optimize_size)"
12228   "shr{l}\t%k0"
12229   [(set_attr "type" "ishift")
12230    (set_attr "length" "2")])
12231
12232 (define_insn "*lshrsi3_1"
12233   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12234         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12235                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238   "@
12239    shr{l}\t{%2, %0|%0, %2}
12240    shr{l}\t{%b2, %0|%0, %b2}"
12241   [(set_attr "type" "ishift")
12242    (set_attr "mode" "SI")])
12243
12244 (define_insn "*lshrsi3_1_zext"
12245   [(set (match_operand:DI 0 "register_operand" "=r,r")
12246         (zero_extend:DI
12247           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12248                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251   "@
12252    shr{l}\t{%2, %k0|%k0, %2}
12253    shr{l}\t{%b2, %k0|%k0, %b2}"
12254   [(set_attr "type" "ishift")
12255    (set_attr "mode" "SI")])
12256
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags.  We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrsi3_one_bit_cmp"
12261   [(set (reg FLAGS_REG)
12262         (compare
12263           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264                        (match_operand:QI 2 "const1_operand" ""))
12265           (const_int 0)))
12266    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12268   "ix86_match_ccmode (insn, CCGOCmode)
12269    && (TARGET_SHIFT1 || optimize_size)
12270    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12271   "shr{l}\t%0"
12272   [(set_attr "type" "ishift")
12273    (set (attr "length") 
12274      (if_then_else (match_operand:SI 0 "register_operand" "") 
12275         (const_string "2")
12276         (const_string "*")))])
12277
12278 (define_insn "*lshrsi3_one_bit_cconly"
12279   [(set (reg FLAGS_REG)
12280         (compare
12281           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282                        (match_operand:QI 2 "const1_operand" ""))
12283           (const_int 0)))
12284    (clobber (match_scratch:SI 0 "=r"))]
12285   "ix86_match_ccmode (insn, CCGOCmode)
12286    && (TARGET_SHIFT1 || optimize_size)
12287    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288   "shr{l}\t%0"
12289   [(set_attr "type" "ishift")
12290    (set_attr "length" "2")])
12291
12292 (define_insn "*lshrsi3_cmp_one_bit_zext"
12293   [(set (reg FLAGS_REG)
12294         (compare
12295           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296                        (match_operand:QI 2 "const1_operand" ""))
12297           (const_int 0)))
12298    (set (match_operand:DI 0 "register_operand" "=r")
12299         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301    && (TARGET_SHIFT1 || optimize_size)
12302    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303   "shr{l}\t%k0"
12304   [(set_attr "type" "ishift")
12305    (set_attr "length" "2")])
12306
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags.  We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrsi3_cmp"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12315           (const_int 0)))
12316    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318   "ix86_match_ccmode (insn, CCGOCmode)
12319    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12320    && (optimize_size
12321        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12322   "shr{l}\t{%2, %0|%0, %2}"
12323   [(set_attr "type" "ishift")
12324    (set_attr "mode" "SI")])
12325
12326 (define_insn "*lshrsi3_cconly"
12327   [(set (reg FLAGS_REG)
12328       (compare
12329         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331         (const_int 0)))
12332    (clobber (match_scratch:SI 0 "=r"))]
12333   "ix86_match_ccmode (insn, CCGOCmode)
12334    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12335    && (optimize_size
12336        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12337   "shr{l}\t{%2, %0|%0, %2}"
12338   [(set_attr "type" "ishift")
12339    (set_attr "mode" "SI")])
12340
12341 (define_insn "*lshrsi3_cmp_zext"
12342   [(set (reg FLAGS_REG)
12343         (compare
12344           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12345                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346           (const_int 0)))
12347    (set (match_operand:DI 0 "register_operand" "=r")
12348         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12349   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12350    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12351    && (optimize_size
12352        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353   "shr{l}\t{%2, %k0|%k0, %2}"
12354   [(set_attr "type" "ishift")
12355    (set_attr "mode" "SI")])
12356
12357 (define_expand "lshrhi3"
12358   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12359         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12360                      (match_operand:QI 2 "nonmemory_operand" "")))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_HIMODE_MATH"
12363   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12364
12365 (define_insn "*lshrhi3_1_one_bit"
12366   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                      (match_operand:QI 2 "const1_operand" "")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "shr{w}\t%0"
12373   [(set_attr "type" "ishift")
12374    (set (attr "length") 
12375      (if_then_else (match_operand 0 "register_operand" "") 
12376         (const_string "2")
12377         (const_string "*")))])
12378
12379 (define_insn "*lshrhi3_1"
12380   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12381         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12382                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385   "@
12386    shr{w}\t{%2, %0|%0, %2}
12387    shr{w}\t{%b2, %0|%0, %b2}"
12388   [(set_attr "type" "ishift")
12389    (set_attr "mode" "HI")])
12390
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags.  We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrhi3_one_bit_cmp"
12395   [(set (reg FLAGS_REG)
12396         (compare
12397           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398                        (match_operand:QI 2 "const1_operand" ""))
12399           (const_int 0)))
12400    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12402   "ix86_match_ccmode (insn, CCGOCmode)
12403    && (TARGET_SHIFT1 || optimize_size)
12404    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405   "shr{w}\t%0"
12406   [(set_attr "type" "ishift")
12407    (set (attr "length") 
12408      (if_then_else (match_operand:SI 0 "register_operand" "") 
12409         (const_string "2")
12410         (const_string "*")))])
12411
12412 (define_insn "*lshrhi3_one_bit_cconly"
12413   [(set (reg FLAGS_REG)
12414         (compare
12415           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416                        (match_operand:QI 2 "const1_operand" ""))
12417           (const_int 0)))
12418    (clobber (match_scratch:HI 0 "=r"))]
12419   "ix86_match_ccmode (insn, CCGOCmode)
12420    && (TARGET_SHIFT1 || optimize_size)
12421    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12422   "shr{w}\t%0"
12423   [(set_attr "type" "ishift")
12424    (set_attr "length" "2")])
12425
12426 ;; This pattern can't accept a variable shift count, since shifts by
12427 ;; zero don't affect the flags.  We assume that shifts by constant
12428 ;; zero are optimized away.
12429 (define_insn "*lshrhi3_cmp"
12430   [(set (reg FLAGS_REG)
12431         (compare
12432           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12433                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12434           (const_int 0)))
12435    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12436         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12437   "ix86_match_ccmode (insn, CCGOCmode)
12438    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12439    && (optimize_size
12440        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12441   "shr{w}\t{%2, %0|%0, %2}"
12442   [(set_attr "type" "ishift")
12443    (set_attr "mode" "HI")])
12444
12445 (define_insn "*lshrhi3_cconly"
12446   [(set (reg FLAGS_REG)
12447         (compare
12448           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12449                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12450           (const_int 0)))
12451    (clobber (match_scratch:HI 0 "=r"))]
12452   "ix86_match_ccmode (insn, CCGOCmode)
12453    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12454    && (optimize_size
12455        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12456   "shr{w}\t{%2, %0|%0, %2}"
12457   [(set_attr "type" "ishift")
12458    (set_attr "mode" "HI")])
12459
12460 (define_expand "lshrqi3"
12461   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12462         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12463                      (match_operand:QI 2 "nonmemory_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "TARGET_QIMODE_MATH"
12466   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12467
12468 (define_insn "*lshrqi3_1_one_bit"
12469   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12471                      (match_operand:QI 2 "const1_operand" "")))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474    && (TARGET_SHIFT1 || optimize_size)"
12475   "shr{b}\t%0"
12476   [(set_attr "type" "ishift")
12477    (set (attr "length") 
12478      (if_then_else (match_operand 0 "register_operand" "") 
12479         (const_string "2")
12480         (const_string "*")))])
12481
12482 (define_insn "*lshrqi3_1_one_bit_slp"
12483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12484         (lshiftrt:QI (match_dup 0)
12485                      (match_operand:QI 1 "const1_operand" "")))
12486    (clobber (reg:CC FLAGS_REG))]
12487   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488    && (TARGET_SHIFT1 || optimize_size)"
12489   "shr{b}\t%0"
12490   [(set_attr "type" "ishift1")
12491    (set (attr "length") 
12492      (if_then_else (match_operand 0 "register_operand" "") 
12493         (const_string "2")
12494         (const_string "*")))])
12495
12496 (define_insn "*lshrqi3_1"
12497   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12498         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12499                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12500    (clobber (reg:CC FLAGS_REG))]
12501   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12502   "@
12503    shr{b}\t{%2, %0|%0, %2}
12504    shr{b}\t{%b2, %0|%0, %b2}"
12505   [(set_attr "type" "ishift")
12506    (set_attr "mode" "QI")])
12507
12508 (define_insn "*lshrqi3_1_slp"
12509   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12510         (lshiftrt:QI (match_dup 0)
12511                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12512    (clobber (reg:CC FLAGS_REG))]
12513   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12514    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12515   "@
12516    shr{b}\t{%1, %0|%0, %1}
12517    shr{b}\t{%b1, %0|%0, %b1}"
12518   [(set_attr "type" "ishift1")
12519    (set_attr "mode" "QI")])
12520
12521 ;; This pattern can't accept a variable shift count, since shifts by
12522 ;; zero don't affect the flags.  We assume that shifts by constant
12523 ;; zero are optimized away.
12524 (define_insn "*lshrqi2_one_bit_cmp"
12525   [(set (reg FLAGS_REG)
12526         (compare
12527           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528                        (match_operand:QI 2 "const1_operand" ""))
12529           (const_int 0)))
12530    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12531         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12532   "ix86_match_ccmode (insn, CCGOCmode)
12533    && (TARGET_SHIFT1 || optimize_size)
12534    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12535   "shr{b}\t%0"
12536   [(set_attr "type" "ishift")
12537    (set (attr "length") 
12538      (if_then_else (match_operand:SI 0 "register_operand" "") 
12539         (const_string "2")
12540         (const_string "*")))])
12541
12542 (define_insn "*lshrqi2_one_bit_cconly"
12543   [(set (reg FLAGS_REG)
12544         (compare
12545           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546                        (match_operand:QI 2 "const1_operand" ""))
12547           (const_int 0)))
12548    (clobber (match_scratch:QI 0 "=q"))]
12549   "ix86_match_ccmode (insn, CCGOCmode)
12550    && (TARGET_SHIFT1 || optimize_size)
12551    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12552   "shr{b}\t%0"
12553   [(set_attr "type" "ishift")
12554    (set_attr "length" "2")])
12555
12556 ;; This pattern can't accept a variable shift count, since shifts by
12557 ;; zero don't affect the flags.  We assume that shifts by constant
12558 ;; zero are optimized away.
12559 (define_insn "*lshrqi2_cmp"
12560   [(set (reg FLAGS_REG)
12561         (compare
12562           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12564           (const_int 0)))
12565    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12567   "ix86_match_ccmode (insn, CCGOCmode)
12568    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12569    && (optimize_size
12570        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12571   "shr{b}\t{%2, %0|%0, %2}"
12572   [(set_attr "type" "ishift")
12573    (set_attr "mode" "QI")])
12574
12575 (define_insn "*lshrqi2_cconly"
12576   [(set (reg FLAGS_REG)
12577         (compare
12578           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12580           (const_int 0)))
12581    (clobber (match_scratch:QI 0 "=q"))]
12582   "ix86_match_ccmode (insn, CCGOCmode)
12583    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12584    && (optimize_size
12585        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12586   "shr{b}\t{%2, %0|%0, %2}"
12587   [(set_attr "type" "ishift")
12588    (set_attr "mode" "QI")])
12589 \f
12590 ;; Rotate instructions
12591
12592 (define_expand "rotldi3"
12593   [(set (match_operand:DI 0 "shiftdi_operand" "")
12594         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12595                    (match_operand:QI 2 "nonmemory_operand" "")))
12596    (clobber (reg:CC FLAGS_REG))]
12597  ""
12598 {
12599   if (TARGET_64BIT)
12600     {
12601       ix86_expand_binary_operator (ROTATE, DImode, operands);
12602       DONE;
12603     }
12604   if (!const_1_to_31_operand (operands[2], VOIDmode))
12605     FAIL;
12606   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12607   DONE;
12608 })
12609
12610 ;; Implement rotation using two double-precision shift instructions
12611 ;; and a scratch register.   
12612 (define_insn_and_split "ix86_rotldi3"
12613  [(set (match_operand:DI 0 "register_operand" "=r")
12614        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12615                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12616   (clobber (reg:CC FLAGS_REG))
12617   (clobber (match_scratch:SI 3 "=&r"))]
12618  "!TARGET_64BIT"
12619  "" 
12620  "&& reload_completed"
12621  [(set (match_dup 3) (match_dup 4))
12622   (parallel
12623    [(set (match_dup 4)
12624          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12625                  (lshiftrt:SI (match_dup 5)
12626                               (minus:QI (const_int 32) (match_dup 2)))))
12627     (clobber (reg:CC FLAGS_REG))])
12628   (parallel
12629    [(set (match_dup 5)
12630          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12631                  (lshiftrt:SI (match_dup 3)
12632                               (minus:QI (const_int 32) (match_dup 2)))))
12633     (clobber (reg:CC FLAGS_REG))])]
12634  "split_di (operands, 1, operands + 4, operands + 5);")
12635  
12636 (define_insn "*rotlsi3_1_one_bit_rex64"
12637   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12638         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12639                    (match_operand:QI 2 "const1_operand" "")))
12640    (clobber (reg:CC FLAGS_REG))]
12641   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12642    && (TARGET_SHIFT1 || optimize_size)"
12643   "rol{q}\t%0"
12644   [(set_attr "type" "rotate")
12645    (set (attr "length") 
12646      (if_then_else (match_operand:DI 0 "register_operand" "") 
12647         (const_string "2")
12648         (const_string "*")))])
12649
12650 (define_insn "*rotldi3_1_rex64"
12651   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12652         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12653                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12656   "@
12657    rol{q}\t{%2, %0|%0, %2}
12658    rol{q}\t{%b2, %0|%0, %b2}"
12659   [(set_attr "type" "rotate")
12660    (set_attr "mode" "DI")])
12661
12662 (define_expand "rotlsi3"
12663   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12664         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12665                    (match_operand:QI 2 "nonmemory_operand" "")))
12666    (clobber (reg:CC FLAGS_REG))]
12667   ""
12668   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12669
12670 (define_insn "*rotlsi3_1_one_bit"
12671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12672         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12673                    (match_operand:QI 2 "const1_operand" "")))
12674    (clobber (reg:CC FLAGS_REG))]
12675   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12676    && (TARGET_SHIFT1 || optimize_size)"
12677   "rol{l}\t%0"
12678   [(set_attr "type" "rotate")
12679    (set (attr "length") 
12680      (if_then_else (match_operand:SI 0 "register_operand" "") 
12681         (const_string "2")
12682         (const_string "*")))])
12683
12684 (define_insn "*rotlsi3_1_one_bit_zext"
12685   [(set (match_operand:DI 0 "register_operand" "=r")
12686         (zero_extend:DI
12687           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12688                      (match_operand:QI 2 "const1_operand" ""))))
12689    (clobber (reg:CC FLAGS_REG))]
12690   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12691    && (TARGET_SHIFT1 || optimize_size)"
12692   "rol{l}\t%k0"
12693   [(set_attr "type" "rotate")
12694    (set_attr "length" "2")])
12695
12696 (define_insn "*rotlsi3_1"
12697   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12698         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12699                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12702   "@
12703    rol{l}\t{%2, %0|%0, %2}
12704    rol{l}\t{%b2, %0|%0, %b2}"
12705   [(set_attr "type" "rotate")
12706    (set_attr "mode" "SI")])
12707
12708 (define_insn "*rotlsi3_1_zext"
12709   [(set (match_operand:DI 0 "register_operand" "=r,r")
12710         (zero_extend:DI
12711           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12712                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12713    (clobber (reg:CC FLAGS_REG))]
12714   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12715   "@
12716    rol{l}\t{%2, %k0|%k0, %2}
12717    rol{l}\t{%b2, %k0|%k0, %b2}"
12718   [(set_attr "type" "rotate")
12719    (set_attr "mode" "SI")])
12720
12721 (define_expand "rotlhi3"
12722   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12723         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12724                    (match_operand:QI 2 "nonmemory_operand" "")))
12725    (clobber (reg:CC FLAGS_REG))]
12726   "TARGET_HIMODE_MATH"
12727   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12728
12729 (define_insn "*rotlhi3_1_one_bit"
12730   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12731         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12732                    (match_operand:QI 2 "const1_operand" "")))
12733    (clobber (reg:CC FLAGS_REG))]
12734   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12735    && (TARGET_SHIFT1 || optimize_size)"
12736   "rol{w}\t%0"
12737   [(set_attr "type" "rotate")
12738    (set (attr "length") 
12739      (if_then_else (match_operand 0 "register_operand" "") 
12740         (const_string "2")
12741         (const_string "*")))])
12742
12743 (define_insn "*rotlhi3_1"
12744   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12745         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12746                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12747    (clobber (reg:CC FLAGS_REG))]
12748   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12749   "@
12750    rol{w}\t{%2, %0|%0, %2}
12751    rol{w}\t{%b2, %0|%0, %b2}"
12752   [(set_attr "type" "rotate")
12753    (set_attr "mode" "HI")])
12754
12755 (define_expand "rotlqi3"
12756   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12757         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12758                    (match_operand:QI 2 "nonmemory_operand" "")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "TARGET_QIMODE_MATH"
12761   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12762
12763 (define_insn "*rotlqi3_1_one_bit_slp"
12764   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12765         (rotate:QI (match_dup 0)
12766                    (match_operand:QI 1 "const1_operand" "")))
12767    (clobber (reg:CC FLAGS_REG))]
12768   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12769    && (TARGET_SHIFT1 || optimize_size)"
12770   "rol{b}\t%0"
12771   [(set_attr "type" "rotate1")
12772    (set (attr "length") 
12773      (if_then_else (match_operand 0 "register_operand" "") 
12774         (const_string "2")
12775         (const_string "*")))])
12776
12777 (define_insn "*rotlqi3_1_one_bit"
12778   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12780                    (match_operand:QI 2 "const1_operand" "")))
12781    (clobber (reg:CC FLAGS_REG))]
12782   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12783    && (TARGET_SHIFT1 || optimize_size)"
12784   "rol{b}\t%0"
12785   [(set_attr "type" "rotate")
12786    (set (attr "length") 
12787      (if_then_else (match_operand 0 "register_operand" "") 
12788         (const_string "2")
12789         (const_string "*")))])
12790
12791 (define_insn "*rotlqi3_1_slp"
12792   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793         (rotate:QI (match_dup 0)
12794                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12798   "@
12799    rol{b}\t{%1, %0|%0, %1}
12800    rol{b}\t{%b1, %0|%0, %b1}"
12801   [(set_attr "type" "rotate1")
12802    (set_attr "mode" "QI")])
12803
12804 (define_insn "*rotlqi3_1"
12805   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12806         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12807                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12808    (clobber (reg:CC FLAGS_REG))]
12809   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12810   "@
12811    rol{b}\t{%2, %0|%0, %2}
12812    rol{b}\t{%b2, %0|%0, %b2}"
12813   [(set_attr "type" "rotate")
12814    (set_attr "mode" "QI")])
12815
12816 (define_expand "rotrdi3"
12817   [(set (match_operand:DI 0 "shiftdi_operand" "")
12818         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12819                    (match_operand:QI 2 "nonmemory_operand" "")))
12820    (clobber (reg:CC FLAGS_REG))]
12821  ""
12822 {
12823   if (TARGET_64BIT)
12824     {
12825       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12826       DONE;
12827     }
12828   if (!const_1_to_31_operand (operands[2], VOIDmode))
12829     FAIL;
12830   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12831   DONE;
12832 })
12833   
12834 ;; Implement rotation using two double-precision shift instructions
12835 ;; and a scratch register.   
12836 (define_insn_and_split "ix86_rotrdi3"
12837  [(set (match_operand:DI 0 "register_operand" "=r")
12838        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12839                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12840   (clobber (reg:CC FLAGS_REG))
12841   (clobber (match_scratch:SI 3 "=&r"))]
12842  "!TARGET_64BIT"
12843  ""
12844  "&& reload_completed"
12845  [(set (match_dup 3) (match_dup 4))
12846   (parallel
12847    [(set (match_dup 4)
12848          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12849                  (ashift:SI (match_dup 5)
12850                             (minus:QI (const_int 32) (match_dup 2)))))
12851     (clobber (reg:CC FLAGS_REG))])
12852   (parallel
12853    [(set (match_dup 5)
12854          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12855                  (ashift:SI (match_dup 3)
12856                             (minus:QI (const_int 32) (match_dup 2)))))
12857     (clobber (reg:CC FLAGS_REG))])]
12858  "split_di (operands, 1, operands + 4, operands + 5);")
12859
12860 (define_insn "*rotrdi3_1_one_bit_rex64"
12861   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12862         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12863                      (match_operand:QI 2 "const1_operand" "")))
12864    (clobber (reg:CC FLAGS_REG))]
12865   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12866    && (TARGET_SHIFT1 || optimize_size)"
12867   "ror{q}\t%0"
12868   [(set_attr "type" "rotate")
12869    (set (attr "length") 
12870      (if_then_else (match_operand:DI 0 "register_operand" "") 
12871         (const_string "2")
12872         (const_string "*")))])
12873
12874 (define_insn "*rotrdi3_1_rex64"
12875   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12876         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12877                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12880   "@
12881    ror{q}\t{%2, %0|%0, %2}
12882    ror{q}\t{%b2, %0|%0, %b2}"
12883   [(set_attr "type" "rotate")
12884    (set_attr "mode" "DI")])
12885
12886 (define_expand "rotrsi3"
12887   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12888         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12889                      (match_operand:QI 2 "nonmemory_operand" "")))
12890    (clobber (reg:CC FLAGS_REG))]
12891   ""
12892   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12893
12894 (define_insn "*rotrsi3_1_one_bit"
12895   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12896         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897                      (match_operand:QI 2 "const1_operand" "")))
12898    (clobber (reg:CC FLAGS_REG))]
12899   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12900    && (TARGET_SHIFT1 || optimize_size)"
12901   "ror{l}\t%0"
12902   [(set_attr "type" "rotate")
12903    (set (attr "length") 
12904      (if_then_else (match_operand:SI 0 "register_operand" "") 
12905         (const_string "2")
12906         (const_string "*")))])
12907
12908 (define_insn "*rotrsi3_1_one_bit_zext"
12909   [(set (match_operand:DI 0 "register_operand" "=r")
12910         (zero_extend:DI
12911           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12912                        (match_operand:QI 2 "const1_operand" ""))))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{l}\t%k0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length") 
12919      (if_then_else (match_operand:SI 0 "register_operand" "") 
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotrsi3_1"
12924   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12929   "@
12930    ror{l}\t{%2, %0|%0, %2}
12931    ror{l}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "SI")])
12934
12935 (define_insn "*rotrsi3_1_zext"
12936   [(set (match_operand:DI 0 "register_operand" "=r,r")
12937         (zero_extend:DI
12938           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12939                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12940    (clobber (reg:CC FLAGS_REG))]
12941   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12942   "@
12943    ror{l}\t{%2, %k0|%k0, %2}
12944    ror{l}\t{%b2, %k0|%k0, %b2}"
12945   [(set_attr "type" "rotate")
12946    (set_attr "mode" "SI")])
12947
12948 (define_expand "rotrhi3"
12949   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12950         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12951                      (match_operand:QI 2 "nonmemory_operand" "")))
12952    (clobber (reg:CC FLAGS_REG))]
12953   "TARGET_HIMODE_MATH"
12954   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12955
12956 (define_insn "*rotrhi3_one_bit"
12957   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12958         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959                      (match_operand:QI 2 "const1_operand" "")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12962    && (TARGET_SHIFT1 || optimize_size)"
12963   "ror{w}\t%0"
12964   [(set_attr "type" "rotate")
12965    (set (attr "length") 
12966      (if_then_else (match_operand 0 "register_operand" "") 
12967         (const_string "2")
12968         (const_string "*")))])
12969
12970 (define_insn "*rotrhi3"
12971   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12972         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12973                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974    (clobber (reg:CC FLAGS_REG))]
12975   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12976   "@
12977    ror{w}\t{%2, %0|%0, %2}
12978    ror{w}\t{%b2, %0|%0, %b2}"
12979   [(set_attr "type" "rotate")
12980    (set_attr "mode" "HI")])
12981
12982 (define_expand "rotrqi3"
12983   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12984         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12985                      (match_operand:QI 2 "nonmemory_operand" "")))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_QIMODE_MATH"
12988   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12989
12990 (define_insn "*rotrqi3_1_one_bit"
12991   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12992         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12993                      (match_operand:QI 2 "const1_operand" "")))
12994    (clobber (reg:CC FLAGS_REG))]
12995   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12996    && (TARGET_SHIFT1 || optimize_size)"
12997   "ror{b}\t%0"
12998   [(set_attr "type" "rotate")
12999    (set (attr "length") 
13000      (if_then_else (match_operand 0 "register_operand" "") 
13001         (const_string "2")
13002         (const_string "*")))])
13003
13004 (define_insn "*rotrqi3_1_one_bit_slp"
13005   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13006         (rotatert:QI (match_dup 0)
13007                      (match_operand:QI 1 "const1_operand" "")))
13008    (clobber (reg:CC FLAGS_REG))]
13009   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010    && (TARGET_SHIFT1 || optimize_size)"
13011   "ror{b}\t%0"
13012   [(set_attr "type" "rotate1")
13013    (set (attr "length") 
13014      (if_then_else (match_operand 0 "register_operand" "") 
13015         (const_string "2")
13016         (const_string "*")))])
13017
13018 (define_insn "*rotrqi3_1"
13019   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13024   "@
13025    ror{b}\t{%2, %0|%0, %2}
13026    ror{b}\t{%b2, %0|%0, %b2}"
13027   [(set_attr "type" "rotate")
13028    (set_attr "mode" "QI")])
13029
13030 (define_insn "*rotrqi3_1_slp"
13031   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13032         (rotatert:QI (match_dup 0)
13033                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13034    (clobber (reg:CC FLAGS_REG))]
13035   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13036    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13037   "@
13038    ror{b}\t{%1, %0|%0, %1}
13039    ror{b}\t{%b1, %0|%0, %b1}"
13040   [(set_attr "type" "rotate1")
13041    (set_attr "mode" "QI")])
13042 \f
13043 ;; Bit set / bit test instructions
13044
13045 (define_expand "extv"
13046   [(set (match_operand:SI 0 "register_operand" "")
13047         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13048                          (match_operand:SI 2 "const8_operand" "")
13049                          (match_operand:SI 3 "const8_operand" "")))]
13050   ""
13051 {
13052   /* Handle extractions from %ah et al.  */
13053   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13054     FAIL;
13055
13056   /* From mips.md: extract_bit_field doesn't verify that our source
13057      matches the predicate, so check it again here.  */
13058   if (! ext_register_operand (operands[1], VOIDmode))
13059     FAIL;
13060 })
13061
13062 (define_expand "extzv"
13063   [(set (match_operand:SI 0 "register_operand" "")
13064         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13065                          (match_operand:SI 2 "const8_operand" "")
13066                          (match_operand:SI 3 "const8_operand" "")))]
13067   ""
13068 {
13069   /* Handle extractions from %ah et al.  */
13070   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13071     FAIL;
13072
13073   /* From mips.md: extract_bit_field doesn't verify that our source
13074      matches the predicate, so check it again here.  */
13075   if (! ext_register_operand (operands[1], VOIDmode))
13076     FAIL;
13077 })
13078
13079 (define_expand "insv"
13080   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13081                       (match_operand 1 "const8_operand" "")
13082                       (match_operand 2 "const8_operand" ""))
13083         (match_operand 3 "register_operand" ""))]
13084   ""
13085 {
13086   /* Handle insertions to %ah et al.  */
13087   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13088     FAIL;
13089
13090   /* From mips.md: insert_bit_field doesn't verify that our source
13091      matches the predicate, so check it again here.  */
13092   if (! ext_register_operand (operands[0], VOIDmode))
13093     FAIL;
13094
13095   if (TARGET_64BIT)
13096     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13097   else
13098     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13099
13100   DONE;
13101 })
13102
13103 ;; %%% bts, btr, btc, bt.
13104 ;; In general these instructions are *slow* when applied to memory,
13105 ;; since they enforce atomic operation.  When applied to registers,
13106 ;; it depends on the cpu implementation.  They're never faster than
13107 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13108 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13109 ;; within the instruction itself, so operating on bits in the high
13110 ;; 32-bits of a register becomes easier.
13111 ;;
13112 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13113 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13114 ;; negdf respectively, so they can never be disabled entirely.
13115
13116 (define_insn "*btsq"
13117   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13118                          (const_int 1)
13119                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13120         (const_int 1))
13121    (clobber (reg:CC FLAGS_REG))]
13122   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13123   "bts{q} %1,%0"
13124   [(set_attr "type" "alu1")])
13125
13126 (define_insn "*btrq"
13127   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13128                          (const_int 1)
13129                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13130         (const_int 0))
13131    (clobber (reg:CC FLAGS_REG))]
13132   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13133   "btr{q} %1,%0"
13134   [(set_attr "type" "alu1")])
13135
13136 (define_insn "*btcq"
13137   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13138                          (const_int 1)
13139                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13140         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13141    (clobber (reg:CC FLAGS_REG))]
13142   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13143   "btc{q} %1,%0"
13144   [(set_attr "type" "alu1")])
13145
13146 ;; Allow Nocona to avoid these instructions if a register is available.
13147
13148 (define_peephole2
13149   [(match_scratch:DI 2 "r")
13150    (parallel [(set (zero_extract:DI
13151                      (match_operand:DI 0 "register_operand" "")
13152                      (const_int 1)
13153                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13154                    (const_int 1))
13155               (clobber (reg:CC FLAGS_REG))])]
13156   "TARGET_64BIT && !TARGET_USE_BT"
13157   [(const_int 0)]
13158 {
13159   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13160   rtx op1;
13161
13162   if (HOST_BITS_PER_WIDE_INT >= 64)
13163     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164   else if (i < HOST_BITS_PER_WIDE_INT)
13165     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166   else
13167     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13168
13169   op1 = immed_double_const (lo, hi, DImode);
13170   if (i >= 31)
13171     {
13172       emit_move_insn (operands[2], op1);
13173       op1 = operands[2];
13174     }
13175
13176   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13177   DONE;
13178 })
13179
13180 (define_peephole2
13181   [(match_scratch:DI 2 "r")
13182    (parallel [(set (zero_extract:DI
13183                      (match_operand:DI 0 "register_operand" "")
13184                      (const_int 1)
13185                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13186                    (const_int 0))
13187               (clobber (reg:CC FLAGS_REG))])]
13188   "TARGET_64BIT && !TARGET_USE_BT"
13189   [(const_int 0)]
13190 {
13191   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13192   rtx op1;
13193
13194   if (HOST_BITS_PER_WIDE_INT >= 64)
13195     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13196   else if (i < HOST_BITS_PER_WIDE_INT)
13197     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13198   else
13199     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13200
13201   op1 = immed_double_const (~lo, ~hi, DImode);
13202   if (i >= 32)
13203     {
13204       emit_move_insn (operands[2], op1);
13205       op1 = operands[2];
13206     }
13207
13208   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13209   DONE;
13210 })
13211
13212 (define_peephole2
13213   [(match_scratch:DI 2 "r")
13214    (parallel [(set (zero_extract:DI
13215                      (match_operand:DI 0 "register_operand" "")
13216                      (const_int 1)
13217                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13218               (not:DI (zero_extract:DI
13219                         (match_dup 0) (const_int 1) (match_dup 1))))
13220               (clobber (reg:CC FLAGS_REG))])]
13221   "TARGET_64BIT && !TARGET_USE_BT"
13222   [(const_int 0)]
13223 {
13224   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13225   rtx op1;
13226
13227   if (HOST_BITS_PER_WIDE_INT >= 64)
13228     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13229   else if (i < HOST_BITS_PER_WIDE_INT)
13230     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13231   else
13232     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13233
13234   op1 = immed_double_const (lo, hi, DImode);
13235   if (i >= 31)
13236     {
13237       emit_move_insn (operands[2], op1);
13238       op1 = operands[2];
13239     }
13240
13241   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13242   DONE;
13243 })
13244 \f
13245 ;; Store-flag instructions.
13246
13247 ;; For all sCOND expanders, also expand the compare or test insn that
13248 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13249
13250 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13251 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13252 ;; way, which can later delete the movzx if only QImode is needed.
13253
13254 (define_expand "seq"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   ""
13258   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13259
13260 (define_expand "sne"
13261   [(set (match_operand:QI 0 "register_operand" "")
13262         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263   ""
13264   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13265
13266 (define_expand "sgt"
13267   [(set (match_operand:QI 0 "register_operand" "")
13268         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269   ""
13270   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13271
13272 (define_expand "sgtu"
13273   [(set (match_operand:QI 0 "register_operand" "")
13274         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275   ""
13276   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13277
13278 (define_expand "slt"
13279   [(set (match_operand:QI 0 "register_operand" "")
13280         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281   ""
13282   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13283
13284 (define_expand "sltu"
13285   [(set (match_operand:QI 0 "register_operand" "")
13286         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287   ""
13288   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13289
13290 (define_expand "sge"
13291   [(set (match_operand:QI 0 "register_operand" "")
13292         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293   ""
13294   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13295
13296 (define_expand "sgeu"
13297   [(set (match_operand:QI 0 "register_operand" "")
13298         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299   ""
13300   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13301
13302 (define_expand "sle"
13303   [(set (match_operand:QI 0 "register_operand" "")
13304         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305   ""
13306   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13307
13308 (define_expand "sleu"
13309   [(set (match_operand:QI 0 "register_operand" "")
13310         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311   ""
13312   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13313
13314 (define_expand "sunordered"
13315   [(set (match_operand:QI 0 "register_operand" "")
13316         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317   "TARGET_80387 || TARGET_SSE"
13318   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13319
13320 (define_expand "sordered"
13321   [(set (match_operand:QI 0 "register_operand" "")
13322         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323   "TARGET_80387"
13324   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13325
13326 (define_expand "suneq"
13327   [(set (match_operand:QI 0 "register_operand" "")
13328         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329   "TARGET_80387 || TARGET_SSE"
13330   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13331
13332 (define_expand "sunge"
13333   [(set (match_operand:QI 0 "register_operand" "")
13334         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335   "TARGET_80387 || TARGET_SSE"
13336   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13337
13338 (define_expand "sungt"
13339   [(set (match_operand:QI 0 "register_operand" "")
13340         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341   "TARGET_80387 || TARGET_SSE"
13342   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13343
13344 (define_expand "sunle"
13345   [(set (match_operand:QI 0 "register_operand" "")
13346         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347   "TARGET_80387 || TARGET_SSE"
13348   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13349
13350 (define_expand "sunlt"
13351   [(set (match_operand:QI 0 "register_operand" "")
13352         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353   "TARGET_80387 || TARGET_SSE"
13354   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13355
13356 (define_expand "sltgt"
13357   [(set (match_operand:QI 0 "register_operand" "")
13358         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13359   "TARGET_80387 || TARGET_SSE"
13360   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13361
13362 (define_insn "*setcc_1"
13363   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13364         (match_operator:QI 1 "ix86_comparison_operator"
13365           [(reg FLAGS_REG) (const_int 0)]))]
13366   ""
13367   "set%C1\t%0"
13368   [(set_attr "type" "setcc")
13369    (set_attr "mode" "QI")])
13370
13371 (define_insn "*setcc_2"
13372   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13373         (match_operator:QI 1 "ix86_comparison_operator"
13374           [(reg FLAGS_REG) (const_int 0)]))]
13375   ""
13376   "set%C1\t%0"
13377   [(set_attr "type" "setcc")
13378    (set_attr "mode" "QI")])
13379
13380 ;; In general it is not safe to assume too much about CCmode registers,
13381 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13382 ;; conditions this is safe on x86, so help combine not create
13383 ;;
13384 ;;      seta    %al
13385 ;;      testb   %al, %al
13386 ;;      sete    %al
13387
13388 (define_split 
13389   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13390         (ne:QI (match_operator 1 "ix86_comparison_operator"
13391                  [(reg FLAGS_REG) (const_int 0)])
13392             (const_int 0)))]
13393   ""
13394   [(set (match_dup 0) (match_dup 1))]
13395 {
13396   PUT_MODE (operands[1], QImode);
13397 })
13398
13399 (define_split 
13400   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13401         (ne:QI (match_operator 1 "ix86_comparison_operator"
13402                  [(reg FLAGS_REG) (const_int 0)])
13403             (const_int 0)))]
13404   ""
13405   [(set (match_dup 0) (match_dup 1))]
13406 {
13407   PUT_MODE (operands[1], QImode);
13408 })
13409
13410 (define_split 
13411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13412         (eq:QI (match_operator 1 "ix86_comparison_operator"
13413                  [(reg FLAGS_REG) (const_int 0)])
13414             (const_int 0)))]
13415   ""
13416   [(set (match_dup 0) (match_dup 1))]
13417 {
13418   rtx new_op1 = copy_rtx (operands[1]);
13419   operands[1] = new_op1;
13420   PUT_MODE (new_op1, QImode);
13421   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13422                                              GET_MODE (XEXP (new_op1, 0))));
13423
13424   /* Make sure that (a) the CCmode we have for the flags is strong
13425      enough for the reversed compare or (b) we have a valid FP compare.  */
13426   if (! ix86_comparison_operator (new_op1, VOIDmode))
13427     FAIL;
13428 })
13429
13430 (define_split 
13431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13432         (eq:QI (match_operator 1 "ix86_comparison_operator"
13433                  [(reg FLAGS_REG) (const_int 0)])
13434             (const_int 0)))]
13435   ""
13436   [(set (match_dup 0) (match_dup 1))]
13437 {
13438   rtx new_op1 = copy_rtx (operands[1]);
13439   operands[1] = new_op1;
13440   PUT_MODE (new_op1, QImode);
13441   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13442                                              GET_MODE (XEXP (new_op1, 0))));
13443
13444   /* Make sure that (a) the CCmode we have for the flags is strong
13445      enough for the reversed compare or (b) we have a valid FP compare.  */
13446   if (! ix86_comparison_operator (new_op1, VOIDmode))
13447     FAIL;
13448 })
13449
13450 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13451 ;; subsequent logical operations are used to imitate conditional moves.
13452 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13453 ;; it directly.
13454
13455 (define_insn "*sse_setccsf"
13456   [(set (match_operand:SF 0 "register_operand" "=x")
13457         (match_operator:SF 1 "sse_comparison_operator"
13458           [(match_operand:SF 2 "register_operand" "0")
13459            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13460   "TARGET_SSE"
13461   "cmp%D1ss\t{%3, %0|%0, %3}"
13462   [(set_attr "type" "ssecmp")
13463    (set_attr "mode" "SF")])
13464
13465 (define_insn "*sse_setccdf"
13466   [(set (match_operand:DF 0 "register_operand" "=Y")
13467         (match_operator:DF 1 "sse_comparison_operator"
13468           [(match_operand:DF 2 "register_operand" "0")
13469            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13470   "TARGET_SSE2"
13471   "cmp%D1sd\t{%3, %0|%0, %3}"
13472   [(set_attr "type" "ssecmp")
13473    (set_attr "mode" "DF")])
13474 \f
13475 ;; Basic conditional jump instructions.
13476 ;; We ignore the overflow flag for signed branch instructions.
13477
13478 ;; For all bCOND expanders, also expand the compare or test insn that
13479 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13480
13481 (define_expand "beq"
13482   [(set (pc)
13483         (if_then_else (match_dup 1)
13484                       (label_ref (match_operand 0 "" ""))
13485                       (pc)))]
13486   ""
13487   "ix86_expand_branch (EQ, operands[0]); DONE;")
13488
13489 (define_expand "bne"
13490   [(set (pc)
13491         (if_then_else (match_dup 1)
13492                       (label_ref (match_operand 0 "" ""))
13493                       (pc)))]
13494   ""
13495   "ix86_expand_branch (NE, operands[0]); DONE;")
13496
13497 (define_expand "bgt"
13498   [(set (pc)
13499         (if_then_else (match_dup 1)
13500                       (label_ref (match_operand 0 "" ""))
13501                       (pc)))]
13502   ""
13503   "ix86_expand_branch (GT, operands[0]); DONE;")
13504
13505 (define_expand "bgtu"
13506   [(set (pc)
13507         (if_then_else (match_dup 1)
13508                       (label_ref (match_operand 0 "" ""))
13509                       (pc)))]
13510   ""
13511   "ix86_expand_branch (GTU, operands[0]); DONE;")
13512
13513 (define_expand "blt"
13514   [(set (pc)
13515         (if_then_else (match_dup 1)
13516                       (label_ref (match_operand 0 "" ""))
13517                       (pc)))]
13518   ""
13519   "ix86_expand_branch (LT, operands[0]); DONE;")
13520
13521 (define_expand "bltu"
13522   [(set (pc)
13523         (if_then_else (match_dup 1)
13524                       (label_ref (match_operand 0 "" ""))
13525                       (pc)))]
13526   ""
13527   "ix86_expand_branch (LTU, operands[0]); DONE;")
13528
13529 (define_expand "bge"
13530   [(set (pc)
13531         (if_then_else (match_dup 1)
13532                       (label_ref (match_operand 0 "" ""))
13533                       (pc)))]
13534   ""
13535   "ix86_expand_branch (GE, operands[0]); DONE;")
13536
13537 (define_expand "bgeu"
13538   [(set (pc)
13539         (if_then_else (match_dup 1)
13540                       (label_ref (match_operand 0 "" ""))
13541                       (pc)))]
13542   ""
13543   "ix86_expand_branch (GEU, operands[0]); DONE;")
13544
13545 (define_expand "ble"
13546   [(set (pc)
13547         (if_then_else (match_dup 1)
13548                       (label_ref (match_operand 0 "" ""))
13549                       (pc)))]
13550   ""
13551   "ix86_expand_branch (LE, operands[0]); DONE;")
13552
13553 (define_expand "bleu"
13554   [(set (pc)
13555         (if_then_else (match_dup 1)
13556                       (label_ref (match_operand 0 "" ""))
13557                       (pc)))]
13558   ""
13559   "ix86_expand_branch (LEU, operands[0]); DONE;")
13560
13561 (define_expand "bunordered"
13562   [(set (pc)
13563         (if_then_else (match_dup 1)
13564                       (label_ref (match_operand 0 "" ""))
13565                       (pc)))]
13566   "TARGET_80387 || TARGET_SSE_MATH"
13567   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13568
13569 (define_expand "bordered"
13570   [(set (pc)
13571         (if_then_else (match_dup 1)
13572                       (label_ref (match_operand 0 "" ""))
13573                       (pc)))]
13574   "TARGET_80387 || TARGET_SSE_MATH"
13575   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13576
13577 (define_expand "buneq"
13578   [(set (pc)
13579         (if_then_else (match_dup 1)
13580                       (label_ref (match_operand 0 "" ""))
13581                       (pc)))]
13582   "TARGET_80387 || TARGET_SSE_MATH"
13583   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13584
13585 (define_expand "bunge"
13586   [(set (pc)
13587         (if_then_else (match_dup 1)
13588                       (label_ref (match_operand 0 "" ""))
13589                       (pc)))]
13590   "TARGET_80387 || TARGET_SSE_MATH"
13591   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13592
13593 (define_expand "bungt"
13594   [(set (pc)
13595         (if_then_else (match_dup 1)
13596                       (label_ref (match_operand 0 "" ""))
13597                       (pc)))]
13598   "TARGET_80387 || TARGET_SSE_MATH"
13599   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13600
13601 (define_expand "bunle"
13602   [(set (pc)
13603         (if_then_else (match_dup 1)
13604                       (label_ref (match_operand 0 "" ""))
13605                       (pc)))]
13606   "TARGET_80387 || TARGET_SSE_MATH"
13607   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13608
13609 (define_expand "bunlt"
13610   [(set (pc)
13611         (if_then_else (match_dup 1)
13612                       (label_ref (match_operand 0 "" ""))
13613                       (pc)))]
13614   "TARGET_80387 || TARGET_SSE_MATH"
13615   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13616
13617 (define_expand "bltgt"
13618   [(set (pc)
13619         (if_then_else (match_dup 1)
13620                       (label_ref (match_operand 0 "" ""))
13621                       (pc)))]
13622   "TARGET_80387 || TARGET_SSE_MATH"
13623   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13624
13625 (define_insn "*jcc_1"
13626   [(set (pc)
13627         (if_then_else (match_operator 1 "ix86_comparison_operator"
13628                                       [(reg FLAGS_REG) (const_int 0)])
13629                       (label_ref (match_operand 0 "" ""))
13630                       (pc)))]
13631   ""
13632   "%+j%C1\t%l0"
13633   [(set_attr "type" "ibr")
13634    (set_attr "modrm" "0")
13635    (set (attr "length")
13636            (if_then_else (and (ge (minus (match_dup 0) (pc))
13637                                   (const_int -126))
13638                               (lt (minus (match_dup 0) (pc))
13639                                   (const_int 128)))
13640              (const_int 2)
13641              (const_int 6)))])
13642
13643 (define_insn "*jcc_2"
13644   [(set (pc)
13645         (if_then_else (match_operator 1 "ix86_comparison_operator"
13646                                       [(reg FLAGS_REG) (const_int 0)])
13647                       (pc)
13648                       (label_ref (match_operand 0 "" ""))))]
13649   ""
13650   "%+j%c1\t%l0"
13651   [(set_attr "type" "ibr")
13652    (set_attr "modrm" "0")
13653    (set (attr "length")
13654            (if_then_else (and (ge (minus (match_dup 0) (pc))
13655                                   (const_int -126))
13656                               (lt (minus (match_dup 0) (pc))
13657                                   (const_int 128)))
13658              (const_int 2)
13659              (const_int 6)))])
13660
13661 ;; In general it is not safe to assume too much about CCmode registers,
13662 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13663 ;; conditions this is safe on x86, so help combine not create
13664 ;;
13665 ;;      seta    %al
13666 ;;      testb   %al, %al
13667 ;;      je      Lfoo
13668
13669 (define_split 
13670   [(set (pc)
13671         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13672                                       [(reg FLAGS_REG) (const_int 0)])
13673                           (const_int 0))
13674                       (label_ref (match_operand 1 "" ""))
13675                       (pc)))]
13676   ""
13677   [(set (pc)
13678         (if_then_else (match_dup 0)
13679                       (label_ref (match_dup 1))
13680                       (pc)))]
13681 {
13682   PUT_MODE (operands[0], VOIDmode);
13683 })
13684   
13685 (define_split 
13686   [(set (pc)
13687         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13688                                       [(reg FLAGS_REG) (const_int 0)])
13689                           (const_int 0))
13690                       (label_ref (match_operand 1 "" ""))
13691                       (pc)))]
13692   ""
13693   [(set (pc)
13694         (if_then_else (match_dup 0)
13695                       (label_ref (match_dup 1))
13696                       (pc)))]
13697 {
13698   rtx new_op0 = copy_rtx (operands[0]);
13699   operands[0] = new_op0;
13700   PUT_MODE (new_op0, VOIDmode);
13701   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13702                                              GET_MODE (XEXP (new_op0, 0))));
13703
13704   /* Make sure that (a) the CCmode we have for the flags is strong
13705      enough for the reversed compare or (b) we have a valid FP compare.  */
13706   if (! ix86_comparison_operator (new_op0, VOIDmode))
13707     FAIL;
13708 })
13709
13710 ;; Define combination compare-and-branch fp compare instructions to use
13711 ;; during early optimization.  Splitting the operation apart early makes
13712 ;; for bad code when we want to reverse the operation.
13713
13714 (define_insn "*fp_jcc_1_mixed"
13715   [(set (pc)
13716         (if_then_else (match_operator 0 "comparison_operator"
13717                         [(match_operand 1 "register_operand" "f,x")
13718                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13719           (label_ref (match_operand 3 "" ""))
13720           (pc)))
13721    (clobber (reg:CCFP FPSR_REG))
13722    (clobber (reg:CCFP FLAGS_REG))]
13723   "TARGET_MIX_SSE_I387
13724    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13725    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727   "#")
13728
13729 (define_insn "*fp_jcc_1_sse"
13730   [(set (pc)
13731         (if_then_else (match_operator 0 "comparison_operator"
13732                         [(match_operand 1 "register_operand" "x")
13733                          (match_operand 2 "nonimmediate_operand" "xm")])
13734           (label_ref (match_operand 3 "" ""))
13735           (pc)))
13736    (clobber (reg:CCFP FPSR_REG))
13737    (clobber (reg:CCFP FLAGS_REG))]
13738   "TARGET_SSE_MATH
13739    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742   "#")
13743
13744 (define_insn "*fp_jcc_1_387"
13745   [(set (pc)
13746         (if_then_else (match_operator 0 "comparison_operator"
13747                         [(match_operand 1 "register_operand" "f")
13748                          (match_operand 2 "register_operand" "f")])
13749           (label_ref (match_operand 3 "" ""))
13750           (pc)))
13751    (clobber (reg:CCFP FPSR_REG))
13752    (clobber (reg:CCFP FLAGS_REG))]
13753   "TARGET_CMOVE && TARGET_80387
13754    && FLOAT_MODE_P (GET_MODE (operands[1]))
13755    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13757   "#")
13758
13759 (define_insn "*fp_jcc_2_mixed"
13760   [(set (pc)
13761         (if_then_else (match_operator 0 "comparison_operator"
13762                         [(match_operand 1 "register_operand" "f,x")
13763                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13764           (pc)
13765           (label_ref (match_operand 3 "" ""))))
13766    (clobber (reg:CCFP FPSR_REG))
13767    (clobber (reg:CCFP FLAGS_REG))]
13768   "TARGET_MIX_SSE_I387
13769    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13770    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772   "#")
13773
13774 (define_insn "*fp_jcc_2_sse"
13775   [(set (pc)
13776         (if_then_else (match_operator 0 "comparison_operator"
13777                         [(match_operand 1 "register_operand" "x")
13778                          (match_operand 2 "nonimmediate_operand" "xm")])
13779           (pc)
13780           (label_ref (match_operand 3 "" ""))))
13781    (clobber (reg:CCFP FPSR_REG))
13782    (clobber (reg:CCFP FLAGS_REG))]
13783   "TARGET_SSE_MATH
13784    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13785    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13786    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13787   "#")
13788
13789 (define_insn "*fp_jcc_2_387"
13790   [(set (pc)
13791         (if_then_else (match_operator 0 "comparison_operator"
13792                         [(match_operand 1 "register_operand" "f")
13793                          (match_operand 2 "register_operand" "f")])
13794           (pc)
13795           (label_ref (match_operand 3 "" ""))))
13796    (clobber (reg:CCFP FPSR_REG))
13797    (clobber (reg:CCFP FLAGS_REG))]
13798   "TARGET_CMOVE && TARGET_80387
13799    && FLOAT_MODE_P (GET_MODE (operands[1]))
13800    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13801    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13802   "#")
13803
13804 (define_insn "*fp_jcc_3_387"
13805   [(set (pc)
13806         (if_then_else (match_operator 0 "comparison_operator"
13807                         [(match_operand 1 "register_operand" "f")
13808                          (match_operand 2 "nonimmediate_operand" "fm")])
13809           (label_ref (match_operand 3 "" ""))
13810           (pc)))
13811    (clobber (reg:CCFP FPSR_REG))
13812    (clobber (reg:CCFP FLAGS_REG))
13813    (clobber (match_scratch:HI 4 "=a"))]
13814   "TARGET_80387
13815    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13816    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13817    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13818    && SELECT_CC_MODE (GET_CODE (operands[0]),
13819                       operands[1], operands[2]) == CCFPmode
13820    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13821   "#")
13822
13823 (define_insn "*fp_jcc_4_387"
13824   [(set (pc)
13825         (if_then_else (match_operator 0 "comparison_operator"
13826                         [(match_operand 1 "register_operand" "f")
13827                          (match_operand 2 "nonimmediate_operand" "fm")])
13828           (pc)
13829           (label_ref (match_operand 3 "" ""))))
13830    (clobber (reg:CCFP FPSR_REG))
13831    (clobber (reg:CCFP FLAGS_REG))
13832    (clobber (match_scratch:HI 4 "=a"))]
13833   "TARGET_80387
13834    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13835    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13837    && SELECT_CC_MODE (GET_CODE (operands[0]),
13838                       operands[1], operands[2]) == CCFPmode
13839    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13840   "#")
13841
13842 (define_insn "*fp_jcc_5_387"
13843   [(set (pc)
13844         (if_then_else (match_operator 0 "comparison_operator"
13845                         [(match_operand 1 "register_operand" "f")
13846                          (match_operand 2 "register_operand" "f")])
13847           (label_ref (match_operand 3 "" ""))
13848           (pc)))
13849    (clobber (reg:CCFP FPSR_REG))
13850    (clobber (reg:CCFP FLAGS_REG))
13851    (clobber (match_scratch:HI 4 "=a"))]
13852   "TARGET_80387
13853    && FLOAT_MODE_P (GET_MODE (operands[1]))
13854    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13855    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13856   "#")
13857
13858 (define_insn "*fp_jcc_6_387"
13859   [(set (pc)
13860         (if_then_else (match_operator 0 "comparison_operator"
13861                         [(match_operand 1 "register_operand" "f")
13862                          (match_operand 2 "register_operand" "f")])
13863           (pc)
13864           (label_ref (match_operand 3 "" ""))))
13865    (clobber (reg:CCFP FPSR_REG))
13866    (clobber (reg:CCFP FLAGS_REG))
13867    (clobber (match_scratch:HI 4 "=a"))]
13868   "TARGET_80387
13869    && FLOAT_MODE_P (GET_MODE (operands[1]))
13870    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13871    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13872   "#")
13873
13874 (define_insn "*fp_jcc_7_387"
13875   [(set (pc)
13876         (if_then_else (match_operator 0 "comparison_operator"
13877                         [(match_operand 1 "register_operand" "f")
13878                          (match_operand 2 "const0_operand" "X")])
13879           (label_ref (match_operand 3 "" ""))
13880           (pc)))
13881    (clobber (reg:CCFP FPSR_REG))
13882    (clobber (reg:CCFP FLAGS_REG))
13883    (clobber (match_scratch:HI 4 "=a"))]
13884   "TARGET_80387
13885    && FLOAT_MODE_P (GET_MODE (operands[1]))
13886    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13887    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13888    && SELECT_CC_MODE (GET_CODE (operands[0]),
13889                       operands[1], operands[2]) == CCFPmode
13890    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13891   "#")
13892
13893 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13894 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13895 ;; with a precedence over other operators and is always put in the first
13896 ;; place. Swap condition and operands to match ficom instruction.
13897
13898 (define_insn "*fp_jcc_8<mode>_387"
13899   [(set (pc)
13900         (if_then_else (match_operator 0 "comparison_operator"
13901                         [(match_operator 1 "float_operator"
13902                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13903                            (match_operand 3 "register_operand" "f,f")])
13904           (label_ref (match_operand 4 "" ""))
13905           (pc)))
13906    (clobber (reg:CCFP FPSR_REG))
13907    (clobber (reg:CCFP FLAGS_REG))
13908    (clobber (match_scratch:HI 5 "=a,a"))]
13909   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13910    && FLOAT_MODE_P (GET_MODE (operands[3]))
13911    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13912    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13913    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13914    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13915   "#")
13916
13917 (define_split
13918   [(set (pc)
13919         (if_then_else (match_operator 0 "comparison_operator"
13920                         [(match_operand 1 "register_operand" "")
13921                          (match_operand 2 "nonimmediate_operand" "")])
13922           (match_operand 3 "" "")
13923           (match_operand 4 "" "")))
13924    (clobber (reg:CCFP FPSR_REG))
13925    (clobber (reg:CCFP FLAGS_REG))]
13926   "reload_completed"
13927   [(const_int 0)]
13928 {
13929   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13930                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13931   DONE;
13932 })
13933
13934 (define_split
13935   [(set (pc)
13936         (if_then_else (match_operator 0 "comparison_operator"
13937                         [(match_operand 1 "register_operand" "")
13938                          (match_operand 2 "general_operand" "")])
13939           (match_operand 3 "" "")
13940           (match_operand 4 "" "")))
13941    (clobber (reg:CCFP FPSR_REG))
13942    (clobber (reg:CCFP FLAGS_REG))
13943    (clobber (match_scratch:HI 5 "=a"))]
13944   "reload_completed"
13945   [(const_int 0)]
13946 {
13947   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13948                         operands[3], operands[4], operands[5], NULL_RTX);
13949   DONE;
13950 })
13951
13952 (define_split
13953   [(set (pc)
13954         (if_then_else (match_operator 0 "comparison_operator"
13955                         [(match_operator 1 "float_operator"
13956                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13957                            (match_operand 3 "register_operand" "")])
13958           (match_operand 4 "" "")
13959           (match_operand 5 "" "")))
13960    (clobber (reg:CCFP FPSR_REG))
13961    (clobber (reg:CCFP FLAGS_REG))
13962    (clobber (match_scratch:HI 6 "=a"))]
13963   "reload_completed"
13964   [(const_int 0)]
13965 {
13966   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13967   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13968                         operands[3], operands[7],
13969                         operands[4], operands[5], operands[6], NULL_RTX);
13970   DONE;
13971 })
13972
13973 ;; %%% Kill this when reload knows how to do it.
13974 (define_split
13975   [(set (pc)
13976         (if_then_else (match_operator 0 "comparison_operator"
13977                         [(match_operator 1 "float_operator"
13978                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13979                            (match_operand 3 "register_operand" "")])
13980           (match_operand 4 "" "")
13981           (match_operand 5 "" "")))
13982    (clobber (reg:CCFP FPSR_REG))
13983    (clobber (reg:CCFP FLAGS_REG))
13984    (clobber (match_scratch:HI 6 "=a"))]
13985   "reload_completed"
13986   [(const_int 0)]
13987 {
13988   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13989   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13990   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13991                         operands[3], operands[7],
13992                         operands[4], operands[5], operands[6], operands[2]);
13993   DONE;
13994 })
13995 \f
13996 ;; Unconditional and other jump instructions
13997
13998 (define_insn "jump"
13999   [(set (pc)
14000         (label_ref (match_operand 0 "" "")))]
14001   ""
14002   "jmp\t%l0"
14003   [(set_attr "type" "ibr")
14004    (set (attr "length")
14005            (if_then_else (and (ge (minus (match_dup 0) (pc))
14006                                   (const_int -126))
14007                               (lt (minus (match_dup 0) (pc))
14008                                   (const_int 128)))
14009              (const_int 2)
14010              (const_int 5)))
14011    (set_attr "modrm" "0")])
14012
14013 (define_expand "indirect_jump"
14014   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14015   ""
14016   "")
14017
14018 (define_insn "*indirect_jump"
14019   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14020   "!TARGET_64BIT"
14021   "jmp\t%A0"
14022   [(set_attr "type" "ibr")
14023    (set_attr "length_immediate" "0")])
14024
14025 (define_insn "*indirect_jump_rtx64"
14026   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14027   "TARGET_64BIT"
14028   "jmp\t%A0"
14029   [(set_attr "type" "ibr")
14030    (set_attr "length_immediate" "0")])
14031
14032 (define_expand "tablejump"
14033   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14034               (use (label_ref (match_operand 1 "" "")))])]
14035   ""
14036 {
14037   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14038      relative.  Convert the relative address to an absolute address.  */
14039   if (flag_pic)
14040     {
14041       rtx op0, op1;
14042       enum rtx_code code;
14043
14044       if (TARGET_64BIT)
14045         {
14046           code = PLUS;
14047           op0 = operands[0];
14048           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14049         }
14050       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14051         {
14052           code = PLUS;
14053           op0 = operands[0];
14054           op1 = pic_offset_table_rtx;
14055         }
14056       else
14057         {
14058           code = MINUS;
14059           op0 = pic_offset_table_rtx;
14060           op1 = operands[0];
14061         }
14062
14063       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14064                                          OPTAB_DIRECT);
14065     }
14066 })
14067
14068 (define_insn "*tablejump_1"
14069   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14070    (use (label_ref (match_operand 1 "" "")))]
14071   "!TARGET_64BIT"
14072   "jmp\t%A0"
14073   [(set_attr "type" "ibr")
14074    (set_attr "length_immediate" "0")])
14075
14076 (define_insn "*tablejump_1_rtx64"
14077   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14078    (use (label_ref (match_operand 1 "" "")))]
14079   "TARGET_64BIT"
14080   "jmp\t%A0"
14081   [(set_attr "type" "ibr")
14082    (set_attr "length_immediate" "0")])
14083 \f
14084 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14085
14086 (define_peephole2
14087   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14088    (set (match_operand:QI 1 "register_operand" "")
14089         (match_operator:QI 2 "ix86_comparison_operator"
14090           [(reg FLAGS_REG) (const_int 0)]))
14091    (set (match_operand 3 "q_regs_operand" "")
14092         (zero_extend (match_dup 1)))]
14093   "(peep2_reg_dead_p (3, operands[1])
14094     || operands_match_p (operands[1], operands[3]))
14095    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14096   [(set (match_dup 4) (match_dup 0))
14097    (set (strict_low_part (match_dup 5))
14098         (match_dup 2))]
14099 {
14100   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14101   operands[5] = gen_lowpart (QImode, operands[3]);
14102   ix86_expand_clear (operands[3]);
14103 })
14104
14105 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14106
14107 (define_peephole2
14108   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14109    (set (match_operand:QI 1 "register_operand" "")
14110         (match_operator:QI 2 "ix86_comparison_operator"
14111           [(reg FLAGS_REG) (const_int 0)]))
14112    (parallel [(set (match_operand 3 "q_regs_operand" "")
14113                    (zero_extend (match_dup 1)))
14114               (clobber (reg:CC FLAGS_REG))])]
14115   "(peep2_reg_dead_p (3, operands[1])
14116     || operands_match_p (operands[1], operands[3]))
14117    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14118   [(set (match_dup 4) (match_dup 0))
14119    (set (strict_low_part (match_dup 5))
14120         (match_dup 2))]
14121 {
14122   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14123   operands[5] = gen_lowpart (QImode, operands[3]);
14124   ix86_expand_clear (operands[3]);
14125 })
14126 \f
14127 ;; Call instructions.
14128
14129 ;; The predicates normally associated with named expanders are not properly
14130 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14131 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14132
14133 ;; Call subroutine returning no value.
14134
14135 (define_expand "call_pop"
14136   [(parallel [(call (match_operand:QI 0 "" "")
14137                     (match_operand:SI 1 "" ""))
14138               (set (reg:SI SP_REG)
14139                    (plus:SI (reg:SI SP_REG)
14140                             (match_operand:SI 3 "" "")))])]
14141   "!TARGET_64BIT"
14142 {
14143   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14144   DONE;
14145 })
14146
14147 (define_insn "*call_pop_0"
14148   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14149          (match_operand:SI 1 "" ""))
14150    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14151                             (match_operand:SI 2 "immediate_operand" "")))]
14152   "!TARGET_64BIT"
14153 {
14154   if (SIBLING_CALL_P (insn))
14155     return "jmp\t%P0";
14156   else
14157     return "call\t%P0";
14158 }
14159   [(set_attr "type" "call")])
14160   
14161 (define_insn "*call_pop_1"
14162   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14163          (match_operand:SI 1 "" ""))
14164    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14165                             (match_operand:SI 2 "immediate_operand" "i")))]
14166   "!TARGET_64BIT"
14167 {
14168   if (constant_call_address_operand (operands[0], Pmode))
14169     {
14170       if (SIBLING_CALL_P (insn))
14171         return "jmp\t%P0";
14172       else
14173         return "call\t%P0";
14174     }
14175   if (SIBLING_CALL_P (insn))
14176     return "jmp\t%A0";
14177   else
14178     return "call\t%A0";
14179 }
14180   [(set_attr "type" "call")])
14181
14182 (define_expand "call"
14183   [(call (match_operand:QI 0 "" "")
14184          (match_operand 1 "" ""))
14185    (use (match_operand 2 "" ""))]
14186   ""
14187 {
14188   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14189   DONE;
14190 })
14191
14192 (define_expand "sibcall"
14193   [(call (match_operand:QI 0 "" "")
14194          (match_operand 1 "" ""))
14195    (use (match_operand 2 "" ""))]
14196   ""
14197 {
14198   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14199   DONE;
14200 })
14201
14202 (define_insn "*call_0"
14203   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14204          (match_operand 1 "" ""))]
14205   ""
14206 {
14207   if (SIBLING_CALL_P (insn))
14208     return "jmp\t%P0";
14209   else
14210     return "call\t%P0";
14211 }
14212   [(set_attr "type" "call")])
14213
14214 (define_insn "*call_1"
14215   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14216          (match_operand 1 "" ""))]
14217   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14218 {
14219   if (constant_call_address_operand (operands[0], Pmode))
14220     return "call\t%P0";
14221   return "call\t%A0";
14222 }
14223   [(set_attr "type" "call")])
14224
14225 (define_insn "*sibcall_1"
14226   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14227          (match_operand 1 "" ""))]
14228   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14229 {
14230   if (constant_call_address_operand (operands[0], Pmode))
14231     return "jmp\t%P0";
14232   return "jmp\t%A0";
14233 }
14234   [(set_attr "type" "call")])
14235
14236 (define_insn "*call_1_rex64"
14237   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14238          (match_operand 1 "" ""))]
14239   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14240 {
14241   if (constant_call_address_operand (operands[0], Pmode))
14242     return "call\t%P0";
14243   return "call\t%A0";
14244 }
14245   [(set_attr "type" "call")])
14246
14247 (define_insn "*sibcall_1_rex64"
14248   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14249          (match_operand 1 "" ""))]
14250   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14251   "jmp\t%P0"
14252   [(set_attr "type" "call")])
14253
14254 (define_insn "*sibcall_1_rex64_v"
14255   [(call (mem:QI (reg:DI 40))
14256          (match_operand 0 "" ""))]
14257   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14258   "jmp\t*%%r11"
14259   [(set_attr "type" "call")])
14260
14261
14262 ;; Call subroutine, returning value in operand 0
14263
14264 (define_expand "call_value_pop"
14265   [(parallel [(set (match_operand 0 "" "")
14266                    (call (match_operand:QI 1 "" "")
14267                          (match_operand:SI 2 "" "")))
14268               (set (reg:SI SP_REG)
14269                    (plus:SI (reg:SI SP_REG)
14270                             (match_operand:SI 4 "" "")))])]
14271   "!TARGET_64BIT"
14272 {
14273   ix86_expand_call (operands[0], operands[1], operands[2],
14274                     operands[3], operands[4], 0);
14275   DONE;
14276 })
14277
14278 (define_expand "call_value"
14279   [(set (match_operand 0 "" "")
14280         (call (match_operand:QI 1 "" "")
14281               (match_operand:SI 2 "" "")))
14282    (use (match_operand:SI 3 "" ""))]
14283   ;; Operand 2 not used on the i386.
14284   ""
14285 {
14286   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14287   DONE;
14288 })
14289
14290 (define_expand "sibcall_value"
14291   [(set (match_operand 0 "" "")
14292         (call (match_operand:QI 1 "" "")
14293               (match_operand:SI 2 "" "")))
14294    (use (match_operand:SI 3 "" ""))]
14295   ;; Operand 2 not used on the i386.
14296   ""
14297 {
14298   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14299   DONE;
14300 })
14301
14302 ;; Call subroutine returning any type.
14303
14304 (define_expand "untyped_call"
14305   [(parallel [(call (match_operand 0 "" "")
14306                     (const_int 0))
14307               (match_operand 1 "" "")
14308               (match_operand 2 "" "")])]
14309   ""
14310 {
14311   int i;
14312
14313   /* In order to give reg-stack an easier job in validating two
14314      coprocessor registers as containing a possible return value,
14315      simply pretend the untyped call returns a complex long double
14316      value.  */
14317
14318   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14319                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14320                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14321                     NULL, 0);
14322
14323   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14324     {
14325       rtx set = XVECEXP (operands[2], 0, i);
14326       emit_move_insn (SET_DEST (set), SET_SRC (set));
14327     }
14328
14329   /* The optimizer does not know that the call sets the function value
14330      registers we stored in the result block.  We avoid problems by
14331      claiming that all hard registers are used and clobbered at this
14332      point.  */
14333   emit_insn (gen_blockage (const0_rtx));
14334
14335   DONE;
14336 })
14337 \f
14338 ;; Prologue and epilogue instructions
14339
14340 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14341 ;; all of memory.  This blocks insns from being moved across this point.
14342
14343 (define_insn "blockage"
14344   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14345   ""
14346   ""
14347   [(set_attr "length" "0")])
14348
14349 ;; Insn emitted into the body of a function to return from a function.
14350 ;; This is only done if the function's epilogue is known to be simple.
14351 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14352
14353 (define_expand "return"
14354   [(return)]
14355   "ix86_can_use_return_insn_p ()"
14356 {
14357   if (current_function_pops_args)
14358     {
14359       rtx popc = GEN_INT (current_function_pops_args);
14360       emit_jump_insn (gen_return_pop_internal (popc));
14361       DONE;
14362     }
14363 })
14364
14365 (define_insn "return_internal"
14366   [(return)]
14367   "reload_completed"
14368   "ret"
14369   [(set_attr "length" "1")
14370    (set_attr "length_immediate" "0")
14371    (set_attr "modrm" "0")])
14372
14373 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14374 ;; instruction Athlon and K8 have.
14375
14376 (define_insn "return_internal_long"
14377   [(return)
14378    (unspec [(const_int 0)] UNSPEC_REP)]
14379   "reload_completed"
14380   "rep {;} ret"
14381   [(set_attr "length" "1")
14382    (set_attr "length_immediate" "0")
14383    (set_attr "prefix_rep" "1")
14384    (set_attr "modrm" "0")])
14385
14386 (define_insn "return_pop_internal"
14387   [(return)
14388    (use (match_operand:SI 0 "const_int_operand" ""))]
14389   "reload_completed"
14390   "ret\t%0"
14391   [(set_attr "length" "3")
14392    (set_attr "length_immediate" "2")
14393    (set_attr "modrm" "0")])
14394
14395 (define_insn "return_indirect_internal"
14396   [(return)
14397    (use (match_operand:SI 0 "register_operand" "r"))]
14398   "reload_completed"
14399   "jmp\t%A0"
14400   [(set_attr "type" "ibr")
14401    (set_attr "length_immediate" "0")])
14402
14403 (define_insn "nop"
14404   [(const_int 0)]
14405   ""
14406   "nop"
14407   [(set_attr "length" "1")
14408    (set_attr "length_immediate" "0")
14409    (set_attr "modrm" "0")])
14410
14411 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14412 ;; branch prediction penalty for the third jump in a 16-byte
14413 ;; block on K8.
14414
14415 (define_insn "align"
14416   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14417   ""
14418 {
14419 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14420   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14421 #else
14422   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14423      The align insn is used to avoid 3 jump instructions in the row to improve
14424      branch prediction and the benefits hardly outweigh the cost of extra 8
14425      nops on the average inserted by full alignment pseudo operation.  */
14426 #endif
14427   return "";
14428 }
14429   [(set_attr "length" "16")])
14430
14431 (define_expand "prologue"
14432   [(const_int 1)]
14433   ""
14434   "ix86_expand_prologue (); DONE;")
14435
14436 (define_insn "set_got"
14437   [(set (match_operand:SI 0 "register_operand" "=r")
14438         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14439    (clobber (reg:CC FLAGS_REG))]
14440   "!TARGET_64BIT"
14441   { return output_set_got (operands[0], NULL_RTX); }
14442   [(set_attr "type" "multi")
14443    (set_attr "length" "12")])
14444
14445 (define_insn "set_got_labelled"
14446   [(set (match_operand:SI 0 "register_operand" "=r")
14447         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14448          UNSPEC_SET_GOT))
14449    (clobber (reg:CC FLAGS_REG))]
14450   "!TARGET_64BIT"
14451   { return output_set_got (operands[0], operands[1]); }
14452   [(set_attr "type" "multi")
14453    (set_attr "length" "12")])
14454
14455 (define_insn "set_got_rex64"
14456   [(set (match_operand:DI 0 "register_operand" "=r")
14457         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14458   "TARGET_64BIT"
14459   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14460   [(set_attr "type" "lea")
14461    (set_attr "length" "6")])
14462
14463 (define_expand "epilogue"
14464   [(const_int 1)]
14465   ""
14466   "ix86_expand_epilogue (1); DONE;")
14467
14468 (define_expand "sibcall_epilogue"
14469   [(const_int 1)]
14470   ""
14471   "ix86_expand_epilogue (0); DONE;")
14472
14473 (define_expand "eh_return"
14474   [(use (match_operand 0 "register_operand" ""))]
14475   ""
14476 {
14477   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14478
14479   /* Tricky bit: we write the address of the handler to which we will
14480      be returning into someone else's stack frame, one word below the
14481      stack address we wish to restore.  */
14482   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484   tmp = gen_rtx_MEM (Pmode, tmp);
14485   emit_move_insn (tmp, ra);
14486
14487   if (Pmode == SImode)
14488     emit_jump_insn (gen_eh_return_si (sa));
14489   else
14490     emit_jump_insn (gen_eh_return_di (sa));
14491   emit_barrier ();
14492   DONE;
14493 })
14494
14495 (define_insn_and_split "eh_return_si"
14496   [(set (pc) 
14497         (unspec [(match_operand:SI 0 "register_operand" "c")]
14498                  UNSPEC_EH_RETURN))]
14499   "!TARGET_64BIT"
14500   "#"
14501   "reload_completed"
14502   [(const_int 1)]
14503   "ix86_expand_epilogue (2); DONE;")
14504
14505 (define_insn_and_split "eh_return_di"
14506   [(set (pc) 
14507         (unspec [(match_operand:DI 0 "register_operand" "c")]
14508                  UNSPEC_EH_RETURN))]
14509   "TARGET_64BIT"
14510   "#"
14511   "reload_completed"
14512   [(const_int 1)]
14513   "ix86_expand_epilogue (2); DONE;")
14514
14515 (define_insn "leave"
14516   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518    (clobber (mem:BLK (scratch)))]
14519   "!TARGET_64BIT"
14520   "leave"
14521   [(set_attr "type" "leave")])
14522
14523 (define_insn "leave_rex64"
14524   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526    (clobber (mem:BLK (scratch)))]
14527   "TARGET_64BIT"
14528   "leave"
14529   [(set_attr "type" "leave")])
14530 \f
14531 (define_expand "ffssi2"
14532   [(parallel
14533      [(set (match_operand:SI 0 "register_operand" "") 
14534            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535       (clobber (match_scratch:SI 2 ""))
14536       (clobber (reg:CC FLAGS_REG))])]
14537   ""
14538   "")
14539
14540 (define_insn_and_split "*ffs_cmove"
14541   [(set (match_operand:SI 0 "register_operand" "=r") 
14542         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543    (clobber (match_scratch:SI 2 "=&r"))
14544    (clobber (reg:CC FLAGS_REG))]
14545   "TARGET_CMOVE"
14546   "#"
14547   "&& reload_completed"
14548   [(set (match_dup 2) (const_int -1))
14549    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551    (set (match_dup 0) (if_then_else:SI
14552                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14553                         (match_dup 2)
14554                         (match_dup 0)))
14555    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556               (clobber (reg:CC FLAGS_REG))])]
14557   "")
14558
14559 (define_insn_and_split "*ffs_no_cmove"
14560   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14561         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562    (clobber (match_scratch:SI 2 "=&q"))
14563    (clobber (reg:CC FLAGS_REG))]
14564   ""
14565   "#"
14566   "reload_completed"
14567   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569    (set (strict_low_part (match_dup 3))
14570         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572               (clobber (reg:CC FLAGS_REG))])
14573    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574               (clobber (reg:CC FLAGS_REG))])
14575    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576               (clobber (reg:CC FLAGS_REG))])]
14577 {
14578   operands[3] = gen_lowpart (QImode, operands[2]);
14579   ix86_expand_clear (operands[2]);
14580 })
14581
14582 (define_insn "*ffssi_1"
14583   [(set (reg:CCZ FLAGS_REG)
14584         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14585                      (const_int 0)))
14586    (set (match_operand:SI 0 "register_operand" "=r")
14587         (ctz:SI (match_dup 1)))]
14588   ""
14589   "bsf{l}\t{%1, %0|%0, %1}"
14590   [(set_attr "prefix_0f" "1")])
14591
14592 (define_expand "ffsdi2"
14593   [(parallel
14594      [(set (match_operand:DI 0 "register_operand" "") 
14595            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596       (clobber (match_scratch:DI 2 ""))
14597       (clobber (reg:CC FLAGS_REG))])]
14598   "TARGET_64BIT && TARGET_CMOVE"
14599   "")
14600
14601 (define_insn_and_split "*ffs_rex64"
14602   [(set (match_operand:DI 0 "register_operand" "=r") 
14603         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604    (clobber (match_scratch:DI 2 "=&r"))
14605    (clobber (reg:CC FLAGS_REG))]
14606   "TARGET_64BIT && TARGET_CMOVE"
14607   "#"
14608   "&& reload_completed"
14609   [(set (match_dup 2) (const_int -1))
14610    (parallel [(set (reg:CCZ FLAGS_REG)
14611                    (compare:CCZ (match_dup 1) (const_int 0)))
14612               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613    (set (match_dup 0) (if_then_else:DI
14614                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14615                         (match_dup 2)
14616                         (match_dup 0)))
14617    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618               (clobber (reg:CC FLAGS_REG))])]
14619   "")
14620
14621 (define_insn "*ffsdi_1"
14622   [(set (reg:CCZ FLAGS_REG)
14623         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14624                      (const_int 0)))
14625    (set (match_operand:DI 0 "register_operand" "=r")
14626         (ctz:DI (match_dup 1)))]
14627   "TARGET_64BIT"
14628   "bsf{q}\t{%1, %0|%0, %1}"
14629   [(set_attr "prefix_0f" "1")])
14630
14631 (define_insn "ctzsi2"
14632   [(set (match_operand:SI 0 "register_operand" "=r")
14633         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634    (clobber (reg:CC FLAGS_REG))]
14635   ""
14636   "bsf{l}\t{%1, %0|%0, %1}"
14637   [(set_attr "prefix_0f" "1")])
14638
14639 (define_insn "ctzdi2"
14640   [(set (match_operand:DI 0 "register_operand" "=r")
14641         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642    (clobber (reg:CC FLAGS_REG))]
14643   "TARGET_64BIT"
14644   "bsf{q}\t{%1, %0|%0, %1}"
14645   [(set_attr "prefix_0f" "1")])
14646
14647 (define_expand "clzsi2"
14648   [(parallel
14649      [(set (match_operand:SI 0 "register_operand" "")
14650            (minus:SI (const_int 31)
14651                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652       (clobber (reg:CC FLAGS_REG))])
14653    (parallel
14654      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655       (clobber (reg:CC FLAGS_REG))])]
14656   ""
14657 {
14658   if (TARGET_ABM)
14659     {
14660       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14661       DONE;
14662     }
14663 })
14664
14665 (define_insn "clzsi2_abm"
14666   [(set (match_operand:SI 0 "register_operand" "=r")
14667         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668    (clobber (reg:CC FLAGS_REG))]
14669   "TARGET_ABM"
14670   "lzcnt{l}\t{%1, %0|%0, %1}"
14671   [(set_attr "prefix_rep" "1")
14672    (set_attr "type" "bitmanip")
14673    (set_attr "mode" "SI")])
14674
14675 (define_insn "*bsr"
14676   [(set (match_operand:SI 0 "register_operand" "=r")
14677         (minus:SI (const_int 31)
14678                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679    (clobber (reg:CC FLAGS_REG))]
14680   ""
14681   "bsr{l}\t{%1, %0|%0, %1}"
14682   [(set_attr "prefix_0f" "1")
14683    (set_attr "mode" "SI")])
14684
14685 (define_insn "popcountsi2"
14686   [(set (match_operand:SI 0 "register_operand" "=r")
14687         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688    (clobber (reg:CC FLAGS_REG))]
14689   "TARGET_POPCNT"
14690   "popcnt{l}\t{%1, %0|%0, %1}"
14691   [(set_attr "prefix_rep" "1")
14692    (set_attr "type" "bitmanip")
14693    (set_attr "mode" "SI")])
14694
14695 (define_insn "*popcountsi2_cmp"
14696   [(set (reg FLAGS_REG)
14697         (compare
14698           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14699           (const_int 0)))
14700    (set (match_operand:SI 0 "register_operand" "=r")
14701         (popcount:SI (match_dup 1)))]
14702   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703   "popcnt{l}\t{%1, %0|%0, %1}"
14704   [(set_attr "prefix_rep" "1")
14705    (set_attr "type" "bitmanip")
14706    (set_attr "mode" "SI")])
14707
14708 (define_insn "*popcountsi2_cmp_zext"
14709   [(set (reg FLAGS_REG)
14710         (compare
14711           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14712           (const_int 0)))
14713    (set (match_operand:DI 0 "register_operand" "=r")
14714         (zero_extend:DI(popcount:SI (match_dup 1))))]
14715   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716   "popcnt{l}\t{%1, %0|%0, %1}"
14717   [(set_attr "prefix_rep" "1")
14718    (set_attr "type" "bitmanip")
14719    (set_attr "mode" "SI")])
14720
14721 (define_expand "clzdi2"
14722   [(parallel
14723      [(set (match_operand:DI 0 "register_operand" "")
14724            (minus:DI (const_int 63)
14725                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14726       (clobber (reg:CC FLAGS_REG))])
14727    (parallel
14728      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14729       (clobber (reg:CC FLAGS_REG))])]
14730   "TARGET_64BIT"
14731 {
14732   if (TARGET_ABM)
14733     {
14734       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14735       DONE;
14736     }
14737 })
14738
14739 (define_insn "clzdi2_abm"
14740   [(set (match_operand:DI 0 "register_operand" "=r")
14741         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14742    (clobber (reg:CC FLAGS_REG))]
14743   "TARGET_64BIT && TARGET_ABM"
14744   "lzcnt{q}\t{%1, %0|%0, %1}"
14745   [(set_attr "prefix_rep" "1")
14746    (set_attr "type" "bitmanip")
14747    (set_attr "mode" "DI")])
14748
14749 (define_insn "*bsr_rex64"
14750   [(set (match_operand:DI 0 "register_operand" "=r")
14751         (minus:DI (const_int 63)
14752                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14753    (clobber (reg:CC FLAGS_REG))]
14754   "TARGET_64BIT"
14755   "bsr{q}\t{%1, %0|%0, %1}"
14756   [(set_attr "prefix_0f" "1")
14757    (set_attr "mode" "DI")])
14758
14759 (define_insn "popcountdi2"
14760   [(set (match_operand:DI 0 "register_operand" "=r")
14761         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14762    (clobber (reg:CC FLAGS_REG))]
14763   "TARGET_64BIT && TARGET_POPCNT"
14764   "popcnt{q}\t{%1, %0|%0, %1}"
14765   [(set_attr "prefix_rep" "1")
14766    (set_attr "type" "bitmanip")
14767    (set_attr "mode" "DI")])
14768
14769 (define_insn "*popcountdi2_cmp"
14770   [(set (reg FLAGS_REG)
14771         (compare
14772           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14773           (const_int 0)))
14774    (set (match_operand:DI 0 "register_operand" "=r")
14775         (popcount:DI (match_dup 1)))]
14776   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14777   "popcnt{q}\t{%1, %0|%0, %1}"
14778   [(set_attr "prefix_rep" "1")
14779    (set_attr "type" "bitmanip")
14780    (set_attr "mode" "DI")])
14781
14782 (define_expand "clzhi2"
14783   [(parallel
14784      [(set (match_operand:HI 0 "register_operand" "")
14785            (minus:HI (const_int 15)
14786                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14787       (clobber (reg:CC FLAGS_REG))])
14788    (parallel
14789      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14790       (clobber (reg:CC FLAGS_REG))])]
14791   ""
14792 {
14793   if (TARGET_ABM)
14794     {
14795       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14796       DONE;
14797     }
14798 })
14799
14800 (define_insn "clzhi2_abm"
14801   [(set (match_operand:HI 0 "register_operand" "=r")
14802         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14803    (clobber (reg:CC FLAGS_REG))]
14804   "TARGET_ABM"
14805   "lzcnt{w}\t{%1, %0|%0, %1}"
14806   [(set_attr "prefix_rep" "1")
14807    (set_attr "type" "bitmanip")
14808    (set_attr "mode" "HI")])
14809
14810 (define_insn "*bsrhi"
14811   [(set (match_operand:HI 0 "register_operand" "=r")
14812         (minus:HI (const_int 15)
14813                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14814    (clobber (reg:CC FLAGS_REG))]
14815   ""
14816   "bsr{w}\t{%1, %0|%0, %1}"
14817   [(set_attr "prefix_0f" "1")
14818    (set_attr "mode" "HI")])
14819
14820 (define_insn "popcounthi2"
14821   [(set (match_operand:HI 0 "register_operand" "=r")
14822         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14823    (clobber (reg:CC FLAGS_REG))]
14824   "TARGET_POPCNT"
14825   "popcnt{w}\t{%1, %0|%0, %1}"
14826   [(set_attr "prefix_rep" "1")
14827    (set_attr "type" "bitmanip")
14828    (set_attr "mode" "HI")])
14829
14830 (define_insn "*popcounthi2_cmp"
14831   [(set (reg FLAGS_REG)
14832         (compare
14833           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14834           (const_int 0)))
14835    (set (match_operand:HI 0 "register_operand" "=r")
14836         (popcount:HI (match_dup 1)))]
14837   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14838   "popcnt{w}\t{%1, %0|%0, %1}"
14839   [(set_attr "prefix_rep" "1")
14840    (set_attr "type" "bitmanip")
14841    (set_attr "mode" "HI")])
14842 \f
14843 ;; Thread-local storage patterns for ELF.
14844 ;;
14845 ;; Note that these code sequences must appear exactly as shown
14846 ;; in order to allow linker relaxation.
14847
14848 (define_insn "*tls_global_dynamic_32_gnu"
14849   [(set (match_operand:SI 0 "register_operand" "=a")
14850         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14851                     (match_operand:SI 2 "tls_symbolic_operand" "")
14852                     (match_operand:SI 3 "call_insn_operand" "")]
14853                     UNSPEC_TLS_GD))
14854    (clobber (match_scratch:SI 4 "=d"))
14855    (clobber (match_scratch:SI 5 "=c"))
14856    (clobber (reg:CC FLAGS_REG))]
14857   "!TARGET_64BIT && TARGET_GNU_TLS"
14858   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14859   [(set_attr "type" "multi")
14860    (set_attr "length" "12")])
14861
14862 (define_insn "*tls_global_dynamic_32_sun"
14863   [(set (match_operand:SI 0 "register_operand" "=a")
14864         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14865                     (match_operand:SI 2 "tls_symbolic_operand" "")
14866                     (match_operand:SI 3 "call_insn_operand" "")]
14867                     UNSPEC_TLS_GD))
14868    (clobber (match_scratch:SI 4 "=d"))
14869    (clobber (match_scratch:SI 5 "=c"))
14870    (clobber (reg:CC FLAGS_REG))]
14871   "!TARGET_64BIT && TARGET_SUN_TLS"
14872   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14873         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14874   [(set_attr "type" "multi")
14875    (set_attr "length" "14")])
14876
14877 (define_expand "tls_global_dynamic_32"
14878   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14879                    (unspec:SI
14880                     [(match_dup 2)
14881                      (match_operand:SI 1 "tls_symbolic_operand" "")
14882                      (match_dup 3)]
14883                     UNSPEC_TLS_GD))
14884               (clobber (match_scratch:SI 4 ""))
14885               (clobber (match_scratch:SI 5 ""))
14886               (clobber (reg:CC FLAGS_REG))])]
14887   ""
14888 {
14889   if (flag_pic)
14890     operands[2] = pic_offset_table_rtx;
14891   else
14892     {
14893       operands[2] = gen_reg_rtx (Pmode);
14894       emit_insn (gen_set_got (operands[2]));
14895     }
14896   if (TARGET_GNU2_TLS)
14897     {
14898        emit_insn (gen_tls_dynamic_gnu2_32
14899                   (operands[0], operands[1], operands[2]));
14900        DONE;
14901     }
14902   operands[3] = ix86_tls_get_addr ();
14903 })
14904
14905 (define_insn "*tls_global_dynamic_64"
14906   [(set (match_operand:DI 0 "register_operand" "=a")
14907         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14908                  (match_operand:DI 3 "" "")))
14909    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14910               UNSPEC_TLS_GD)]
14911   "TARGET_64BIT"
14912   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14913   [(set_attr "type" "multi")
14914    (set_attr "length" "16")])
14915
14916 (define_expand "tls_global_dynamic_64"
14917   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14918                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14919               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14920                          UNSPEC_TLS_GD)])]
14921   ""
14922 {
14923   if (TARGET_GNU2_TLS)
14924     {
14925        emit_insn (gen_tls_dynamic_gnu2_64
14926                   (operands[0], operands[1]));
14927        DONE;
14928     }
14929   operands[2] = ix86_tls_get_addr ();
14930 })
14931
14932 (define_insn "*tls_local_dynamic_base_32_gnu"
14933   [(set (match_operand:SI 0 "register_operand" "=a")
14934         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14935                     (match_operand:SI 2 "call_insn_operand" "")]
14936                    UNSPEC_TLS_LD_BASE))
14937    (clobber (match_scratch:SI 3 "=d"))
14938    (clobber (match_scratch:SI 4 "=c"))
14939    (clobber (reg:CC FLAGS_REG))]
14940   "!TARGET_64BIT && TARGET_GNU_TLS"
14941   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14942   [(set_attr "type" "multi")
14943    (set_attr "length" "11")])
14944
14945 (define_insn "*tls_local_dynamic_base_32_sun"
14946   [(set (match_operand:SI 0 "register_operand" "=a")
14947         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14948                     (match_operand:SI 2 "call_insn_operand" "")]
14949                    UNSPEC_TLS_LD_BASE))
14950    (clobber (match_scratch:SI 3 "=d"))
14951    (clobber (match_scratch:SI 4 "=c"))
14952    (clobber (reg:CC FLAGS_REG))]
14953   "!TARGET_64BIT && TARGET_SUN_TLS"
14954   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14955         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14956   [(set_attr "type" "multi")
14957    (set_attr "length" "13")])
14958
14959 (define_expand "tls_local_dynamic_base_32"
14960   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14961                    (unspec:SI [(match_dup 1) (match_dup 2)]
14962                               UNSPEC_TLS_LD_BASE))
14963               (clobber (match_scratch:SI 3 ""))
14964               (clobber (match_scratch:SI 4 ""))
14965               (clobber (reg:CC FLAGS_REG))])]
14966   ""
14967 {
14968   if (flag_pic)
14969     operands[1] = pic_offset_table_rtx;
14970   else
14971     {
14972       operands[1] = gen_reg_rtx (Pmode);
14973       emit_insn (gen_set_got (operands[1]));
14974     }
14975   if (TARGET_GNU2_TLS)
14976     {
14977        emit_insn (gen_tls_dynamic_gnu2_32
14978                   (operands[0], ix86_tls_module_base (), operands[1]));
14979        DONE;
14980     }
14981   operands[2] = ix86_tls_get_addr ();
14982 })
14983
14984 (define_insn "*tls_local_dynamic_base_64"
14985   [(set (match_operand:DI 0 "register_operand" "=a")
14986         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14987                  (match_operand:DI 2 "" "")))
14988    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14989   "TARGET_64BIT"
14990   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14991   [(set_attr "type" "multi")
14992    (set_attr "length" "12")])
14993
14994 (define_expand "tls_local_dynamic_base_64"
14995   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14996                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14997               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14998   ""
14999 {
15000   if (TARGET_GNU2_TLS)
15001     {
15002        emit_insn (gen_tls_dynamic_gnu2_64
15003                   (operands[0], ix86_tls_module_base ()));
15004        DONE;
15005     }
15006   operands[1] = ix86_tls_get_addr ();
15007 })
15008
15009 ;; Local dynamic of a single variable is a lose.  Show combine how
15010 ;; to convert that back to global dynamic.
15011
15012 (define_insn_and_split "*tls_local_dynamic_32_once"
15013   [(set (match_operand:SI 0 "register_operand" "=a")
15014         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15015                              (match_operand:SI 2 "call_insn_operand" "")]
15016                             UNSPEC_TLS_LD_BASE)
15017                  (const:SI (unspec:SI
15018                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15019                             UNSPEC_DTPOFF))))
15020    (clobber (match_scratch:SI 4 "=d"))
15021    (clobber (match_scratch:SI 5 "=c"))
15022    (clobber (reg:CC FLAGS_REG))]
15023   ""
15024   "#"
15025   ""
15026   [(parallel [(set (match_dup 0)
15027                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15028                               UNSPEC_TLS_GD))
15029               (clobber (match_dup 4))
15030               (clobber (match_dup 5))
15031               (clobber (reg:CC FLAGS_REG))])]
15032   "")
15033
15034 ;; Load and add the thread base pointer from %gs:0.
15035
15036 (define_insn "*load_tp_si"
15037   [(set (match_operand:SI 0 "register_operand" "=r")
15038         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15039   "!TARGET_64BIT"
15040   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15041   [(set_attr "type" "imov")
15042    (set_attr "modrm" "0")
15043    (set_attr "length" "7")
15044    (set_attr "memory" "load")
15045    (set_attr "imm_disp" "false")])
15046
15047 (define_insn "*add_tp_si"
15048   [(set (match_operand:SI 0 "register_operand" "=r")
15049         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15050                  (match_operand:SI 1 "register_operand" "0")))
15051    (clobber (reg:CC FLAGS_REG))]
15052   "!TARGET_64BIT"
15053   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15054   [(set_attr "type" "alu")
15055    (set_attr "modrm" "0")
15056    (set_attr "length" "7")
15057    (set_attr "memory" "load")
15058    (set_attr "imm_disp" "false")])
15059
15060 (define_insn "*load_tp_di"
15061   [(set (match_operand:DI 0 "register_operand" "=r")
15062         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15063   "TARGET_64BIT"
15064   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15065   [(set_attr "type" "imov")
15066    (set_attr "modrm" "0")
15067    (set_attr "length" "7")
15068    (set_attr "memory" "load")
15069    (set_attr "imm_disp" "false")])
15070
15071 (define_insn "*add_tp_di"
15072   [(set (match_operand:DI 0 "register_operand" "=r")
15073         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15074                  (match_operand:DI 1 "register_operand" "0")))
15075    (clobber (reg:CC FLAGS_REG))]
15076   "TARGET_64BIT"
15077   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15078   [(set_attr "type" "alu")
15079    (set_attr "modrm" "0")
15080    (set_attr "length" "7")
15081    (set_attr "memory" "load")
15082    (set_attr "imm_disp" "false")])
15083
15084 ;; GNU2 TLS patterns can be split.
15085
15086 (define_expand "tls_dynamic_gnu2_32"
15087   [(set (match_dup 3)
15088         (plus:SI (match_operand:SI 2 "register_operand" "")
15089                  (const:SI
15090                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15091                              UNSPEC_TLSDESC))))
15092    (parallel
15093     [(set (match_operand:SI 0 "register_operand" "")
15094           (unspec:SI [(match_dup 1) (match_dup 3)
15095                       (match_dup 2) (reg:SI SP_REG)]
15096                       UNSPEC_TLSDESC))
15097      (clobber (reg:CC FLAGS_REG))])]
15098   "!TARGET_64BIT && TARGET_GNU2_TLS"
15099 {
15100   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15101   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15102 })
15103
15104 (define_insn "*tls_dynamic_lea_32"
15105   [(set (match_operand:SI 0 "register_operand" "=r")
15106         (plus:SI (match_operand:SI 1 "register_operand" "b")
15107                  (const:SI
15108                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15109                               UNSPEC_TLSDESC))))]
15110   "!TARGET_64BIT && TARGET_GNU2_TLS"
15111   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15112   [(set_attr "type" "lea")
15113    (set_attr "mode" "SI")
15114    (set_attr "length" "6")
15115    (set_attr "length_address" "4")])
15116
15117 (define_insn "*tls_dynamic_call_32"
15118   [(set (match_operand:SI 0 "register_operand" "=a")
15119         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15120                     (match_operand:SI 2 "register_operand" "0")
15121                     ;; we have to make sure %ebx still points to the GOT
15122                     (match_operand:SI 3 "register_operand" "b")
15123                     (reg:SI SP_REG)]
15124                    UNSPEC_TLSDESC))
15125    (clobber (reg:CC FLAGS_REG))]
15126   "!TARGET_64BIT && TARGET_GNU2_TLS"
15127   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15128   [(set_attr "type" "call")
15129    (set_attr "length" "2")
15130    (set_attr "length_address" "0")])
15131
15132 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15133   [(set (match_operand:SI 0 "register_operand" "=&a")
15134         (plus:SI
15135          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15136                      (match_operand:SI 4 "" "")
15137                      (match_operand:SI 2 "register_operand" "b")
15138                      (reg:SI SP_REG)]
15139                     UNSPEC_TLSDESC)
15140          (const:SI (unspec:SI
15141                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15142                     UNSPEC_DTPOFF))))
15143    (clobber (reg:CC FLAGS_REG))]
15144   "!TARGET_64BIT && TARGET_GNU2_TLS"
15145   "#"
15146   ""
15147   [(set (match_dup 0) (match_dup 5))]
15148 {
15149   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15150   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15151 })
15152
15153 (define_expand "tls_dynamic_gnu2_64"
15154   [(set (match_dup 2)
15155         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15156                    UNSPEC_TLSDESC))
15157    (parallel
15158     [(set (match_operand:DI 0 "register_operand" "")
15159           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15160                      UNSPEC_TLSDESC))
15161      (clobber (reg:CC FLAGS_REG))])]
15162   "TARGET_64BIT && TARGET_GNU2_TLS"
15163 {
15164   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15165   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15166 })
15167
15168 (define_insn "*tls_dynamic_lea_64"
15169   [(set (match_operand:DI 0 "register_operand" "=r")
15170         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15171                    UNSPEC_TLSDESC))]
15172   "TARGET_64BIT && TARGET_GNU2_TLS"
15173   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15174   [(set_attr "type" "lea")
15175    (set_attr "mode" "DI")
15176    (set_attr "length" "7")
15177    (set_attr "length_address" "4")])
15178
15179 (define_insn "*tls_dynamic_call_64"
15180   [(set (match_operand:DI 0 "register_operand" "=a")
15181         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15182                     (match_operand:DI 2 "register_operand" "0")
15183                     (reg:DI SP_REG)]
15184                    UNSPEC_TLSDESC))
15185    (clobber (reg:CC FLAGS_REG))]
15186   "TARGET_64BIT && TARGET_GNU2_TLS"
15187   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15188   [(set_attr "type" "call")
15189    (set_attr "length" "2")
15190    (set_attr "length_address" "0")])
15191
15192 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15193   [(set (match_operand:DI 0 "register_operand" "=&a")
15194         (plus:DI
15195          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15196                      (match_operand:DI 3 "" "")
15197                      (reg:DI SP_REG)]
15198                     UNSPEC_TLSDESC)
15199          (const:DI (unspec:DI
15200                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15201                     UNSPEC_DTPOFF))))
15202    (clobber (reg:CC FLAGS_REG))]
15203   "TARGET_64BIT && TARGET_GNU2_TLS"
15204   "#"
15205   ""
15206   [(set (match_dup 0) (match_dup 4))]
15207 {
15208   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15209   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15210 })
15211
15212 ;;
15213 \f
15214 ;; These patterns match the binary 387 instructions for addM3, subM3,
15215 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15216 ;; SFmode.  The first is the normal insn, the second the same insn but
15217 ;; with one operand a conversion, and the third the same insn but with
15218 ;; the other operand a conversion.  The conversion may be SFmode or
15219 ;; SImode if the target mode DFmode, but only SImode if the target mode
15220 ;; is SFmode.
15221
15222 ;; Gcc is slightly more smart about handling normal two address instructions
15223 ;; so use special patterns for add and mull.
15224
15225 (define_insn "*fop_sf_comm_mixed"
15226   [(set (match_operand:SF 0 "register_operand" "=f,x")
15227         (match_operator:SF 3 "binary_fp_operator"
15228                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15229                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15230   "TARGET_MIX_SSE_I387
15231    && COMMUTATIVE_ARITH_P (operands[3])
15232    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15233   "* return output_387_binary_op (insn, operands);"
15234   [(set (attr "type") 
15235         (if_then_else (eq_attr "alternative" "1")
15236            (if_then_else (match_operand:SF 3 "mult_operator" "") 
15237               (const_string "ssemul")
15238               (const_string "sseadd"))
15239            (if_then_else (match_operand:SF 3 "mult_operator" "") 
15240               (const_string "fmul")
15241               (const_string "fop"))))
15242    (set_attr "mode" "SF")])
15243
15244 (define_insn "*fop_sf_comm_sse"
15245   [(set (match_operand:SF 0 "register_operand" "=x")
15246         (match_operator:SF 3 "binary_fp_operator"
15247                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15248                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15249   "TARGET_SSE_MATH
15250    && COMMUTATIVE_ARITH_P (operands[3])
15251    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15252   "* return output_387_binary_op (insn, operands);"
15253   [(set (attr "type") 
15254         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15255            (const_string "ssemul")
15256            (const_string "sseadd")))
15257    (set_attr "mode" "SF")])
15258
15259 (define_insn "*fop_sf_comm_i387"
15260   [(set (match_operand:SF 0 "register_operand" "=f")
15261         (match_operator:SF 3 "binary_fp_operator"
15262                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15263                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15264   "TARGET_80387
15265    && COMMUTATIVE_ARITH_P (operands[3])
15266    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15267   "* return output_387_binary_op (insn, operands);"
15268   [(set (attr "type") 
15269         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15270            (const_string "fmul")
15271            (const_string "fop")))
15272    (set_attr "mode" "SF")])
15273
15274 (define_insn "*fop_sf_1_mixed"
15275   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15276         (match_operator:SF 3 "binary_fp_operator"
15277                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15278                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15279   "TARGET_MIX_SSE_I387
15280    && !COMMUTATIVE_ARITH_P (operands[3])
15281    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15282   "* return output_387_binary_op (insn, operands);"
15283   [(set (attr "type") 
15284         (cond [(and (eq_attr "alternative" "2")
15285                     (match_operand:SF 3 "mult_operator" ""))
15286                  (const_string "ssemul")
15287                (and (eq_attr "alternative" "2")
15288                     (match_operand:SF 3 "div_operator" ""))
15289                  (const_string "ssediv")
15290                (eq_attr "alternative" "2")
15291                  (const_string "sseadd")
15292                (match_operand:SF 3 "mult_operator" "") 
15293                  (const_string "fmul")
15294                (match_operand:SF 3 "div_operator" "") 
15295                  (const_string "fdiv")
15296               ]
15297               (const_string "fop")))
15298    (set_attr "mode" "SF")])
15299
15300 (define_insn "*fop_sf_1_sse"
15301   [(set (match_operand:SF 0 "register_operand" "=x")
15302         (match_operator:SF 3 "binary_fp_operator"
15303                         [(match_operand:SF 1 "register_operand" "0")
15304                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15305   "TARGET_SSE_MATH
15306    && !COMMUTATIVE_ARITH_P (operands[3])"
15307   "* return output_387_binary_op (insn, operands);"
15308   [(set (attr "type") 
15309         (cond [(match_operand:SF 3 "mult_operator" "")
15310                  (const_string "ssemul")
15311                (match_operand:SF 3 "div_operator" "")
15312                  (const_string "ssediv")
15313               ]
15314               (const_string "sseadd")))
15315    (set_attr "mode" "SF")])
15316
15317 ;; This pattern is not fully shadowed by the pattern above.
15318 (define_insn "*fop_sf_1_i387"
15319   [(set (match_operand:SF 0 "register_operand" "=f,f")
15320         (match_operator:SF 3 "binary_fp_operator"
15321                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15322                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15323   "TARGET_80387 && !TARGET_SSE_MATH
15324    && !COMMUTATIVE_ARITH_P (operands[3])
15325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15326   "* return output_387_binary_op (insn, operands);"
15327   [(set (attr "type") 
15328         (cond [(match_operand:SF 3 "mult_operator" "") 
15329                  (const_string "fmul")
15330                (match_operand:SF 3 "div_operator" "") 
15331                  (const_string "fdiv")
15332               ]
15333               (const_string "fop")))
15334    (set_attr "mode" "SF")])
15335
15336 ;; ??? Add SSE splitters for these!
15337 (define_insn "*fop_sf_2<mode>_i387"
15338   [(set (match_operand:SF 0 "register_operand" "=f,f")
15339         (match_operator:SF 3 "binary_fp_operator"
15340           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15341            (match_operand:SF 2 "register_operand" "0,0")]))]
15342   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15343   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15344   [(set (attr "type") 
15345         (cond [(match_operand:SF 3 "mult_operator" "") 
15346                  (const_string "fmul")
15347                (match_operand:SF 3 "div_operator" "") 
15348                  (const_string "fdiv")
15349               ]
15350               (const_string "fop")))
15351    (set_attr "fp_int_src" "true")
15352    (set_attr "mode" "<MODE>")])
15353
15354 (define_insn "*fop_sf_3<mode>_i387"
15355   [(set (match_operand:SF 0 "register_operand" "=f,f")
15356         (match_operator:SF 3 "binary_fp_operator"
15357           [(match_operand:SF 1 "register_operand" "0,0")
15358            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15359   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15360   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15361   [(set (attr "type") 
15362         (cond [(match_operand:SF 3 "mult_operator" "") 
15363                  (const_string "fmul")
15364                (match_operand:SF 3 "div_operator" "") 
15365                  (const_string "fdiv")
15366               ]
15367               (const_string "fop")))
15368    (set_attr "fp_int_src" "true")
15369    (set_attr "mode" "<MODE>")])
15370
15371 (define_insn "*fop_df_comm_mixed"
15372   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15373         (match_operator:DF 3 "binary_fp_operator"
15374                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15375                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15376   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15377    && COMMUTATIVE_ARITH_P (operands[3])
15378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15379   "* return output_387_binary_op (insn, operands);"
15380   [(set (attr "type") 
15381         (if_then_else (eq_attr "alternative" "1")
15382            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15383               (const_string "ssemul")
15384               (const_string "sseadd"))
15385            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15386               (const_string "fmul")
15387               (const_string "fop"))))
15388    (set_attr "mode" "DF")])
15389
15390 (define_insn "*fop_df_comm_sse"
15391   [(set (match_operand:DF 0 "register_operand" "=Y")
15392         (match_operator:DF 3 "binary_fp_operator"
15393                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15394                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15395   "TARGET_SSE2 && TARGET_SSE_MATH
15396    && COMMUTATIVE_ARITH_P (operands[3])
15397    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15398   "* return output_387_binary_op (insn, operands);"
15399   [(set (attr "type") 
15400         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15401            (const_string "ssemul")
15402            (const_string "sseadd")))
15403    (set_attr "mode" "DF")])
15404
15405 (define_insn "*fop_df_comm_i387"
15406   [(set (match_operand:DF 0 "register_operand" "=f")
15407         (match_operator:DF 3 "binary_fp_operator"
15408                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15409                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15410   "TARGET_80387
15411    && COMMUTATIVE_ARITH_P (operands[3])
15412    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15413   "* return output_387_binary_op (insn, operands);"
15414   [(set (attr "type") 
15415         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15416            (const_string "fmul")
15417            (const_string "fop")))
15418    (set_attr "mode" "DF")])
15419
15420 (define_insn "*fop_df_1_mixed"
15421   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15422         (match_operator:DF 3 "binary_fp_operator"
15423                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15424                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15425   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15426    && !COMMUTATIVE_ARITH_P (operands[3])
15427    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15428   "* return output_387_binary_op (insn, operands);"
15429   [(set (attr "type") 
15430         (cond [(and (eq_attr "alternative" "2")
15431                     (match_operand:DF 3 "mult_operator" ""))
15432                  (const_string "ssemul")
15433                (and (eq_attr "alternative" "2")
15434                     (match_operand:DF 3 "div_operator" ""))
15435                  (const_string "ssediv")
15436                (eq_attr "alternative" "2")
15437                  (const_string "sseadd")
15438                (match_operand:DF 3 "mult_operator" "") 
15439                  (const_string "fmul")
15440                (match_operand:DF 3 "div_operator" "") 
15441                  (const_string "fdiv")
15442               ]
15443               (const_string "fop")))
15444    (set_attr "mode" "DF")])
15445
15446 (define_insn "*fop_df_1_sse"
15447   [(set (match_operand:DF 0 "register_operand" "=Y")
15448         (match_operator:DF 3 "binary_fp_operator"
15449                         [(match_operand:DF 1 "register_operand" "0")
15450                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15451   "TARGET_SSE2 && TARGET_SSE_MATH
15452    && !COMMUTATIVE_ARITH_P (operands[3])"
15453   "* return output_387_binary_op (insn, operands);"
15454   [(set_attr "mode" "DF")
15455    (set (attr "type") 
15456         (cond [(match_operand:DF 3 "mult_operator" "")
15457                  (const_string "ssemul")
15458                (match_operand:DF 3 "div_operator" "")
15459                  (const_string "ssediv")
15460               ]
15461               (const_string "sseadd")))])
15462
15463 ;; This pattern is not fully shadowed by the pattern above.
15464 (define_insn "*fop_df_1_i387"
15465   [(set (match_operand:DF 0 "register_operand" "=f,f")
15466         (match_operator:DF 3 "binary_fp_operator"
15467                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15468                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15469   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15470    && !COMMUTATIVE_ARITH_P (operands[3])
15471    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15472   "* return output_387_binary_op (insn, operands);"
15473   [(set (attr "type") 
15474         (cond [(match_operand:DF 3 "mult_operator" "") 
15475                  (const_string "fmul")
15476                (match_operand:DF 3 "div_operator" "")
15477                  (const_string "fdiv")
15478               ]
15479               (const_string "fop")))
15480    (set_attr "mode" "DF")])
15481
15482 ;; ??? Add SSE splitters for these!
15483 (define_insn "*fop_df_2<mode>_i387"
15484   [(set (match_operand:DF 0 "register_operand" "=f,f")
15485         (match_operator:DF 3 "binary_fp_operator"
15486            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15487             (match_operand:DF 2 "register_operand" "0,0")]))]
15488   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15489    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15490   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15491   [(set (attr "type") 
15492         (cond [(match_operand:DF 3 "mult_operator" "") 
15493                  (const_string "fmul")
15494                (match_operand:DF 3 "div_operator" "") 
15495                  (const_string "fdiv")
15496               ]
15497               (const_string "fop")))
15498    (set_attr "fp_int_src" "true")
15499    (set_attr "mode" "<MODE>")])
15500
15501 (define_insn "*fop_df_3<mode>_i387"
15502   [(set (match_operand:DF 0 "register_operand" "=f,f")
15503         (match_operator:DF 3 "binary_fp_operator"
15504            [(match_operand:DF 1 "register_operand" "0,0")
15505             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15506   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15507    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15508   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15509   [(set (attr "type") 
15510         (cond [(match_operand:DF 3 "mult_operator" "") 
15511                  (const_string "fmul")
15512                (match_operand:DF 3 "div_operator" "") 
15513                  (const_string "fdiv")
15514               ]
15515               (const_string "fop")))
15516    (set_attr "fp_int_src" "true")
15517    (set_attr "mode" "<MODE>")])
15518
15519 (define_insn "*fop_df_4_i387"
15520   [(set (match_operand:DF 0 "register_operand" "=f,f")
15521         (match_operator:DF 3 "binary_fp_operator"
15522            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15523             (match_operand:DF 2 "register_operand" "0,f")]))]
15524   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15525    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15526   "* return output_387_binary_op (insn, operands);"
15527   [(set (attr "type") 
15528         (cond [(match_operand:DF 3 "mult_operator" "") 
15529                  (const_string "fmul")
15530                (match_operand:DF 3 "div_operator" "") 
15531                  (const_string "fdiv")
15532               ]
15533               (const_string "fop")))
15534    (set_attr "mode" "SF")])
15535
15536 (define_insn "*fop_df_5_i387"
15537   [(set (match_operand:DF 0 "register_operand" "=f,f")
15538         (match_operator:DF 3 "binary_fp_operator"
15539           [(match_operand:DF 1 "register_operand" "0,f")
15540            (float_extend:DF
15541             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15542   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15543   "* return output_387_binary_op (insn, operands);"
15544   [(set (attr "type") 
15545         (cond [(match_operand:DF 3 "mult_operator" "") 
15546                  (const_string "fmul")
15547                (match_operand:DF 3 "div_operator" "") 
15548                  (const_string "fdiv")
15549               ]
15550               (const_string "fop")))
15551    (set_attr "mode" "SF")])
15552
15553 (define_insn "*fop_df_6_i387"
15554   [(set (match_operand:DF 0 "register_operand" "=f,f")
15555         (match_operator:DF 3 "binary_fp_operator"
15556           [(float_extend:DF
15557             (match_operand:SF 1 "register_operand" "0,f"))
15558            (float_extend:DF
15559             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15560   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15561   "* return output_387_binary_op (insn, operands);"
15562   [(set (attr "type") 
15563         (cond [(match_operand:DF 3 "mult_operator" "") 
15564                  (const_string "fmul")
15565                (match_operand:DF 3 "div_operator" "") 
15566                  (const_string "fdiv")
15567               ]
15568               (const_string "fop")))
15569    (set_attr "mode" "SF")])
15570
15571 (define_insn "*fop_xf_comm_i387"
15572   [(set (match_operand:XF 0 "register_operand" "=f")
15573         (match_operator:XF 3 "binary_fp_operator"
15574                         [(match_operand:XF 1 "register_operand" "%0")
15575                          (match_operand:XF 2 "register_operand" "f")]))]
15576   "TARGET_80387
15577    && COMMUTATIVE_ARITH_P (operands[3])"
15578   "* return output_387_binary_op (insn, operands);"
15579   [(set (attr "type") 
15580         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15581            (const_string "fmul")
15582            (const_string "fop")))
15583    (set_attr "mode" "XF")])
15584
15585 (define_insn "*fop_xf_1_i387"
15586   [(set (match_operand:XF 0 "register_operand" "=f,f")
15587         (match_operator:XF 3 "binary_fp_operator"
15588                         [(match_operand:XF 1 "register_operand" "0,f")
15589                          (match_operand:XF 2 "register_operand" "f,0")]))]
15590   "TARGET_80387
15591    && !COMMUTATIVE_ARITH_P (operands[3])"
15592   "* return output_387_binary_op (insn, operands);"
15593   [(set (attr "type") 
15594         (cond [(match_operand:XF 3 "mult_operator" "") 
15595                  (const_string "fmul")
15596                (match_operand:XF 3 "div_operator" "") 
15597                  (const_string "fdiv")
15598               ]
15599               (const_string "fop")))
15600    (set_attr "mode" "XF")])
15601
15602 (define_insn "*fop_xf_2<mode>_i387"
15603   [(set (match_operand:XF 0 "register_operand" "=f,f")
15604         (match_operator:XF 3 "binary_fp_operator"
15605            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15606             (match_operand:XF 2 "register_operand" "0,0")]))]
15607   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15608   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15609   [(set (attr "type") 
15610         (cond [(match_operand:XF 3 "mult_operator" "") 
15611                  (const_string "fmul")
15612                (match_operand:XF 3 "div_operator" "") 
15613                  (const_string "fdiv")
15614               ]
15615               (const_string "fop")))
15616    (set_attr "fp_int_src" "true")
15617    (set_attr "mode" "<MODE>")])
15618
15619 (define_insn "*fop_xf_3<mode>_i387"
15620   [(set (match_operand:XF 0 "register_operand" "=f,f")
15621         (match_operator:XF 3 "binary_fp_operator"
15622           [(match_operand:XF 1 "register_operand" "0,0")
15623            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15624   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15625   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15626   [(set (attr "type") 
15627         (cond [(match_operand:XF 3 "mult_operator" "") 
15628                  (const_string "fmul")
15629                (match_operand:XF 3 "div_operator" "") 
15630                  (const_string "fdiv")
15631               ]
15632               (const_string "fop")))
15633    (set_attr "fp_int_src" "true")
15634    (set_attr "mode" "<MODE>")])
15635
15636 (define_insn "*fop_xf_4_i387"
15637   [(set (match_operand:XF 0 "register_operand" "=f,f")
15638         (match_operator:XF 3 "binary_fp_operator"
15639            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15640             (match_operand:XF 2 "register_operand" "0,f")]))]
15641   "TARGET_80387"
15642   "* return output_387_binary_op (insn, operands);"
15643   [(set (attr "type") 
15644         (cond [(match_operand:XF 3 "mult_operator" "") 
15645                  (const_string "fmul")
15646                (match_operand:XF 3 "div_operator" "") 
15647                  (const_string "fdiv")
15648               ]
15649               (const_string "fop")))
15650    (set_attr "mode" "SF")])
15651
15652 (define_insn "*fop_xf_5_i387"
15653   [(set (match_operand:XF 0 "register_operand" "=f,f")
15654         (match_operator:XF 3 "binary_fp_operator"
15655           [(match_operand:XF 1 "register_operand" "0,f")
15656            (float_extend:XF
15657             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15658   "TARGET_80387"
15659   "* return output_387_binary_op (insn, operands);"
15660   [(set (attr "type") 
15661         (cond [(match_operand:XF 3 "mult_operator" "") 
15662                  (const_string "fmul")
15663                (match_operand:XF 3 "div_operator" "") 
15664                  (const_string "fdiv")
15665               ]
15666               (const_string "fop")))
15667    (set_attr "mode" "SF")])
15668
15669 (define_insn "*fop_xf_6_i387"
15670   [(set (match_operand:XF 0 "register_operand" "=f,f")
15671         (match_operator:XF 3 "binary_fp_operator"
15672           [(float_extend:XF
15673             (match_operand 1 "register_operand" "0,f"))
15674            (float_extend:XF
15675             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15676   "TARGET_80387"
15677   "* return output_387_binary_op (insn, operands);"
15678   [(set (attr "type") 
15679         (cond [(match_operand:XF 3 "mult_operator" "") 
15680                  (const_string "fmul")
15681                (match_operand:XF 3 "div_operator" "") 
15682                  (const_string "fdiv")
15683               ]
15684               (const_string "fop")))
15685    (set_attr "mode" "SF")])
15686
15687 (define_split
15688   [(set (match_operand 0 "register_operand" "")
15689         (match_operator 3 "binary_fp_operator"
15690            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15691             (match_operand 2 "register_operand" "")]))]
15692   "TARGET_80387 && reload_completed
15693    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15694   [(const_int 0)]
15695
15696   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15697   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15698   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15699                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15700                                           GET_MODE (operands[3]),
15701                                           operands[4],
15702                                           operands[2])));
15703   ix86_free_from_memory (GET_MODE (operands[1]));
15704   DONE;
15705 })
15706
15707 (define_split
15708   [(set (match_operand 0 "register_operand" "")
15709         (match_operator 3 "binary_fp_operator"
15710            [(match_operand 1 "register_operand" "")
15711             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15712   "TARGET_80387 && reload_completed
15713    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15714   [(const_int 0)]
15715 {
15716   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15717   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15718   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15719                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15720                                           GET_MODE (operands[3]),
15721                                           operands[1],
15722                                           operands[4])));
15723   ix86_free_from_memory (GET_MODE (operands[2]));
15724   DONE;
15725 })
15726 \f
15727 ;; FPU special functions.
15728
15729 (define_expand "sqrtsf2"
15730   [(set (match_operand:SF 0 "register_operand" "")
15731         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15732   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15733 {
15734   if (!TARGET_SSE_MATH)
15735     operands[1] = force_reg (SFmode, operands[1]);
15736 })
15737
15738 (define_insn "*sqrtsf2_mixed"
15739   [(set (match_operand:SF 0 "register_operand" "=f,x")
15740         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15741   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15742   "@
15743    fsqrt
15744    sqrtss\t{%1, %0|%0, %1}"
15745   [(set_attr "type" "fpspc,sse")
15746    (set_attr "mode" "SF,SF")
15747    (set_attr "athlon_decode" "direct,*")
15748    (set_attr "amdfam10_decode" "direct,*")])
15749
15750 (define_insn "*sqrtsf2_sse"
15751   [(set (match_operand:SF 0 "register_operand" "=x")
15752         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15753   "TARGET_SSE_MATH"
15754   "sqrtss\t{%1, %0|%0, %1}"
15755   [(set_attr "type" "sse")
15756    (set_attr "mode" "SF")
15757    (set_attr "athlon_decode" "*")
15758    (set_attr "amdfam10_decode" "*")])
15759
15760 (define_insn "*sqrtsf2_i387"
15761   [(set (match_operand:SF 0 "register_operand" "=f")
15762         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15763   "TARGET_USE_FANCY_MATH_387"
15764   "fsqrt"
15765   [(set_attr "type" "fpspc")
15766    (set_attr "mode" "SF")
15767    (set_attr "athlon_decode" "direct")
15768    (set_attr "amdfam10_decode" "direct")])
15769
15770 (define_expand "sqrtdf2"
15771   [(set (match_operand:DF 0 "register_operand" "")
15772         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15773   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15774 {
15775   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15776     operands[1] = force_reg (DFmode, operands[1]);
15777 })
15778
15779 (define_insn "*sqrtdf2_mixed"
15780   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15781         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15782   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15783   "@
15784    fsqrt
15785    sqrtsd\t{%1, %0|%0, %1}"
15786   [(set_attr "type" "fpspc,sse")
15787    (set_attr "mode" "DF,DF")
15788    (set_attr "athlon_decode" "direct,*")
15789    (set_attr "amdfam10_decode" "direct,*")])
15790
15791 (define_insn "*sqrtdf2_sse"
15792   [(set (match_operand:DF 0 "register_operand" "=Y")
15793         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15794   "TARGET_SSE2 && TARGET_SSE_MATH"
15795   "sqrtsd\t{%1, %0|%0, %1}"
15796   [(set_attr "type" "sse")
15797    (set_attr "mode" "DF")
15798    (set_attr "athlon_decode" "*")
15799    (set_attr "amdfam10_decode" "*")])
15800
15801 (define_insn "*sqrtdf2_i387"
15802   [(set (match_operand:DF 0 "register_operand" "=f")
15803         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15804   "TARGET_USE_FANCY_MATH_387"
15805   "fsqrt"
15806   [(set_attr "type" "fpspc")
15807    (set_attr "mode" "DF")
15808    (set_attr "athlon_decode" "direct")
15809    (set_attr "amdfam10_decode" "direct")])
15810
15811 (define_insn "*sqrtextendsfdf2_i387"
15812   [(set (match_operand:DF 0 "register_operand" "=f")
15813         (sqrt:DF (float_extend:DF
15814                   (match_operand:SF 1 "register_operand" "0"))))]
15815   "TARGET_USE_FANCY_MATH_387
15816    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15817   "fsqrt"
15818   [(set_attr "type" "fpspc")
15819    (set_attr "mode" "DF")
15820    (set_attr "athlon_decode" "direct")
15821    (set_attr "amdfam10_decode" "direct")])
15822
15823 (define_insn "sqrtxf2"
15824   [(set (match_operand:XF 0 "register_operand" "=f")
15825         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15826   "TARGET_USE_FANCY_MATH_387"
15827   "fsqrt"
15828   [(set_attr "type" "fpspc")
15829    (set_attr "mode" "XF")
15830    (set_attr "athlon_decode" "direct")
15831    (set_attr "amdfam10_decode" "direct")])
15832
15833 (define_insn "*sqrtextendsfxf2_i387"
15834   [(set (match_operand:XF 0 "register_operand" "=f")
15835         (sqrt:XF (float_extend:XF
15836                   (match_operand:SF 1 "register_operand" "0"))))]
15837   "TARGET_USE_FANCY_MATH_387"
15838   "fsqrt"
15839   [(set_attr "type" "fpspc")
15840    (set_attr "mode" "XF")
15841    (set_attr "athlon_decode" "direct")
15842    (set_attr "amdfam10_decode" "direct")])
15843
15844 (define_insn "*sqrtextenddfxf2_i387"
15845   [(set (match_operand:XF 0 "register_operand" "=f")
15846         (sqrt:XF (float_extend:XF
15847                   (match_operand:DF 1 "register_operand" "0"))))]
15848   "TARGET_USE_FANCY_MATH_387"
15849   "fsqrt"
15850   [(set_attr "type" "fpspc")
15851    (set_attr "mode" "XF")
15852    (set_attr "athlon_decode" "direct")
15853    (set_attr "amdfam10_decode" "direct")])
15854
15855 (define_insn "fpremxf4"
15856   [(set (match_operand:XF 0 "register_operand" "=f")
15857         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15858                     (match_operand:XF 3 "register_operand" "1")]
15859                    UNSPEC_FPREM_F))
15860    (set (match_operand:XF 1 "register_operand" "=u")
15861         (unspec:XF [(match_dup 2) (match_dup 3)]
15862                    UNSPEC_FPREM_U))
15863    (set (reg:CCFP FPSR_REG)
15864         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15865   "TARGET_USE_FANCY_MATH_387
15866    && flag_unsafe_math_optimizations"
15867   "fprem"
15868   [(set_attr "type" "fpspc")
15869    (set_attr "mode" "XF")])
15870
15871 (define_expand "fmodsf3"
15872   [(use (match_operand:SF 0 "register_operand" ""))
15873    (use (match_operand:SF 1 "register_operand" ""))
15874    (use (match_operand:SF 2 "register_operand" ""))]
15875   "TARGET_USE_FANCY_MATH_387
15876    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15877    && flag_unsafe_math_optimizations"
15878 {
15879   rtx label = gen_label_rtx ();
15880
15881   rtx op1 = gen_reg_rtx (XFmode);
15882   rtx op2 = gen_reg_rtx (XFmode);
15883
15884   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15885   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15886
15887   emit_label (label);
15888
15889   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15890   ix86_emit_fp_unordered_jump (label);
15891
15892   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15893   DONE;
15894 })
15895
15896 (define_expand "fmoddf3"
15897   [(use (match_operand:DF 0 "register_operand" ""))
15898    (use (match_operand:DF 1 "register_operand" ""))
15899    (use (match_operand:DF 2 "register_operand" ""))]
15900   "TARGET_USE_FANCY_MATH_387
15901    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902    && flag_unsafe_math_optimizations"
15903 {
15904   rtx label = gen_label_rtx ();
15905
15906   rtx op1 = gen_reg_rtx (XFmode);
15907   rtx op2 = gen_reg_rtx (XFmode);
15908
15909   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15910   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15911
15912   emit_label (label);
15913
15914   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15915   ix86_emit_fp_unordered_jump (label);
15916
15917   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15918   DONE;
15919 })
15920
15921 (define_expand "fmodxf3"
15922   [(use (match_operand:XF 0 "register_operand" ""))
15923    (use (match_operand:XF 1 "register_operand" ""))
15924    (use (match_operand:XF 2 "register_operand" ""))]
15925   "TARGET_USE_FANCY_MATH_387
15926    && flag_unsafe_math_optimizations"
15927 {
15928   rtx label = gen_label_rtx ();
15929
15930   emit_label (label);
15931
15932   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15933                            operands[1], operands[2]));
15934   ix86_emit_fp_unordered_jump (label);
15935
15936   emit_move_insn (operands[0], operands[1]);
15937   DONE;
15938 })
15939
15940 (define_insn "fprem1xf4"
15941   [(set (match_operand:XF 0 "register_operand" "=f")
15942         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15943                     (match_operand:XF 3 "register_operand" "1")]
15944                    UNSPEC_FPREM1_F))
15945    (set (match_operand:XF 1 "register_operand" "=u")
15946         (unspec:XF [(match_dup 2) (match_dup 3)]
15947                    UNSPEC_FPREM1_U))
15948    (set (reg:CCFP FPSR_REG)
15949         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15950   "TARGET_USE_FANCY_MATH_387
15951    && flag_unsafe_math_optimizations"
15952   "fprem1"
15953   [(set_attr "type" "fpspc")
15954    (set_attr "mode" "XF")])
15955
15956 (define_expand "dremsf3"
15957   [(use (match_operand:SF 0 "register_operand" ""))
15958    (use (match_operand:SF 1 "register_operand" ""))
15959    (use (match_operand:SF 2 "register_operand" ""))]
15960   "TARGET_USE_FANCY_MATH_387
15961    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15962    && flag_unsafe_math_optimizations"
15963 {
15964   rtx label = gen_label_rtx ();
15965
15966   rtx op1 = gen_reg_rtx (XFmode);
15967   rtx op2 = gen_reg_rtx (XFmode);
15968
15969   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15970   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15971
15972   emit_label (label);
15973
15974   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15975   ix86_emit_fp_unordered_jump (label);
15976
15977   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15978   DONE;
15979 })
15980
15981 (define_expand "dremdf3"
15982   [(use (match_operand:DF 0 "register_operand" ""))
15983    (use (match_operand:DF 1 "register_operand" ""))
15984    (use (match_operand:DF 2 "register_operand" ""))]
15985   "TARGET_USE_FANCY_MATH_387
15986    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987    && flag_unsafe_math_optimizations"
15988 {
15989   rtx label = gen_label_rtx ();
15990
15991   rtx op1 = gen_reg_rtx (XFmode);
15992   rtx op2 = gen_reg_rtx (XFmode);
15993
15994   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15995   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15996
15997   emit_label (label);
15998
15999   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16000   ix86_emit_fp_unordered_jump (label);
16001
16002   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16003   DONE;
16004 })
16005
16006 (define_expand "dremxf3"
16007   [(use (match_operand:XF 0 "register_operand" ""))
16008    (use (match_operand:XF 1 "register_operand" ""))
16009    (use (match_operand:XF 2 "register_operand" ""))]
16010   "TARGET_USE_FANCY_MATH_387
16011    && flag_unsafe_math_optimizations"
16012 {
16013   rtx label = gen_label_rtx ();
16014
16015   emit_label (label);
16016
16017   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16018                             operands[1], operands[2]));
16019   ix86_emit_fp_unordered_jump (label);
16020
16021   emit_move_insn (operands[0], operands[1]);
16022   DONE;
16023 })
16024
16025 (define_insn "*sindf2"
16026   [(set (match_operand:DF 0 "register_operand" "=f")
16027         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16028   "TARGET_USE_FANCY_MATH_387
16029    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16030    && flag_unsafe_math_optimizations"
16031   "fsin"
16032   [(set_attr "type" "fpspc")
16033    (set_attr "mode" "DF")])
16034
16035 (define_insn "*sinsf2"
16036   [(set (match_operand:SF 0 "register_operand" "=f")
16037         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16038   "TARGET_USE_FANCY_MATH_387
16039    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16040    && flag_unsafe_math_optimizations"
16041   "fsin"
16042   [(set_attr "type" "fpspc")
16043    (set_attr "mode" "SF")])
16044
16045 (define_insn "*sinextendsfdf2"
16046   [(set (match_operand:DF 0 "register_operand" "=f")
16047         (unspec:DF [(float_extend:DF
16048                      (match_operand:SF 1 "register_operand" "0"))]
16049                    UNSPEC_SIN))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16052    && flag_unsafe_math_optimizations"
16053   "fsin"
16054   [(set_attr "type" "fpspc")
16055    (set_attr "mode" "DF")])
16056
16057 (define_insn "*sinxf2"
16058   [(set (match_operand:XF 0 "register_operand" "=f")
16059         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16060   "TARGET_USE_FANCY_MATH_387
16061    && flag_unsafe_math_optimizations"
16062   "fsin"
16063   [(set_attr "type" "fpspc")
16064    (set_attr "mode" "XF")])
16065
16066 (define_insn "*cosdf2"
16067   [(set (match_operand:DF 0 "register_operand" "=f")
16068         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16069   "TARGET_USE_FANCY_MATH_387
16070    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16071    && flag_unsafe_math_optimizations"
16072   "fcos"
16073   [(set_attr "type" "fpspc")
16074    (set_attr "mode" "DF")])
16075
16076 (define_insn "*cossf2"
16077   [(set (match_operand:SF 0 "register_operand" "=f")
16078         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16079   "TARGET_USE_FANCY_MATH_387
16080    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16081    && flag_unsafe_math_optimizations"
16082   "fcos"
16083   [(set_attr "type" "fpspc")
16084    (set_attr "mode" "SF")])
16085
16086 (define_insn "*cosextendsfdf2"
16087   [(set (match_operand:DF 0 "register_operand" "=f")
16088         (unspec:DF [(float_extend:DF
16089                      (match_operand:SF 1 "register_operand" "0"))]
16090                    UNSPEC_COS))]
16091   "TARGET_USE_FANCY_MATH_387
16092    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16093    && flag_unsafe_math_optimizations"
16094   "fcos"
16095   [(set_attr "type" "fpspc")
16096    (set_attr "mode" "DF")])
16097
16098 (define_insn "*cosxf2"
16099   [(set (match_operand:XF 0 "register_operand" "=f")
16100         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16101   "TARGET_USE_FANCY_MATH_387
16102    && flag_unsafe_math_optimizations"
16103   "fcos"
16104   [(set_attr "type" "fpspc")
16105    (set_attr "mode" "XF")])
16106
16107 ;; With sincos pattern defined, sin and cos builtin function will be
16108 ;; expanded to sincos pattern with one of its outputs left unused. 
16109 ;; Cse pass  will detected, if two sincos patterns can be combined,
16110 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16111 ;; depending on the unused output.
16112
16113 (define_insn "sincosdf3"
16114   [(set (match_operand:DF 0 "register_operand" "=f")
16115         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16116                    UNSPEC_SINCOS_COS))
16117    (set (match_operand:DF 1 "register_operand" "=u")
16118         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16119   "TARGET_USE_FANCY_MATH_387
16120    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16121    && flag_unsafe_math_optimizations"
16122   "fsincos"
16123   [(set_attr "type" "fpspc")
16124    (set_attr "mode" "DF")])
16125
16126 (define_split
16127   [(set (match_operand:DF 0 "register_operand" "")
16128         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16129                    UNSPEC_SINCOS_COS))
16130    (set (match_operand:DF 1 "register_operand" "")
16131         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16132   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16133    && !reload_completed && !reload_in_progress"
16134   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16135   "")
16136
16137 (define_split
16138   [(set (match_operand:DF 0 "register_operand" "")
16139         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16140                    UNSPEC_SINCOS_COS))
16141    (set (match_operand:DF 1 "register_operand" "")
16142         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16143   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16144    && !reload_completed && !reload_in_progress"
16145   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16146   "")
16147
16148 (define_insn "sincossf3"
16149   [(set (match_operand:SF 0 "register_operand" "=f")
16150         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16151                    UNSPEC_SINCOS_COS))
16152    (set (match_operand:SF 1 "register_operand" "=u")
16153         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16154   "TARGET_USE_FANCY_MATH_387
16155    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16156    && flag_unsafe_math_optimizations"
16157   "fsincos"
16158   [(set_attr "type" "fpspc")
16159    (set_attr "mode" "SF")])
16160
16161 (define_split
16162   [(set (match_operand:SF 0 "register_operand" "")
16163         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16164                    UNSPEC_SINCOS_COS))
16165    (set (match_operand:SF 1 "register_operand" "")
16166         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16167   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16168    && !reload_completed && !reload_in_progress"
16169   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16170   "")
16171
16172 (define_split
16173   [(set (match_operand:SF 0 "register_operand" "")
16174         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16175                    UNSPEC_SINCOS_COS))
16176    (set (match_operand:SF 1 "register_operand" "")
16177         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16178   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16179    && !reload_completed && !reload_in_progress"
16180   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16181   "")
16182
16183 (define_insn "*sincosextendsfdf3"
16184   [(set (match_operand:DF 0 "register_operand" "=f")
16185         (unspec:DF [(float_extend:DF
16186                      (match_operand:SF 2 "register_operand" "0"))]
16187                    UNSPEC_SINCOS_COS))
16188    (set (match_operand:DF 1 "register_operand" "=u")
16189         (unspec:DF [(float_extend:DF
16190                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16193    && flag_unsafe_math_optimizations"
16194   "fsincos"
16195   [(set_attr "type" "fpspc")
16196    (set_attr "mode" "DF")])
16197
16198 (define_split
16199   [(set (match_operand:DF 0 "register_operand" "")
16200         (unspec:DF [(float_extend:DF
16201                      (match_operand:SF 2 "register_operand" ""))]
16202                    UNSPEC_SINCOS_COS))
16203    (set (match_operand:DF 1 "register_operand" "")
16204         (unspec:DF [(float_extend:DF
16205                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16206   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16207    && !reload_completed && !reload_in_progress"
16208   [(set (match_dup 1) (unspec:DF [(float_extend:DF
16209                                    (match_dup 2))] UNSPEC_SIN))]
16210   "")
16211
16212 (define_split
16213   [(set (match_operand:DF 0 "register_operand" "")
16214         (unspec:DF [(float_extend:DF
16215                      (match_operand:SF 2 "register_operand" ""))]
16216                    UNSPEC_SINCOS_COS))
16217    (set (match_operand:DF 1 "register_operand" "")
16218         (unspec:DF [(float_extend:DF
16219                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16220   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16221    && !reload_completed && !reload_in_progress"
16222   [(set (match_dup 0) (unspec:DF [(float_extend:DF
16223                                    (match_dup 2))] UNSPEC_COS))]
16224   "")
16225
16226 (define_insn "sincosxf3"
16227   [(set (match_operand:XF 0 "register_operand" "=f")
16228         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16229                    UNSPEC_SINCOS_COS))
16230    (set (match_operand:XF 1 "register_operand" "=u")
16231         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && flag_unsafe_math_optimizations"
16234   "fsincos"
16235   [(set_attr "type" "fpspc")
16236    (set_attr "mode" "XF")])
16237
16238 (define_split
16239   [(set (match_operand:XF 0 "register_operand" "")
16240         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16241                    UNSPEC_SINCOS_COS))
16242    (set (match_operand:XF 1 "register_operand" "")
16243         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16244   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16245    && !reload_completed && !reload_in_progress"
16246   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16247   "")
16248
16249 (define_split
16250   [(set (match_operand:XF 0 "register_operand" "")
16251         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16252                    UNSPEC_SINCOS_COS))
16253    (set (match_operand:XF 1 "register_operand" "")
16254         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16255   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16256    && !reload_completed && !reload_in_progress"
16257   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16258   "")
16259
16260 (define_insn "*tandf3_1"
16261   [(set (match_operand:DF 0 "register_operand" "=f")
16262         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16263                    UNSPEC_TAN_ONE))
16264    (set (match_operand:DF 1 "register_operand" "=u")
16265         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16266   "TARGET_USE_FANCY_MATH_387
16267    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16268    && flag_unsafe_math_optimizations"
16269   "fptan"
16270   [(set_attr "type" "fpspc")
16271    (set_attr "mode" "DF")])
16272
16273 ;; optimize sequence: fptan
16274 ;;                    fstp    %st(0)
16275 ;;                    fld1
16276 ;; into fptan insn.
16277
16278 (define_peephole2
16279   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16280                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16281                              UNSPEC_TAN_ONE))
16282              (set (match_operand:DF 1 "register_operand" "")
16283                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16284    (set (match_dup 0)
16285         (match_operand:DF 3 "immediate_operand" ""))]
16286   "standard_80387_constant_p (operands[3]) == 2"
16287   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16288              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16289   "")
16290
16291 (define_expand "tandf2"
16292   [(parallel [(set (match_dup 2)
16293                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16294                               UNSPEC_TAN_ONE))
16295               (set (match_operand:DF 0 "register_operand" "")
16296                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16297   "TARGET_USE_FANCY_MATH_387
16298    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16299    && flag_unsafe_math_optimizations"
16300 {
16301   operands[2] = gen_reg_rtx (DFmode);
16302 })
16303
16304 (define_insn "*tansf3_1"
16305   [(set (match_operand:SF 0 "register_operand" "=f")
16306         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16307                    UNSPEC_TAN_ONE))
16308    (set (match_operand:SF 1 "register_operand" "=u")
16309         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16310   "TARGET_USE_FANCY_MATH_387
16311    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16312    && flag_unsafe_math_optimizations"
16313   "fptan"
16314   [(set_attr "type" "fpspc")
16315    (set_attr "mode" "SF")])
16316
16317 ;; optimize sequence: fptan
16318 ;;                    fstp    %st(0)
16319 ;;                    fld1
16320 ;; into fptan insn.
16321
16322 (define_peephole2
16323   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16324                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16325                              UNSPEC_TAN_ONE))
16326              (set (match_operand:SF 1 "register_operand" "")
16327                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16328    (set (match_dup 0)
16329         (match_operand:SF 3 "immediate_operand" ""))]
16330   "standard_80387_constant_p (operands[3]) == 2"
16331   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16332              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16333   "")
16334
16335 (define_expand "tansf2"
16336   [(parallel [(set (match_dup 2)
16337                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16338                               UNSPEC_TAN_ONE))
16339               (set (match_operand:SF 0 "register_operand" "")
16340                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16341   "TARGET_USE_FANCY_MATH_387
16342    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16343    && flag_unsafe_math_optimizations"
16344 {
16345   operands[2] = gen_reg_rtx (SFmode);
16346 })
16347
16348 (define_insn "*tanxf3_1"
16349   [(set (match_operand:XF 0 "register_operand" "=f")
16350         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16351                    UNSPEC_TAN_ONE))
16352    (set (match_operand:XF 1 "register_operand" "=u")
16353         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16354   "TARGET_USE_FANCY_MATH_387
16355    && flag_unsafe_math_optimizations"
16356   "fptan"
16357   [(set_attr "type" "fpspc")
16358    (set_attr "mode" "XF")])
16359
16360 ;; optimize sequence: fptan
16361 ;;                    fstp    %st(0)
16362 ;;                    fld1
16363 ;; into fptan insn.
16364
16365 (define_peephole2
16366   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16367                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16368                              UNSPEC_TAN_ONE))
16369              (set (match_operand:XF 1 "register_operand" "")
16370                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16371    (set (match_dup 0)
16372         (match_operand:XF 3 "immediate_operand" ""))]
16373   "standard_80387_constant_p (operands[3]) == 2"
16374   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16375              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16376   "")
16377
16378 (define_expand "tanxf2"
16379   [(parallel [(set (match_dup 2)
16380                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16381                               UNSPEC_TAN_ONE))
16382               (set (match_operand:XF 0 "register_operand" "")
16383                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16384   "TARGET_USE_FANCY_MATH_387
16385    && flag_unsafe_math_optimizations"
16386 {
16387   operands[2] = gen_reg_rtx (XFmode);
16388 })
16389
16390 (define_insn "atan2df3_1"
16391   [(set (match_operand:DF 0 "register_operand" "=f")
16392         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16393                     (match_operand:DF 1 "register_operand" "u")]
16394                    UNSPEC_FPATAN))
16395    (clobber (match_scratch:DF 3 "=1"))]
16396   "TARGET_USE_FANCY_MATH_387
16397    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16398    && flag_unsafe_math_optimizations"
16399   "fpatan"
16400   [(set_attr "type" "fpspc")
16401    (set_attr "mode" "DF")])
16402
16403 (define_expand "atan2df3"
16404   [(use (match_operand:DF 0 "register_operand" ""))
16405    (use (match_operand:DF 2 "register_operand" ""))
16406    (use (match_operand:DF 1 "register_operand" ""))]
16407   "TARGET_USE_FANCY_MATH_387
16408    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16409    && flag_unsafe_math_optimizations"
16410 {
16411   rtx copy = gen_reg_rtx (DFmode);
16412   emit_move_insn (copy, operands[1]);
16413   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16414   DONE;
16415 })
16416
16417 (define_expand "atandf2"
16418   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16419                    (unspec:DF [(match_dup 2)
16420                                (match_operand:DF 1 "register_operand" "")]
16421                     UNSPEC_FPATAN))
16422               (clobber (match_scratch:DF 3 ""))])]
16423   "TARGET_USE_FANCY_MATH_387
16424    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16425    && flag_unsafe_math_optimizations"
16426 {
16427   operands[2] = gen_reg_rtx (DFmode);
16428   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16429 })
16430
16431 (define_insn "atan2sf3_1"
16432   [(set (match_operand:SF 0 "register_operand" "=f")
16433         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16434                     (match_operand:SF 1 "register_operand" "u")]
16435                    UNSPEC_FPATAN))
16436    (clobber (match_scratch:SF 3 "=1"))]
16437   "TARGET_USE_FANCY_MATH_387
16438    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16439    && flag_unsafe_math_optimizations"
16440   "fpatan"
16441   [(set_attr "type" "fpspc")
16442    (set_attr "mode" "SF")])
16443
16444 (define_expand "atan2sf3"
16445   [(use (match_operand:SF 0 "register_operand" ""))
16446    (use (match_operand:SF 2 "register_operand" ""))
16447    (use (match_operand:SF 1 "register_operand" ""))]
16448   "TARGET_USE_FANCY_MATH_387
16449    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16450    && flag_unsafe_math_optimizations"
16451 {
16452   rtx copy = gen_reg_rtx (SFmode);
16453   emit_move_insn (copy, operands[1]);
16454   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16455   DONE;
16456 })
16457
16458 (define_expand "atansf2"
16459   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16460                    (unspec:SF [(match_dup 2)
16461                                (match_operand:SF 1 "register_operand" "")]
16462                     UNSPEC_FPATAN))
16463               (clobber (match_scratch:SF 3 ""))])]
16464   "TARGET_USE_FANCY_MATH_387
16465    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466    && flag_unsafe_math_optimizations"
16467 {
16468   operands[2] = gen_reg_rtx (SFmode);
16469   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16470 })
16471
16472 (define_insn "atan2xf3_1"
16473   [(set (match_operand:XF 0 "register_operand" "=f")
16474         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16475                     (match_operand:XF 1 "register_operand" "u")]
16476                    UNSPEC_FPATAN))
16477    (clobber (match_scratch:XF 3 "=1"))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && flag_unsafe_math_optimizations"
16480   "fpatan"
16481   [(set_attr "type" "fpspc")
16482    (set_attr "mode" "XF")])
16483
16484 (define_expand "atan2xf3"
16485   [(use (match_operand:XF 0 "register_operand" ""))
16486    (use (match_operand:XF 2 "register_operand" ""))
16487    (use (match_operand:XF 1 "register_operand" ""))]
16488   "TARGET_USE_FANCY_MATH_387
16489    && flag_unsafe_math_optimizations"
16490 {
16491   rtx copy = gen_reg_rtx (XFmode);
16492   emit_move_insn (copy, operands[1]);
16493   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16494   DONE;
16495 })
16496
16497 (define_expand "atanxf2"
16498   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16499                    (unspec:XF [(match_dup 2)
16500                                (match_operand:XF 1 "register_operand" "")]
16501                     UNSPEC_FPATAN))
16502               (clobber (match_scratch:XF 3 ""))])]
16503   "TARGET_USE_FANCY_MATH_387
16504    && flag_unsafe_math_optimizations"
16505 {
16506   operands[2] = gen_reg_rtx (XFmode);
16507   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16508 })
16509
16510 (define_expand "asindf2"
16511   [(set (match_dup 2)
16512         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16513    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16514    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16515    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16516    (parallel [(set (match_dup 7)
16517                    (unspec:XF [(match_dup 6) (match_dup 2)]
16518                               UNSPEC_FPATAN))
16519               (clobber (match_scratch:XF 8 ""))])
16520    (set (match_operand:DF 0 "register_operand" "")
16521         (float_truncate:DF (match_dup 7)))]
16522   "TARGET_USE_FANCY_MATH_387
16523    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16524    && flag_unsafe_math_optimizations"
16525 {
16526   int i;
16527
16528   for (i=2; i<8; i++)
16529     operands[i] = gen_reg_rtx (XFmode);
16530
16531   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16532 })
16533
16534 (define_expand "asinsf2"
16535   [(set (match_dup 2)
16536         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16537    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16538    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16539    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16540    (parallel [(set (match_dup 7)
16541                    (unspec:XF [(match_dup 6) (match_dup 2)]
16542                               UNSPEC_FPATAN))
16543               (clobber (match_scratch:XF 8 ""))])
16544    (set (match_operand:SF 0 "register_operand" "")
16545         (float_truncate:SF (match_dup 7)))]
16546   "TARGET_USE_FANCY_MATH_387
16547    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16548    && flag_unsafe_math_optimizations"
16549 {
16550   int i;
16551
16552   for (i=2; i<8; i++)
16553     operands[i] = gen_reg_rtx (XFmode);
16554
16555   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16556 })
16557
16558 (define_expand "asinxf2"
16559   [(set (match_dup 2)
16560         (mult:XF (match_operand:XF 1 "register_operand" "")
16561                  (match_dup 1)))
16562    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16563    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16564    (parallel [(set (match_operand:XF 0 "register_operand" "")
16565                    (unspec:XF [(match_dup 5) (match_dup 1)]
16566                               UNSPEC_FPATAN))
16567               (clobber (match_scratch:XF 6 ""))])]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570 {
16571   int i;
16572
16573   for (i=2; i<6; i++)
16574     operands[i] = gen_reg_rtx (XFmode);
16575
16576   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16577 })
16578
16579 (define_expand "acosdf2"
16580   [(set (match_dup 2)
16581         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16582    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16583    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16584    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16585    (parallel [(set (match_dup 7)
16586                    (unspec:XF [(match_dup 2) (match_dup 6)]
16587                               UNSPEC_FPATAN))
16588               (clobber (match_scratch:XF 8 ""))])
16589    (set (match_operand:DF 0 "register_operand" "")
16590         (float_truncate:DF (match_dup 7)))]
16591   "TARGET_USE_FANCY_MATH_387
16592    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16593    && flag_unsafe_math_optimizations"
16594 {
16595   int i;
16596
16597   for (i=2; i<8; i++)
16598     operands[i] = gen_reg_rtx (XFmode);
16599
16600   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16601 })
16602
16603 (define_expand "acossf2"
16604   [(set (match_dup 2)
16605         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16606    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16607    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16608    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16609    (parallel [(set (match_dup 7)
16610                    (unspec:XF [(match_dup 2) (match_dup 6)]
16611                               UNSPEC_FPATAN))
16612               (clobber (match_scratch:XF 8 ""))])
16613    (set (match_operand:SF 0 "register_operand" "")
16614         (float_truncate:SF (match_dup 7)))]
16615   "TARGET_USE_FANCY_MATH_387
16616    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16617    && flag_unsafe_math_optimizations"
16618 {
16619   int i;
16620
16621   for (i=2; i<8; i++)
16622     operands[i] = gen_reg_rtx (XFmode);
16623
16624   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16625 })
16626
16627 (define_expand "acosxf2"
16628   [(set (match_dup 2)
16629         (mult:XF (match_operand:XF 1 "register_operand" "")
16630                  (match_dup 1)))
16631    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16632    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16633    (parallel [(set (match_operand:XF 0 "register_operand" "")
16634                    (unspec:XF [(match_dup 1) (match_dup 5)]
16635                               UNSPEC_FPATAN))
16636               (clobber (match_scratch:XF 6 ""))])]
16637   "TARGET_USE_FANCY_MATH_387
16638    && flag_unsafe_math_optimizations"
16639 {
16640   int i;
16641
16642   for (i=2; i<6; i++)
16643     operands[i] = gen_reg_rtx (XFmode);
16644
16645   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16646 })
16647
16648 (define_insn "fyl2x_xf3"
16649   [(set (match_operand:XF 0 "register_operand" "=f")
16650         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16651                     (match_operand:XF 1 "register_operand" "u")]
16652                    UNSPEC_FYL2X))
16653    (clobber (match_scratch:XF 3 "=1"))]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations"
16656   "fyl2x"
16657   [(set_attr "type" "fpspc")
16658    (set_attr "mode" "XF")])
16659
16660 (define_expand "logsf2"
16661   [(set (match_dup 2)
16662         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16663    (parallel [(set (match_dup 4)
16664                    (unspec:XF [(match_dup 2)
16665                                (match_dup 3)] UNSPEC_FYL2X))
16666               (clobber (match_scratch:XF 5 ""))])
16667    (set (match_operand:SF 0 "register_operand" "")
16668         (float_truncate:SF (match_dup 4)))]
16669   "TARGET_USE_FANCY_MATH_387
16670    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16671    && flag_unsafe_math_optimizations"
16672 {
16673   rtx temp;
16674
16675   operands[2] = gen_reg_rtx (XFmode);
16676   operands[3] = gen_reg_rtx (XFmode);
16677   operands[4] = gen_reg_rtx (XFmode);
16678
16679   temp = standard_80387_constant_rtx (4); /* fldln2 */
16680   emit_move_insn (operands[3], temp);
16681 })
16682
16683 (define_expand "logdf2"
16684   [(set (match_dup 2)
16685         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16686    (parallel [(set (match_dup 4)
16687                    (unspec:XF [(match_dup 2)
16688                                (match_dup 3)] UNSPEC_FYL2X))
16689               (clobber (match_scratch:XF 5 ""))])
16690    (set (match_operand:DF 0 "register_operand" "")
16691         (float_truncate:DF (match_dup 4)))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16694    && flag_unsafe_math_optimizations"
16695 {
16696   rtx temp;
16697
16698   operands[2] = gen_reg_rtx (XFmode);
16699   operands[3] = gen_reg_rtx (XFmode);
16700   operands[4] = gen_reg_rtx (XFmode);
16701
16702   temp = standard_80387_constant_rtx (4); /* fldln2 */
16703   emit_move_insn (operands[3], temp);
16704 })
16705
16706 (define_expand "logxf2"
16707   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16708                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16709                                (match_dup 2)] UNSPEC_FYL2X))
16710               (clobber (match_scratch:XF 3 ""))])]
16711   "TARGET_USE_FANCY_MATH_387
16712    && flag_unsafe_math_optimizations"
16713 {
16714   rtx temp;
16715
16716   operands[2] = gen_reg_rtx (XFmode);
16717   temp = standard_80387_constant_rtx (4); /* fldln2 */
16718   emit_move_insn (operands[2], temp);
16719 })
16720
16721 (define_expand "log10sf2"
16722   [(set (match_dup 2)
16723         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16724    (parallel [(set (match_dup 4)
16725                    (unspec:XF [(match_dup 2)
16726                                (match_dup 3)] UNSPEC_FYL2X))
16727               (clobber (match_scratch:XF 5 ""))])
16728    (set (match_operand:SF 0 "register_operand" "")
16729         (float_truncate:SF (match_dup 4)))]
16730   "TARGET_USE_FANCY_MATH_387
16731    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16732    && flag_unsafe_math_optimizations"
16733 {
16734   rtx temp;
16735
16736   operands[2] = gen_reg_rtx (XFmode);
16737   operands[3] = gen_reg_rtx (XFmode);
16738   operands[4] = gen_reg_rtx (XFmode);
16739
16740   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16741   emit_move_insn (operands[3], temp);
16742 })
16743
16744 (define_expand "log10df2"
16745   [(set (match_dup 2)
16746         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16747    (parallel [(set (match_dup 4)
16748                    (unspec:XF [(match_dup 2)
16749                                (match_dup 3)] UNSPEC_FYL2X))
16750               (clobber (match_scratch:XF 5 ""))])
16751    (set (match_operand:DF 0 "register_operand" "")
16752         (float_truncate:DF (match_dup 4)))]
16753   "TARGET_USE_FANCY_MATH_387
16754    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16755    && flag_unsafe_math_optimizations"
16756 {
16757   rtx temp;
16758
16759   operands[2] = gen_reg_rtx (XFmode);
16760   operands[3] = gen_reg_rtx (XFmode);
16761   operands[4] = gen_reg_rtx (XFmode);
16762
16763   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16764   emit_move_insn (operands[3], temp);
16765 })
16766
16767 (define_expand "log10xf2"
16768   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16769                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16770                                (match_dup 2)] UNSPEC_FYL2X))
16771               (clobber (match_scratch:XF 3 ""))])]
16772   "TARGET_USE_FANCY_MATH_387
16773    && flag_unsafe_math_optimizations"
16774 {
16775   rtx temp;
16776
16777   operands[2] = gen_reg_rtx (XFmode);
16778   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16779   emit_move_insn (operands[2], temp);
16780 })
16781
16782 (define_expand "log2sf2"
16783   [(set (match_dup 2)
16784         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16785    (parallel [(set (match_dup 4)
16786                    (unspec:XF [(match_dup 2)
16787                                (match_dup 3)] UNSPEC_FYL2X))
16788               (clobber (match_scratch:XF 5 ""))])
16789    (set (match_operand:SF 0 "register_operand" "")
16790         (float_truncate:SF (match_dup 4)))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16793    && flag_unsafe_math_optimizations"
16794 {
16795   operands[2] = gen_reg_rtx (XFmode);
16796   operands[3] = gen_reg_rtx (XFmode);
16797   operands[4] = gen_reg_rtx (XFmode);
16798
16799   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16800 })
16801
16802 (define_expand "log2df2"
16803   [(set (match_dup 2)
16804         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16805    (parallel [(set (match_dup 4)
16806                    (unspec:XF [(match_dup 2)
16807                                (match_dup 3)] UNSPEC_FYL2X))
16808               (clobber (match_scratch:XF 5 ""))])
16809    (set (match_operand:DF 0 "register_operand" "")
16810         (float_truncate:DF (match_dup 4)))]
16811   "TARGET_USE_FANCY_MATH_387
16812    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16813    && flag_unsafe_math_optimizations"
16814 {
16815   operands[2] = gen_reg_rtx (XFmode);
16816   operands[3] = gen_reg_rtx (XFmode);
16817   operands[4] = gen_reg_rtx (XFmode);
16818
16819   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16820 })
16821
16822 (define_expand "log2xf2"
16823   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16824                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16825                                (match_dup 2)] UNSPEC_FYL2X))
16826               (clobber (match_scratch:XF 3 ""))])]
16827   "TARGET_USE_FANCY_MATH_387
16828    && flag_unsafe_math_optimizations"
16829 {
16830   operands[2] = gen_reg_rtx (XFmode);
16831   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16832 })
16833
16834 (define_insn "fyl2xp1_xf3"
16835   [(set (match_operand:XF 0 "register_operand" "=f")
16836         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16837                     (match_operand:XF 1 "register_operand" "u")]
16838                    UNSPEC_FYL2XP1))
16839    (clobber (match_scratch:XF 3 "=1"))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations"
16842   "fyl2xp1"
16843   [(set_attr "type" "fpspc")
16844    (set_attr "mode" "XF")])
16845
16846 (define_expand "log1psf2"
16847   [(use (match_operand:SF 0 "register_operand" ""))
16848    (use (match_operand:SF 1 "register_operand" ""))]
16849   "TARGET_USE_FANCY_MATH_387
16850    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16851    && flag_unsafe_math_optimizations"
16852 {
16853   rtx op0 = gen_reg_rtx (XFmode);
16854   rtx op1 = gen_reg_rtx (XFmode);
16855
16856   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16857   ix86_emit_i387_log1p (op0, op1);
16858   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16859   DONE;
16860 })
16861
16862 (define_expand "log1pdf2"
16863   [(use (match_operand:DF 0 "register_operand" ""))
16864    (use (match_operand:DF 1 "register_operand" ""))]
16865   "TARGET_USE_FANCY_MATH_387
16866    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16867    && flag_unsafe_math_optimizations"
16868 {
16869   rtx op0 = gen_reg_rtx (XFmode);
16870   rtx op1 = gen_reg_rtx (XFmode);
16871
16872   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16873   ix86_emit_i387_log1p (op0, op1);
16874   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16875   DONE;
16876 })
16877
16878 (define_expand "log1pxf2"
16879   [(use (match_operand:XF 0 "register_operand" ""))
16880    (use (match_operand:XF 1 "register_operand" ""))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && flag_unsafe_math_optimizations"
16883 {
16884   ix86_emit_i387_log1p (operands[0], operands[1]);
16885   DONE;
16886 })
16887
16888 (define_insn "*fxtractxf3"
16889   [(set (match_operand:XF 0 "register_operand" "=f")
16890         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16891                    UNSPEC_XTRACT_FRACT))
16892    (set (match_operand:XF 1 "register_operand" "=u")
16893         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16894   "TARGET_USE_FANCY_MATH_387
16895    && flag_unsafe_math_optimizations"
16896   "fxtract"
16897   [(set_attr "type" "fpspc")
16898    (set_attr "mode" "XF")])
16899
16900 (define_expand "logbsf2"
16901   [(set (match_dup 2)
16902         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16903    (parallel [(set (match_dup 3)
16904                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16905               (set (match_dup 4)
16906                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16907    (set (match_operand:SF 0 "register_operand" "")
16908         (float_truncate:SF (match_dup 4)))]
16909   "TARGET_USE_FANCY_MATH_387
16910    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16911    && flag_unsafe_math_optimizations"
16912 {
16913   operands[2] = gen_reg_rtx (XFmode);
16914   operands[3] = gen_reg_rtx (XFmode);
16915   operands[4] = gen_reg_rtx (XFmode);
16916 })
16917
16918 (define_expand "logbdf2"
16919   [(set (match_dup 2)
16920         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16921    (parallel [(set (match_dup 3)
16922                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16923               (set (match_dup 4)
16924                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16925    (set (match_operand:DF 0 "register_operand" "")
16926         (float_truncate:DF (match_dup 4)))]
16927   "TARGET_USE_FANCY_MATH_387
16928    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16929    && flag_unsafe_math_optimizations"
16930 {
16931   operands[2] = gen_reg_rtx (XFmode);
16932   operands[3] = gen_reg_rtx (XFmode);
16933   operands[4] = gen_reg_rtx (XFmode);
16934 })
16935
16936 (define_expand "logbxf2"
16937   [(parallel [(set (match_dup 2)
16938                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16939                               UNSPEC_XTRACT_FRACT))
16940               (set (match_operand:XF 0 "register_operand" "")
16941                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16942   "TARGET_USE_FANCY_MATH_387
16943    && flag_unsafe_math_optimizations"
16944 {
16945   operands[2] = gen_reg_rtx (XFmode);
16946 })
16947
16948 (define_expand "ilogbsi2"
16949   [(parallel [(set (match_dup 2)
16950                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16951                               UNSPEC_XTRACT_FRACT))
16952               (set (match_operand:XF 3 "register_operand" "")
16953                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16954    (parallel [(set (match_operand:SI 0 "register_operand" "")
16955                    (fix:SI (match_dup 3)))
16956               (clobber (reg:CC FLAGS_REG))])]
16957   "TARGET_USE_FANCY_MATH_387
16958    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959    && flag_unsafe_math_optimizations"
16960 {
16961   operands[2] = gen_reg_rtx (XFmode);
16962   operands[3] = gen_reg_rtx (XFmode);
16963 })
16964
16965 (define_insn "*f2xm1xf2"
16966   [(set (match_operand:XF 0 "register_operand" "=f")
16967         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16968          UNSPEC_F2XM1))]
16969   "TARGET_USE_FANCY_MATH_387
16970    && flag_unsafe_math_optimizations"
16971   "f2xm1"
16972   [(set_attr "type" "fpspc")
16973    (set_attr "mode" "XF")])
16974
16975 (define_insn "*fscalexf4"
16976   [(set (match_operand:XF 0 "register_operand" "=f")
16977         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16978                     (match_operand:XF 3 "register_operand" "1")]
16979                    UNSPEC_FSCALE_FRACT))
16980    (set (match_operand:XF 1 "register_operand" "=u")
16981         (unspec:XF [(match_dup 2) (match_dup 3)]
16982                    UNSPEC_FSCALE_EXP))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && flag_unsafe_math_optimizations"
16985   "fscale"
16986   [(set_attr "type" "fpspc")
16987    (set_attr "mode" "XF")])
16988
16989 (define_expand "expsf2"
16990   [(set (match_dup 2)
16991         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16992    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16993    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16994    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16995    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16996    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16997    (parallel [(set (match_dup 10)
16998                    (unspec:XF [(match_dup 9) (match_dup 5)]
16999                               UNSPEC_FSCALE_FRACT))
17000               (set (match_dup 11)
17001                    (unspec:XF [(match_dup 9) (match_dup 5)]
17002                               UNSPEC_FSCALE_EXP))])
17003    (set (match_operand:SF 0 "register_operand" "")
17004         (float_truncate:SF (match_dup 10)))]
17005   "TARGET_USE_FANCY_MATH_387
17006    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17007    && flag_unsafe_math_optimizations"
17008 {
17009   rtx temp;
17010   int i;
17011
17012   for (i=2; i<12; i++)
17013     operands[i] = gen_reg_rtx (XFmode);
17014   temp = standard_80387_constant_rtx (5); /* fldl2e */
17015   emit_move_insn (operands[3], temp);
17016   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17017 })
17018
17019 (define_expand "expdf2"
17020   [(set (match_dup 2)
17021         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17022    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17023    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17024    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17025    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17026    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17027    (parallel [(set (match_dup 10)
17028                    (unspec:XF [(match_dup 9) (match_dup 5)]
17029                               UNSPEC_FSCALE_FRACT))
17030               (set (match_dup 11)
17031                    (unspec:XF [(match_dup 9) (match_dup 5)]
17032                               UNSPEC_FSCALE_EXP))])
17033    (set (match_operand:DF 0 "register_operand" "")
17034         (float_truncate:DF (match_dup 10)))]
17035   "TARGET_USE_FANCY_MATH_387
17036    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17037    && flag_unsafe_math_optimizations"
17038 {
17039   rtx temp;
17040   int i;
17041
17042   for (i=2; i<12; i++)
17043     operands[i] = gen_reg_rtx (XFmode);
17044   temp = standard_80387_constant_rtx (5); /* fldl2e */
17045   emit_move_insn (operands[3], temp);
17046   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17047 })
17048
17049 (define_expand "expxf2"
17050   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17051                                (match_dup 2)))
17052    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17056    (parallel [(set (match_operand:XF 0 "register_operand" "")
17057                    (unspec:XF [(match_dup 8) (match_dup 4)]
17058                               UNSPEC_FSCALE_FRACT))
17059               (set (match_dup 9)
17060                    (unspec:XF [(match_dup 8) (match_dup 4)]
17061                               UNSPEC_FSCALE_EXP))])]
17062   "TARGET_USE_FANCY_MATH_387
17063    && flag_unsafe_math_optimizations"
17064 {
17065   rtx temp;
17066   int i;
17067
17068   for (i=2; i<10; i++)
17069     operands[i] = gen_reg_rtx (XFmode);
17070   temp = standard_80387_constant_rtx (5); /* fldl2e */
17071   emit_move_insn (operands[2], temp);
17072   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17073 })
17074
17075 (define_expand "exp10sf2"
17076   [(set (match_dup 2)
17077         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17078    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17079    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17080    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17081    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17082    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17083    (parallel [(set (match_dup 10)
17084                    (unspec:XF [(match_dup 9) (match_dup 5)]
17085                               UNSPEC_FSCALE_FRACT))
17086               (set (match_dup 11)
17087                    (unspec:XF [(match_dup 9) (match_dup 5)]
17088                               UNSPEC_FSCALE_EXP))])
17089    (set (match_operand:SF 0 "register_operand" "")
17090         (float_truncate:SF (match_dup 10)))]
17091   "TARGET_USE_FANCY_MATH_387
17092    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17093    && flag_unsafe_math_optimizations"
17094 {
17095   rtx temp;
17096   int i;
17097
17098   for (i=2; i<12; i++)
17099     operands[i] = gen_reg_rtx (XFmode);
17100   temp = standard_80387_constant_rtx (6); /* fldl2t */
17101   emit_move_insn (operands[3], temp);
17102   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17103 })
17104
17105 (define_expand "exp10df2"
17106   [(set (match_dup 2)
17107         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17108    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17109    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17110    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17111    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17112    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17113    (parallel [(set (match_dup 10)
17114                    (unspec:XF [(match_dup 9) (match_dup 5)]
17115                               UNSPEC_FSCALE_FRACT))
17116               (set (match_dup 11)
17117                    (unspec:XF [(match_dup 9) (match_dup 5)]
17118                               UNSPEC_FSCALE_EXP))])
17119    (set (match_operand:DF 0 "register_operand" "")
17120         (float_truncate:DF (match_dup 10)))]
17121   "TARGET_USE_FANCY_MATH_387
17122    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17123    && flag_unsafe_math_optimizations"
17124 {
17125   rtx temp;
17126   int i;
17127
17128   for (i=2; i<12; i++)
17129     operands[i] = gen_reg_rtx (XFmode);
17130   temp = standard_80387_constant_rtx (6); /* fldl2t */
17131   emit_move_insn (operands[3], temp);
17132   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17133 })
17134
17135 (define_expand "exp10xf2"
17136   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17137                                (match_dup 2)))
17138    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17139    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17140    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17141    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17142    (parallel [(set (match_operand:XF 0 "register_operand" "")
17143                    (unspec:XF [(match_dup 8) (match_dup 4)]
17144                               UNSPEC_FSCALE_FRACT))
17145               (set (match_dup 9)
17146                    (unspec:XF [(match_dup 8) (match_dup 4)]
17147                               UNSPEC_FSCALE_EXP))])]
17148   "TARGET_USE_FANCY_MATH_387
17149    && flag_unsafe_math_optimizations"
17150 {
17151   rtx temp;
17152   int i;
17153
17154   for (i=2; i<10; i++)
17155     operands[i] = gen_reg_rtx (XFmode);
17156   temp = standard_80387_constant_rtx (6); /* fldl2t */
17157   emit_move_insn (operands[2], temp);
17158   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17159 })
17160
17161 (define_expand "exp2sf2"
17162   [(set (match_dup 2)
17163         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17164    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17165    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17166    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17167    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17168    (parallel [(set (match_dup 8)
17169                    (unspec:XF [(match_dup 7) (match_dup 3)]
17170                               UNSPEC_FSCALE_FRACT))
17171               (set (match_dup 9)
17172                    (unspec:XF [(match_dup 7) (match_dup 3)]
17173                               UNSPEC_FSCALE_EXP))])
17174    (set (match_operand:SF 0 "register_operand" "")
17175         (float_truncate:SF (match_dup 8)))]
17176   "TARGET_USE_FANCY_MATH_387
17177    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17178    && flag_unsafe_math_optimizations"
17179 {
17180   int i;
17181
17182   for (i=2; i<10; i++)
17183     operands[i] = gen_reg_rtx (XFmode);
17184   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17185 })
17186
17187 (define_expand "exp2df2"
17188   [(set (match_dup 2)
17189         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17190    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17191    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17192    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17193    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17194    (parallel [(set (match_dup 8)
17195                    (unspec:XF [(match_dup 7) (match_dup 3)]
17196                               UNSPEC_FSCALE_FRACT))
17197               (set (match_dup 9)
17198                    (unspec:XF [(match_dup 7) (match_dup 3)]
17199                               UNSPEC_FSCALE_EXP))])
17200    (set (match_operand:DF 0 "register_operand" "")
17201         (float_truncate:DF (match_dup 8)))]
17202   "TARGET_USE_FANCY_MATH_387
17203    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17204    && flag_unsafe_math_optimizations"
17205 {
17206   int i;
17207
17208   for (i=2; i<10; i++)
17209     operands[i] = gen_reg_rtx (XFmode);
17210   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17211 })
17212
17213 (define_expand "exp2xf2"
17214   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17215    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17216    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17217    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17218    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17219    (parallel [(set (match_operand:XF 0 "register_operand" "")
17220                    (unspec:XF [(match_dup 7) (match_dup 3)]
17221                               UNSPEC_FSCALE_FRACT))
17222               (set (match_dup 8)
17223                    (unspec:XF [(match_dup 7) (match_dup 3)]
17224                               UNSPEC_FSCALE_EXP))])]
17225   "TARGET_USE_FANCY_MATH_387
17226    && flag_unsafe_math_optimizations"
17227 {
17228   int i;
17229
17230   for (i=2; i<9; i++)
17231     operands[i] = gen_reg_rtx (XFmode);
17232   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17233 })
17234
17235 (define_expand "expm1df2"
17236   [(set (match_dup 2)
17237         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17238    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17239    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17240    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17241    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17242    (parallel [(set (match_dup 8)
17243                    (unspec:XF [(match_dup 7) (match_dup 5)]
17244                               UNSPEC_FSCALE_FRACT))
17245                    (set (match_dup 9)
17246                    (unspec:XF [(match_dup 7) (match_dup 5)]
17247                               UNSPEC_FSCALE_EXP))])
17248    (parallel [(set (match_dup 11)
17249                    (unspec:XF [(match_dup 10) (match_dup 9)]
17250                               UNSPEC_FSCALE_FRACT))
17251               (set (match_dup 12)
17252                    (unspec:XF [(match_dup 10) (match_dup 9)]
17253                               UNSPEC_FSCALE_EXP))])
17254    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17255    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17256    (set (match_operand:DF 0 "register_operand" "")
17257         (float_truncate:DF (match_dup 14)))]
17258   "TARGET_USE_FANCY_MATH_387
17259    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17260    && flag_unsafe_math_optimizations"
17261 {
17262   rtx temp;
17263   int i;
17264
17265   for (i=2; i<15; i++)
17266     operands[i] = gen_reg_rtx (XFmode);
17267   temp = standard_80387_constant_rtx (5); /* fldl2e */
17268   emit_move_insn (operands[3], temp);
17269   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17270 })
17271
17272 (define_expand "expm1sf2"
17273   [(set (match_dup 2)
17274         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17275    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17276    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17277    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17278    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17279    (parallel [(set (match_dup 8)
17280                    (unspec:XF [(match_dup 7) (match_dup 5)]
17281                               UNSPEC_FSCALE_FRACT))
17282                    (set (match_dup 9)
17283                    (unspec:XF [(match_dup 7) (match_dup 5)]
17284                               UNSPEC_FSCALE_EXP))])
17285    (parallel [(set (match_dup 11)
17286                    (unspec:XF [(match_dup 10) (match_dup 9)]
17287                               UNSPEC_FSCALE_FRACT))
17288               (set (match_dup 12)
17289                    (unspec:XF [(match_dup 10) (match_dup 9)]
17290                               UNSPEC_FSCALE_EXP))])
17291    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17292    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17293    (set (match_operand:SF 0 "register_operand" "")
17294         (float_truncate:SF (match_dup 14)))]
17295   "TARGET_USE_FANCY_MATH_387
17296    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17297    && flag_unsafe_math_optimizations"
17298 {
17299   rtx temp;
17300   int i;
17301
17302   for (i=2; i<15; i++)
17303     operands[i] = gen_reg_rtx (XFmode);
17304   temp = standard_80387_constant_rtx (5); /* fldl2e */
17305   emit_move_insn (operands[3], temp);
17306   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17307 })
17308
17309 (define_expand "expm1xf2"
17310   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17311                                (match_dup 2)))
17312    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17313    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17314    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17315    (parallel [(set (match_dup 7)
17316                    (unspec:XF [(match_dup 6) (match_dup 4)]
17317                               UNSPEC_FSCALE_FRACT))
17318                    (set (match_dup 8)
17319                    (unspec:XF [(match_dup 6) (match_dup 4)]
17320                               UNSPEC_FSCALE_EXP))])
17321    (parallel [(set (match_dup 10)
17322                    (unspec:XF [(match_dup 9) (match_dup 8)]
17323                               UNSPEC_FSCALE_FRACT))
17324               (set (match_dup 11)
17325                    (unspec:XF [(match_dup 9) (match_dup 8)]
17326                               UNSPEC_FSCALE_EXP))])
17327    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17328    (set (match_operand:XF 0 "register_operand" "")
17329         (plus:XF (match_dup 12) (match_dup 7)))]
17330   "TARGET_USE_FANCY_MATH_387
17331    && flag_unsafe_math_optimizations"
17332 {
17333   rtx temp;
17334   int i;
17335
17336   for (i=2; i<13; i++)
17337     operands[i] = gen_reg_rtx (XFmode);
17338   temp = standard_80387_constant_rtx (5); /* fldl2e */
17339   emit_move_insn (operands[2], temp);
17340   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17341 })
17342
17343 (define_expand "ldexpdf3"
17344   [(set (match_dup 3)
17345         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17346    (set (match_dup 4)
17347         (float:XF (match_operand:SI 2 "register_operand" "")))
17348    (parallel [(set (match_dup 5)
17349                    (unspec:XF [(match_dup 3) (match_dup 4)]
17350                               UNSPEC_FSCALE_FRACT))
17351               (set (match_dup 6)
17352                    (unspec:XF [(match_dup 3) (match_dup 4)]
17353                               UNSPEC_FSCALE_EXP))])
17354    (set (match_operand:DF 0 "register_operand" "")
17355         (float_truncate:DF (match_dup 5)))]
17356   "TARGET_USE_FANCY_MATH_387
17357    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17358    && flag_unsafe_math_optimizations"
17359 {
17360   int i;
17361
17362   for (i=3; i<7; i++)
17363     operands[i] = gen_reg_rtx (XFmode);
17364 })
17365
17366 (define_expand "ldexpsf3"
17367   [(set (match_dup 3)
17368         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17369    (set (match_dup 4)
17370         (float:XF (match_operand:SI 2 "register_operand" "")))
17371    (parallel [(set (match_dup 5)
17372                    (unspec:XF [(match_dup 3) (match_dup 4)]
17373                               UNSPEC_FSCALE_FRACT))
17374               (set (match_dup 6)
17375                    (unspec:XF [(match_dup 3) (match_dup 4)]
17376                               UNSPEC_FSCALE_EXP))])
17377    (set (match_operand:SF 0 "register_operand" "")
17378         (float_truncate:SF (match_dup 5)))]
17379   "TARGET_USE_FANCY_MATH_387
17380    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17381    && flag_unsafe_math_optimizations"
17382 {
17383   int i;
17384
17385   for (i=3; i<7; i++)
17386     operands[i] = gen_reg_rtx (XFmode);
17387 })
17388
17389 (define_expand "ldexpxf3"
17390   [(set (match_dup 3)
17391         (float:XF (match_operand:SI 2 "register_operand" "")))
17392    (parallel [(set (match_operand:XF 0 " register_operand" "")
17393                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17394                                (match_dup 3)]
17395                               UNSPEC_FSCALE_FRACT))
17396               (set (match_dup 4)
17397                    (unspec:XF [(match_dup 1) (match_dup 3)]
17398                               UNSPEC_FSCALE_EXP))])]
17399   "TARGET_USE_FANCY_MATH_387
17400    && flag_unsafe_math_optimizations"
17401 {
17402   int i;
17403
17404   for (i=3; i<5; i++)
17405     operands[i] = gen_reg_rtx (XFmode);
17406 })
17407 \f
17408
17409 (define_insn "frndintxf2"
17410   [(set (match_operand:XF 0 "register_operand" "=f")
17411         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17412          UNSPEC_FRNDINT))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && flag_unsafe_math_optimizations"
17415   "frndint"
17416   [(set_attr "type" "fpspc")
17417    (set_attr "mode" "XF")])
17418
17419 (define_expand "rintdf2"
17420   [(use (match_operand:DF 0 "register_operand" ""))
17421    (use (match_operand:DF 1 "register_operand" ""))]
17422   "TARGET_USE_FANCY_MATH_387
17423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17424    && flag_unsafe_math_optimizations"
17425 {
17426   rtx op0 = gen_reg_rtx (XFmode);
17427   rtx op1 = gen_reg_rtx (XFmode);
17428
17429   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17430   emit_insn (gen_frndintxf2 (op0, op1));
17431
17432   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17433   DONE;
17434 })
17435
17436 (define_expand "rintsf2"
17437   [(use (match_operand:SF 0 "register_operand" ""))
17438    (use (match_operand:SF 1 "register_operand" ""))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && (!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_extendsfxf2 (op1, operands[1]));
17447   emit_insn (gen_frndintxf2 (op0, op1));
17448
17449   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17450   DONE;
17451 })
17452
17453 (define_expand "rintxf2"
17454   [(use (match_operand:XF 0 "register_operand" ""))
17455    (use (match_operand:XF 1 "register_operand" ""))]
17456   "TARGET_USE_FANCY_MATH_387
17457    && flag_unsafe_math_optimizations"
17458 {
17459   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17460   DONE;
17461 })
17462
17463 (define_insn_and_split "*fistdi2_1"
17464   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17465         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17466          UNSPEC_FIST))]
17467   "TARGET_USE_FANCY_MATH_387
17468    && flag_unsafe_math_optimizations
17469    && !(reload_completed || reload_in_progress)"
17470   "#"
17471   "&& 1"
17472   [(const_int 0)]
17473 {
17474   if (memory_operand (operands[0], VOIDmode))
17475     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17476   else
17477     {
17478       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17479       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17480                                          operands[2]));
17481     }
17482   DONE;
17483 }
17484   [(set_attr "type" "fpspc")
17485    (set_attr "mode" "DI")])
17486
17487 (define_insn "fistdi2"
17488   [(set (match_operand:DI 0 "memory_operand" "=m")
17489         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17490          UNSPEC_FIST))
17491    (clobber (match_scratch:XF 2 "=&1f"))]
17492   "TARGET_USE_FANCY_MATH_387
17493    && flag_unsafe_math_optimizations"
17494   "* return output_fix_trunc (insn, operands, 0);"
17495   [(set_attr "type" "fpspc")
17496    (set_attr "mode" "DI")])
17497
17498 (define_insn "fistdi2_with_temp"
17499   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17500         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17501          UNSPEC_FIST))
17502    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17503    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17504   "TARGET_USE_FANCY_MATH_387
17505    && flag_unsafe_math_optimizations"
17506   "#"
17507   [(set_attr "type" "fpspc")
17508    (set_attr "mode" "DI")])
17509
17510 (define_split 
17511   [(set (match_operand:DI 0 "register_operand" "")
17512         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17513          UNSPEC_FIST))
17514    (clobber (match_operand:DI 2 "memory_operand" ""))
17515    (clobber (match_scratch 3 ""))]
17516   "reload_completed"
17517   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17518               (clobber (match_dup 3))])
17519    (set (match_dup 0) (match_dup 2))]
17520   "")
17521
17522 (define_split 
17523   [(set (match_operand:DI 0 "memory_operand" "")
17524         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17525          UNSPEC_FIST))
17526    (clobber (match_operand:DI 2 "memory_operand" ""))
17527    (clobber (match_scratch 3 ""))]
17528   "reload_completed"
17529   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17530               (clobber (match_dup 3))])]
17531   "")
17532
17533 (define_insn_and_split "*fist<mode>2_1"
17534   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17535         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17536          UNSPEC_FIST))]
17537   "TARGET_USE_FANCY_MATH_387
17538    && flag_unsafe_math_optimizations
17539    && !(reload_completed || reload_in_progress)"
17540   "#"
17541   "&& 1"
17542   [(const_int 0)]
17543 {
17544   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17545   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17546                                         operands[2]));
17547   DONE;
17548 }
17549   [(set_attr "type" "fpspc")
17550    (set_attr "mode" "<MODE>")])
17551
17552 (define_insn "fist<mode>2"
17553   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17554         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17555          UNSPEC_FIST))]
17556   "TARGET_USE_FANCY_MATH_387
17557    && flag_unsafe_math_optimizations"
17558   "* return output_fix_trunc (insn, operands, 0);"
17559   [(set_attr "type" "fpspc")
17560    (set_attr "mode" "<MODE>")])
17561
17562 (define_insn "fist<mode>2_with_temp"
17563   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17564         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17565          UNSPEC_FIST))
17566    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17567   "TARGET_USE_FANCY_MATH_387
17568    && flag_unsafe_math_optimizations"
17569   "#"
17570   [(set_attr "type" "fpspc")
17571    (set_attr "mode" "<MODE>")])
17572
17573 (define_split 
17574   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17575         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17576          UNSPEC_FIST))
17577    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17578   "reload_completed"
17579   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17580                        UNSPEC_FIST))
17581    (set (match_dup 0) (match_dup 2))]
17582   "")
17583
17584 (define_split 
17585   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17586         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17587          UNSPEC_FIST))
17588    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17589   "reload_completed"
17590   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17591                        UNSPEC_FIST))]
17592   "")
17593
17594 (define_expand "lrint<mode>2"
17595   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17596         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17597          UNSPEC_FIST))]
17598   "TARGET_USE_FANCY_MATH_387
17599    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17600    && flag_unsafe_math_optimizations"
17601   "")
17602
17603 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17604 (define_insn_and_split "frndintxf2_floor"
17605   [(set (match_operand:XF 0 "register_operand" "=f")
17606         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607          UNSPEC_FRNDINT_FLOOR))
17608    (clobber (reg:CC FLAGS_REG))]
17609   "TARGET_USE_FANCY_MATH_387
17610    && flag_unsafe_math_optimizations
17611    && !(reload_completed || reload_in_progress)"
17612   "#"
17613   "&& 1"
17614   [(const_int 0)]
17615 {
17616   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17617
17618   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17619   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17620
17621   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17622                                         operands[2], operands[3]));
17623   DONE;
17624 }
17625   [(set_attr "type" "frndint")
17626    (set_attr "i387_cw" "floor")
17627    (set_attr "mode" "XF")])
17628
17629 (define_insn "frndintxf2_floor_i387"
17630   [(set (match_operand:XF 0 "register_operand" "=f")
17631         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17632          UNSPEC_FRNDINT_FLOOR))
17633    (use (match_operand:HI 2 "memory_operand" "m"))
17634    (use (match_operand:HI 3 "memory_operand" "m"))]
17635   "TARGET_USE_FANCY_MATH_387
17636    && flag_unsafe_math_optimizations"
17637   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17638   [(set_attr "type" "frndint")
17639    (set_attr "i387_cw" "floor")
17640    (set_attr "mode" "XF")])
17641
17642 (define_expand "floorxf2"
17643   [(use (match_operand:XF 0 "register_operand" ""))
17644    (use (match_operand:XF 1 "register_operand" ""))]
17645   "TARGET_USE_FANCY_MATH_387
17646    && flag_unsafe_math_optimizations"
17647 {
17648   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17649   DONE;
17650 })
17651
17652 (define_expand "floordf2"
17653   [(use (match_operand:DF 0 "register_operand" ""))
17654    (use (match_operand:DF 1 "register_operand" ""))]
17655   "TARGET_USE_FANCY_MATH_387
17656    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17657    && flag_unsafe_math_optimizations"
17658 {
17659   rtx op0 = gen_reg_rtx (XFmode);
17660   rtx op1 = gen_reg_rtx (XFmode);
17661
17662   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17663   emit_insn (gen_frndintxf2_floor (op0, op1));
17664
17665   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17666   DONE;
17667 })
17668
17669 (define_expand "floorsf2"
17670   [(use (match_operand:SF 0 "register_operand" ""))
17671    (use (match_operand:SF 1 "register_operand" ""))]
17672   "TARGET_USE_FANCY_MATH_387
17673    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17674    && flag_unsafe_math_optimizations"
17675 {
17676   rtx op0 = gen_reg_rtx (XFmode);
17677   rtx op1 = gen_reg_rtx (XFmode);
17678
17679   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17680   emit_insn (gen_frndintxf2_floor (op0, op1));
17681
17682   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17683   DONE;
17684 })
17685
17686 (define_insn_and_split "*fist<mode>2_floor_1"
17687   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17688         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17689          UNSPEC_FIST_FLOOR))
17690    (clobber (reg:CC FLAGS_REG))]
17691   "TARGET_USE_FANCY_MATH_387
17692    && flag_unsafe_math_optimizations
17693    && !(reload_completed || reload_in_progress)"
17694   "#"
17695   "&& 1"
17696   [(const_int 0)]
17697 {
17698   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17699
17700   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17701   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17702   if (memory_operand (operands[0], VOIDmode))
17703     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17704                                       operands[2], operands[3]));
17705   else
17706     {
17707       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17708       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17709                                                   operands[2], operands[3],
17710                                                   operands[4]));
17711     }
17712   DONE;
17713 }
17714   [(set_attr "type" "fistp")
17715    (set_attr "i387_cw" "floor")
17716    (set_attr "mode" "<MODE>")])
17717
17718 (define_insn "fistdi2_floor"
17719   [(set (match_operand:DI 0 "memory_operand" "=m")
17720         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17721          UNSPEC_FIST_FLOOR))
17722    (use (match_operand:HI 2 "memory_operand" "m"))
17723    (use (match_operand:HI 3 "memory_operand" "m"))
17724    (clobber (match_scratch:XF 4 "=&1f"))]
17725   "TARGET_USE_FANCY_MATH_387
17726    && flag_unsafe_math_optimizations"
17727   "* return output_fix_trunc (insn, operands, 0);"
17728   [(set_attr "type" "fistp")
17729    (set_attr "i387_cw" "floor")
17730    (set_attr "mode" "DI")])
17731
17732 (define_insn "fistdi2_floor_with_temp"
17733   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17734         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17735          UNSPEC_FIST_FLOOR))
17736    (use (match_operand:HI 2 "memory_operand" "m,m"))
17737    (use (match_operand:HI 3 "memory_operand" "m,m"))
17738    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17739    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17740   "TARGET_USE_FANCY_MATH_387
17741    && flag_unsafe_math_optimizations"
17742   "#"
17743   [(set_attr "type" "fistp")
17744    (set_attr "i387_cw" "floor")
17745    (set_attr "mode" "DI")])
17746
17747 (define_split 
17748   [(set (match_operand:DI 0 "register_operand" "")
17749         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17750          UNSPEC_FIST_FLOOR))
17751    (use (match_operand:HI 2 "memory_operand" ""))
17752    (use (match_operand:HI 3 "memory_operand" ""))
17753    (clobber (match_operand:DI 4 "memory_operand" ""))
17754    (clobber (match_scratch 5 ""))]
17755   "reload_completed"
17756   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17757               (use (match_dup 2))
17758               (use (match_dup 3))
17759               (clobber (match_dup 5))])
17760    (set (match_dup 0) (match_dup 4))]
17761   "")
17762
17763 (define_split 
17764   [(set (match_operand:DI 0 "memory_operand" "")
17765         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17766          UNSPEC_FIST_FLOOR))
17767    (use (match_operand:HI 2 "memory_operand" ""))
17768    (use (match_operand:HI 3 "memory_operand" ""))
17769    (clobber (match_operand:DI 4 "memory_operand" ""))
17770    (clobber (match_scratch 5 ""))]
17771   "reload_completed"
17772   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17773               (use (match_dup 2))
17774               (use (match_dup 3))
17775               (clobber (match_dup 5))])]
17776   "")
17777
17778 (define_insn "fist<mode>2_floor"
17779   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17780         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17781          UNSPEC_FIST_FLOOR))
17782    (use (match_operand:HI 2 "memory_operand" "m"))
17783    (use (match_operand:HI 3 "memory_operand" "m"))]
17784   "TARGET_USE_FANCY_MATH_387
17785    && flag_unsafe_math_optimizations"
17786   "* return output_fix_trunc (insn, operands, 0);"
17787   [(set_attr "type" "fistp")
17788    (set_attr "i387_cw" "floor")
17789    (set_attr "mode" "<MODE>")])
17790
17791 (define_insn "fist<mode>2_floor_with_temp"
17792   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17793         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17794          UNSPEC_FIST_FLOOR))
17795    (use (match_operand:HI 2 "memory_operand" "m,m"))
17796    (use (match_operand:HI 3 "memory_operand" "m,m"))
17797    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17798   "TARGET_USE_FANCY_MATH_387
17799    && flag_unsafe_math_optimizations"
17800   "#"
17801   [(set_attr "type" "fistp")
17802    (set_attr "i387_cw" "floor")
17803    (set_attr "mode" "<MODE>")])
17804
17805 (define_split 
17806   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17807         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17808          UNSPEC_FIST_FLOOR))
17809    (use (match_operand:HI 2 "memory_operand" ""))
17810    (use (match_operand:HI 3 "memory_operand" ""))
17811    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17812   "reload_completed"
17813   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17814                                   UNSPEC_FIST_FLOOR))
17815               (use (match_dup 2))
17816               (use (match_dup 3))])
17817    (set (match_dup 0) (match_dup 4))]
17818   "")
17819
17820 (define_split 
17821   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17822         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17823          UNSPEC_FIST_FLOOR))
17824    (use (match_operand:HI 2 "memory_operand" ""))
17825    (use (match_operand:HI 3 "memory_operand" ""))
17826    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17827   "reload_completed"
17828   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17829                                   UNSPEC_FIST_FLOOR))
17830               (use (match_dup 2))
17831               (use (match_dup 3))])]
17832   "")
17833
17834 (define_expand "lfloor<mode>2"
17835   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17836                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17837                     UNSPEC_FIST_FLOOR))
17838               (clobber (reg:CC FLAGS_REG))])]
17839   "TARGET_USE_FANCY_MATH_387
17840    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17841    && flag_unsafe_math_optimizations"
17842   "")
17843
17844 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17845 (define_insn_and_split "frndintxf2_ceil"
17846   [(set (match_operand:XF 0 "register_operand" "=f")
17847         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848          UNSPEC_FRNDINT_CEIL))
17849    (clobber (reg:CC FLAGS_REG))]
17850   "TARGET_USE_FANCY_MATH_387
17851    && flag_unsafe_math_optimizations
17852    && !(reload_completed || reload_in_progress)"
17853   "#"
17854   "&& 1"
17855   [(const_int 0)]
17856 {
17857   ix86_optimize_mode_switching[I387_CEIL] = 1;
17858
17859   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17860   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17861
17862   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17863                                        operands[2], operands[3]));
17864   DONE;
17865 }
17866   [(set_attr "type" "frndint")
17867    (set_attr "i387_cw" "ceil")
17868    (set_attr "mode" "XF")])
17869
17870 (define_insn "frndintxf2_ceil_i387"
17871   [(set (match_operand:XF 0 "register_operand" "=f")
17872         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17873          UNSPEC_FRNDINT_CEIL))
17874    (use (match_operand:HI 2 "memory_operand" "m"))
17875    (use (match_operand:HI 3 "memory_operand" "m"))]
17876   "TARGET_USE_FANCY_MATH_387
17877    && flag_unsafe_math_optimizations"
17878   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17879   [(set_attr "type" "frndint")
17880    (set_attr "i387_cw" "ceil")
17881    (set_attr "mode" "XF")])
17882
17883 (define_expand "ceilxf2"
17884   [(use (match_operand:XF 0 "register_operand" ""))
17885    (use (match_operand:XF 1 "register_operand" ""))]
17886   "TARGET_USE_FANCY_MATH_387
17887    && flag_unsafe_math_optimizations"
17888 {
17889   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17890   DONE;
17891 })
17892
17893 (define_expand "ceildf2"
17894   [(use (match_operand:DF 0 "register_operand" ""))
17895    (use (match_operand:DF 1 "register_operand" ""))]
17896   "TARGET_USE_FANCY_MATH_387
17897    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17898    && flag_unsafe_math_optimizations"
17899 {
17900   rtx op0 = gen_reg_rtx (XFmode);
17901   rtx op1 = gen_reg_rtx (XFmode);
17902
17903   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17904   emit_insn (gen_frndintxf2_ceil (op0, op1));
17905
17906   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17907   DONE;
17908 })
17909
17910 (define_expand "ceilsf2"
17911   [(use (match_operand:SF 0 "register_operand" ""))
17912    (use (match_operand:SF 1 "register_operand" ""))]
17913   "TARGET_USE_FANCY_MATH_387
17914    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17915    && flag_unsafe_math_optimizations"
17916 {
17917   rtx op0 = gen_reg_rtx (XFmode);
17918   rtx op1 = gen_reg_rtx (XFmode);
17919
17920   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17921   emit_insn (gen_frndintxf2_ceil (op0, op1));
17922
17923   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17924   DONE;
17925 })
17926
17927 (define_insn_and_split "*fist<mode>2_ceil_1"
17928   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17929         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17930          UNSPEC_FIST_CEIL))
17931    (clobber (reg:CC FLAGS_REG))]
17932   "TARGET_USE_FANCY_MATH_387
17933    && flag_unsafe_math_optimizations
17934    && !(reload_completed || reload_in_progress)"
17935   "#"
17936   "&& 1"
17937   [(const_int 0)]
17938 {
17939   ix86_optimize_mode_switching[I387_CEIL] = 1;
17940
17941   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17942   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17943   if (memory_operand (operands[0], VOIDmode))
17944     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17945                                      operands[2], operands[3]));
17946   else
17947     {
17948       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17949       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17950                                                  operands[2], operands[3],
17951                                                  operands[4]));
17952     }
17953   DONE;
17954 }
17955   [(set_attr "type" "fistp")
17956    (set_attr "i387_cw" "ceil")
17957    (set_attr "mode" "<MODE>")])
17958
17959 (define_insn "fistdi2_ceil"
17960   [(set (match_operand:DI 0 "memory_operand" "=m")
17961         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17962          UNSPEC_FIST_CEIL))
17963    (use (match_operand:HI 2 "memory_operand" "m"))
17964    (use (match_operand:HI 3 "memory_operand" "m"))
17965    (clobber (match_scratch:XF 4 "=&1f"))]
17966   "TARGET_USE_FANCY_MATH_387
17967    && flag_unsafe_math_optimizations"
17968   "* return output_fix_trunc (insn, operands, 0);"
17969   [(set_attr "type" "fistp")
17970    (set_attr "i387_cw" "ceil")
17971    (set_attr "mode" "DI")])
17972
17973 (define_insn "fistdi2_ceil_with_temp"
17974   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17975         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17976          UNSPEC_FIST_CEIL))
17977    (use (match_operand:HI 2 "memory_operand" "m,m"))
17978    (use (match_operand:HI 3 "memory_operand" "m,m"))
17979    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17980    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17981   "TARGET_USE_FANCY_MATH_387
17982    && flag_unsafe_math_optimizations"
17983   "#"
17984   [(set_attr "type" "fistp")
17985    (set_attr "i387_cw" "ceil")
17986    (set_attr "mode" "DI")])
17987
17988 (define_split 
17989   [(set (match_operand:DI 0 "register_operand" "")
17990         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17991          UNSPEC_FIST_CEIL))
17992    (use (match_operand:HI 2 "memory_operand" ""))
17993    (use (match_operand:HI 3 "memory_operand" ""))
17994    (clobber (match_operand:DI 4 "memory_operand" ""))
17995    (clobber (match_scratch 5 ""))]
17996   "reload_completed"
17997   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17998               (use (match_dup 2))
17999               (use (match_dup 3))
18000               (clobber (match_dup 5))])
18001    (set (match_dup 0) (match_dup 4))]
18002   "")
18003
18004 (define_split 
18005   [(set (match_operand:DI 0 "memory_operand" "")
18006         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18007          UNSPEC_FIST_CEIL))
18008    (use (match_operand:HI 2 "memory_operand" ""))
18009    (use (match_operand:HI 3 "memory_operand" ""))
18010    (clobber (match_operand:DI 4 "memory_operand" ""))
18011    (clobber (match_scratch 5 ""))]
18012   "reload_completed"
18013   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18014               (use (match_dup 2))
18015               (use (match_dup 3))
18016               (clobber (match_dup 5))])]
18017   "")
18018
18019 (define_insn "fist<mode>2_ceil"
18020   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18021         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18022          UNSPEC_FIST_CEIL))
18023    (use (match_operand:HI 2 "memory_operand" "m"))
18024    (use (match_operand:HI 3 "memory_operand" "m"))]
18025   "TARGET_USE_FANCY_MATH_387
18026    && flag_unsafe_math_optimizations"
18027   "* return output_fix_trunc (insn, operands, 0);"
18028   [(set_attr "type" "fistp")
18029    (set_attr "i387_cw" "ceil")
18030    (set_attr "mode" "<MODE>")])
18031
18032 (define_insn "fist<mode>2_ceil_with_temp"
18033   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18034         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18035          UNSPEC_FIST_CEIL))
18036    (use (match_operand:HI 2 "memory_operand" "m,m"))
18037    (use (match_operand:HI 3 "memory_operand" "m,m"))
18038    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18039   "TARGET_USE_FANCY_MATH_387
18040    && flag_unsafe_math_optimizations"
18041   "#"
18042   [(set_attr "type" "fistp")
18043    (set_attr "i387_cw" "ceil")
18044    (set_attr "mode" "<MODE>")])
18045
18046 (define_split 
18047   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18048         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18049          UNSPEC_FIST_CEIL))
18050    (use (match_operand:HI 2 "memory_operand" ""))
18051    (use (match_operand:HI 3 "memory_operand" ""))
18052    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18053   "reload_completed"
18054   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18055                                   UNSPEC_FIST_CEIL))
18056               (use (match_dup 2))
18057               (use (match_dup 3))])
18058    (set (match_dup 0) (match_dup 4))]
18059   "")
18060
18061 (define_split 
18062   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18063         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18064          UNSPEC_FIST_CEIL))
18065    (use (match_operand:HI 2 "memory_operand" ""))
18066    (use (match_operand:HI 3 "memory_operand" ""))
18067    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18068   "reload_completed"
18069   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18070                                   UNSPEC_FIST_CEIL))
18071               (use (match_dup 2))
18072               (use (match_dup 3))])]
18073   "")
18074
18075 (define_expand "lceil<mode>2"
18076   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18077                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18078                     UNSPEC_FIST_CEIL))
18079               (clobber (reg:CC FLAGS_REG))])]
18080   "TARGET_USE_FANCY_MATH_387
18081    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18082    && flag_unsafe_math_optimizations"
18083   "")
18084
18085 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18086 (define_insn_and_split "frndintxf2_trunc"
18087   [(set (match_operand:XF 0 "register_operand" "=f")
18088         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18089          UNSPEC_FRNDINT_TRUNC))
18090    (clobber (reg:CC FLAGS_REG))]
18091   "TARGET_USE_FANCY_MATH_387
18092    && flag_unsafe_math_optimizations
18093    && !(reload_completed || reload_in_progress)"
18094   "#"
18095   "&& 1"
18096   [(const_int 0)]
18097 {
18098   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18099
18100   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18101   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18102
18103   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18104                                         operands[2], operands[3]));
18105   DONE;
18106 }
18107   [(set_attr "type" "frndint")
18108    (set_attr "i387_cw" "trunc")
18109    (set_attr "mode" "XF")])
18110
18111 (define_insn "frndintxf2_trunc_i387"
18112   [(set (match_operand:XF 0 "register_operand" "=f")
18113         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18114          UNSPEC_FRNDINT_TRUNC))
18115    (use (match_operand:HI 2 "memory_operand" "m"))
18116    (use (match_operand:HI 3 "memory_operand" "m"))]
18117   "TARGET_USE_FANCY_MATH_387
18118    && flag_unsafe_math_optimizations"
18119   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18120   [(set_attr "type" "frndint")
18121    (set_attr "i387_cw" "trunc")
18122    (set_attr "mode" "XF")])
18123
18124 (define_expand "btruncxf2"
18125   [(use (match_operand:XF 0 "register_operand" ""))
18126    (use (match_operand:XF 1 "register_operand" ""))]
18127   "TARGET_USE_FANCY_MATH_387
18128    && flag_unsafe_math_optimizations"
18129 {
18130   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18131   DONE;
18132 })
18133
18134 (define_expand "btruncdf2"
18135   [(use (match_operand:DF 0 "register_operand" ""))
18136    (use (match_operand:DF 1 "register_operand" ""))]
18137   "TARGET_USE_FANCY_MATH_387
18138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18139    && flag_unsafe_math_optimizations"
18140 {
18141   rtx op0 = gen_reg_rtx (XFmode);
18142   rtx op1 = gen_reg_rtx (XFmode);
18143
18144   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18145   emit_insn (gen_frndintxf2_trunc (op0, op1));
18146
18147   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18148   DONE;
18149 })
18150
18151 (define_expand "btruncsf2"
18152   [(use (match_operand:SF 0 "register_operand" ""))
18153    (use (match_operand:SF 1 "register_operand" ""))]
18154   "TARGET_USE_FANCY_MATH_387
18155    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18156    && flag_unsafe_math_optimizations"
18157 {
18158   rtx op0 = gen_reg_rtx (XFmode);
18159   rtx op1 = gen_reg_rtx (XFmode);
18160
18161   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18162   emit_insn (gen_frndintxf2_trunc (op0, op1));
18163
18164   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18165   DONE;
18166 })
18167
18168 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18169 (define_insn_and_split "frndintxf2_mask_pm"
18170   [(set (match_operand:XF 0 "register_operand" "=f")
18171         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18172          UNSPEC_FRNDINT_MASK_PM))
18173    (clobber (reg:CC FLAGS_REG))]
18174   "TARGET_USE_FANCY_MATH_387
18175    && flag_unsafe_math_optimizations
18176    && !(reload_completed || reload_in_progress)"
18177   "#"
18178   "&& 1"
18179   [(const_int 0)]
18180 {
18181   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18182
18183   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18184   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18185
18186   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18187                                           operands[2], operands[3]));
18188   DONE;
18189 }
18190   [(set_attr "type" "frndint")
18191    (set_attr "i387_cw" "mask_pm")
18192    (set_attr "mode" "XF")])
18193
18194 (define_insn "frndintxf2_mask_pm_i387"
18195   [(set (match_operand:XF 0 "register_operand" "=f")
18196         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18197          UNSPEC_FRNDINT_MASK_PM))
18198    (use (match_operand:HI 2 "memory_operand" "m"))
18199    (use (match_operand:HI 3 "memory_operand" "m"))]
18200   "TARGET_USE_FANCY_MATH_387
18201    && flag_unsafe_math_optimizations"
18202   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18203   [(set_attr "type" "frndint")
18204    (set_attr "i387_cw" "mask_pm")
18205    (set_attr "mode" "XF")])
18206
18207 (define_expand "nearbyintxf2"
18208   [(use (match_operand:XF 0 "register_operand" ""))
18209    (use (match_operand:XF 1 "register_operand" ""))]
18210   "TARGET_USE_FANCY_MATH_387
18211    && flag_unsafe_math_optimizations"
18212 {
18213   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18214
18215   DONE;
18216 })
18217
18218 (define_expand "nearbyintdf2"
18219   [(use (match_operand:DF 0 "register_operand" ""))
18220    (use (match_operand:DF 1 "register_operand" ""))]
18221   "TARGET_USE_FANCY_MATH_387
18222    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18223    && flag_unsafe_math_optimizations"
18224 {
18225   rtx op0 = gen_reg_rtx (XFmode);
18226   rtx op1 = gen_reg_rtx (XFmode);
18227
18228   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18229   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18230
18231   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18232   DONE;
18233 })
18234
18235 (define_expand "nearbyintsf2"
18236   [(use (match_operand:SF 0 "register_operand" ""))
18237    (use (match_operand:SF 1 "register_operand" ""))]
18238   "TARGET_USE_FANCY_MATH_387
18239    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18240    && flag_unsafe_math_optimizations"
18241 {
18242   rtx op0 = gen_reg_rtx (XFmode);
18243   rtx op1 = gen_reg_rtx (XFmode);
18244
18245   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18246   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18247
18248   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18249   DONE;
18250 })
18251
18252 \f
18253 ;; Block operation instructions
18254
18255 (define_insn "cld"
18256  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18257  ""
18258  "cld"
18259   [(set_attr "type" "cld")])
18260
18261 (define_expand "movmemsi"
18262   [(use (match_operand:BLK 0 "memory_operand" ""))
18263    (use (match_operand:BLK 1 "memory_operand" ""))
18264    (use (match_operand:SI 2 "nonmemory_operand" ""))
18265    (use (match_operand:SI 3 "const_int_operand" ""))]
18266   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18267 {
18268  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18269    DONE;
18270  else
18271    FAIL;
18272 })
18273
18274 (define_expand "movmemdi"
18275   [(use (match_operand:BLK 0 "memory_operand" ""))
18276    (use (match_operand:BLK 1 "memory_operand" ""))
18277    (use (match_operand:DI 2 "nonmemory_operand" ""))
18278    (use (match_operand:DI 3 "const_int_operand" ""))]
18279   "TARGET_64BIT"
18280 {
18281  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18282    DONE;
18283  else
18284    FAIL;
18285 })
18286
18287 ;; Most CPUs don't like single string operations
18288 ;; Handle this case here to simplify previous expander.
18289
18290 (define_expand "strmov"
18291   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18292    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18293    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18294               (clobber (reg:CC FLAGS_REG))])
18295    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18296               (clobber (reg:CC FLAGS_REG))])]
18297   ""
18298 {
18299   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18300
18301   /* If .md ever supports :P for Pmode, these can be directly
18302      in the pattern above.  */
18303   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18304   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18305
18306   if (TARGET_SINGLE_STRINGOP || optimize_size)
18307     {
18308       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18309                                       operands[2], operands[3],
18310                                       operands[5], operands[6]));
18311       DONE;
18312     }
18313
18314   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18315 })
18316
18317 (define_expand "strmov_singleop"
18318   [(parallel [(set (match_operand 1 "memory_operand" "")
18319                    (match_operand 3 "memory_operand" ""))
18320               (set (match_operand 0 "register_operand" "")
18321                    (match_operand 4 "" ""))
18322               (set (match_operand 2 "register_operand" "")
18323                    (match_operand 5 "" ""))
18324               (use (reg:SI DIRFLAG_REG))])]
18325   "TARGET_SINGLE_STRINGOP || optimize_size"
18326   "")
18327
18328 (define_insn "*strmovdi_rex_1"
18329   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18330         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18331    (set (match_operand:DI 0 "register_operand" "=D")
18332         (plus:DI (match_dup 2)
18333                  (const_int 8)))
18334    (set (match_operand:DI 1 "register_operand" "=S")
18335         (plus:DI (match_dup 3)
18336                  (const_int 8)))
18337    (use (reg:SI DIRFLAG_REG))]
18338   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18339   "movsq"
18340   [(set_attr "type" "str")
18341    (set_attr "mode" "DI")
18342    (set_attr "memory" "both")])
18343
18344 (define_insn "*strmovsi_1"
18345   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18346         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18347    (set (match_operand:SI 0 "register_operand" "=D")
18348         (plus:SI (match_dup 2)
18349                  (const_int 4)))
18350    (set (match_operand:SI 1 "register_operand" "=S")
18351         (plus:SI (match_dup 3)
18352                  (const_int 4)))
18353    (use (reg:SI DIRFLAG_REG))]
18354   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18355   "{movsl|movsd}"
18356   [(set_attr "type" "str")
18357    (set_attr "mode" "SI")
18358    (set_attr "memory" "both")])
18359
18360 (define_insn "*strmovsi_rex_1"
18361   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18362         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18363    (set (match_operand:DI 0 "register_operand" "=D")
18364         (plus:DI (match_dup 2)
18365                  (const_int 4)))
18366    (set (match_operand:DI 1 "register_operand" "=S")
18367         (plus:DI (match_dup 3)
18368                  (const_int 4)))
18369    (use (reg:SI DIRFLAG_REG))]
18370   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18371   "{movsl|movsd}"
18372   [(set_attr "type" "str")
18373    (set_attr "mode" "SI")
18374    (set_attr "memory" "both")])
18375
18376 (define_insn "*strmovhi_1"
18377   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18378         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18379    (set (match_operand:SI 0 "register_operand" "=D")
18380         (plus:SI (match_dup 2)
18381                  (const_int 2)))
18382    (set (match_operand:SI 1 "register_operand" "=S")
18383         (plus:SI (match_dup 3)
18384                  (const_int 2)))
18385    (use (reg:SI DIRFLAG_REG))]
18386   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387   "movsw"
18388   [(set_attr "type" "str")
18389    (set_attr "memory" "both")
18390    (set_attr "mode" "HI")])
18391
18392 (define_insn "*strmovhi_rex_1"
18393   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18394         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18395    (set (match_operand:DI 0 "register_operand" "=D")
18396         (plus:DI (match_dup 2)
18397                  (const_int 2)))
18398    (set (match_operand:DI 1 "register_operand" "=S")
18399         (plus:DI (match_dup 3)
18400                  (const_int 2)))
18401    (use (reg:SI DIRFLAG_REG))]
18402   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18403   "movsw"
18404   [(set_attr "type" "str")
18405    (set_attr "memory" "both")
18406    (set_attr "mode" "HI")])
18407
18408 (define_insn "*strmovqi_1"
18409   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18410         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18411    (set (match_operand:SI 0 "register_operand" "=D")
18412         (plus:SI (match_dup 2)
18413                  (const_int 1)))
18414    (set (match_operand:SI 1 "register_operand" "=S")
18415         (plus:SI (match_dup 3)
18416                  (const_int 1)))
18417    (use (reg:SI DIRFLAG_REG))]
18418   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419   "movsb"
18420   [(set_attr "type" "str")
18421    (set_attr "memory" "both")
18422    (set_attr "mode" "QI")])
18423
18424 (define_insn "*strmovqi_rex_1"
18425   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18426         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18427    (set (match_operand:DI 0 "register_operand" "=D")
18428         (plus:DI (match_dup 2)
18429                  (const_int 1)))
18430    (set (match_operand:DI 1 "register_operand" "=S")
18431         (plus:DI (match_dup 3)
18432                  (const_int 1)))
18433    (use (reg:SI DIRFLAG_REG))]
18434   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18435   "movsb"
18436   [(set_attr "type" "str")
18437    (set_attr "memory" "both")
18438    (set_attr "mode" "QI")])
18439
18440 (define_expand "rep_mov"
18441   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18442               (set (match_operand 0 "register_operand" "")
18443                    (match_operand 5 "" ""))
18444               (set (match_operand 2 "register_operand" "")
18445                    (match_operand 6 "" ""))
18446               (set (match_operand 1 "memory_operand" "")
18447                    (match_operand 3 "memory_operand" ""))
18448               (use (match_dup 4))
18449               (use (reg:SI DIRFLAG_REG))])]
18450   ""
18451   "")
18452
18453 (define_insn "*rep_movdi_rex64"
18454   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18455    (set (match_operand:DI 0 "register_operand" "=D") 
18456         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18457                             (const_int 3))
18458                  (match_operand:DI 3 "register_operand" "0")))
18459    (set (match_operand:DI 1 "register_operand" "=S") 
18460         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18461                  (match_operand:DI 4 "register_operand" "1")))
18462    (set (mem:BLK (match_dup 3))
18463         (mem:BLK (match_dup 4)))
18464    (use (match_dup 5))
18465    (use (reg:SI DIRFLAG_REG))]
18466   "TARGET_64BIT"
18467   "{rep\;movsq|rep movsq}"
18468   [(set_attr "type" "str")
18469    (set_attr "prefix_rep" "1")
18470    (set_attr "memory" "both")
18471    (set_attr "mode" "DI")])
18472
18473 (define_insn "*rep_movsi"
18474   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18475    (set (match_operand:SI 0 "register_operand" "=D") 
18476         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18477                             (const_int 2))
18478                  (match_operand:SI 3 "register_operand" "0")))
18479    (set (match_operand:SI 1 "register_operand" "=S") 
18480         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18481                  (match_operand:SI 4 "register_operand" "1")))
18482    (set (mem:BLK (match_dup 3))
18483         (mem:BLK (match_dup 4)))
18484    (use (match_dup 5))
18485    (use (reg:SI DIRFLAG_REG))]
18486   "!TARGET_64BIT"
18487   "{rep\;movsl|rep movsd}"
18488   [(set_attr "type" "str")
18489    (set_attr "prefix_rep" "1")
18490    (set_attr "memory" "both")
18491    (set_attr "mode" "SI")])
18492
18493 (define_insn "*rep_movsi_rex64"
18494   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18495    (set (match_operand:DI 0 "register_operand" "=D") 
18496         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18497                             (const_int 2))
18498                  (match_operand:DI 3 "register_operand" "0")))
18499    (set (match_operand:DI 1 "register_operand" "=S") 
18500         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18501                  (match_operand:DI 4 "register_operand" "1")))
18502    (set (mem:BLK (match_dup 3))
18503         (mem:BLK (match_dup 4)))
18504    (use (match_dup 5))
18505    (use (reg:SI DIRFLAG_REG))]
18506   "TARGET_64BIT"
18507   "{rep\;movsl|rep movsd}"
18508   [(set_attr "type" "str")
18509    (set_attr "prefix_rep" "1")
18510    (set_attr "memory" "both")
18511    (set_attr "mode" "SI")])
18512
18513 (define_insn "*rep_movqi"
18514   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18515    (set (match_operand:SI 0 "register_operand" "=D") 
18516         (plus:SI (match_operand:SI 3 "register_operand" "0")
18517                  (match_operand:SI 5 "register_operand" "2")))
18518    (set (match_operand:SI 1 "register_operand" "=S") 
18519         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18520    (set (mem:BLK (match_dup 3))
18521         (mem:BLK (match_dup 4)))
18522    (use (match_dup 5))
18523    (use (reg:SI DIRFLAG_REG))]
18524   "!TARGET_64BIT"
18525   "{rep\;movsb|rep movsb}"
18526   [(set_attr "type" "str")
18527    (set_attr "prefix_rep" "1")
18528    (set_attr "memory" "both")
18529    (set_attr "mode" "SI")])
18530
18531 (define_insn "*rep_movqi_rex64"
18532   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18533    (set (match_operand:DI 0 "register_operand" "=D") 
18534         (plus:DI (match_operand:DI 3 "register_operand" "0")
18535                  (match_operand:DI 5 "register_operand" "2")))
18536    (set (match_operand:DI 1 "register_operand" "=S") 
18537         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18538    (set (mem:BLK (match_dup 3))
18539         (mem:BLK (match_dup 4)))
18540    (use (match_dup 5))
18541    (use (reg:SI DIRFLAG_REG))]
18542   "TARGET_64BIT"
18543   "{rep\;movsb|rep movsb}"
18544   [(set_attr "type" "str")
18545    (set_attr "prefix_rep" "1")
18546    (set_attr "memory" "both")
18547    (set_attr "mode" "SI")])
18548
18549 (define_expand "setmemsi"
18550    [(use (match_operand:BLK 0 "memory_operand" ""))
18551     (use (match_operand:SI 1 "nonmemory_operand" ""))
18552     (use (match_operand 2 "const_int_operand" ""))
18553     (use (match_operand 3 "const_int_operand" ""))]
18554   ""
18555 {
18556  /* If value to set is not zero, use the library routine.  */
18557  if (operands[2] != const0_rtx)
18558    FAIL;
18559
18560  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18561    DONE;
18562  else
18563    FAIL;
18564 })
18565
18566 (define_expand "setmemdi"
18567    [(use (match_operand:BLK 0 "memory_operand" ""))
18568     (use (match_operand:DI 1 "nonmemory_operand" ""))
18569     (use (match_operand 2 "const_int_operand" ""))
18570     (use (match_operand 3 "const_int_operand" ""))]
18571   "TARGET_64BIT"
18572 {
18573  /* If value to set is not zero, use the library routine.  */
18574  if (operands[2] != const0_rtx)
18575    FAIL;
18576
18577  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18578    DONE;
18579  else
18580    FAIL;
18581 })
18582
18583 ;; Most CPUs don't like single string operations
18584 ;; Handle this case here to simplify previous expander.
18585
18586 (define_expand "strset"
18587   [(set (match_operand 1 "memory_operand" "")
18588         (match_operand 2 "register_operand" ""))
18589    (parallel [(set (match_operand 0 "register_operand" "")
18590                    (match_dup 3))
18591               (clobber (reg:CC FLAGS_REG))])]
18592   ""
18593 {
18594   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18595     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18596
18597   /* If .md ever supports :P for Pmode, this can be directly
18598      in the pattern above.  */
18599   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18600                               GEN_INT (GET_MODE_SIZE (GET_MODE
18601                                                       (operands[2]))));
18602   if (TARGET_SINGLE_STRINGOP || optimize_size)
18603     {
18604       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18605                                       operands[3]));
18606       DONE;
18607     }
18608 })
18609
18610 (define_expand "strset_singleop"
18611   [(parallel [(set (match_operand 1 "memory_operand" "")
18612                    (match_operand 2 "register_operand" ""))
18613               (set (match_operand 0 "register_operand" "")
18614                    (match_operand 3 "" ""))
18615               (use (reg:SI DIRFLAG_REG))])]
18616   "TARGET_SINGLE_STRINGOP || optimize_size"
18617   "")
18618
18619 (define_insn "*strsetdi_rex_1"
18620   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18621         (match_operand:DI 2 "register_operand" "a"))
18622    (set (match_operand:DI 0 "register_operand" "=D")
18623         (plus:DI (match_dup 1)
18624                  (const_int 8)))
18625    (use (reg:SI DIRFLAG_REG))]
18626   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18627   "stosq"
18628   [(set_attr "type" "str")
18629    (set_attr "memory" "store")
18630    (set_attr "mode" "DI")])
18631
18632 (define_insn "*strsetsi_1"
18633   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18634         (match_operand:SI 2 "register_operand" "a"))
18635    (set (match_operand:SI 0 "register_operand" "=D")
18636         (plus:SI (match_dup 1)
18637                  (const_int 4)))
18638    (use (reg:SI DIRFLAG_REG))]
18639   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18640   "{stosl|stosd}"
18641   [(set_attr "type" "str")
18642    (set_attr "memory" "store")
18643    (set_attr "mode" "SI")])
18644
18645 (define_insn "*strsetsi_rex_1"
18646   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18647         (match_operand:SI 2 "register_operand" "a"))
18648    (set (match_operand:DI 0 "register_operand" "=D")
18649         (plus:DI (match_dup 1)
18650                  (const_int 4)))
18651    (use (reg:SI DIRFLAG_REG))]
18652   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18653   "{stosl|stosd}"
18654   [(set_attr "type" "str")
18655    (set_attr "memory" "store")
18656    (set_attr "mode" "SI")])
18657
18658 (define_insn "*strsethi_1"
18659   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18660         (match_operand:HI 2 "register_operand" "a"))
18661    (set (match_operand:SI 0 "register_operand" "=D")
18662         (plus:SI (match_dup 1)
18663                  (const_int 2)))
18664    (use (reg:SI DIRFLAG_REG))]
18665   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18666   "stosw"
18667   [(set_attr "type" "str")
18668    (set_attr "memory" "store")
18669    (set_attr "mode" "HI")])
18670
18671 (define_insn "*strsethi_rex_1"
18672   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18673         (match_operand:HI 2 "register_operand" "a"))
18674    (set (match_operand:DI 0 "register_operand" "=D")
18675         (plus:DI (match_dup 1)
18676                  (const_int 2)))
18677    (use (reg:SI DIRFLAG_REG))]
18678   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18679   "stosw"
18680   [(set_attr "type" "str")
18681    (set_attr "memory" "store")
18682    (set_attr "mode" "HI")])
18683
18684 (define_insn "*strsetqi_1"
18685   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18686         (match_operand:QI 2 "register_operand" "a"))
18687    (set (match_operand:SI 0 "register_operand" "=D")
18688         (plus:SI (match_dup 1)
18689                  (const_int 1)))
18690    (use (reg:SI DIRFLAG_REG))]
18691   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692   "stosb"
18693   [(set_attr "type" "str")
18694    (set_attr "memory" "store")
18695    (set_attr "mode" "QI")])
18696
18697 (define_insn "*strsetqi_rex_1"
18698   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18699         (match_operand:QI 2 "register_operand" "a"))
18700    (set (match_operand:DI 0 "register_operand" "=D")
18701         (plus:DI (match_dup 1)
18702                  (const_int 1)))
18703    (use (reg:SI DIRFLAG_REG))]
18704   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18705   "stosb"
18706   [(set_attr "type" "str")
18707    (set_attr "memory" "store")
18708    (set_attr "mode" "QI")])
18709
18710 (define_expand "rep_stos"
18711   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18712               (set (match_operand 0 "register_operand" "")
18713                    (match_operand 4 "" ""))
18714               (set (match_operand 2 "memory_operand" "") (const_int 0))
18715               (use (match_operand 3 "register_operand" ""))
18716               (use (match_dup 1))
18717               (use (reg:SI DIRFLAG_REG))])]
18718   ""
18719   "")
18720
18721 (define_insn "*rep_stosdi_rex64"
18722   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18723    (set (match_operand:DI 0 "register_operand" "=D") 
18724         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18725                             (const_int 3))
18726                  (match_operand:DI 3 "register_operand" "0")))
18727    (set (mem:BLK (match_dup 3))
18728         (const_int 0))
18729    (use (match_operand:DI 2 "register_operand" "a"))
18730    (use (match_dup 4))
18731    (use (reg:SI DIRFLAG_REG))]
18732   "TARGET_64BIT"
18733   "{rep\;stosq|rep stosq}"
18734   [(set_attr "type" "str")
18735    (set_attr "prefix_rep" "1")
18736    (set_attr "memory" "store")
18737    (set_attr "mode" "DI")])
18738
18739 (define_insn "*rep_stossi"
18740   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18741    (set (match_operand:SI 0 "register_operand" "=D") 
18742         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18743                             (const_int 2))
18744                  (match_operand:SI 3 "register_operand" "0")))
18745    (set (mem:BLK (match_dup 3))
18746         (const_int 0))
18747    (use (match_operand:SI 2 "register_operand" "a"))
18748    (use (match_dup 4))
18749    (use (reg:SI DIRFLAG_REG))]
18750   "!TARGET_64BIT"
18751   "{rep\;stosl|rep stosd}"
18752   [(set_attr "type" "str")
18753    (set_attr "prefix_rep" "1")
18754    (set_attr "memory" "store")
18755    (set_attr "mode" "SI")])
18756
18757 (define_insn "*rep_stossi_rex64"
18758   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759    (set (match_operand:DI 0 "register_operand" "=D") 
18760         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18761                             (const_int 2))
18762                  (match_operand:DI 3 "register_operand" "0")))
18763    (set (mem:BLK (match_dup 3))
18764         (const_int 0))
18765    (use (match_operand:SI 2 "register_operand" "a"))
18766    (use (match_dup 4))
18767    (use (reg:SI DIRFLAG_REG))]
18768   "TARGET_64BIT"
18769   "{rep\;stosl|rep stosd}"
18770   [(set_attr "type" "str")
18771    (set_attr "prefix_rep" "1")
18772    (set_attr "memory" "store")
18773    (set_attr "mode" "SI")])
18774
18775 (define_insn "*rep_stosqi"
18776   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18777    (set (match_operand:SI 0 "register_operand" "=D") 
18778         (plus:SI (match_operand:SI 3 "register_operand" "0")
18779                  (match_operand:SI 4 "register_operand" "1")))
18780    (set (mem:BLK (match_dup 3))
18781         (const_int 0))
18782    (use (match_operand:QI 2 "register_operand" "a"))
18783    (use (match_dup 4))
18784    (use (reg:SI DIRFLAG_REG))]
18785   "!TARGET_64BIT"
18786   "{rep\;stosb|rep stosb}"
18787   [(set_attr "type" "str")
18788    (set_attr "prefix_rep" "1")
18789    (set_attr "memory" "store")
18790    (set_attr "mode" "QI")])
18791
18792 (define_insn "*rep_stosqi_rex64"
18793   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18794    (set (match_operand:DI 0 "register_operand" "=D") 
18795         (plus:DI (match_operand:DI 3 "register_operand" "0")
18796                  (match_operand:DI 4 "register_operand" "1")))
18797    (set (mem:BLK (match_dup 3))
18798         (const_int 0))
18799    (use (match_operand:QI 2 "register_operand" "a"))
18800    (use (match_dup 4))
18801    (use (reg:SI DIRFLAG_REG))]
18802   "TARGET_64BIT"
18803   "{rep\;stosb|rep stosb}"
18804   [(set_attr "type" "str")
18805    (set_attr "prefix_rep" "1")
18806    (set_attr "memory" "store")
18807    (set_attr "mode" "QI")])
18808
18809 (define_expand "cmpstrnsi"
18810   [(set (match_operand:SI 0 "register_operand" "")
18811         (compare:SI (match_operand:BLK 1 "general_operand" "")
18812                     (match_operand:BLK 2 "general_operand" "")))
18813    (use (match_operand 3 "general_operand" ""))
18814    (use (match_operand 4 "immediate_operand" ""))]
18815   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18816 {
18817   rtx addr1, addr2, out, outlow, count, countreg, align;
18818
18819   /* Can't use this if the user has appropriated esi or edi.  */
18820   if (global_regs[4] || global_regs[5])
18821     FAIL;
18822
18823   out = operands[0];
18824   if (GET_CODE (out) != REG)
18825     out = gen_reg_rtx (SImode);
18826
18827   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18828   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18829   if (addr1 != XEXP (operands[1], 0))
18830     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18831   if (addr2 != XEXP (operands[2], 0))
18832     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18833
18834   count = operands[3];
18835   countreg = ix86_zero_extend_to_Pmode (count);
18836
18837   /* %%% Iff we are testing strict equality, we can use known alignment
18838      to good advantage.  This may be possible with combine, particularly
18839      once cc0 is dead.  */
18840   align = operands[4];
18841
18842   emit_insn (gen_cld ());
18843   if (GET_CODE (count) == CONST_INT)
18844     {
18845       if (INTVAL (count) == 0)
18846         {
18847           emit_move_insn (operands[0], const0_rtx);
18848           DONE;
18849         }
18850       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18851                                      operands[1], operands[2]));
18852     }
18853   else
18854     {
18855       if (TARGET_64BIT)
18856         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18857       else
18858         emit_insn (gen_cmpsi_1 (countreg, countreg));
18859       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18860                                   operands[1], operands[2]));
18861     }
18862
18863   outlow = gen_lowpart (QImode, out);
18864   emit_insn (gen_cmpintqi (outlow));
18865   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18866
18867   if (operands[0] != out)
18868     emit_move_insn (operands[0], out);
18869
18870   DONE;
18871 })
18872
18873 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18874
18875 (define_expand "cmpintqi"
18876   [(set (match_dup 1)
18877         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18878    (set (match_dup 2)
18879         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18880    (parallel [(set (match_operand:QI 0 "register_operand" "")
18881                    (minus:QI (match_dup 1)
18882                              (match_dup 2)))
18883               (clobber (reg:CC FLAGS_REG))])]
18884   ""
18885   "operands[1] = gen_reg_rtx (QImode);
18886    operands[2] = gen_reg_rtx (QImode);")
18887
18888 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18889 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18890
18891 (define_expand "cmpstrnqi_nz_1"
18892   [(parallel [(set (reg:CC FLAGS_REG)
18893                    (compare:CC (match_operand 4 "memory_operand" "")
18894                                (match_operand 5 "memory_operand" "")))
18895               (use (match_operand 2 "register_operand" ""))
18896               (use (match_operand:SI 3 "immediate_operand" ""))
18897               (use (reg:SI DIRFLAG_REG))
18898               (clobber (match_operand 0 "register_operand" ""))
18899               (clobber (match_operand 1 "register_operand" ""))
18900               (clobber (match_dup 2))])]
18901   ""
18902   "")
18903
18904 (define_insn "*cmpstrnqi_nz_1"
18905   [(set (reg:CC FLAGS_REG)
18906         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18907                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18908    (use (match_operand:SI 6 "register_operand" "2"))
18909    (use (match_operand:SI 3 "immediate_operand" "i"))
18910    (use (reg:SI DIRFLAG_REG))
18911    (clobber (match_operand:SI 0 "register_operand" "=S"))
18912    (clobber (match_operand:SI 1 "register_operand" "=D"))
18913    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18914   "!TARGET_64BIT"
18915   "repz{\;| }cmpsb"
18916   [(set_attr "type" "str")
18917    (set_attr "mode" "QI")
18918    (set_attr "prefix_rep" "1")])
18919
18920 (define_insn "*cmpstrnqi_nz_rex_1"
18921   [(set (reg:CC FLAGS_REG)
18922         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18923                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18924    (use (match_operand:DI 6 "register_operand" "2"))
18925    (use (match_operand:SI 3 "immediate_operand" "i"))
18926    (use (reg:SI DIRFLAG_REG))
18927    (clobber (match_operand:DI 0 "register_operand" "=S"))
18928    (clobber (match_operand:DI 1 "register_operand" "=D"))
18929    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18930   "TARGET_64BIT"
18931   "repz{\;| }cmpsb"
18932   [(set_attr "type" "str")
18933    (set_attr "mode" "QI")
18934    (set_attr "prefix_rep" "1")])
18935
18936 ;; The same, but the count is not known to not be zero.
18937
18938 (define_expand "cmpstrnqi_1"
18939   [(parallel [(set (reg:CC FLAGS_REG)
18940                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18941                                      (const_int 0))
18942                   (compare:CC (match_operand 4 "memory_operand" "")
18943                               (match_operand 5 "memory_operand" ""))
18944                   (const_int 0)))
18945               (use (match_operand:SI 3 "immediate_operand" ""))
18946               (use (reg:CC FLAGS_REG))
18947               (use (reg:SI DIRFLAG_REG))
18948               (clobber (match_operand 0 "register_operand" ""))
18949               (clobber (match_operand 1 "register_operand" ""))
18950               (clobber (match_dup 2))])]
18951   ""
18952   "")
18953
18954 (define_insn "*cmpstrnqi_1"
18955   [(set (reg:CC FLAGS_REG)
18956         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18957                              (const_int 0))
18958           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18959                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18960           (const_int 0)))
18961    (use (match_operand:SI 3 "immediate_operand" "i"))
18962    (use (reg:CC FLAGS_REG))
18963    (use (reg:SI DIRFLAG_REG))
18964    (clobber (match_operand:SI 0 "register_operand" "=S"))
18965    (clobber (match_operand:SI 1 "register_operand" "=D"))
18966    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18967   "!TARGET_64BIT"
18968   "repz{\;| }cmpsb"
18969   [(set_attr "type" "str")
18970    (set_attr "mode" "QI")
18971    (set_attr "prefix_rep" "1")])
18972
18973 (define_insn "*cmpstrnqi_rex_1"
18974   [(set (reg:CC FLAGS_REG)
18975         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18976                              (const_int 0))
18977           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18978                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18979           (const_int 0)))
18980    (use (match_operand:SI 3 "immediate_operand" "i"))
18981    (use (reg:CC FLAGS_REG))
18982    (use (reg:SI DIRFLAG_REG))
18983    (clobber (match_operand:DI 0 "register_operand" "=S"))
18984    (clobber (match_operand:DI 1 "register_operand" "=D"))
18985    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18986   "TARGET_64BIT"
18987   "repz{\;| }cmpsb"
18988   [(set_attr "type" "str")
18989    (set_attr "mode" "QI")
18990    (set_attr "prefix_rep" "1")])
18991
18992 (define_expand "strlensi"
18993   [(set (match_operand:SI 0 "register_operand" "")
18994         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18995                     (match_operand:QI 2 "immediate_operand" "")
18996                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18997   ""
18998 {
18999  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19000    DONE;
19001  else
19002    FAIL;
19003 })
19004
19005 (define_expand "strlendi"
19006   [(set (match_operand:DI 0 "register_operand" "")
19007         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19008                     (match_operand:QI 2 "immediate_operand" "")
19009                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19010   ""
19011 {
19012  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19013    DONE;
19014  else
19015    FAIL;
19016 })
19017
19018 (define_expand "strlenqi_1"
19019   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19020               (use (reg:SI DIRFLAG_REG))
19021               (clobber (match_operand 1 "register_operand" ""))
19022               (clobber (reg:CC FLAGS_REG))])]
19023   ""
19024   "")
19025
19026 (define_insn "*strlenqi_1"
19027   [(set (match_operand:SI 0 "register_operand" "=&c")
19028         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19029                     (match_operand:QI 2 "register_operand" "a")
19030                     (match_operand:SI 3 "immediate_operand" "i")
19031                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19032    (use (reg:SI DIRFLAG_REG))
19033    (clobber (match_operand:SI 1 "register_operand" "=D"))
19034    (clobber (reg:CC FLAGS_REG))]
19035   "!TARGET_64BIT"
19036   "repnz{\;| }scasb"
19037   [(set_attr "type" "str")
19038    (set_attr "mode" "QI")
19039    (set_attr "prefix_rep" "1")])
19040
19041 (define_insn "*strlenqi_rex_1"
19042   [(set (match_operand:DI 0 "register_operand" "=&c")
19043         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19044                     (match_operand:QI 2 "register_operand" "a")
19045                     (match_operand:DI 3 "immediate_operand" "i")
19046                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19047    (use (reg:SI DIRFLAG_REG))
19048    (clobber (match_operand:DI 1 "register_operand" "=D"))
19049    (clobber (reg:CC FLAGS_REG))]
19050   "TARGET_64BIT"
19051   "repnz{\;| }scasb"
19052   [(set_attr "type" "str")
19053    (set_attr "mode" "QI")
19054    (set_attr "prefix_rep" "1")])
19055
19056 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19057 ;; handled in combine, but it is not currently up to the task.
19058 ;; When used for their truth value, the cmpstrn* expanders generate
19059 ;; code like this:
19060 ;;
19061 ;;   repz cmpsb
19062 ;;   seta       %al
19063 ;;   setb       %dl
19064 ;;   cmpb       %al, %dl
19065 ;;   jcc        label
19066 ;;
19067 ;; The intermediate three instructions are unnecessary.
19068
19069 ;; This one handles cmpstrn*_nz_1...
19070 (define_peephole2
19071   [(parallel[
19072      (set (reg:CC FLAGS_REG)
19073           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19074                       (mem:BLK (match_operand 5 "register_operand" ""))))
19075      (use (match_operand 6 "register_operand" ""))
19076      (use (match_operand:SI 3 "immediate_operand" ""))
19077      (use (reg:SI DIRFLAG_REG))
19078      (clobber (match_operand 0 "register_operand" ""))
19079      (clobber (match_operand 1 "register_operand" ""))
19080      (clobber (match_operand 2 "register_operand" ""))])
19081    (set (match_operand:QI 7 "register_operand" "")
19082         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083    (set (match_operand:QI 8 "register_operand" "")
19084         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085    (set (reg FLAGS_REG)
19086         (compare (match_dup 7) (match_dup 8)))
19087   ]
19088   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19089   [(parallel[
19090      (set (reg:CC FLAGS_REG)
19091           (compare:CC (mem:BLK (match_dup 4))
19092                       (mem:BLK (match_dup 5))))
19093      (use (match_dup 6))
19094      (use (match_dup 3))
19095      (use (reg:SI DIRFLAG_REG))
19096      (clobber (match_dup 0))
19097      (clobber (match_dup 1))
19098      (clobber (match_dup 2))])]
19099   "")
19100
19101 ;; ...and this one handles cmpstrn*_1.
19102 (define_peephole2
19103   [(parallel[
19104      (set (reg:CC FLAGS_REG)
19105           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19106                                (const_int 0))
19107             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19108                         (mem:BLK (match_operand 5 "register_operand" "")))
19109             (const_int 0)))
19110      (use (match_operand:SI 3 "immediate_operand" ""))
19111      (use (reg:CC FLAGS_REG))
19112      (use (reg:SI DIRFLAG_REG))
19113      (clobber (match_operand 0 "register_operand" ""))
19114      (clobber (match_operand 1 "register_operand" ""))
19115      (clobber (match_operand 2 "register_operand" ""))])
19116    (set (match_operand:QI 7 "register_operand" "")
19117         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19118    (set (match_operand:QI 8 "register_operand" "")
19119         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19120    (set (reg FLAGS_REG)
19121         (compare (match_dup 7) (match_dup 8)))
19122   ]
19123   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19124   [(parallel[
19125      (set (reg:CC FLAGS_REG)
19126           (if_then_else:CC (ne (match_dup 6)
19127                                (const_int 0))
19128             (compare:CC (mem:BLK (match_dup 4))
19129                         (mem:BLK (match_dup 5)))
19130             (const_int 0)))
19131      (use (match_dup 3))
19132      (use (reg:CC FLAGS_REG))
19133      (use (reg:SI DIRFLAG_REG))
19134      (clobber (match_dup 0))
19135      (clobber (match_dup 1))
19136      (clobber (match_dup 2))])]
19137   "")
19138
19139
19140 \f
19141 ;; Conditional move instructions.
19142
19143 (define_expand "movdicc"
19144   [(set (match_operand:DI 0 "register_operand" "")
19145         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19146                          (match_operand:DI 2 "general_operand" "")
19147                          (match_operand:DI 3 "general_operand" "")))]
19148   "TARGET_64BIT"
19149   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19150
19151 (define_insn "x86_movdicc_0_m1_rex64"
19152   [(set (match_operand:DI 0 "register_operand" "=r")
19153         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19154           (const_int -1)
19155           (const_int 0)))
19156    (clobber (reg:CC FLAGS_REG))]
19157   "TARGET_64BIT"
19158   "sbb{q}\t%0, %0"
19159   ; Since we don't have the proper number of operands for an alu insn,
19160   ; fill in all the blanks.
19161   [(set_attr "type" "alu")
19162    (set_attr "pent_pair" "pu")
19163    (set_attr "memory" "none")
19164    (set_attr "imm_disp" "false")
19165    (set_attr "mode" "DI")
19166    (set_attr "length_immediate" "0")])
19167
19168 (define_insn "*movdicc_c_rex64"
19169   [(set (match_operand:DI 0 "register_operand" "=r,r")
19170         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
19171                                 [(reg FLAGS_REG) (const_int 0)])
19172                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19173                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19174   "TARGET_64BIT && TARGET_CMOVE
19175    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19176   "@
19177    cmov%O2%C1\t{%2, %0|%0, %2}
19178    cmov%O2%c1\t{%3, %0|%0, %3}"
19179   [(set_attr "type" "icmov")
19180    (set_attr "mode" "DI")])
19181
19182 (define_expand "movsicc"
19183   [(set (match_operand:SI 0 "register_operand" "")
19184         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19185                          (match_operand:SI 2 "general_operand" "")
19186                          (match_operand:SI 3 "general_operand" "")))]
19187   ""
19188   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19189
19190 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19191 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19192 ;; So just document what we're doing explicitly.
19193
19194 (define_insn "x86_movsicc_0_m1"
19195   [(set (match_operand:SI 0 "register_operand" "=r")
19196         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19197           (const_int -1)
19198           (const_int 0)))
19199    (clobber (reg:CC FLAGS_REG))]
19200   ""
19201   "sbb{l}\t%0, %0"
19202   ; Since we don't have the proper number of operands for an alu insn,
19203   ; fill in all the blanks.
19204   [(set_attr "type" "alu")
19205    (set_attr "pent_pair" "pu")
19206    (set_attr "memory" "none")
19207    (set_attr "imm_disp" "false")
19208    (set_attr "mode" "SI")
19209    (set_attr "length_immediate" "0")])
19210
19211 (define_insn "*movsicc_noc"
19212   [(set (match_operand:SI 0 "register_operand" "=r,r")
19213         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
19214                                 [(reg FLAGS_REG) (const_int 0)])
19215                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19216                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19217   "TARGET_CMOVE
19218    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19219   "@
19220    cmov%O2%C1\t{%2, %0|%0, %2}
19221    cmov%O2%c1\t{%3, %0|%0, %3}"
19222   [(set_attr "type" "icmov")
19223    (set_attr "mode" "SI")])
19224
19225 (define_expand "movhicc"
19226   [(set (match_operand:HI 0 "register_operand" "")
19227         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19228                          (match_operand:HI 2 "general_operand" "")
19229                          (match_operand:HI 3 "general_operand" "")))]
19230   "TARGET_HIMODE_MATH"
19231   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19232
19233 (define_insn "*movhicc_noc"
19234   [(set (match_operand:HI 0 "register_operand" "=r,r")
19235         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
19236                                 [(reg FLAGS_REG) (const_int 0)])
19237                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19238                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19239   "TARGET_CMOVE
19240    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19241   "@
19242    cmov%O2%C1\t{%2, %0|%0, %2}
19243    cmov%O2%c1\t{%3, %0|%0, %3}"
19244   [(set_attr "type" "icmov")
19245    (set_attr "mode" "HI")])
19246
19247 (define_expand "movqicc"
19248   [(set (match_operand:QI 0 "register_operand" "")
19249         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19250                          (match_operand:QI 2 "general_operand" "")
19251                          (match_operand:QI 3 "general_operand" "")))]
19252   "TARGET_QIMODE_MATH"
19253   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19254
19255 (define_insn_and_split "*movqicc_noc"
19256   [(set (match_operand:QI 0 "register_operand" "=r,r")
19257         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
19258                                 [(match_operand 4 "flags_reg_operand" "")
19259                                  (const_int 0)])
19260                       (match_operand:QI 2 "register_operand" "r,0")
19261                       (match_operand:QI 3 "register_operand" "0,r")))]
19262   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19263   "#"
19264   "&& reload_completed"
19265   [(set (match_dup 0)
19266         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19267                       (match_dup 2)
19268                       (match_dup 3)))]
19269   "operands[0] = gen_lowpart (SImode, operands[0]);
19270    operands[2] = gen_lowpart (SImode, operands[2]);
19271    operands[3] = gen_lowpart (SImode, operands[3]);"
19272   [(set_attr "type" "icmov")
19273    (set_attr "mode" "SI")])
19274
19275 (define_expand "movsfcc"
19276   [(set (match_operand:SF 0 "register_operand" "")
19277         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19278                          (match_operand:SF 2 "register_operand" "")
19279                          (match_operand:SF 3 "register_operand" "")))]
19280   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19281   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19282
19283 (define_insn "*movsfcc_1_387"
19284   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19285         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19286                                 [(reg FLAGS_REG) (const_int 0)])
19287                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19288                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19289   "TARGET_80387 && TARGET_CMOVE
19290    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19291   "@
19292    fcmov%F1\t{%2, %0|%0, %2}
19293    fcmov%f1\t{%3, %0|%0, %3}
19294    cmov%O2%C1\t{%2, %0|%0, %2}
19295    cmov%O2%c1\t{%3, %0|%0, %3}"
19296   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19297    (set_attr "mode" "SF,SF,SI,SI")])
19298
19299 (define_expand "movdfcc"
19300   [(set (match_operand:DF 0 "register_operand" "")
19301         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19302                          (match_operand:DF 2 "register_operand" "")
19303                          (match_operand:DF 3 "register_operand" "")))]
19304   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19305   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19306
19307 (define_insn "*movdfcc_1"
19308   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19309         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19310                                 [(reg FLAGS_REG) (const_int 0)])
19311                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19312                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19313   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19314    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19315   "@
19316    fcmov%F1\t{%2, %0|%0, %2}
19317    fcmov%f1\t{%3, %0|%0, %3}
19318    #
19319    #"
19320   [(set_attr "type" "fcmov,fcmov,multi,multi")
19321    (set_attr "mode" "DF")])
19322
19323 (define_insn "*movdfcc_1_rex64"
19324   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19325         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19326                                 [(reg FLAGS_REG) (const_int 0)])
19327                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19328                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19329   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19330    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19331   "@
19332    fcmov%F1\t{%2, %0|%0, %2}
19333    fcmov%f1\t{%3, %0|%0, %3}
19334    cmov%O2%C1\t{%2, %0|%0, %2}
19335    cmov%O2%c1\t{%3, %0|%0, %3}"
19336   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19337    (set_attr "mode" "DF")])
19338
19339 (define_split
19340   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19341         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19342                                 [(match_operand 4 "flags_reg_operand" "")
19343                                  (const_int 0)])
19344                       (match_operand:DF 2 "nonimmediate_operand" "")
19345                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19346   "!TARGET_64BIT && reload_completed"
19347   [(set (match_dup 2)
19348         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19349                       (match_dup 5)
19350                       (match_dup 7)))
19351    (set (match_dup 3)
19352         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19353                       (match_dup 6)
19354                       (match_dup 8)))]
19355   "split_di (operands+2, 1, operands+5, operands+6);
19356    split_di (operands+3, 1, operands+7, operands+8);
19357    split_di (operands, 1, operands+2, operands+3);")
19358
19359 (define_expand "movxfcc"
19360   [(set (match_operand:XF 0 "register_operand" "")
19361         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19362                          (match_operand:XF 2 "register_operand" "")
19363                          (match_operand:XF 3 "register_operand" "")))]
19364   "TARGET_80387 && TARGET_CMOVE"
19365   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19366
19367 (define_insn "*movxfcc_1"
19368   [(set (match_operand:XF 0 "register_operand" "=f,f")
19369         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19370                                 [(reg FLAGS_REG) (const_int 0)])
19371                       (match_operand:XF 2 "register_operand" "f,0")
19372                       (match_operand:XF 3 "register_operand" "0,f")))]
19373   "TARGET_80387 && TARGET_CMOVE"
19374   "@
19375    fcmov%F1\t{%2, %0|%0, %2}
19376    fcmov%f1\t{%3, %0|%0, %3}"
19377   [(set_attr "type" "fcmov")
19378    (set_attr "mode" "XF")])
19379
19380 ;; These versions of the min/max patterns are intentionally ignorant of
19381 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19382 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19383 ;; are undefined in this condition, we're certain this is correct.
19384
19385 (define_insn "sminsf3"
19386   [(set (match_operand:SF 0 "register_operand" "=x")
19387         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19388                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19389   "TARGET_SSE_MATH"
19390   "minss\t{%2, %0|%0, %2}"
19391   [(set_attr "type" "sseadd")
19392    (set_attr "mode" "SF")])
19393
19394 (define_insn "smaxsf3"
19395   [(set (match_operand:SF 0 "register_operand" "=x")
19396         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19397                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19398   "TARGET_SSE_MATH"
19399   "maxss\t{%2, %0|%0, %2}"
19400   [(set_attr "type" "sseadd")
19401    (set_attr "mode" "SF")])
19402
19403 (define_insn "smindf3"
19404   [(set (match_operand:DF 0 "register_operand" "=x")
19405         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19406                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19407   "TARGET_SSE2 && TARGET_SSE_MATH"
19408   "minsd\t{%2, %0|%0, %2}"
19409   [(set_attr "type" "sseadd")
19410    (set_attr "mode" "DF")])
19411
19412 (define_insn "smaxdf3"
19413   [(set (match_operand:DF 0 "register_operand" "=x")
19414         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19415                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19416   "TARGET_SSE2 && TARGET_SSE_MATH"
19417   "maxsd\t{%2, %0|%0, %2}"
19418   [(set_attr "type" "sseadd")
19419    (set_attr "mode" "DF")])
19420
19421 ;; These versions of the min/max patterns implement exactly the operations
19422 ;;   min = (op1 < op2 ? op1 : op2)
19423 ;;   max = (!(op1 < op2) ? op1 : op2)
19424 ;; Their operands are not commutative, and thus they may be used in the
19425 ;; presence of -0.0 and NaN.
19426
19427 (define_insn "*ieee_sminsf3"
19428   [(set (match_operand:SF 0 "register_operand" "=x")
19429         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19430                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19431                    UNSPEC_IEEE_MIN))]
19432   "TARGET_SSE_MATH"
19433   "minss\t{%2, %0|%0, %2}"
19434   [(set_attr "type" "sseadd")
19435    (set_attr "mode" "SF")])
19436
19437 (define_insn "*ieee_smaxsf3"
19438   [(set (match_operand:SF 0 "register_operand" "=x")
19439         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19440                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19441                    UNSPEC_IEEE_MAX))]
19442   "TARGET_SSE_MATH"
19443   "maxss\t{%2, %0|%0, %2}"
19444   [(set_attr "type" "sseadd")
19445    (set_attr "mode" "SF")])
19446
19447 (define_insn "*ieee_smindf3"
19448   [(set (match_operand:DF 0 "register_operand" "=x")
19449         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19450                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19451                    UNSPEC_IEEE_MIN))]
19452   "TARGET_SSE2 && TARGET_SSE_MATH"
19453   "minsd\t{%2, %0|%0, %2}"
19454   [(set_attr "type" "sseadd")
19455    (set_attr "mode" "DF")])
19456
19457 (define_insn "*ieee_smaxdf3"
19458   [(set (match_operand:DF 0 "register_operand" "=x")
19459         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19460                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19461                    UNSPEC_IEEE_MAX))]
19462   "TARGET_SSE2 && TARGET_SSE_MATH"
19463   "maxsd\t{%2, %0|%0, %2}"
19464   [(set_attr "type" "sseadd")
19465    (set_attr "mode" "DF")])
19466
19467 ;; Make two stack loads independent:
19468 ;;   fld aa              fld aa
19469 ;;   fld %st(0)     ->   fld bb
19470 ;;   fmul bb             fmul %st(1), %st
19471 ;;
19472 ;; Actually we only match the last two instructions for simplicity.
19473 (define_peephole2
19474   [(set (match_operand 0 "fp_register_operand" "")
19475         (match_operand 1 "fp_register_operand" ""))
19476    (set (match_dup 0)
19477         (match_operator 2 "binary_fp_operator"
19478            [(match_dup 0)
19479             (match_operand 3 "memory_operand" "")]))]
19480   "REGNO (operands[0]) != REGNO (operands[1])"
19481   [(set (match_dup 0) (match_dup 3))
19482    (set (match_dup 0) (match_dup 4))]
19483
19484   ;; The % modifier is not operational anymore in peephole2's, so we have to
19485   ;; swap the operands manually in the case of addition and multiplication.
19486   "if (COMMUTATIVE_ARITH_P (operands[2]))
19487      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19488                                  operands[0], operands[1]);
19489    else
19490      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491                                  operands[1], operands[0]);")
19492
19493 ;; Conditional addition patterns
19494 (define_expand "addqicc"
19495   [(match_operand:QI 0 "register_operand" "")
19496    (match_operand 1 "comparison_operator" "")
19497    (match_operand:QI 2 "register_operand" "")
19498    (match_operand:QI 3 "const_int_operand" "")]
19499   ""
19500   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19501
19502 (define_expand "addhicc"
19503   [(match_operand:HI 0 "register_operand" "")
19504    (match_operand 1 "comparison_operator" "")
19505    (match_operand:HI 2 "register_operand" "")
19506    (match_operand:HI 3 "const_int_operand" "")]
19507   ""
19508   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19509
19510 (define_expand "addsicc"
19511   [(match_operand:SI 0 "register_operand" "")
19512    (match_operand 1 "comparison_operator" "")
19513    (match_operand:SI 2 "register_operand" "")
19514    (match_operand:SI 3 "const_int_operand" "")]
19515   ""
19516   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19517
19518 (define_expand "adddicc"
19519   [(match_operand:DI 0 "register_operand" "")
19520    (match_operand 1 "comparison_operator" "")
19521    (match_operand:DI 2 "register_operand" "")
19522    (match_operand:DI 3 "const_int_operand" "")]
19523   "TARGET_64BIT"
19524   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19525
19526 \f
19527 ;; Misc patterns (?)
19528
19529 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19530 ;; Otherwise there will be nothing to keep
19531 ;; 
19532 ;; [(set (reg ebp) (reg esp))]
19533 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19534 ;;  (clobber (eflags)]
19535 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19536 ;;
19537 ;; in proper program order.
19538 (define_insn "pro_epilogue_adjust_stack_1"
19539   [(set (match_operand:SI 0 "register_operand" "=r,r")
19540         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19541                  (match_operand:SI 2 "immediate_operand" "i,i")))
19542    (clobber (reg:CC FLAGS_REG))
19543    (clobber (mem:BLK (scratch)))]
19544   "!TARGET_64BIT"
19545 {
19546   switch (get_attr_type (insn))
19547     {
19548     case TYPE_IMOV:
19549       return "mov{l}\t{%1, %0|%0, %1}";
19550
19551     case TYPE_ALU:
19552       if (GET_CODE (operands[2]) == CONST_INT
19553           && (INTVAL (operands[2]) == 128
19554               || (INTVAL (operands[2]) < 0
19555                   && INTVAL (operands[2]) != -128)))
19556         {
19557           operands[2] = GEN_INT (-INTVAL (operands[2]));
19558           return "sub{l}\t{%2, %0|%0, %2}";
19559         }
19560       return "add{l}\t{%2, %0|%0, %2}";
19561
19562     case TYPE_LEA:
19563       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19564       return "lea{l}\t{%a2, %0|%0, %a2}";
19565
19566     default:
19567       gcc_unreachable ();
19568     }
19569 }
19570   [(set (attr "type")
19571         (cond [(eq_attr "alternative" "0")
19572                  (const_string "alu")
19573                (match_operand:SI 2 "const0_operand" "")
19574                  (const_string "imov")
19575               ]
19576               (const_string "lea")))
19577    (set_attr "mode" "SI")])
19578
19579 (define_insn "pro_epilogue_adjust_stack_rex64"
19580   [(set (match_operand:DI 0 "register_operand" "=r,r")
19581         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19582                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19583    (clobber (reg:CC FLAGS_REG))
19584    (clobber (mem:BLK (scratch)))]
19585   "TARGET_64BIT"
19586 {
19587   switch (get_attr_type (insn))
19588     {
19589     case TYPE_IMOV:
19590       return "mov{q}\t{%1, %0|%0, %1}";
19591
19592     case TYPE_ALU:
19593       if (GET_CODE (operands[2]) == CONST_INT
19594           /* Avoid overflows.  */
19595           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19596           && (INTVAL (operands[2]) == 128
19597               || (INTVAL (operands[2]) < 0
19598                   && INTVAL (operands[2]) != -128)))
19599         {
19600           operands[2] = GEN_INT (-INTVAL (operands[2]));
19601           return "sub{q}\t{%2, %0|%0, %2}";
19602         }
19603       return "add{q}\t{%2, %0|%0, %2}";
19604
19605     case TYPE_LEA:
19606       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607       return "lea{q}\t{%a2, %0|%0, %a2}";
19608
19609     default:
19610       gcc_unreachable ();
19611     }
19612 }
19613   [(set (attr "type")
19614         (cond [(eq_attr "alternative" "0")
19615                  (const_string "alu")
19616                (match_operand:DI 2 "const0_operand" "")
19617                  (const_string "imov")
19618               ]
19619               (const_string "lea")))
19620    (set_attr "mode" "DI")])
19621
19622 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19623   [(set (match_operand:DI 0 "register_operand" "=r,r")
19624         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625                  (match_operand:DI 3 "immediate_operand" "i,i")))
19626    (use (match_operand:DI 2 "register_operand" "r,r"))
19627    (clobber (reg:CC FLAGS_REG))
19628    (clobber (mem:BLK (scratch)))]
19629   "TARGET_64BIT"
19630 {
19631   switch (get_attr_type (insn))
19632     {
19633     case TYPE_ALU:
19634       return "add{q}\t{%2, %0|%0, %2}";
19635
19636     case TYPE_LEA:
19637       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19638       return "lea{q}\t{%a2, %0|%0, %a2}";
19639
19640     default:
19641       gcc_unreachable ();
19642     }
19643 }
19644   [(set_attr "type" "alu,lea")
19645    (set_attr "mode" "DI")])
19646
19647 (define_expand "allocate_stack_worker"
19648   [(match_operand:SI 0 "register_operand" "")]
19649   "TARGET_STACK_PROBE"
19650 {
19651   if (reload_completed)
19652     {
19653       if (TARGET_64BIT)
19654         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19655       else
19656         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19657     }
19658   else
19659     {
19660       if (TARGET_64BIT)
19661         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19662       else
19663         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19664     }
19665   DONE;
19666 })
19667
19668 (define_insn "allocate_stack_worker_1"
19669   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19670     UNSPECV_STACK_PROBE)
19671    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19672    (clobber (match_scratch:SI 1 "=0"))
19673    (clobber (reg:CC FLAGS_REG))]
19674   "!TARGET_64BIT && TARGET_STACK_PROBE"
19675   "call\t__alloca"
19676   [(set_attr "type" "multi")
19677    (set_attr "length" "5")])
19678
19679 (define_expand "allocate_stack_worker_postreload"
19680   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19681                                     UNSPECV_STACK_PROBE)
19682               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19683               (clobber (match_dup 0))
19684               (clobber (reg:CC FLAGS_REG))])]
19685   ""
19686   "")
19687
19688 (define_insn "allocate_stack_worker_rex64"
19689   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19690     UNSPECV_STACK_PROBE)
19691    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19692    (clobber (match_scratch:DI 1 "=0"))
19693    (clobber (reg:CC FLAGS_REG))]
19694   "TARGET_64BIT && TARGET_STACK_PROBE"
19695   "call\t__alloca"
19696   [(set_attr "type" "multi")
19697    (set_attr "length" "5")])
19698
19699 (define_expand "allocate_stack_worker_rex64_postreload"
19700   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19701                                     UNSPECV_STACK_PROBE)
19702               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19703               (clobber (match_dup 0))
19704               (clobber (reg:CC FLAGS_REG))])]
19705   ""
19706   "")
19707
19708 (define_expand "allocate_stack"
19709   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19710                    (minus:SI (reg:SI SP_REG)
19711                              (match_operand:SI 1 "general_operand" "")))
19712               (clobber (reg:CC FLAGS_REG))])
19713    (parallel [(set (reg:SI SP_REG)
19714                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19715               (clobber (reg:CC FLAGS_REG))])]
19716   "TARGET_STACK_PROBE"
19717 {
19718 #ifdef CHECK_STACK_LIMIT
19719   if (GET_CODE (operands[1]) == CONST_INT
19720       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19721     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19722                            operands[1]));
19723   else 
19724 #endif
19725     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19726                                                             operands[1])));
19727
19728   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19729   DONE;
19730 })
19731
19732 (define_expand "builtin_setjmp_receiver"
19733   [(label_ref (match_operand 0 "" ""))]
19734   "!TARGET_64BIT && flag_pic"
19735 {
19736   if (TARGET_MACHO)
19737     {
19738       rtx xops[3];
19739       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19740       rtx label_rtx = gen_label_rtx ();
19741       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19742       xops[0] = xops[1] = picreg;
19743       xops[2] = gen_rtx_CONST (SImode,
19744                   gen_rtx_MINUS (SImode,
19745                     gen_rtx_LABEL_REF (SImode, label_rtx),
19746                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19747       ix86_expand_binary_operator (MINUS, SImode, xops);
19748     }
19749   else
19750     emit_insn (gen_set_got (pic_offset_table_rtx));
19751   DONE;
19752 })
19753 \f
19754 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19755
19756 (define_split
19757   [(set (match_operand 0 "register_operand" "")
19758         (match_operator 3 "promotable_binary_operator"
19759            [(match_operand 1 "register_operand" "")
19760             (match_operand 2 "aligned_operand" "")]))
19761    (clobber (reg:CC FLAGS_REG))]
19762   "! TARGET_PARTIAL_REG_STALL && reload_completed
19763    && ((GET_MODE (operands[0]) == HImode 
19764         && ((!optimize_size && !TARGET_FAST_PREFIX)
19765             /* ??? next two lines just !satisfies_constraint_K (...) */
19766             || GET_CODE (operands[2]) != CONST_INT
19767             || satisfies_constraint_K (operands[2])))
19768        || (GET_MODE (operands[0]) == QImode 
19769            && (TARGET_PROMOTE_QImode || optimize_size)))"
19770   [(parallel [(set (match_dup 0)
19771                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19772               (clobber (reg:CC FLAGS_REG))])]
19773   "operands[0] = gen_lowpart (SImode, operands[0]);
19774    operands[1] = gen_lowpart (SImode, operands[1]);
19775    if (GET_CODE (operands[3]) != ASHIFT)
19776      operands[2] = gen_lowpart (SImode, operands[2]);
19777    PUT_MODE (operands[3], SImode);")
19778
19779 ; Promote the QImode tests, as i386 has encoding of the AND
19780 ; instruction with 32-bit sign-extended immediate and thus the
19781 ; instruction size is unchanged, except in the %eax case for
19782 ; which it is increased by one byte, hence the ! optimize_size.
19783 (define_split
19784   [(set (match_operand 0 "flags_reg_operand" "")
19785         (match_operator 2 "compare_operator"
19786           [(and (match_operand 3 "aligned_operand" "")
19787                 (match_operand 4 "const_int_operand" ""))
19788            (const_int 0)]))
19789    (set (match_operand 1 "register_operand" "")
19790         (and (match_dup 3) (match_dup 4)))]
19791   "! TARGET_PARTIAL_REG_STALL && reload_completed
19792    /* Ensure that the operand will remain sign-extended immediate.  */
19793    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19794    && ! optimize_size
19795    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19796        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19797   [(parallel [(set (match_dup 0)
19798                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19799                                     (const_int 0)]))
19800               (set (match_dup 1)
19801                    (and:SI (match_dup 3) (match_dup 4)))])]
19802 {
19803   operands[4]
19804     = gen_int_mode (INTVAL (operands[4])
19805                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19806   operands[1] = gen_lowpart (SImode, operands[1]);
19807   operands[3] = gen_lowpart (SImode, operands[3]);
19808 })
19809
19810 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19811 ; the TEST instruction with 32-bit sign-extended immediate and thus
19812 ; the instruction size would at least double, which is not what we
19813 ; want even with ! optimize_size.
19814 (define_split
19815   [(set (match_operand 0 "flags_reg_operand" "")
19816         (match_operator 1 "compare_operator"
19817           [(and (match_operand:HI 2 "aligned_operand" "")
19818                 (match_operand:HI 3 "const_int_operand" ""))
19819            (const_int 0)]))]
19820   "! TARGET_PARTIAL_REG_STALL && reload_completed
19821    /* Ensure that the operand will remain sign-extended immediate.  */
19822    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19823    && ! TARGET_FAST_PREFIX
19824    && ! optimize_size"
19825   [(set (match_dup 0)
19826         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19827                          (const_int 0)]))]
19828 {
19829   operands[3]
19830     = gen_int_mode (INTVAL (operands[3])
19831                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19832   operands[2] = gen_lowpart (SImode, operands[2]);
19833 })
19834
19835 (define_split
19836   [(set (match_operand 0 "register_operand" "")
19837         (neg (match_operand 1 "register_operand" "")))
19838    (clobber (reg:CC FLAGS_REG))]
19839   "! TARGET_PARTIAL_REG_STALL && reload_completed
19840    && (GET_MODE (operands[0]) == HImode
19841        || (GET_MODE (operands[0]) == QImode 
19842            && (TARGET_PROMOTE_QImode || optimize_size)))"
19843   [(parallel [(set (match_dup 0)
19844                    (neg:SI (match_dup 1)))
19845               (clobber (reg:CC FLAGS_REG))])]
19846   "operands[0] = gen_lowpart (SImode, operands[0]);
19847    operands[1] = gen_lowpart (SImode, operands[1]);")
19848
19849 (define_split
19850   [(set (match_operand 0 "register_operand" "")
19851         (not (match_operand 1 "register_operand" "")))]
19852   "! TARGET_PARTIAL_REG_STALL && reload_completed
19853    && (GET_MODE (operands[0]) == HImode
19854        || (GET_MODE (operands[0]) == QImode 
19855            && (TARGET_PROMOTE_QImode || optimize_size)))"
19856   [(set (match_dup 0)
19857         (not:SI (match_dup 1)))]
19858   "operands[0] = gen_lowpart (SImode, operands[0]);
19859    operands[1] = gen_lowpart (SImode, operands[1]);")
19860
19861 (define_split 
19862   [(set (match_operand 0 "register_operand" "")
19863         (if_then_else (match_operator 1 "comparison_operator" 
19864                                 [(reg FLAGS_REG) (const_int 0)])
19865                       (match_operand 2 "register_operand" "")
19866                       (match_operand 3 "register_operand" "")))]
19867   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19868    && (GET_MODE (operands[0]) == HImode
19869        || (GET_MODE (operands[0]) == QImode 
19870            && (TARGET_PROMOTE_QImode || optimize_size)))"
19871   [(set (match_dup 0)
19872         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19873   "operands[0] = gen_lowpart (SImode, operands[0]);
19874    operands[2] = gen_lowpart (SImode, operands[2]);
19875    operands[3] = gen_lowpart (SImode, operands[3]);")
19876                         
19877 \f
19878 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19879 ;; transform a complex memory operation into two memory to register operations.
19880
19881 ;; Don't push memory operands
19882 (define_peephole2
19883   [(set (match_operand:SI 0 "push_operand" "")
19884         (match_operand:SI 1 "memory_operand" ""))
19885    (match_scratch:SI 2 "r")]
19886   "!optimize_size && !TARGET_PUSH_MEMORY
19887    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19888   [(set (match_dup 2) (match_dup 1))
19889    (set (match_dup 0) (match_dup 2))]
19890   "")
19891
19892 (define_peephole2
19893   [(set (match_operand:DI 0 "push_operand" "")
19894         (match_operand:DI 1 "memory_operand" ""))
19895    (match_scratch:DI 2 "r")]
19896   "!optimize_size && !TARGET_PUSH_MEMORY
19897    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19898   [(set (match_dup 2) (match_dup 1))
19899    (set (match_dup 0) (match_dup 2))]
19900   "")
19901
19902 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19903 ;; SImode pushes.
19904 (define_peephole2
19905   [(set (match_operand:SF 0 "push_operand" "")
19906         (match_operand:SF 1 "memory_operand" ""))
19907    (match_scratch:SF 2 "r")]
19908   "!optimize_size && !TARGET_PUSH_MEMORY
19909    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910   [(set (match_dup 2) (match_dup 1))
19911    (set (match_dup 0) (match_dup 2))]
19912   "")
19913
19914 (define_peephole2
19915   [(set (match_operand:HI 0 "push_operand" "")
19916         (match_operand:HI 1 "memory_operand" ""))
19917    (match_scratch:HI 2 "r")]
19918   "!optimize_size && !TARGET_PUSH_MEMORY
19919    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920   [(set (match_dup 2) (match_dup 1))
19921    (set (match_dup 0) (match_dup 2))]
19922   "")
19923
19924 (define_peephole2
19925   [(set (match_operand:QI 0 "push_operand" "")
19926         (match_operand:QI 1 "memory_operand" ""))
19927    (match_scratch:QI 2 "q")]
19928   "!optimize_size && !TARGET_PUSH_MEMORY
19929    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930   [(set (match_dup 2) (match_dup 1))
19931    (set (match_dup 0) (match_dup 2))]
19932   "")
19933
19934 ;; Don't move an immediate directly to memory when the instruction
19935 ;; gets too big.
19936 (define_peephole2
19937   [(match_scratch:SI 1 "r")
19938    (set (match_operand:SI 0 "memory_operand" "")
19939         (const_int 0))]
19940   "! optimize_size
19941    && ! TARGET_USE_MOV0
19942    && TARGET_SPLIT_LONG_MOVES
19943    && get_attr_length (insn) >= ix86_cost->large_insn
19944    && peep2_regno_dead_p (0, FLAGS_REG)"
19945   [(parallel [(set (match_dup 1) (const_int 0))
19946               (clobber (reg:CC FLAGS_REG))])
19947    (set (match_dup 0) (match_dup 1))]
19948   "")
19949
19950 (define_peephole2
19951   [(match_scratch:HI 1 "r")
19952    (set (match_operand:HI 0 "memory_operand" "")
19953         (const_int 0))]
19954   "! optimize_size
19955    && ! TARGET_USE_MOV0
19956    && TARGET_SPLIT_LONG_MOVES
19957    && get_attr_length (insn) >= ix86_cost->large_insn
19958    && peep2_regno_dead_p (0, FLAGS_REG)"
19959   [(parallel [(set (match_dup 2) (const_int 0))
19960               (clobber (reg:CC FLAGS_REG))])
19961    (set (match_dup 0) (match_dup 1))]
19962   "operands[2] = gen_lowpart (SImode, operands[1]);")
19963
19964 (define_peephole2
19965   [(match_scratch:QI 1 "q")
19966    (set (match_operand:QI 0 "memory_operand" "")
19967         (const_int 0))]
19968   "! optimize_size
19969    && ! TARGET_USE_MOV0
19970    && TARGET_SPLIT_LONG_MOVES
19971    && get_attr_length (insn) >= ix86_cost->large_insn
19972    && peep2_regno_dead_p (0, FLAGS_REG)"
19973   [(parallel [(set (match_dup 2) (const_int 0))
19974               (clobber (reg:CC FLAGS_REG))])
19975    (set (match_dup 0) (match_dup 1))]
19976   "operands[2] = gen_lowpart (SImode, operands[1]);")
19977
19978 (define_peephole2
19979   [(match_scratch:SI 2 "r")
19980    (set (match_operand:SI 0 "memory_operand" "")
19981         (match_operand:SI 1 "immediate_operand" ""))]
19982   "! optimize_size
19983    && get_attr_length (insn) >= ix86_cost->large_insn
19984    && TARGET_SPLIT_LONG_MOVES"
19985   [(set (match_dup 2) (match_dup 1))
19986    (set (match_dup 0) (match_dup 2))]
19987   "")
19988
19989 (define_peephole2
19990   [(match_scratch:HI 2 "r")
19991    (set (match_operand:HI 0 "memory_operand" "")
19992         (match_operand:HI 1 "immediate_operand" ""))]
19993   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19994   && TARGET_SPLIT_LONG_MOVES"
19995   [(set (match_dup 2) (match_dup 1))
19996    (set (match_dup 0) (match_dup 2))]
19997   "")
19998
19999 (define_peephole2
20000   [(match_scratch:QI 2 "q")
20001    (set (match_operand:QI 0 "memory_operand" "")
20002         (match_operand:QI 1 "immediate_operand" ""))]
20003   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20004   && TARGET_SPLIT_LONG_MOVES"
20005   [(set (match_dup 2) (match_dup 1))
20006    (set (match_dup 0) (match_dup 2))]
20007   "")
20008
20009 ;; Don't compare memory with zero, load and use a test instead.
20010 (define_peephole2
20011   [(set (match_operand 0 "flags_reg_operand" "")
20012         (match_operator 1 "compare_operator"
20013           [(match_operand:SI 2 "memory_operand" "")
20014            (const_int 0)]))
20015    (match_scratch:SI 3 "r")]
20016   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20017   [(set (match_dup 3) (match_dup 2))
20018    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20019   "")
20020
20021 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
20022 ;; Don't split NOTs with a displacement operand, because resulting XOR
20023 ;; will not be pairable anyway.
20024 ;;
20025 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20026 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20027 ;; so this split helps here as well.
20028 ;;
20029 ;; Note: Can't do this as a regular split because we can't get proper
20030 ;; lifetime information then.
20031
20032 (define_peephole2
20033   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20034         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20035   "!optimize_size
20036    && peep2_regno_dead_p (0, FLAGS_REG)
20037    && ((TARGET_PENTIUM 
20038         && (GET_CODE (operands[0]) != MEM
20039             || !memory_displacement_operand (operands[0], SImode)))
20040        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20041   [(parallel [(set (match_dup 0)
20042                    (xor:SI (match_dup 1) (const_int -1)))
20043               (clobber (reg:CC FLAGS_REG))])]
20044   "")
20045
20046 (define_peephole2
20047   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20048         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20049   "!optimize_size
20050    && peep2_regno_dead_p (0, FLAGS_REG)
20051    && ((TARGET_PENTIUM 
20052         && (GET_CODE (operands[0]) != MEM
20053             || !memory_displacement_operand (operands[0], HImode)))
20054        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20055   [(parallel [(set (match_dup 0)
20056                    (xor:HI (match_dup 1) (const_int -1)))
20057               (clobber (reg:CC FLAGS_REG))])]
20058   "")
20059
20060 (define_peephole2
20061   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20062         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20063   "!optimize_size
20064    && peep2_regno_dead_p (0, FLAGS_REG)
20065    && ((TARGET_PENTIUM 
20066         && (GET_CODE (operands[0]) != MEM
20067             || !memory_displacement_operand (operands[0], QImode)))
20068        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20069   [(parallel [(set (match_dup 0)
20070                    (xor:QI (match_dup 1) (const_int -1)))
20071               (clobber (reg:CC FLAGS_REG))])]
20072   "")
20073
20074 ;; Non pairable "test imm, reg" instructions can be translated to
20075 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20076 ;; byte opcode instead of two, have a short form for byte operands),
20077 ;; so do it for other CPUs as well.  Given that the value was dead,
20078 ;; this should not create any new dependencies.  Pass on the sub-word
20079 ;; versions if we're concerned about partial register stalls.
20080
20081 (define_peephole2
20082   [(set (match_operand 0 "flags_reg_operand" "")
20083         (match_operator 1 "compare_operator"
20084           [(and:SI (match_operand:SI 2 "register_operand" "")
20085                    (match_operand:SI 3 "immediate_operand" ""))
20086            (const_int 0)]))]
20087   "ix86_match_ccmode (insn, CCNOmode)
20088    && (true_regnum (operands[2]) != 0
20089        || satisfies_constraint_K (operands[3]))
20090    && peep2_reg_dead_p (1, operands[2])"
20091   [(parallel
20092      [(set (match_dup 0)
20093            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20094                             (const_int 0)]))
20095       (set (match_dup 2)
20096            (and:SI (match_dup 2) (match_dup 3)))])]
20097   "")
20098
20099 ;; We don't need to handle HImode case, because it will be promoted to SImode
20100 ;; on ! TARGET_PARTIAL_REG_STALL
20101
20102 (define_peephole2
20103   [(set (match_operand 0 "flags_reg_operand" "")
20104         (match_operator 1 "compare_operator"
20105           [(and:QI (match_operand:QI 2 "register_operand" "")
20106                    (match_operand:QI 3 "immediate_operand" ""))
20107            (const_int 0)]))]
20108   "! TARGET_PARTIAL_REG_STALL
20109    && ix86_match_ccmode (insn, CCNOmode)
20110    && true_regnum (operands[2]) != 0
20111    && peep2_reg_dead_p (1, operands[2])"
20112   [(parallel
20113      [(set (match_dup 0)
20114            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20115                             (const_int 0)]))
20116       (set (match_dup 2)
20117            (and:QI (match_dup 2) (match_dup 3)))])]
20118   "")
20119
20120 (define_peephole2
20121   [(set (match_operand 0 "flags_reg_operand" "")
20122         (match_operator 1 "compare_operator"
20123           [(and:SI
20124              (zero_extract:SI
20125                (match_operand 2 "ext_register_operand" "")
20126                (const_int 8)
20127                (const_int 8))
20128              (match_operand 3 "const_int_operand" ""))
20129            (const_int 0)]))]
20130   "! TARGET_PARTIAL_REG_STALL
20131    && ix86_match_ccmode (insn, CCNOmode)
20132    && true_regnum (operands[2]) != 0
20133    && peep2_reg_dead_p (1, operands[2])"
20134   [(parallel [(set (match_dup 0)
20135                    (match_op_dup 1
20136                      [(and:SI
20137                         (zero_extract:SI
20138                           (match_dup 2)
20139                           (const_int 8)
20140                           (const_int 8))
20141                         (match_dup 3))
20142                       (const_int 0)]))
20143               (set (zero_extract:SI (match_dup 2)
20144                                     (const_int 8)
20145                                     (const_int 8))
20146                    (and:SI 
20147                      (zero_extract:SI
20148                        (match_dup 2)
20149                        (const_int 8)
20150                        (const_int 8))
20151                      (match_dup 3)))])]
20152   "")
20153
20154 ;; Don't do logical operations with memory inputs.
20155 (define_peephole2
20156   [(match_scratch:SI 2 "r")
20157    (parallel [(set (match_operand:SI 0 "register_operand" "")
20158                    (match_operator:SI 3 "arith_or_logical_operator"
20159                      [(match_dup 0)
20160                       (match_operand:SI 1 "memory_operand" "")]))
20161               (clobber (reg:CC FLAGS_REG))])]
20162   "! optimize_size && ! TARGET_READ_MODIFY"
20163   [(set (match_dup 2) (match_dup 1))
20164    (parallel [(set (match_dup 0)
20165                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20166               (clobber (reg:CC FLAGS_REG))])]
20167   "")
20168
20169 (define_peephole2
20170   [(match_scratch:SI 2 "r")
20171    (parallel [(set (match_operand:SI 0 "register_operand" "")
20172                    (match_operator:SI 3 "arith_or_logical_operator"
20173                      [(match_operand:SI 1 "memory_operand" "")
20174                       (match_dup 0)]))
20175               (clobber (reg:CC FLAGS_REG))])]
20176   "! optimize_size && ! TARGET_READ_MODIFY"
20177   [(set (match_dup 2) (match_dup 1))
20178    (parallel [(set (match_dup 0)
20179                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20180               (clobber (reg:CC FLAGS_REG))])]
20181   "")
20182
20183 ; Don't do logical operations with memory outputs
20184 ;
20185 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20186 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20187 ; the same decoder scheduling characteristics as the original.
20188
20189 (define_peephole2
20190   [(match_scratch:SI 2 "r")
20191    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20192                    (match_operator:SI 3 "arith_or_logical_operator"
20193                      [(match_dup 0)
20194                       (match_operand:SI 1 "nonmemory_operand" "")]))
20195               (clobber (reg:CC FLAGS_REG))])]
20196   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20197   [(set (match_dup 2) (match_dup 0))
20198    (parallel [(set (match_dup 2)
20199                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20200               (clobber (reg:CC FLAGS_REG))])
20201    (set (match_dup 0) (match_dup 2))]
20202   "")
20203
20204 (define_peephole2
20205   [(match_scratch:SI 2 "r")
20206    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20207                    (match_operator:SI 3 "arith_or_logical_operator"
20208                      [(match_operand:SI 1 "nonmemory_operand" "")
20209                       (match_dup 0)]))
20210               (clobber (reg:CC FLAGS_REG))])]
20211   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20212   [(set (match_dup 2) (match_dup 0))
20213    (parallel [(set (match_dup 2)
20214                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20215               (clobber (reg:CC FLAGS_REG))])
20216    (set (match_dup 0) (match_dup 2))]
20217   "")
20218
20219 ;; Attempt to always use XOR for zeroing registers.
20220 (define_peephole2
20221   [(set (match_operand 0 "register_operand" "")
20222         (match_operand 1 "const0_operand" ""))]
20223   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20224    && (! TARGET_USE_MOV0 || optimize_size)
20225    && GENERAL_REG_P (operands[0])
20226    && peep2_regno_dead_p (0, FLAGS_REG)"
20227   [(parallel [(set (match_dup 0) (const_int 0))
20228               (clobber (reg:CC FLAGS_REG))])]
20229 {
20230   operands[0] = gen_lowpart (word_mode, operands[0]);
20231 })
20232
20233 (define_peephole2
20234   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20235         (const_int 0))]
20236   "(GET_MODE (operands[0]) == QImode
20237     || GET_MODE (operands[0]) == HImode)
20238    && (! TARGET_USE_MOV0 || optimize_size)
20239    && peep2_regno_dead_p (0, FLAGS_REG)"
20240   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20241               (clobber (reg:CC FLAGS_REG))])])
20242
20243 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20244 (define_peephole2
20245   [(set (match_operand 0 "register_operand" "")
20246         (const_int -1))]
20247   "(GET_MODE (operands[0]) == HImode
20248     || GET_MODE (operands[0]) == SImode 
20249     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20250    && (optimize_size || TARGET_PENTIUM)
20251    && peep2_regno_dead_p (0, FLAGS_REG)"
20252   [(parallel [(set (match_dup 0) (const_int -1))
20253               (clobber (reg:CC FLAGS_REG))])]
20254   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20255                               operands[0]);")
20256
20257 ;; Attempt to convert simple leas to adds. These can be created by
20258 ;; move expanders.
20259 (define_peephole2
20260   [(set (match_operand:SI 0 "register_operand" "")
20261         (plus:SI (match_dup 0)
20262                  (match_operand:SI 1 "nonmemory_operand" "")))]
20263   "peep2_regno_dead_p (0, FLAGS_REG)"
20264   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20265               (clobber (reg:CC FLAGS_REG))])]
20266   "")
20267
20268 (define_peephole2
20269   [(set (match_operand:SI 0 "register_operand" "")
20270         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20271                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20272   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20273   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20274               (clobber (reg:CC FLAGS_REG))])]
20275   "operands[2] = gen_lowpart (SImode, operands[2]);")
20276
20277 (define_peephole2
20278   [(set (match_operand:DI 0 "register_operand" "")
20279         (plus:DI (match_dup 0)
20280                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20281   "peep2_regno_dead_p (0, FLAGS_REG)"
20282   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20283               (clobber (reg:CC FLAGS_REG))])]
20284   "")
20285
20286 (define_peephole2
20287   [(set (match_operand:SI 0 "register_operand" "")
20288         (mult:SI (match_dup 0)
20289                  (match_operand:SI 1 "const_int_operand" "")))]
20290   "exact_log2 (INTVAL (operands[1])) >= 0
20291    && peep2_regno_dead_p (0, FLAGS_REG)"
20292   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20293               (clobber (reg:CC FLAGS_REG))])]
20294   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20295
20296 (define_peephole2
20297   [(set (match_operand:DI 0 "register_operand" "")
20298         (mult:DI (match_dup 0)
20299                  (match_operand:DI 1 "const_int_operand" "")))]
20300   "exact_log2 (INTVAL (operands[1])) >= 0
20301    && peep2_regno_dead_p (0, FLAGS_REG)"
20302   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20303               (clobber (reg:CC FLAGS_REG))])]
20304   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20305
20306 (define_peephole2
20307   [(set (match_operand:SI 0 "register_operand" "")
20308         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20309                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20310   "exact_log2 (INTVAL (operands[2])) >= 0
20311    && REGNO (operands[0]) == REGNO (operands[1])
20312    && peep2_regno_dead_p (0, FLAGS_REG)"
20313   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20314               (clobber (reg:CC FLAGS_REG))])]
20315   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20316
20317 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20318 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20319 ;; many CPUs it is also faster, since special hardware to avoid esp
20320 ;; dependencies is present.
20321
20322 ;; While some of these conversions may be done using splitters, we use peepholes
20323 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20324
20325 ;; Convert prologue esp subtractions to push.
20326 ;; We need register to push.  In order to keep verify_flow_info happy we have
20327 ;; two choices
20328 ;; - use scratch and clobber it in order to avoid dependencies
20329 ;; - use already live register
20330 ;; We can't use the second way right now, since there is no reliable way how to
20331 ;; verify that given register is live.  First choice will also most likely in
20332 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20333 ;; call clobbered registers are dead.  We may want to use base pointer as an
20334 ;; alternative when no register is available later.
20335
20336 (define_peephole2
20337   [(match_scratch:SI 0 "r")
20338    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20339               (clobber (reg:CC FLAGS_REG))
20340               (clobber (mem:BLK (scratch)))])]
20341   "optimize_size || !TARGET_SUB_ESP_4"
20342   [(clobber (match_dup 0))
20343    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20344               (clobber (mem:BLK (scratch)))])])
20345
20346 (define_peephole2
20347   [(match_scratch:SI 0 "r")
20348    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20349               (clobber (reg:CC FLAGS_REG))
20350               (clobber (mem:BLK (scratch)))])]
20351   "optimize_size || !TARGET_SUB_ESP_8"
20352   [(clobber (match_dup 0))
20353    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20354    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20355               (clobber (mem:BLK (scratch)))])])
20356
20357 ;; Convert esp subtractions to push.
20358 (define_peephole2
20359   [(match_scratch:SI 0 "r")
20360    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20361               (clobber (reg:CC FLAGS_REG))])]
20362   "optimize_size || !TARGET_SUB_ESP_4"
20363   [(clobber (match_dup 0))
20364    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20365
20366 (define_peephole2
20367   [(match_scratch:SI 0 "r")
20368    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20369               (clobber (reg:CC FLAGS_REG))])]
20370   "optimize_size || !TARGET_SUB_ESP_8"
20371   [(clobber (match_dup 0))
20372    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20374
20375 ;; Convert epilogue deallocator to pop.
20376 (define_peephole2
20377   [(match_scratch:SI 0 "r")
20378    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20379               (clobber (reg:CC FLAGS_REG))
20380               (clobber (mem:BLK (scratch)))])]
20381   "optimize_size || !TARGET_ADD_ESP_4"
20382   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20383               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20384               (clobber (mem:BLK (scratch)))])]
20385   "")
20386
20387 ;; Two pops case is tricky, since pop causes dependency on destination register.
20388 ;; We use two registers if available.
20389 (define_peephole2
20390   [(match_scratch:SI 0 "r")
20391    (match_scratch:SI 1 "r")
20392    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20393               (clobber (reg:CC FLAGS_REG))
20394               (clobber (mem:BLK (scratch)))])]
20395   "optimize_size || !TARGET_ADD_ESP_8"
20396   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20397               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20398               (clobber (mem:BLK (scratch)))])
20399    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20400               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20401   "")
20402
20403 (define_peephole2
20404   [(match_scratch:SI 0 "r")
20405    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20406               (clobber (reg:CC FLAGS_REG))
20407               (clobber (mem:BLK (scratch)))])]
20408   "optimize_size"
20409   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20410               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20411               (clobber (mem:BLK (scratch)))])
20412    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20414   "")
20415
20416 ;; Convert esp additions to pop.
20417 (define_peephole2
20418   [(match_scratch:SI 0 "r")
20419    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20420               (clobber (reg:CC FLAGS_REG))])]
20421   ""
20422   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20423               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20424   "")
20425
20426 ;; Two pops case is tricky, since pop causes dependency on destination register.
20427 ;; We use two registers if available.
20428 (define_peephole2
20429   [(match_scratch:SI 0 "r")
20430    (match_scratch:SI 1 "r")
20431    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20432               (clobber (reg:CC FLAGS_REG))])]
20433   ""
20434   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20436    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20437               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438   "")
20439
20440 (define_peephole2
20441   [(match_scratch:SI 0 "r")
20442    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443               (clobber (reg:CC FLAGS_REG))])]
20444   "optimize_size"
20445   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20446               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20447    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20448               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20449   "")
20450 \f
20451 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20452 ;; required and register dies.  Similarly for 128 to plus -128.
20453 (define_peephole2
20454   [(set (match_operand 0 "flags_reg_operand" "")
20455         (match_operator 1 "compare_operator"
20456           [(match_operand 2 "register_operand" "")
20457            (match_operand 3 "const_int_operand" "")]))]
20458   "(INTVAL (operands[3]) == -1
20459     || INTVAL (operands[3]) == 1
20460     || INTVAL (operands[3]) == 128)
20461    && ix86_match_ccmode (insn, CCGCmode)
20462    && peep2_reg_dead_p (1, operands[2])"
20463   [(parallel [(set (match_dup 0)
20464                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20465               (clobber (match_dup 2))])]
20466   "")
20467 \f
20468 (define_peephole2
20469   [(match_scratch:DI 0 "r")
20470    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20471               (clobber (reg:CC FLAGS_REG))
20472               (clobber (mem:BLK (scratch)))])]
20473   "optimize_size || !TARGET_SUB_ESP_4"
20474   [(clobber (match_dup 0))
20475    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20476               (clobber (mem:BLK (scratch)))])])
20477
20478 (define_peephole2
20479   [(match_scratch:DI 0 "r")
20480    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20481               (clobber (reg:CC FLAGS_REG))
20482               (clobber (mem:BLK (scratch)))])]
20483   "optimize_size || !TARGET_SUB_ESP_8"
20484   [(clobber (match_dup 0))
20485    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20486    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20487               (clobber (mem:BLK (scratch)))])])
20488
20489 ;; Convert esp subtractions to push.
20490 (define_peephole2
20491   [(match_scratch:DI 0 "r")
20492    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20493               (clobber (reg:CC FLAGS_REG))])]
20494   "optimize_size || !TARGET_SUB_ESP_4"
20495   [(clobber (match_dup 0))
20496    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20497
20498 (define_peephole2
20499   [(match_scratch:DI 0 "r")
20500    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20501               (clobber (reg:CC FLAGS_REG))])]
20502   "optimize_size || !TARGET_SUB_ESP_8"
20503   [(clobber (match_dup 0))
20504    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20506
20507 ;; Convert epilogue deallocator to pop.
20508 (define_peephole2
20509   [(match_scratch:DI 0 "r")
20510    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20511               (clobber (reg:CC FLAGS_REG))
20512               (clobber (mem:BLK (scratch)))])]
20513   "optimize_size || !TARGET_ADD_ESP_4"
20514   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20515               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20516               (clobber (mem:BLK (scratch)))])]
20517   "")
20518
20519 ;; Two pops case is tricky, since pop causes dependency on destination register.
20520 ;; We use two registers if available.
20521 (define_peephole2
20522   [(match_scratch:DI 0 "r")
20523    (match_scratch:DI 1 "r")
20524    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20525               (clobber (reg:CC FLAGS_REG))
20526               (clobber (mem:BLK (scratch)))])]
20527   "optimize_size || !TARGET_ADD_ESP_8"
20528   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20529               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20530               (clobber (mem:BLK (scratch)))])
20531    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20532               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20533   "")
20534
20535 (define_peephole2
20536   [(match_scratch:DI 0 "r")
20537    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20538               (clobber (reg:CC FLAGS_REG))
20539               (clobber (mem:BLK (scratch)))])]
20540   "optimize_size"
20541   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20542               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20543               (clobber (mem:BLK (scratch)))])
20544    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20546   "")
20547
20548 ;; Convert esp additions to pop.
20549 (define_peephole2
20550   [(match_scratch:DI 0 "r")
20551    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20552               (clobber (reg:CC FLAGS_REG))])]
20553   ""
20554   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20555               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20556   "")
20557
20558 ;; Two pops case is tricky, since pop causes dependency on destination register.
20559 ;; We use two registers if available.
20560 (define_peephole2
20561   [(match_scratch:DI 0 "r")
20562    (match_scratch:DI 1 "r")
20563    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20564               (clobber (reg:CC FLAGS_REG))])]
20565   ""
20566   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20568    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20569               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570   "")
20571
20572 (define_peephole2
20573   [(match_scratch:DI 0 "r")
20574    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575               (clobber (reg:CC FLAGS_REG))])]
20576   "optimize_size"
20577   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20578               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20579    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20580               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20581   "")
20582 \f
20583 ;; Convert imul by three, five and nine into lea
20584 (define_peephole2
20585   [(parallel
20586     [(set (match_operand:SI 0 "register_operand" "")
20587           (mult:SI (match_operand:SI 1 "register_operand" "")
20588                    (match_operand:SI 2 "const_int_operand" "")))
20589      (clobber (reg:CC FLAGS_REG))])]
20590   "INTVAL (operands[2]) == 3
20591    || INTVAL (operands[2]) == 5
20592    || INTVAL (operands[2]) == 9"
20593   [(set (match_dup 0)
20594         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20595                  (match_dup 1)))]
20596   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20597
20598 (define_peephole2
20599   [(parallel
20600     [(set (match_operand:SI 0 "register_operand" "")
20601           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20602                    (match_operand:SI 2 "const_int_operand" "")))
20603      (clobber (reg:CC FLAGS_REG))])]
20604   "!optimize_size 
20605    && (INTVAL (operands[2]) == 3
20606        || INTVAL (operands[2]) == 5
20607        || INTVAL (operands[2]) == 9)"
20608   [(set (match_dup 0) (match_dup 1))
20609    (set (match_dup 0)
20610         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20611                  (match_dup 0)))]
20612   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20613
20614 (define_peephole2
20615   [(parallel
20616     [(set (match_operand:DI 0 "register_operand" "")
20617           (mult:DI (match_operand:DI 1 "register_operand" "")
20618                    (match_operand:DI 2 "const_int_operand" "")))
20619      (clobber (reg:CC FLAGS_REG))])]
20620   "TARGET_64BIT
20621    && (INTVAL (operands[2]) == 3
20622        || INTVAL (operands[2]) == 5
20623        || INTVAL (operands[2]) == 9)"
20624   [(set (match_dup 0)
20625         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20626                  (match_dup 1)))]
20627   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20628
20629 (define_peephole2
20630   [(parallel
20631     [(set (match_operand:DI 0 "register_operand" "")
20632           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20633                    (match_operand:DI 2 "const_int_operand" "")))
20634      (clobber (reg:CC FLAGS_REG))])]
20635   "TARGET_64BIT
20636    && !optimize_size 
20637    && (INTVAL (operands[2]) == 3
20638        || INTVAL (operands[2]) == 5
20639        || INTVAL (operands[2]) == 9)"
20640   [(set (match_dup 0) (match_dup 1))
20641    (set (match_dup 0)
20642         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20643                  (match_dup 0)))]
20644   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20645
20646 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20647 ;; imul $32bit_imm, reg, reg is direct decoded.
20648 (define_peephole2
20649   [(match_scratch:DI 3 "r")
20650    (parallel [(set (match_operand:DI 0 "register_operand" "")
20651                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20652                             (match_operand:DI 2 "immediate_operand" "")))
20653               (clobber (reg:CC FLAGS_REG))])]
20654   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20655    && !satisfies_constraint_K (operands[2])"
20656   [(set (match_dup 3) (match_dup 1))
20657    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20658               (clobber (reg:CC FLAGS_REG))])]
20659 "")
20660
20661 (define_peephole2
20662   [(match_scratch:SI 3 "r")
20663    (parallel [(set (match_operand:SI 0 "register_operand" "")
20664                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20665                             (match_operand:SI 2 "immediate_operand" "")))
20666               (clobber (reg:CC FLAGS_REG))])]
20667   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20668    && !satisfies_constraint_K (operands[2])"
20669   [(set (match_dup 3) (match_dup 1))
20670    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20671               (clobber (reg:CC FLAGS_REG))])]
20672 "")
20673
20674 (define_peephole2
20675   [(match_scratch:SI 3 "r")
20676    (parallel [(set (match_operand:DI 0 "register_operand" "")
20677                    (zero_extend:DI
20678                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20679                               (match_operand:SI 2 "immediate_operand" ""))))
20680               (clobber (reg:CC FLAGS_REG))])]
20681   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20682    && !satisfies_constraint_K (operands[2])"
20683   [(set (match_dup 3) (match_dup 1))
20684    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20685               (clobber (reg:CC FLAGS_REG))])]
20686 "")
20687
20688 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20689 ;; Convert it into imul reg, reg
20690 ;; It would be better to force assembler to encode instruction using long
20691 ;; immediate, but there is apparently no way to do so.
20692 (define_peephole2
20693   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20694                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20695                             (match_operand:DI 2 "const_int_operand" "")))
20696               (clobber (reg:CC FLAGS_REG))])
20697    (match_scratch:DI 3 "r")]
20698   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20699    && satisfies_constraint_K (operands[2])"
20700   [(set (match_dup 3) (match_dup 2))
20701    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20702               (clobber (reg:CC FLAGS_REG))])]
20703 {
20704   if (!rtx_equal_p (operands[0], operands[1]))
20705     emit_move_insn (operands[0], operands[1]);
20706 })
20707
20708 (define_peephole2
20709   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20710                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20711                             (match_operand:SI 2 "const_int_operand" "")))
20712               (clobber (reg:CC FLAGS_REG))])
20713    (match_scratch:SI 3 "r")]
20714   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20715    && satisfies_constraint_K (operands[2])"
20716   [(set (match_dup 3) (match_dup 2))
20717    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20718               (clobber (reg:CC FLAGS_REG))])]
20719 {
20720   if (!rtx_equal_p (operands[0], operands[1]))
20721     emit_move_insn (operands[0], operands[1]);
20722 })
20723
20724 (define_peephole2
20725   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20726                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20727                             (match_operand:HI 2 "immediate_operand" "")))
20728               (clobber (reg:CC FLAGS_REG))])
20729    (match_scratch:HI 3 "r")]
20730   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20731   [(set (match_dup 3) (match_dup 2))
20732    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20733               (clobber (reg:CC FLAGS_REG))])]
20734 {
20735   if (!rtx_equal_p (operands[0], operands[1]))
20736     emit_move_insn (operands[0], operands[1]);
20737 })
20738
20739 ;; After splitting up read-modify operations, array accesses with memory
20740 ;; operands might end up in form:
20741 ;;  sall    $2, %eax
20742 ;;  movl    4(%esp), %edx
20743 ;;  addl    %edx, %eax
20744 ;; instead of pre-splitting:
20745 ;;  sall    $2, %eax
20746 ;;  addl    4(%esp), %eax
20747 ;; Turn it into:
20748 ;;  movl    4(%esp), %edx
20749 ;;  leal    (%edx,%eax,4), %eax
20750
20751 (define_peephole2
20752   [(parallel [(set (match_operand 0 "register_operand" "")
20753                    (ashift (match_operand 1 "register_operand" "")
20754                            (match_operand 2 "const_int_operand" "")))
20755                (clobber (reg:CC FLAGS_REG))])
20756    (set (match_operand 3 "register_operand")
20757         (match_operand 4 "x86_64_general_operand" ""))
20758    (parallel [(set (match_operand 5 "register_operand" "")
20759                    (plus (match_operand 6 "register_operand" "")
20760                          (match_operand 7 "register_operand" "")))
20761                    (clobber (reg:CC FLAGS_REG))])]
20762   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20763    /* Validate MODE for lea.  */
20764    && ((!TARGET_PARTIAL_REG_STALL
20765         && (GET_MODE (operands[0]) == QImode
20766             || GET_MODE (operands[0]) == HImode))
20767        || GET_MODE (operands[0]) == SImode 
20768        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20769    /* We reorder load and the shift.  */
20770    && !rtx_equal_p (operands[1], operands[3])
20771    && !reg_overlap_mentioned_p (operands[0], operands[4])
20772    /* Last PLUS must consist of operand 0 and 3.  */
20773    && !rtx_equal_p (operands[0], operands[3])
20774    && (rtx_equal_p (operands[3], operands[6])
20775        || rtx_equal_p (operands[3], operands[7]))
20776    && (rtx_equal_p (operands[0], operands[6])
20777        || rtx_equal_p (operands[0], operands[7]))
20778    /* The intermediate operand 0 must die or be same as output.  */
20779    && (rtx_equal_p (operands[0], operands[5])
20780        || peep2_reg_dead_p (3, operands[0]))"
20781   [(set (match_dup 3) (match_dup 4))
20782    (set (match_dup 0) (match_dup 1))]
20783 {
20784   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20785   int scale = 1 << INTVAL (operands[2]);
20786   rtx index = gen_lowpart (Pmode, operands[1]);
20787   rtx base = gen_lowpart (Pmode, operands[3]);
20788   rtx dest = gen_lowpart (mode, operands[5]);
20789
20790   operands[1] = gen_rtx_PLUS (Pmode, base,
20791                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20792   if (mode != Pmode)
20793     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20794   operands[0] = dest;
20795 })
20796 \f
20797 ;; Call-value patterns last so that the wildcard operand does not
20798 ;; disrupt insn-recog's switch tables.
20799
20800 (define_insn "*call_value_pop_0"
20801   [(set (match_operand 0 "" "")
20802         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20803               (match_operand:SI 2 "" "")))
20804    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20805                             (match_operand:SI 3 "immediate_operand" "")))]
20806   "!TARGET_64BIT"
20807 {
20808   if (SIBLING_CALL_P (insn))
20809     return "jmp\t%P1";
20810   else
20811     return "call\t%P1";
20812 }
20813   [(set_attr "type" "callv")])
20814
20815 (define_insn "*call_value_pop_1"
20816   [(set (match_operand 0 "" "")
20817         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20818               (match_operand:SI 2 "" "")))
20819    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20820                             (match_operand:SI 3 "immediate_operand" "i")))]
20821   "!TARGET_64BIT"
20822 {
20823   if (constant_call_address_operand (operands[1], Pmode))
20824     {
20825       if (SIBLING_CALL_P (insn))
20826         return "jmp\t%P1";
20827       else
20828         return "call\t%P1";
20829     }
20830   if (SIBLING_CALL_P (insn))
20831     return "jmp\t%A1";
20832   else
20833     return "call\t%A1";
20834 }
20835   [(set_attr "type" "callv")])
20836
20837 (define_insn "*call_value_0"
20838   [(set (match_operand 0 "" "")
20839         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20840               (match_operand:SI 2 "" "")))]
20841   "!TARGET_64BIT"
20842 {
20843   if (SIBLING_CALL_P (insn))
20844     return "jmp\t%P1";
20845   else
20846     return "call\t%P1";
20847 }
20848   [(set_attr "type" "callv")])
20849
20850 (define_insn "*call_value_0_rex64"
20851   [(set (match_operand 0 "" "")
20852         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20853               (match_operand:DI 2 "const_int_operand" "")))]
20854   "TARGET_64BIT"
20855 {
20856   if (SIBLING_CALL_P (insn))
20857     return "jmp\t%P1";
20858   else
20859     return "call\t%P1";
20860 }
20861   [(set_attr "type" "callv")])
20862
20863 (define_insn "*call_value_1"
20864   [(set (match_operand 0 "" "")
20865         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20866               (match_operand:SI 2 "" "")))]
20867   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20868 {
20869   if (constant_call_address_operand (operands[1], Pmode))
20870     return "call\t%P1";
20871   return "call\t%A1";
20872 }
20873   [(set_attr "type" "callv")])
20874
20875 (define_insn "*sibcall_value_1"
20876   [(set (match_operand 0 "" "")
20877         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20878               (match_operand:SI 2 "" "")))]
20879   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20880 {
20881   if (constant_call_address_operand (operands[1], Pmode))
20882     return "jmp\t%P1";
20883   return "jmp\t%A1";
20884 }
20885   [(set_attr "type" "callv")])
20886
20887 (define_insn "*call_value_1_rex64"
20888   [(set (match_operand 0 "" "")
20889         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20890               (match_operand:DI 2 "" "")))]
20891   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20892 {
20893   if (constant_call_address_operand (operands[1], Pmode))
20894     return "call\t%P1";
20895   return "call\t%A1";
20896 }
20897   [(set_attr "type" "callv")])
20898
20899 (define_insn "*sibcall_value_1_rex64"
20900   [(set (match_operand 0 "" "")
20901         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20902               (match_operand:DI 2 "" "")))]
20903   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20904   "jmp\t%P1"
20905   [(set_attr "type" "callv")])
20906
20907 (define_insn "*sibcall_value_1_rex64_v"
20908   [(set (match_operand 0 "" "")
20909         (call (mem:QI (reg:DI 40))
20910               (match_operand:DI 1 "" "")))]
20911   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20912   "jmp\t*%%r11"
20913   [(set_attr "type" "callv")])
20914 \f
20915 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20916 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20917 ;; caught for use by garbage collectors and the like.  Using an insn that
20918 ;; maps to SIGILL makes it more likely the program will rightfully die.
20919 ;; Keeping with tradition, "6" is in honor of #UD.
20920 (define_insn "trap"
20921   [(trap_if (const_int 1) (const_int 6))]
20922   ""
20923   { return ASM_SHORT "0x0b0f"; }
20924   [(set_attr "length" "2")])
20925
20926 (define_expand "sse_prologue_save"
20927   [(parallel [(set (match_operand:BLK 0 "" "")
20928                    (unspec:BLK [(reg:DI 21)
20929                                 (reg:DI 22)
20930                                 (reg:DI 23)
20931                                 (reg:DI 24)
20932                                 (reg:DI 25)
20933                                 (reg:DI 26)
20934                                 (reg:DI 27)
20935                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20936               (use (match_operand:DI 1 "register_operand" ""))
20937               (use (match_operand:DI 2 "immediate_operand" ""))
20938               (use (label_ref:DI (match_operand 3 "" "")))])]
20939   "TARGET_64BIT"
20940   "")
20941
20942 (define_insn "*sse_prologue_save_insn"
20943   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20944                           (match_operand:DI 4 "const_int_operand" "n")))
20945         (unspec:BLK [(reg:DI 21)
20946                      (reg:DI 22)
20947                      (reg:DI 23)
20948                      (reg:DI 24)
20949                      (reg:DI 25)
20950                      (reg:DI 26)
20951                      (reg:DI 27)
20952                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20953    (use (match_operand:DI 1 "register_operand" "r"))
20954    (use (match_operand:DI 2 "const_int_operand" "i"))
20955    (use (label_ref:DI (match_operand 3 "" "X")))]
20956   "TARGET_64BIT
20957    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20958    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20959   "*
20960 {
20961   int i;
20962   operands[0] = gen_rtx_MEM (Pmode,
20963                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20964   output_asm_insn (\"jmp\\t%A1\", operands);
20965   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20966     {
20967       operands[4] = adjust_address (operands[0], DImode, i*16);
20968       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20969       PUT_MODE (operands[4], TImode);
20970       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20971         output_asm_insn (\"rex\", operands);
20972       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20973     }
20974   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20975                              CODE_LABEL_NUMBER (operands[3]));
20976   RET;
20977 }
20978   "
20979   [(set_attr "type" "other")
20980    (set_attr "length_immediate" "0")
20981    (set_attr "length_address" "0")
20982    (set_attr "length" "135")
20983    (set_attr "memory" "store")
20984    (set_attr "modrm" "0")
20985    (set_attr "mode" "DI")])
20986
20987 (define_expand "prefetch"
20988   [(prefetch (match_operand 0 "address_operand" "")
20989              (match_operand:SI 1 "const_int_operand" "")
20990              (match_operand:SI 2 "const_int_operand" ""))]
20991   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20992 {
20993   int rw = INTVAL (operands[1]);
20994   int locality = INTVAL (operands[2]);
20995
20996   gcc_assert (rw == 0 || rw == 1);
20997   gcc_assert (locality >= 0 && locality <= 3);
20998   gcc_assert (GET_MODE (operands[0]) == Pmode
20999               || GET_MODE (operands[0]) == VOIDmode);
21000
21001   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21002      supported by SSE counterpart or the SSE prefetch is not available
21003      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21004      of locality.  */
21005   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21006     operands[2] = GEN_INT (3);
21007   else
21008     operands[1] = const0_rtx;
21009 })
21010
21011 (define_insn "*prefetch_sse"
21012   [(prefetch (match_operand:SI 0 "address_operand" "p")
21013              (const_int 0)
21014              (match_operand:SI 1 "const_int_operand" ""))]
21015   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21016 {
21017   static const char * const patterns[4] = {
21018    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21019   };
21020
21021   int locality = INTVAL (operands[1]);
21022   gcc_assert (locality >= 0 && locality <= 3);
21023
21024   return patterns[locality];  
21025 }
21026   [(set_attr "type" "sse")
21027    (set_attr "memory" "none")])
21028
21029 (define_insn "*prefetch_sse_rex"
21030   [(prefetch (match_operand:DI 0 "address_operand" "p")
21031              (const_int 0)
21032              (match_operand:SI 1 "const_int_operand" ""))]
21033   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21034 {
21035   static const char * const patterns[4] = {
21036    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21037   };
21038
21039   int locality = INTVAL (operands[1]);
21040   gcc_assert (locality >= 0 && locality <= 3);
21041
21042   return patterns[locality];  
21043 }
21044   [(set_attr "type" "sse")
21045    (set_attr "memory" "none")])
21046
21047 (define_insn "*prefetch_3dnow"
21048   [(prefetch (match_operand:SI 0 "address_operand" "p")
21049              (match_operand:SI 1 "const_int_operand" "n")
21050              (const_int 3))]
21051   "TARGET_3DNOW && !TARGET_64BIT"
21052 {
21053   if (INTVAL (operands[1]) == 0)
21054     return "prefetch\t%a0";
21055   else
21056     return "prefetchw\t%a0";
21057 }
21058   [(set_attr "type" "mmx")
21059    (set_attr "memory" "none")])
21060
21061 (define_insn "*prefetch_3dnow_rex"
21062   [(prefetch (match_operand:DI 0 "address_operand" "p")
21063              (match_operand:SI 1 "const_int_operand" "n")
21064              (const_int 3))]
21065   "TARGET_3DNOW && TARGET_64BIT"
21066 {
21067   if (INTVAL (operands[1]) == 0)
21068     return "prefetch\t%a0";
21069   else
21070     return "prefetchw\t%a0";
21071 }
21072   [(set_attr "type" "mmx")
21073    (set_attr "memory" "none")])
21074
21075 (define_expand "stack_protect_set"
21076   [(match_operand 0 "memory_operand" "")
21077    (match_operand 1 "memory_operand" "")]
21078   ""
21079 {
21080 #ifdef TARGET_THREAD_SSP_OFFSET
21081   if (TARGET_64BIT)
21082     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21083                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21084   else
21085     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21086                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21087 #else
21088   if (TARGET_64BIT)
21089     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21090   else
21091     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21092 #endif
21093   DONE;
21094 })
21095
21096 (define_insn "stack_protect_set_si"
21097   [(set (match_operand:SI 0 "memory_operand" "=m")
21098         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21099    (set (match_scratch:SI 2 "=&r") (const_int 0))
21100    (clobber (reg:CC FLAGS_REG))]
21101   ""
21102   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21103   [(set_attr "type" "multi")])
21104
21105 (define_insn "stack_protect_set_di"
21106   [(set (match_operand:DI 0 "memory_operand" "=m")
21107         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21108    (set (match_scratch:DI 2 "=&r") (const_int 0))
21109    (clobber (reg:CC FLAGS_REG))]
21110   "TARGET_64BIT"
21111   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21112   [(set_attr "type" "multi")])
21113
21114 (define_insn "stack_tls_protect_set_si"
21115   [(set (match_operand:SI 0 "memory_operand" "=m")
21116         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21117    (set (match_scratch:SI 2 "=&r") (const_int 0))
21118    (clobber (reg:CC FLAGS_REG))]
21119   ""
21120   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121   [(set_attr "type" "multi")])
21122
21123 (define_insn "stack_tls_protect_set_di"
21124   [(set (match_operand:DI 0 "memory_operand" "=m")
21125         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21126    (set (match_scratch:DI 2 "=&r") (const_int 0))
21127    (clobber (reg:CC FLAGS_REG))]
21128   "TARGET_64BIT"
21129   {
21130      /* The kernel uses a different segment register for performance reasons; a
21131         system call would not have to trash the userspace segment register,
21132         which would be expensive */
21133      if (ix86_cmodel != CM_KERNEL)
21134         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21135      else
21136         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21137   }
21138   [(set_attr "type" "multi")])
21139
21140 (define_expand "stack_protect_test"
21141   [(match_operand 0 "memory_operand" "")
21142    (match_operand 1 "memory_operand" "")
21143    (match_operand 2 "" "")]
21144   ""
21145 {
21146   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21147   ix86_compare_op0 = operands[0];
21148   ix86_compare_op1 = operands[1];
21149   ix86_compare_emitted = flags;
21150
21151 #ifdef TARGET_THREAD_SSP_OFFSET
21152   if (TARGET_64BIT)
21153     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21154                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21155   else
21156     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21157                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21158 #else
21159   if (TARGET_64BIT)
21160     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21161   else
21162     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21163 #endif
21164   emit_jump_insn (gen_beq (operands[2]));
21165   DONE;
21166 })
21167
21168 (define_insn "stack_protect_test_si"
21169   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21170         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21171                      (match_operand:SI 2 "memory_operand" "m")]
21172                     UNSPEC_SP_TEST))
21173    (clobber (match_scratch:SI 3 "=&r"))]
21174   ""
21175   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21176   [(set_attr "type" "multi")])
21177
21178 (define_insn "stack_protect_test_di"
21179   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21180         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21181                      (match_operand:DI 2 "memory_operand" "m")]
21182                     UNSPEC_SP_TEST))
21183    (clobber (match_scratch:DI 3 "=&r"))]
21184   "TARGET_64BIT"
21185   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21186   [(set_attr "type" "multi")])
21187
21188 (define_insn "stack_tls_protect_test_si"
21189   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21190         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21191                      (match_operand:SI 2 "const_int_operand" "i")]
21192                     UNSPEC_SP_TLS_TEST))
21193    (clobber (match_scratch:SI 3 "=r"))]
21194   ""
21195   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21196   [(set_attr "type" "multi")])
21197
21198 (define_insn "stack_tls_protect_test_di"
21199   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21200         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21201                      (match_operand:DI 2 "const_int_operand" "i")]
21202                     UNSPEC_SP_TLS_TEST))
21203    (clobber (match_scratch:DI 3 "=r"))]
21204   "TARGET_64BIT"
21205   {
21206      /* The kernel uses a different segment register for performance reasons; a
21207         system call would not have to trash the userspace segment register,
21208         which would be expensive */
21209      if (ix86_cmodel != CM_KERNEL)
21210         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21211      else
21212         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21213   }
21214   [(set_attr "type" "multi")])
21215
21216 (include "mmx.md")
21217 (include "sse.md")
21218 (include "sync.md")