OSDN Git Service

* alias.c, c-common.h, c-incpath.c, c-incpath.h, expr.c,
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
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, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_SIN                  21)
78    (UNSPEC_COS                  22)
79    (UNSPEC_FNSTSW               24)
80    (UNSPEC_SAHF                 25)
81    (UNSPEC_FSTCW                26)
82    (UNSPEC_ADD_CARRY            27)
83    (UNSPEC_FLDCW                28)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX                  30)
87    (UNSPEC_FIX_NOTRUNC          31)
88    (UNSPEC_MASKMOV              32)
89    (UNSPEC_MOVMSK               33)
90    (UNSPEC_MOVNT                34)
91    (UNSPEC_MOVA                 38)
92    (UNSPEC_MOVU                 39)
93    (UNSPEC_SHUFFLE              41)
94    (UNSPEC_RCP                  42)
95    (UNSPEC_RSQRT                43)
96    (UNSPEC_SFENCE               44)
97    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
98    (UNSPEC_PAVGUSB              49)
99    (UNSPEC_PFRCP                50)
100    (UNSPEC_PFRCPIT1             51)
101    (UNSPEC_PFRCPIT2             52)
102    (UNSPEC_PFRSQRT              53)
103    (UNSPEC_PFRSQIT1             54)
104    (UNSPEC_PSHUFLW              55)
105    (UNSPEC_PSHUFHW              56)
106    (UNSPEC_MFENCE               59)
107    (UNSPEC_LFENCE               60)
108    (UNSPEC_PSADBW               61)
109    (UNSPEC_ADDSUB               71)
110    (UNSPEC_HADD                 72)
111    (UNSPEC_HSUB                 73)
112    (UNSPEC_MOVSHDUP             74)
113    (UNSPEC_MOVSLDUP             75)
114    (UNSPEC_LDQQU                76)
115    (UNSPEC_MOVDDUP              77)
116
117    ; x87 Floating point
118    (UNSPEC_FPATAN               65)
119    (UNSPEC_FYL2X                66)
120    (UNSPEC_FYL2XP1              67)
121    (UNSPEC_FRNDINT              68)
122    (UNSPEC_F2XM1                69)
123
124    ; x87 Double output FP
125    (UNSPEC_SINCOS_COS           80)
126    (UNSPEC_SINCOS_SIN           81)
127    (UNSPEC_TAN_ONE              82)
128    (UNSPEC_TAN_TAN              83)
129    (UNSPEC_XTRACT_FRACT         84)
130    (UNSPEC_XTRACT_EXP           85)
131    (UNSPEC_FSCALE_FRACT         86)
132    (UNSPEC_FSCALE_EXP           87)
133    (UNSPEC_FPREM_F              88)
134    (UNSPEC_FPREM_U              89)
135    (UNSPEC_FPREM1_F             90)
136    (UNSPEC_FPREM1_U             91)
137
138    ; x87 Rounding
139    (UNSPEC_FRNDINT_FLOOR        96)
140    (UNSPEC_FRNDINT_CEIL         97)
141    (UNSPEC_FRNDINT_TRUNC        98)
142    (UNSPEC_FRNDINT_MASK_PM      99)
143
144    ; REP instruction
145    (UNSPEC_REP                  75)
146
147    (UNSPEC_EH_RETURN            76)
148   ])
149
150 (define_constants
151   [(UNSPECV_BLOCKAGE            0)
152    (UNSPECV_STACK_PROBE         10)
153    (UNSPECV_EMMS                31)
154    (UNSPECV_LDMXCSR             37)
155    (UNSPECV_STMXCSR             40)
156    (UNSPECV_FEMMS               46)
157    (UNSPECV_CLFLUSH             57)
158    (UNSPECV_ALIGN               68)
159    (UNSPECV_MONITOR             69)
160    (UNSPECV_MWAIT               70)
161   ])
162
163 ;; Registers by name.
164 (define_constants
165   [(BP_REG                       6)
166    (SP_REG                       7)
167    (FLAGS_REG                   17)
168    (FPSR_REG                    18)
169    (DIRFLAG_REG                 19)
170   ])
171
172 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
173 ;; from i386.c.
174
175 ;; In C guard expressions, put expressions which may be compile-time
176 ;; constants first.  This allows for better optimization.  For
177 ;; example, write "TARGET_64BIT && reload_completed", not
178 ;; "reload_completed && TARGET_64BIT".
179
180 \f
181 ;; Processor type.  This attribute must exactly match the processor_type
182 ;; enumeration in i386.h.
183 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
184   (const (symbol_ref "ix86_tune")))
185
186 ;; A basic instruction type.  Refinements due to arguments to be
187 ;; provided in other attributes.
188 (define_attr "type"
189   "other,multi,
190    alu,alu1,negnot,imov,imovx,lea,
191    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
192    icmp,test,ibr,setcc,icmov,
193    push,pop,call,callv,leave,
194    str,cld,
195    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
196    sselog,sselog1,sseiadd,sseishft,sseimul,
197    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
198    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
199   (const_string "other"))
200
201 ;; Main data type used by the insn
202 (define_attr "mode"
203   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
204   (const_string "unknown"))
205
206 ;; The CPU unit operations uses.
207 (define_attr "unit" "integer,i387,sse,mmx,unknown"
208   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
209            (const_string "i387")
210          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
211                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
212            (const_string "sse")
213          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
214            (const_string "mmx")
215          (eq_attr "type" "other")
216            (const_string "unknown")]
217          (const_string "integer")))
218
219 ;; The (bounding maximum) length of an instruction immediate.
220 (define_attr "length_immediate" ""
221   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
222            (const_int 0)
223          (eq_attr "unit" "i387,sse,mmx")
224            (const_int 0)
225          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
226                           imul,icmp,push,pop")
227            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
228          (eq_attr "type" "imov,test")
229            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
230          (eq_attr "type" "call")
231            (if_then_else (match_operand 0 "constant_call_address_operand" "")
232              (const_int 4)
233              (const_int 0))
234          (eq_attr "type" "callv")
235            (if_then_else (match_operand 1 "constant_call_address_operand" "")
236              (const_int 4)
237              (const_int 0))
238          ;; We don't know the size before shorten_branches.  Expect
239          ;; the instruction to fit for better scheduling.
240          (eq_attr "type" "ibr")
241            (const_int 1)
242          ]
243          (symbol_ref "/* Update immediate_length and other attributes! */
244                       abort(),1")))
245
246 ;; The (bounding maximum) length of an instruction address.
247 (define_attr "length_address" ""
248   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
249            (const_int 0)
250          (and (eq_attr "type" "call")
251               (match_operand 0 "constant_call_address_operand" ""))
252              (const_int 0)
253          (and (eq_attr "type" "callv")
254               (match_operand 1 "constant_call_address_operand" ""))
255              (const_int 0)
256          ]
257          (symbol_ref "ix86_attr_length_address_default (insn)")))
258
259 ;; Set when length prefix is used.
260 (define_attr "prefix_data16" ""
261   (if_then_else (ior (eq_attr "mode" "HI")
262                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
263     (const_int 1)
264     (const_int 0)))
265
266 ;; Set when string REP prefix is used.
267 (define_attr "prefix_rep" "" 
268   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
269     (const_int 1)
270     (const_int 0)))
271
272 ;; Set when 0f opcode prefix is used.
273 (define_attr "prefix_0f" ""
274   (if_then_else 
275     (ior (eq_attr "type" "imovx,setcc,icmov")
276          (eq_attr "unit" "sse,mmx"))
277     (const_int 1)
278     (const_int 0)))
279
280 ;; Set when REX opcode prefix is used.
281 (define_attr "prefix_rex" ""
282   (cond [(and (eq_attr "mode" "DI")
283               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
284            (const_int 1)
285          (and (eq_attr "mode" "QI")
286               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
287                   (const_int 0)))
288            (const_int 1)
289          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
290              (const_int 0))
291            (const_int 1)
292         ]
293         (const_int 0)))
294
295 ;; Set when modrm byte is used.
296 (define_attr "modrm" ""
297   (cond [(eq_attr "type" "str,cld,leave")
298            (const_int 0)
299          (eq_attr "unit" "i387")
300            (const_int 0)
301          (and (eq_attr "type" "incdec")
302               (ior (match_operand:SI 1 "register_operand" "")
303                    (match_operand:HI 1 "register_operand" "")))
304            (const_int 0)
305          (and (eq_attr "type" "push")
306               (not (match_operand 1 "memory_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "pop")
309               (not (match_operand 0 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "imov")
312               (and (match_operand 0 "register_operand" "")
313                    (match_operand 1 "immediate_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "call")
316               (match_operand 0 "constant_call_address_operand" ""))
317              (const_int 0)
318          (and (eq_attr "type" "callv")
319               (match_operand 1 "constant_call_address_operand" ""))
320              (const_int 0)
321          ]
322          (const_int 1)))
323
324 ;; The (bounding maximum) length of an instruction in bytes.
325 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
326 ;; Later we may want to split them and compute proper length as for
327 ;; other insns.
328 (define_attr "length" ""
329   (cond [(eq_attr "type" "other,multi,fistp,frndint")
330            (const_int 16)
331          (eq_attr "type" "fcmp")
332            (const_int 4)
333          (eq_attr "unit" "i387")
334            (plus (const_int 2)
335                  (plus (attr "prefix_data16")
336                        (attr "length_address")))]
337          (plus (plus (attr "modrm")
338                      (plus (attr "prefix_0f")
339                            (plus (attr "prefix_rex")
340                                  (const_int 1))))
341                (plus (attr "prefix_rep")
342                      (plus (attr "prefix_data16")
343                            (plus (attr "length_immediate")
344                                  (attr "length_address")))))))
345
346 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
347 ;; `store' if there is a simple memory reference therein, or `unknown'
348 ;; if the instruction is complex.
349
350 (define_attr "memory" "none,load,store,both,unknown"
351   (cond [(eq_attr "type" "other,multi,str")
352            (const_string "unknown")
353          (eq_attr "type" "lea,fcmov,fpspc,cld")
354            (const_string "none")
355          (eq_attr "type" "fistp,leave")
356            (const_string "both")
357          (eq_attr "type" "frndint")
358            (const_string "load")
359          (eq_attr "type" "push")
360            (if_then_else (match_operand 1 "memory_operand" "")
361              (const_string "both")
362              (const_string "store"))
363          (eq_attr "type" "pop")
364            (if_then_else (match_operand 0 "memory_operand" "")
365              (const_string "both")
366              (const_string "load"))
367          (eq_attr "type" "setcc")
368            (if_then_else (match_operand 0 "memory_operand" "")
369              (const_string "store")
370              (const_string "none"))
371          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
372            (if_then_else (ior (match_operand 0 "memory_operand" "")
373                               (match_operand 1 "memory_operand" ""))
374              (const_string "load")
375              (const_string "none"))
376          (eq_attr "type" "ibr")
377            (if_then_else (match_operand 0 "memory_operand" "")
378              (const_string "load")
379              (const_string "none"))
380          (eq_attr "type" "call")
381            (if_then_else (match_operand 0 "constant_call_address_operand" "")
382              (const_string "none")
383              (const_string "load"))
384          (eq_attr "type" "callv")
385            (if_then_else (match_operand 1 "constant_call_address_operand" "")
386              (const_string "none")
387              (const_string "load"))
388          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
389               (match_operand 1 "memory_operand" ""))
390            (const_string "both")
391          (and (match_operand 0 "memory_operand" "")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (match_operand 0 "memory_operand" "")
395            (const_string "store")
396          (match_operand 1 "memory_operand" "")
397            (const_string "load")
398          (and (eq_attr "type"
399                  "!alu1,negnot,ishift1,
400                    imov,imovx,icmp,test,
401                    fmov,fcmp,fsgn,
402                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
403                    mmx,mmxmov,mmxcmp,mmxcvt")
404               (match_operand 2 "memory_operand" ""))
405            (const_string "load")
406          (and (eq_attr "type" "icmov")
407               (match_operand 3 "memory_operand" ""))
408            (const_string "load")
409         ]
410         (const_string "none")))
411
412 ;; Indicates if an instruction has both an immediate and a displacement.
413
414 (define_attr "imm_disp" "false,true,unknown"
415   (cond [(eq_attr "type" "other,multi")
416            (const_string "unknown")
417          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
418               (and (match_operand 0 "memory_displacement_operand" "")
419                    (match_operand 1 "immediate_operand" "")))
420            (const_string "true")
421          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
422               (and (match_operand 0 "memory_displacement_operand" "")
423                    (match_operand 2 "immediate_operand" "")))
424            (const_string "true")
425         ]
426         (const_string "false")))
427
428 ;; Indicates if an FP operation has an integer source.
429
430 (define_attr "fp_int_src" "false,true"
431   (const_string "false"))
432
433 ;; Defines rounding mode of an FP operation.
434
435 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
436   (const_string "any"))
437
438 ;; Describe a user's asm statement.
439 (define_asm_attributes
440   [(set_attr "length" "128")
441    (set_attr "type" "multi")])
442 \f
443 ;; Scheduling descriptions
444
445 (include "pentium.md")
446 (include "ppro.md")
447 (include "k6.md")
448 (include "athlon.md")
449
450 \f
451 ;; Operand and operator predicates
452
453 (include "predicates.md")
454
455 \f
456 ;; Compare instructions.
457
458 ;; All compare insns have expanders that save the operands away without
459 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
460 ;; after the cmp) will actually emit the cmpM.
461
462 (define_expand "cmpdi"
463   [(set (reg:CC FLAGS_REG)
464         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
465                     (match_operand:DI 1 "x86_64_general_operand" "")))]
466   ""
467 {
468   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469     operands[0] = force_reg (DImode, operands[0]);
470   ix86_compare_op0 = operands[0];
471   ix86_compare_op1 = operands[1];
472   DONE;
473 })
474
475 (define_expand "cmpsi"
476   [(set (reg:CC FLAGS_REG)
477         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
478                     (match_operand:SI 1 "general_operand" "")))]
479   ""
480 {
481   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
482     operands[0] = force_reg (SImode, operands[0]);
483   ix86_compare_op0 = operands[0];
484   ix86_compare_op1 = operands[1];
485   DONE;
486 })
487
488 (define_expand "cmphi"
489   [(set (reg:CC FLAGS_REG)
490         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
491                     (match_operand:HI 1 "general_operand" "")))]
492   ""
493 {
494   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495     operands[0] = force_reg (HImode, operands[0]);
496   ix86_compare_op0 = operands[0];
497   ix86_compare_op1 = operands[1];
498   DONE;
499 })
500
501 (define_expand "cmpqi"
502   [(set (reg:CC FLAGS_REG)
503         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
504                     (match_operand:QI 1 "general_operand" "")))]
505   "TARGET_QIMODE_MATH"
506 {
507   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508     operands[0] = force_reg (QImode, operands[0]);
509   ix86_compare_op0 = operands[0];
510   ix86_compare_op1 = operands[1];
511   DONE;
512 })
513
514 (define_insn "cmpdi_ccno_1_rex64"
515   [(set (reg FLAGS_REG)
516         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
517                  (match_operand:DI 1 "const0_operand" "n,n")))]
518   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
519   "@
520    test{q}\t{%0, %0|%0, %0}
521    cmp{q}\t{%1, %0|%0, %1}"
522   [(set_attr "type" "test,icmp")
523    (set_attr "length_immediate" "0,1")
524    (set_attr "mode" "DI")])
525
526 (define_insn "*cmpdi_minus_1_rex64"
527   [(set (reg FLAGS_REG)
528         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
529                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
530                  (const_int 0)))]
531   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
532   "cmp{q}\t{%1, %0|%0, %1}"
533   [(set_attr "type" "icmp")
534    (set_attr "mode" "DI")])
535
536 (define_expand "cmpdi_1_rex64"
537   [(set (reg:CC FLAGS_REG)
538         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
539                     (match_operand:DI 1 "general_operand" "")))]
540   "TARGET_64BIT"
541   "")
542
543 (define_insn "cmpdi_1_insn_rex64"
544   [(set (reg FLAGS_REG)
545         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
546                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
547   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
548   "cmp{q}\t{%1, %0|%0, %1}"
549   [(set_attr "type" "icmp")
550    (set_attr "mode" "DI")])
551
552
553 (define_insn "*cmpsi_ccno_1"
554   [(set (reg FLAGS_REG)
555         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
556                  (match_operand:SI 1 "const0_operand" "n,n")))]
557   "ix86_match_ccmode (insn, CCNOmode)"
558   "@
559    test{l}\t{%0, %0|%0, %0}
560    cmp{l}\t{%1, %0|%0, %1}"
561   [(set_attr "type" "test,icmp")
562    (set_attr "length_immediate" "0,1")
563    (set_attr "mode" "SI")])
564
565 (define_insn "*cmpsi_minus_1"
566   [(set (reg FLAGS_REG)
567         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
568                            (match_operand:SI 1 "general_operand" "ri,mr"))
569                  (const_int 0)))]
570   "ix86_match_ccmode (insn, CCGOCmode)"
571   "cmp{l}\t{%1, %0|%0, %1}"
572   [(set_attr "type" "icmp")
573    (set_attr "mode" "SI")])
574
575 (define_expand "cmpsi_1"
576   [(set (reg:CC FLAGS_REG)
577         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
578                     (match_operand:SI 1 "general_operand" "ri,mr")))]
579   ""
580   "")
581
582 (define_insn "*cmpsi_1_insn"
583   [(set (reg FLAGS_REG)
584         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
585                  (match_operand:SI 1 "general_operand" "ri,mr")))]
586   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
587     && ix86_match_ccmode (insn, CCmode)"
588   "cmp{l}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "SI")])
591
592 (define_insn "*cmphi_ccno_1"
593   [(set (reg FLAGS_REG)
594         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
595                  (match_operand:HI 1 "const0_operand" "n,n")))]
596   "ix86_match_ccmode (insn, CCNOmode)"
597   "@
598    test{w}\t{%0, %0|%0, %0}
599    cmp{w}\t{%1, %0|%0, %1}"
600   [(set_attr "type" "test,icmp")
601    (set_attr "length_immediate" "0,1")
602    (set_attr "mode" "HI")])
603
604 (define_insn "*cmphi_minus_1"
605   [(set (reg FLAGS_REG)
606         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
607                            (match_operand:HI 1 "general_operand" "ri,mr"))
608                  (const_int 0)))]
609   "ix86_match_ccmode (insn, CCGOCmode)"
610   "cmp{w}\t{%1, %0|%0, %1}"
611   [(set_attr "type" "icmp")
612    (set_attr "mode" "HI")])
613
614 (define_insn "*cmphi_1"
615   [(set (reg FLAGS_REG)
616         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
617                  (match_operand:HI 1 "general_operand" "ri,mr")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619    && ix86_match_ccmode (insn, CCmode)"
620   "cmp{w}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "HI")])
623
624 (define_insn "*cmpqi_ccno_1"
625   [(set (reg FLAGS_REG)
626         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
627                  (match_operand:QI 1 "const0_operand" "n,n")))]
628   "ix86_match_ccmode (insn, CCNOmode)"
629   "@
630    test{b}\t{%0, %0|%0, %0}
631    cmp{b}\t{$0, %0|%0, 0}"
632   [(set_attr "type" "test,icmp")
633    (set_attr "length_immediate" "0,1")
634    (set_attr "mode" "QI")])
635
636 (define_insn "*cmpqi_1"
637   [(set (reg FLAGS_REG)
638         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
639                  (match_operand:QI 1 "general_operand" "qi,mq")))]
640   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
641     && ix86_match_ccmode (insn, CCmode)"
642   "cmp{b}\t{%1, %0|%0, %1}"
643   [(set_attr "type" "icmp")
644    (set_attr "mode" "QI")])
645
646 (define_insn "*cmpqi_minus_1"
647   [(set (reg FLAGS_REG)
648         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
649                            (match_operand:QI 1 "general_operand" "qi,mq"))
650                  (const_int 0)))]
651   "ix86_match_ccmode (insn, CCGOCmode)"
652   "cmp{b}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "QI")])
655
656 (define_insn "*cmpqi_ext_1"
657   [(set (reg FLAGS_REG)
658         (compare
659           (match_operand:QI 0 "general_operand" "Qm")
660           (subreg:QI
661             (zero_extract:SI
662               (match_operand 1 "ext_register_operand" "Q")
663               (const_int 8)
664               (const_int 8)) 0)))]
665   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
666   "cmp{b}\t{%h1, %0|%0, %h1}"
667   [(set_attr "type" "icmp")
668    (set_attr "mode" "QI")])
669
670 (define_insn "*cmpqi_ext_1_rex64"
671   [(set (reg FLAGS_REG)
672         (compare
673           (match_operand:QI 0 "register_operand" "Q")
674           (subreg:QI
675             (zero_extract:SI
676               (match_operand 1 "ext_register_operand" "Q")
677               (const_int 8)
678               (const_int 8)) 0)))]
679   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
680   "cmp{b}\t{%h1, %0|%0, %h1}"
681   [(set_attr "type" "icmp")
682    (set_attr "mode" "QI")])
683
684 (define_insn "*cmpqi_ext_2"
685   [(set (reg FLAGS_REG)
686         (compare
687           (subreg:QI
688             (zero_extract:SI
689               (match_operand 0 "ext_register_operand" "Q")
690               (const_int 8)
691               (const_int 8)) 0)
692           (match_operand:QI 1 "const0_operand" "n")))]
693   "ix86_match_ccmode (insn, CCNOmode)"
694   "test{b}\t%h0, %h0"
695   [(set_attr "type" "test")
696    (set_attr "length_immediate" "0")
697    (set_attr "mode" "QI")])
698
699 (define_expand "cmpqi_ext_3"
700   [(set (reg:CC FLAGS_REG)
701         (compare:CC
702           (subreg:QI
703             (zero_extract:SI
704               (match_operand 0 "ext_register_operand" "")
705               (const_int 8)
706               (const_int 8)) 0)
707           (match_operand:QI 1 "general_operand" "")))]
708   ""
709   "")
710
711 (define_insn "cmpqi_ext_3_insn"
712   [(set (reg FLAGS_REG)
713         (compare
714           (subreg:QI
715             (zero_extract:SI
716               (match_operand 0 "ext_register_operand" "Q")
717               (const_int 8)
718               (const_int 8)) 0)
719           (match_operand:QI 1 "general_operand" "Qmn")))]
720   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%1, %h0|%h0, %1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "cmpqi_ext_3_insn_rex64"
726   [(set (reg FLAGS_REG)
727         (compare
728           (subreg:QI
729             (zero_extract:SI
730               (match_operand 0 "ext_register_operand" "Q")
731               (const_int 8)
732               (const_int 8)) 0)
733           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%1, %h0|%h0, %1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_4"
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           (subreg:QI
748             (zero_extract:SI
749               (match_operand 1 "ext_register_operand" "Q")
750               (const_int 8)
751               (const_int 8)) 0)))]
752   "ix86_match_ccmode (insn, CCmode)"
753   "cmp{b}\t{%h1, %h0|%h0, %h1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "QI")])
756
757 ;; These implement float point compares.
758 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
759 ;; which would allow mix and match FP modes on the compares.  Which is what
760 ;; the old patterns did, but with many more of them.
761
762 (define_expand "cmpxf"
763   [(set (reg:CC FLAGS_REG)
764         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
765                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
766   "TARGET_80387"
767 {
768   ix86_compare_op0 = operands[0];
769   ix86_compare_op1 = operands[1];
770   DONE;
771 })
772
773 (define_expand "cmpdf"
774   [(set (reg:CC FLAGS_REG)
775         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
776                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
777   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
778 {
779   ix86_compare_op0 = operands[0];
780   ix86_compare_op1 = operands[1];
781   DONE;
782 })
783
784 (define_expand "cmpsf"
785   [(set (reg:CC FLAGS_REG)
786         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
787                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
788   "TARGET_80387 || TARGET_SSE_MATH"
789 {
790   ix86_compare_op0 = operands[0];
791   ix86_compare_op1 = operands[1];
792   DONE;
793 })
794
795 ;; FP compares, step 1:
796 ;; Set the FP condition codes.
797 ;;
798 ;; CCFPmode     compare with exceptions
799 ;; CCFPUmode    compare with no exceptions
800
801 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
802 ;; used to manage the reg stack popping would not be preserved.
803
804 (define_insn "*cmpfp_0_sf"
805   [(set (match_operand:HI 0 "register_operand" "=a")
806         (unspec:HI
807           [(compare:CCFP
808              (match_operand:SF 1 "register_operand" "f")
809              (match_operand:SF 2 "const0_operand" "X"))]
810         UNSPEC_FNSTSW))]
811   "TARGET_80387"
812   "* return output_fp_compare (insn, operands, 0, 0);"
813   [(set_attr "type" "multi")
814    (set_attr "mode" "SF")])
815
816 (define_insn "*cmpfp_0_df"
817   [(set (match_operand:HI 0 "register_operand" "=a")
818         (unspec:HI
819           [(compare:CCFP
820              (match_operand:DF 1 "register_operand" "f")
821              (match_operand:DF 2 "const0_operand" "X"))]
822         UNSPEC_FNSTSW))]
823   "TARGET_80387"
824   "* return output_fp_compare (insn, operands, 0, 0);"
825   [(set_attr "type" "multi")
826    (set_attr "mode" "DF")])
827
828 (define_insn "*cmpfp_0_xf"
829   [(set (match_operand:HI 0 "register_operand" "=a")
830         (unspec:HI
831           [(compare:CCFP
832              (match_operand:XF 1 "register_operand" "f")
833              (match_operand:XF 2 "const0_operand" "X"))]
834         UNSPEC_FNSTSW))]
835   "TARGET_80387"
836   "* return output_fp_compare (insn, operands, 0, 0);"
837   [(set_attr "type" "multi")
838    (set_attr "mode" "XF")])
839
840 (define_insn "*cmpfp_sf"
841   [(set (match_operand:HI 0 "register_operand" "=a")
842         (unspec:HI
843           [(compare:CCFP
844              (match_operand:SF 1 "register_operand" "f")
845              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
846           UNSPEC_FNSTSW))]
847   "TARGET_80387"
848   "* return output_fp_compare (insn, operands, 0, 0);"
849   [(set_attr "type" "multi")
850    (set_attr "mode" "SF")])
851
852 (define_insn "*cmpfp_df"
853   [(set (match_operand:HI 0 "register_operand" "=a")
854         (unspec:HI
855           [(compare:CCFP
856              (match_operand:DF 1 "register_operand" "f")
857              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
858           UNSPEC_FNSTSW))]
859   "TARGET_80387"
860   "* return output_fp_compare (insn, operands, 0, 0);"
861   [(set_attr "type" "multi")
862    (set_attr "mode" "DF")])
863
864 (define_insn "*cmpfp_xf"
865   [(set (match_operand:HI 0 "register_operand" "=a")
866         (unspec:HI
867           [(compare:CCFP
868              (match_operand:XF 1 "register_operand" "f")
869              (match_operand:XF 2 "register_operand" "f"))]
870           UNSPEC_FNSTSW))]
871   "TARGET_80387"
872   "* return output_fp_compare (insn, operands, 0, 0);"
873   [(set_attr "type" "multi")
874    (set_attr "mode" "XF")])
875
876 (define_insn "*cmpfp_u"
877   [(set (match_operand:HI 0 "register_operand" "=a")
878         (unspec:HI
879           [(compare:CCFPU
880              (match_operand 1 "register_operand" "f")
881              (match_operand 2 "register_operand" "f"))]
882           UNSPEC_FNSTSW))]
883   "TARGET_80387
884    && FLOAT_MODE_P (GET_MODE (operands[1]))
885    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
886   "* return output_fp_compare (insn, operands, 0, 1);"
887   [(set_attr "type" "multi")
888    (set (attr "mode")
889      (cond [(match_operand:SF 1 "" "")
890               (const_string "SF")
891             (match_operand:DF 1 "" "")
892               (const_string "DF")
893            ]
894            (const_string "XF")))])
895
896 (define_insn "*cmpfp_si"
897   [(set (match_operand:HI 0 "register_operand" "=a")
898         (unspec:HI
899           [(compare:CCFP
900              (match_operand 1 "register_operand" "f")
901              (match_operator 3 "float_operator"
902                [(match_operand:SI 2 "memory_operand" "m")]))]
903           UNSPEC_FNSTSW))]
904   "TARGET_80387 && TARGET_USE_FIOP
905    && FLOAT_MODE_P (GET_MODE (operands[1]))
906    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
907   "* return output_fp_compare (insn, operands, 0, 0);"
908   [(set_attr "type" "multi")
909    (set_attr "fp_int_src" "true")
910    (set_attr "mode" "SI")])
911
912 ;; FP compares, step 2
913 ;; Move the fpsw to ax.
914
915 (define_insn "x86_fnstsw_1"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
918   "TARGET_80387"
919   "fnstsw\t%0"
920   [(set_attr "length" "2")
921    (set_attr "mode" "SI")
922    (set_attr "unit" "i387")])
923
924 ;; FP compares, step 3
925 ;; Get ax into flags, general case.
926
927 (define_insn "x86_sahf_1"
928   [(set (reg:CC FLAGS_REG)
929         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
930   "!TARGET_64BIT"
931   "sahf"
932   [(set_attr "length" "1")
933    (set_attr "athlon_decode" "vector")
934    (set_attr "mode" "SI")])
935
936 ;; Pentium Pro can do steps 1 through 3 in one go.
937
938 (define_insn "*cmpfp_i_mixed"
939   [(set (reg:CCFP FLAGS_REG)
940         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
941                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
942   "TARGET_MIX_SSE_I387
943    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
944    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945   "* return output_fp_compare (insn, operands, 1, 0);"
946   [(set_attr "type" "fcmp,ssecomi")
947    (set (attr "mode")
948      (if_then_else (match_operand:SF 1 "" "")
949         (const_string "SF")
950         (const_string "DF")))
951    (set_attr "athlon_decode" "vector")])
952
953 (define_insn "*cmpfp_i_sse"
954   [(set (reg:CCFP FLAGS_REG)
955         (compare:CCFP (match_operand 0 "register_operand" "x")
956                       (match_operand 1 "nonimmediate_operand" "xm")))]
957   "TARGET_SSE_MATH
958    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
959    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
960   "* return output_fp_compare (insn, operands, 1, 0);"
961   [(set_attr "type" "ssecomi")
962    (set (attr "mode")
963      (if_then_else (match_operand:SF 1 "" "")
964         (const_string "SF")
965         (const_string "DF")))
966    (set_attr "athlon_decode" "vector")])
967
968 (define_insn "*cmpfp_i_i387"
969   [(set (reg:CCFP FLAGS_REG)
970         (compare:CCFP (match_operand 0 "register_operand" "f")
971                       (match_operand 1 "register_operand" "f")))]
972   "TARGET_80387 && TARGET_CMOVE
973    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
974    && FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 0);"
977   [(set_attr "type" "fcmp")
978    (set (attr "mode")
979      (cond [(match_operand:SF 1 "" "")
980               (const_string "SF")
981             (match_operand:DF 1 "" "")
982               (const_string "DF")
983            ]
984            (const_string "XF")))
985    (set_attr "athlon_decode" "vector")])
986
987 (define_insn "*cmpfp_iu_mixed"
988   [(set (reg:CCFPU FLAGS_REG)
989         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
990                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
991   "TARGET_MIX_SSE_I387
992    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
993    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
994   "* return output_fp_compare (insn, operands, 1, 1);"
995   [(set_attr "type" "fcmp,ssecomi")
996    (set (attr "mode")
997      (if_then_else (match_operand:SF 1 "" "")
998         (const_string "SF")
999         (const_string "DF")))
1000    (set_attr "athlon_decode" "vector")])
1001
1002 (define_insn "*cmpfp_iu_sse"
1003   [(set (reg:CCFPU FLAGS_REG)
1004         (compare:CCFPU (match_operand 0 "register_operand" "x")
1005                        (match_operand 1 "nonimmediate_operand" "xm")))]
1006   "TARGET_SSE_MATH
1007    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1008    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1009   "* return output_fp_compare (insn, operands, 1, 1);"
1010   [(set_attr "type" "ssecomi")
1011    (set (attr "mode")
1012      (if_then_else (match_operand:SF 1 "" "")
1013         (const_string "SF")
1014         (const_string "DF")))
1015    (set_attr "athlon_decode" "vector")])
1016
1017 (define_insn "*cmpfp_iu_387"
1018   [(set (reg:CCFPU FLAGS_REG)
1019         (compare:CCFPU (match_operand 0 "register_operand" "f")
1020                        (match_operand 1 "register_operand" "f")))]
1021   "TARGET_80387 && TARGET_CMOVE
1022    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1023    && FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "fcmp")
1027    (set (attr "mode")
1028      (cond [(match_operand:SF 1 "" "")
1029               (const_string "SF")
1030             (match_operand:DF 1 "" "")
1031               (const_string "DF")
1032            ]
1033            (const_string "XF")))
1034    (set_attr "athlon_decode" "vector")])
1035 \f
1036 ;; Move instructions.
1037
1038 ;; General case of fullword move.
1039
1040 (define_expand "movsi"
1041   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042         (match_operand:SI 1 "general_operand" ""))]
1043   ""
1044   "ix86_expand_move (SImode, operands); DONE;")
1045
1046 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1047 ;; general_operand.
1048 ;;
1049 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1050 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1051 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1052 ;; targets without our curiosities, and it is just as easy to represent
1053 ;; this differently.
1054
1055 (define_insn "*pushsi2"
1056   [(set (match_operand:SI 0 "push_operand" "=<")
1057         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1058   "!TARGET_64BIT"
1059   "push{l}\t%1"
1060   [(set_attr "type" "push")
1061    (set_attr "mode" "SI")])
1062
1063 ;; For 64BIT abi we always round up to 8 bytes.
1064 (define_insn "*pushsi2_rex64"
1065   [(set (match_operand:SI 0 "push_operand" "=X")
1066         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1067   "TARGET_64BIT"
1068   "push{q}\t%q1"
1069   [(set_attr "type" "push")
1070    (set_attr "mode" "SI")])
1071
1072 (define_insn "*pushsi2_prologue"
1073   [(set (match_operand:SI 0 "push_operand" "=<")
1074         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1075    (clobber (mem:BLK (scratch)))]
1076   "!TARGET_64BIT"
1077   "push{l}\t%1"
1078   [(set_attr "type" "push")
1079    (set_attr "mode" "SI")])
1080
1081 (define_insn "*popsi1_epilogue"
1082   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1083         (mem:SI (reg:SI SP_REG)))
1084    (set (reg:SI SP_REG)
1085         (plus:SI (reg:SI SP_REG) (const_int 4)))
1086    (clobber (mem:BLK (scratch)))]
1087   "!TARGET_64BIT"
1088   "pop{l}\t%0"
1089   [(set_attr "type" "pop")
1090    (set_attr "mode" "SI")])
1091
1092 (define_insn "popsi1"
1093   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1094         (mem:SI (reg:SI SP_REG)))
1095    (set (reg:SI SP_REG)
1096         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1097   "!TARGET_64BIT"
1098   "pop{l}\t%0"
1099   [(set_attr "type" "pop")
1100    (set_attr "mode" "SI")])
1101
1102 (define_insn "*movsi_xor"
1103   [(set (match_operand:SI 0 "register_operand" "=r")
1104         (match_operand:SI 1 "const0_operand" "i"))
1105    (clobber (reg:CC FLAGS_REG))]
1106   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1107   "xor{l}\t{%0, %0|%0, %0}"
1108   [(set_attr "type" "alu1")
1109    (set_attr "mode" "SI")
1110    (set_attr "length_immediate" "0")])
1111  
1112 (define_insn "*movsi_or"
1113   [(set (match_operand:SI 0 "register_operand" "=r")
1114         (match_operand:SI 1 "immediate_operand" "i"))
1115    (clobber (reg:CC FLAGS_REG))]
1116   "reload_completed
1117    && operands[1] == constm1_rtx
1118    && (TARGET_PENTIUM || optimize_size)"
1119 {
1120   operands[1] = constm1_rtx;
1121   return "or{l}\t{%1, %0|%0, %1}";
1122 }
1123   [(set_attr "type" "alu1")
1124    (set_attr "mode" "SI")
1125    (set_attr "length_immediate" "1")])
1126
1127 (define_insn "*movsi_1"
1128   [(set (match_operand:SI 0 "nonimmediate_operand"
1129                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1130         (match_operand:SI 1 "general_operand"
1131                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1132   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1133 {
1134   switch (get_attr_type (insn))
1135     {
1136     case TYPE_SSELOG1:
1137       if (get_attr_mode (insn) == MODE_TI)
1138         return "pxor\t%0, %0";
1139       return "xorps\t%0, %0";
1140
1141     case TYPE_SSEMOV:
1142       switch (get_attr_mode (insn))
1143         {
1144         case MODE_TI:
1145           return "movdqa\t{%1, %0|%0, %1}";
1146         case MODE_V4SF:
1147           return "movaps\t{%1, %0|%0, %1}";
1148         case MODE_SI:
1149           return "movd\t{%1, %0|%0, %1}";
1150         case MODE_SF:
1151           return "movss\t{%1, %0|%0, %1}";
1152         default:
1153           gcc_unreachable ();
1154         }
1155
1156     case TYPE_MMXADD:
1157       return "pxor\t%0, %0";
1158
1159     case TYPE_MMXMOV:
1160       if (get_attr_mode (insn) == MODE_DI)
1161         return "movq\t{%1, %0|%0, %1}";
1162       return "movd\t{%1, %0|%0, %1}";
1163
1164     case TYPE_LEA:
1165       return "lea{l}\t{%1, %0|%0, %1}";
1166
1167     default:
1168       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1169         abort();
1170       return "mov{l}\t{%1, %0|%0, %1}";
1171     }
1172 }
1173   [(set (attr "type")
1174      (cond [(eq_attr "alternative" "2")
1175               (const_string "mmxadd")
1176             (eq_attr "alternative" "3,4,5")
1177               (const_string "mmxmov")
1178             (eq_attr "alternative" "6")
1179               (const_string "sselog1")
1180             (eq_attr "alternative" "7,8,9,10,11")
1181               (const_string "ssemov")
1182             (and (ne (symbol_ref "flag_pic") (const_int 0))
1183                  (match_operand:SI 1 "symbolic_operand" ""))
1184               (const_string "lea")
1185            ]
1186            (const_string "imov")))
1187    (set (attr "mode")
1188      (cond [(eq_attr "alternative" "2,3")
1189               (const_string "DI")
1190             (eq_attr "alternative" "6,7")
1191               (if_then_else
1192                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1193                 (const_string "V4SF")
1194                 (const_string "TI"))
1195             (and (eq_attr "alternative" "8,9,10,11")
1196                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1197               (const_string "SF")
1198            ]
1199            (const_string "SI")))])
1200
1201 ;; Stores and loads of ax to arbitrary constant address.
1202 ;; We fake an second form of instruction to force reload to load address
1203 ;; into register when rax is not available
1204 (define_insn "*movabssi_1_rex64"
1205   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1206         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1207   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1208   "@
1209    movabs{l}\t{%1, %P0|%P0, %1}
1210    mov{l}\t{%1, %a0|%a0, %1}"
1211   [(set_attr "type" "imov")
1212    (set_attr "modrm" "0,*")
1213    (set_attr "length_address" "8,0")
1214    (set_attr "length_immediate" "0,*")
1215    (set_attr "memory" "store")
1216    (set_attr "mode" "SI")])
1217
1218 (define_insn "*movabssi_2_rex64"
1219   [(set (match_operand:SI 0 "register_operand" "=a,r")
1220         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1221   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1222   "@
1223    movabs{l}\t{%P1, %0|%0, %P1}
1224    mov{l}\t{%a1, %0|%0, %a1}"
1225   [(set_attr "type" "imov")
1226    (set_attr "modrm" "0,*")
1227    (set_attr "length_address" "8,0")
1228    (set_attr "length_immediate" "0")
1229    (set_attr "memory" "load")
1230    (set_attr "mode" "SI")])
1231
1232 (define_insn "*swapsi"
1233   [(set (match_operand:SI 0 "register_operand" "+r")
1234         (match_operand:SI 1 "register_operand" "+r"))
1235    (set (match_dup 1)
1236         (match_dup 0))]
1237   ""
1238   "xchg{l}\t%1, %0"
1239   [(set_attr "type" "imov")
1240    (set_attr "mode" "SI")
1241    (set_attr "pent_pair" "np")
1242    (set_attr "athlon_decode" "vector")])
1243
1244 (define_expand "movhi"
1245   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1246         (match_operand:HI 1 "general_operand" ""))]
1247   ""
1248   "ix86_expand_move (HImode, operands); DONE;")
1249
1250 (define_insn "*pushhi2"
1251   [(set (match_operand:HI 0 "push_operand" "=<,<")
1252         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1253   "!TARGET_64BIT"
1254   "@
1255    push{w}\t{|WORD PTR }%1
1256    push{w}\t%1"
1257   [(set_attr "type" "push")
1258    (set_attr "mode" "HI")])
1259
1260 ;; For 64BIT abi we always round up to 8 bytes.
1261 (define_insn "*pushhi2_rex64"
1262   [(set (match_operand:HI 0 "push_operand" "=X")
1263         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1264   "TARGET_64BIT"
1265   "push{q}\t%q1"
1266   [(set_attr "type" "push")
1267    (set_attr "mode" "QI")])
1268
1269 (define_insn "*movhi_1"
1270   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1271         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1272   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1273 {
1274   switch (get_attr_type (insn))
1275     {
1276     case TYPE_IMOVX:
1277       /* movzwl is faster than movw on p2 due to partial word stalls,
1278          though not as fast as an aligned movl.  */
1279       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1280     default:
1281       if (get_attr_mode (insn) == MODE_SI)
1282         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1283       else
1284         return "mov{w}\t{%1, %0|%0, %1}";
1285     }
1286 }
1287   [(set (attr "type")
1288      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1289               (const_string "imov")
1290             (and (eq_attr "alternative" "0")
1291                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1292                           (const_int 0))
1293                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1294                           (const_int 0))))
1295               (const_string "imov")
1296             (and (eq_attr "alternative" "1,2")
1297                  (match_operand:HI 1 "aligned_operand" ""))
1298               (const_string "imov")
1299             (and (ne (symbol_ref "TARGET_MOVX")
1300                      (const_int 0))
1301                  (eq_attr "alternative" "0,2"))
1302               (const_string "imovx")
1303            ]
1304            (const_string "imov")))
1305     (set (attr "mode")
1306       (cond [(eq_attr "type" "imovx")
1307                (const_string "SI")
1308              (and (eq_attr "alternative" "1,2")
1309                   (match_operand:HI 1 "aligned_operand" ""))
1310                (const_string "SI")
1311              (and (eq_attr "alternative" "0")
1312                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1313                            (const_int 0))
1314                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1315                            (const_int 0))))
1316                (const_string "SI")
1317             ]
1318             (const_string "HI")))])
1319
1320 ;; Stores and loads of ax to arbitrary constant address.
1321 ;; We fake an second form of instruction to force reload to load address
1322 ;; into register when rax is not available
1323 (define_insn "*movabshi_1_rex64"
1324   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1325         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1326   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1327   "@
1328    movabs{w}\t{%1, %P0|%P0, %1}
1329    mov{w}\t{%1, %a0|%a0, %1}"
1330   [(set_attr "type" "imov")
1331    (set_attr "modrm" "0,*")
1332    (set_attr "length_address" "8,0")
1333    (set_attr "length_immediate" "0,*")
1334    (set_attr "memory" "store")
1335    (set_attr "mode" "HI")])
1336
1337 (define_insn "*movabshi_2_rex64"
1338   [(set (match_operand:HI 0 "register_operand" "=a,r")
1339         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1340   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1341   "@
1342    movabs{w}\t{%P1, %0|%0, %P1}
1343    mov{w}\t{%a1, %0|%0, %a1}"
1344   [(set_attr "type" "imov")
1345    (set_attr "modrm" "0,*")
1346    (set_attr "length_address" "8,0")
1347    (set_attr "length_immediate" "0")
1348    (set_attr "memory" "load")
1349    (set_attr "mode" "HI")])
1350
1351 (define_insn "*swaphi_1"
1352   [(set (match_operand:HI 0 "register_operand" "+r")
1353         (match_operand:HI 1 "register_operand" "+r"))
1354    (set (match_dup 1)
1355         (match_dup 0))]
1356   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1357   "xchg{l}\t%k1, %k0"
1358   [(set_attr "type" "imov")
1359    (set_attr "mode" "SI")
1360    (set_attr "pent_pair" "np")
1361    (set_attr "athlon_decode" "vector")])
1362
1363 (define_insn "*swaphi_2"
1364   [(set (match_operand:HI 0 "register_operand" "+r")
1365         (match_operand:HI 1 "register_operand" "+r"))
1366    (set (match_dup 1)
1367         (match_dup 0))]
1368   "TARGET_PARTIAL_REG_STALL"
1369   "xchg{w}\t%1, %0"
1370   [(set_attr "type" "imov")
1371    (set_attr "mode" "HI")
1372    (set_attr "pent_pair" "np")
1373    (set_attr "athlon_decode" "vector")])
1374
1375 (define_expand "movstricthi"
1376   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1377         (match_operand:HI 1 "general_operand" ""))]
1378   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1379 {
1380   /* Don't generate memory->memory moves, go through a register */
1381   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1382     operands[1] = force_reg (HImode, operands[1]);
1383 })
1384
1385 (define_insn "*movstricthi_1"
1386   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1387         (match_operand:HI 1 "general_operand" "rn,m"))]
1388   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1389    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1390   "mov{w}\t{%1, %0|%0, %1}"
1391   [(set_attr "type" "imov")
1392    (set_attr "mode" "HI")])
1393
1394 (define_insn "*movstricthi_xor"
1395   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1396         (match_operand:HI 1 "const0_operand" "i"))
1397    (clobber (reg:CC FLAGS_REG))]
1398   "reload_completed
1399    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1400   "xor{w}\t{%0, %0|%0, %0}"
1401   [(set_attr "type" "alu1")
1402    (set_attr "mode" "HI")
1403    (set_attr "length_immediate" "0")])
1404
1405 (define_expand "movqi"
1406   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1407         (match_operand:QI 1 "general_operand" ""))]
1408   ""
1409   "ix86_expand_move (QImode, operands); DONE;")
1410
1411 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1412 ;; "push a byte".  But actually we use pushw, which has the effect
1413 ;; of rounding the amount pushed up to a halfword.
1414
1415 (define_insn "*pushqi2"
1416   [(set (match_operand:QI 0 "push_operand" "=X,X")
1417         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1418   "!TARGET_64BIT"
1419   "@
1420    push{w}\t{|word ptr }%1
1421    push{w}\t%w1"
1422   [(set_attr "type" "push")
1423    (set_attr "mode" "HI")])
1424
1425 ;; For 64BIT abi we always round up to 8 bytes.
1426 (define_insn "*pushqi2_rex64"
1427   [(set (match_operand:QI 0 "push_operand" "=X")
1428         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1429   "TARGET_64BIT"
1430   "push{q}\t%q1"
1431   [(set_attr "type" "push")
1432    (set_attr "mode" "QI")])
1433
1434 ;; Situation is quite tricky about when to choose full sized (SImode) move
1435 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1436 ;; partial register dependency machines (such as AMD Athlon), where QImode
1437 ;; moves issue extra dependency and for partial register stalls machines
1438 ;; that don't use QImode patterns (and QImode move cause stall on the next
1439 ;; instruction).
1440 ;;
1441 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1442 ;; register stall machines with, where we use QImode instructions, since
1443 ;; partial register stall can be caused there.  Then we use movzx.
1444 (define_insn "*movqi_1"
1445   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1446         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1447   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1448 {
1449   switch (get_attr_type (insn))
1450     {
1451     case TYPE_IMOVX:
1452       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1453         abort ();
1454       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1455     default:
1456       if (get_attr_mode (insn) == MODE_SI)
1457         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1458       else
1459         return "mov{b}\t{%1, %0|%0, %1}";
1460     }
1461 }
1462   [(set (attr "type")
1463      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1464               (const_string "imov")
1465             (and (eq_attr "alternative" "3")
1466                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1467                           (const_int 0))
1468                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1469                           (const_int 0))))
1470               (const_string "imov")
1471             (eq_attr "alternative" "3,5")
1472               (const_string "imovx")
1473             (and (ne (symbol_ref "TARGET_MOVX")
1474                      (const_int 0))
1475                  (eq_attr "alternative" "2"))
1476               (const_string "imovx")
1477            ]
1478            (const_string "imov")))
1479    (set (attr "mode")
1480       (cond [(eq_attr "alternative" "3,4,5")
1481                (const_string "SI")
1482              (eq_attr "alternative" "6")
1483                (const_string "QI")
1484              (eq_attr "type" "imovx")
1485                (const_string "SI")
1486              (and (eq_attr "type" "imov")
1487                   (and (eq_attr "alternative" "0,1")
1488                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1489                            (const_int 0))))
1490                (const_string "SI")
1491              ;; Avoid partial register stalls when not using QImode arithmetic
1492              (and (eq_attr "type" "imov")
1493                   (and (eq_attr "alternative" "0,1")
1494                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495                                 (const_int 0))
1496                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1497                                 (const_int 0)))))
1498                (const_string "SI")
1499            ]
1500            (const_string "QI")))])
1501
1502 (define_expand "reload_outqi"
1503   [(parallel [(match_operand:QI 0 "" "=m")
1504               (match_operand:QI 1 "register_operand" "r")
1505               (match_operand:QI 2 "register_operand" "=&q")])]
1506   ""
1507 {
1508   rtx op0, op1, op2;
1509   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1510
1511   if (reg_overlap_mentioned_p (op2, op0))
1512     abort ();
1513   if (! q_regs_operand (op1, QImode))
1514     {
1515       emit_insn (gen_movqi (op2, op1));
1516       op1 = op2;
1517     }
1518   emit_insn (gen_movqi (op0, op1));
1519   DONE;
1520 })
1521
1522 (define_insn "*swapqi_1"
1523   [(set (match_operand:QI 0 "register_operand" "+r")
1524         (match_operand:QI 1 "register_operand" "+r"))
1525    (set (match_dup 1)
1526         (match_dup 0))]
1527   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1528   "xchg{l}\t%k1, %k0"
1529   [(set_attr "type" "imov")
1530    (set_attr "mode" "SI")
1531    (set_attr "pent_pair" "np")
1532    (set_attr "athlon_decode" "vector")])
1533
1534 (define_insn "*swapqi_2"
1535   [(set (match_operand:QI 0 "register_operand" "+q")
1536         (match_operand:QI 1 "register_operand" "+q"))
1537    (set (match_dup 1)
1538         (match_dup 0))]
1539   "TARGET_PARTIAL_REG_STALL"
1540   "xchg{b}\t%1, %0"
1541   [(set_attr "type" "imov")
1542    (set_attr "mode" "QI")
1543    (set_attr "pent_pair" "np")
1544    (set_attr "athlon_decode" "vector")])
1545
1546 (define_expand "movstrictqi"
1547   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1548         (match_operand:QI 1 "general_operand" ""))]
1549   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1550 {
1551   /* Don't generate memory->memory moves, go through a register.  */
1552   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1553     operands[1] = force_reg (QImode, operands[1]);
1554 })
1555
1556 (define_insn "*movstrictqi_1"
1557   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1558         (match_operand:QI 1 "general_operand" "*qn,m"))]
1559   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1560    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1561   "mov{b}\t{%1, %0|%0, %1}"
1562   [(set_attr "type" "imov")
1563    (set_attr "mode" "QI")])
1564
1565 (define_insn "*movstrictqi_xor"
1566   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1567         (match_operand:QI 1 "const0_operand" "i"))
1568    (clobber (reg:CC FLAGS_REG))]
1569   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1570   "xor{b}\t{%0, %0|%0, %0}"
1571   [(set_attr "type" "alu1")
1572    (set_attr "mode" "QI")
1573    (set_attr "length_immediate" "0")])
1574
1575 (define_insn "*movsi_extv_1"
1576   [(set (match_operand:SI 0 "register_operand" "=R")
1577         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1578                          (const_int 8)
1579                          (const_int 8)))]
1580   ""
1581   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1582   [(set_attr "type" "imovx")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "*movhi_extv_1"
1586   [(set (match_operand:HI 0 "register_operand" "=R")
1587         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1588                          (const_int 8)
1589                          (const_int 8)))]
1590   ""
1591   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1592   [(set_attr "type" "imovx")
1593    (set_attr "mode" "SI")])
1594
1595 (define_insn "*movqi_extv_1"
1596   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1597         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1598                          (const_int 8)
1599                          (const_int 8)))]
1600   "!TARGET_64BIT"
1601 {
1602   switch (get_attr_type (insn))
1603     {
1604     case TYPE_IMOVX:
1605       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1606     default:
1607       return "mov{b}\t{%h1, %0|%0, %h1}";
1608     }
1609 }
1610   [(set (attr "type")
1611      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1612                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1613                              (ne (symbol_ref "TARGET_MOVX")
1614                                  (const_int 0))))
1615         (const_string "imovx")
1616         (const_string "imov")))
1617    (set (attr "mode")
1618      (if_then_else (eq_attr "type" "imovx")
1619         (const_string "SI")
1620         (const_string "QI")))])
1621
1622 (define_insn "*movqi_extv_1_rex64"
1623   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1624         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1625                          (const_int 8)
1626                          (const_int 8)))]
1627   "TARGET_64BIT"
1628 {
1629   switch (get_attr_type (insn))
1630     {
1631     case TYPE_IMOVX:
1632       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1633     default:
1634       return "mov{b}\t{%h1, %0|%0, %h1}";
1635     }
1636 }
1637   [(set (attr "type")
1638      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1639                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1640                              (ne (symbol_ref "TARGET_MOVX")
1641                                  (const_int 0))))
1642         (const_string "imovx")
1643         (const_string "imov")))
1644    (set (attr "mode")
1645      (if_then_else (eq_attr "type" "imovx")
1646         (const_string "SI")
1647         (const_string "QI")))])
1648
1649 ;; Stores and loads of ax to arbitrary constant address.
1650 ;; We fake an second form of instruction to force reload to load address
1651 ;; into register when rax is not available
1652 (define_insn "*movabsqi_1_rex64"
1653   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1654         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1655   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1656   "@
1657    movabs{b}\t{%1, %P0|%P0, %1}
1658    mov{b}\t{%1, %a0|%a0, %1}"
1659   [(set_attr "type" "imov")
1660    (set_attr "modrm" "0,*")
1661    (set_attr "length_address" "8,0")
1662    (set_attr "length_immediate" "0,*")
1663    (set_attr "memory" "store")
1664    (set_attr "mode" "QI")])
1665
1666 (define_insn "*movabsqi_2_rex64"
1667   [(set (match_operand:QI 0 "register_operand" "=a,r")
1668         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1669   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1670   "@
1671    movabs{b}\t{%P1, %0|%0, %P1}
1672    mov{b}\t{%a1, %0|%0, %a1}"
1673   [(set_attr "type" "imov")
1674    (set_attr "modrm" "0,*")
1675    (set_attr "length_address" "8,0")
1676    (set_attr "length_immediate" "0")
1677    (set_attr "memory" "load")
1678    (set_attr "mode" "QI")])
1679
1680 (define_insn "*movsi_extzv_1"
1681   [(set (match_operand:SI 0 "register_operand" "=R")
1682         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1683                          (const_int 8)
1684                          (const_int 8)))]
1685   ""
1686   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1687   [(set_attr "type" "imovx")
1688    (set_attr "mode" "SI")])
1689
1690 (define_insn "*movqi_extzv_2"
1691   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1692         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1693                                     (const_int 8)
1694                                     (const_int 8)) 0))]
1695   "!TARGET_64BIT"
1696 {
1697   switch (get_attr_type (insn))
1698     {
1699     case TYPE_IMOVX:
1700       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1701     default:
1702       return "mov{b}\t{%h1, %0|%0, %h1}";
1703     }
1704 }
1705   [(set (attr "type")
1706      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1707                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1708                              (ne (symbol_ref "TARGET_MOVX")
1709                                  (const_int 0))))
1710         (const_string "imovx")
1711         (const_string "imov")))
1712    (set (attr "mode")
1713      (if_then_else (eq_attr "type" "imovx")
1714         (const_string "SI")
1715         (const_string "QI")))])
1716
1717 (define_insn "*movqi_extzv_2_rex64"
1718   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1719         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1720                                     (const_int 8)
1721                                     (const_int 8)) 0))]
1722   "TARGET_64BIT"
1723 {
1724   switch (get_attr_type (insn))
1725     {
1726     case TYPE_IMOVX:
1727       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1728     default:
1729       return "mov{b}\t{%h1, %0|%0, %h1}";
1730     }
1731 }
1732   [(set (attr "type")
1733      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1734                         (ne (symbol_ref "TARGET_MOVX")
1735                             (const_int 0)))
1736         (const_string "imovx")
1737         (const_string "imov")))
1738    (set (attr "mode")
1739      (if_then_else (eq_attr "type" "imovx")
1740         (const_string "SI")
1741         (const_string "QI")))])
1742
1743 (define_insn "movsi_insv_1"
1744   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1745                          (const_int 8)
1746                          (const_int 8))
1747         (match_operand:SI 1 "general_operand" "Qmn"))]
1748   "!TARGET_64BIT"
1749   "mov{b}\t{%b1, %h0|%h0, %b1}"
1750   [(set_attr "type" "imov")
1751    (set_attr "mode" "QI")])
1752
1753 (define_insn "movdi_insv_1_rex64"
1754   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1755                          (const_int 8)
1756                          (const_int 8))
1757         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1758   "TARGET_64BIT"
1759   "mov{b}\t{%b1, %h0|%h0, %b1}"
1760   [(set_attr "type" "imov")
1761    (set_attr "mode" "QI")])
1762
1763 (define_insn "*movqi_insv_2"
1764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1765                          (const_int 8)
1766                          (const_int 8))
1767         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1768                      (const_int 8)))]
1769   ""
1770   "mov{b}\t{%h1, %h0|%h0, %h1}"
1771   [(set_attr "type" "imov")
1772    (set_attr "mode" "QI")])
1773
1774 (define_expand "movdi"
1775   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1776         (match_operand:DI 1 "general_operand" ""))]
1777   ""
1778   "ix86_expand_move (DImode, operands); DONE;")
1779
1780 (define_insn "*pushdi"
1781   [(set (match_operand:DI 0 "push_operand" "=<")
1782         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1783   "!TARGET_64BIT"
1784   "#")
1785
1786 (define_insn "*pushdi2_rex64"
1787   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1788         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1789   "TARGET_64BIT"
1790   "@
1791    push{q}\t%1
1792    #"
1793   [(set_attr "type" "push,multi")
1794    (set_attr "mode" "DI")])
1795
1796 ;; Convert impossible pushes of immediate to existing instructions.
1797 ;; First try to get scratch register and go through it.  In case this
1798 ;; fails, push sign extended lower part first and then overwrite
1799 ;; upper part by 32bit move.
1800 (define_peephole2
1801   [(match_scratch:DI 2 "r")
1802    (set (match_operand:DI 0 "push_operand" "")
1803         (match_operand:DI 1 "immediate_operand" ""))]
1804   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1805    && !x86_64_immediate_operand (operands[1], DImode)"
1806   [(set (match_dup 2) (match_dup 1))
1807    (set (match_dup 0) (match_dup 2))]
1808   "")
1809
1810 ;; We need to define this as both peepholer and splitter for case
1811 ;; peephole2 pass is not run.
1812 ;; "&& 1" is needed to keep it from matching the previous pattern.
1813 (define_peephole2
1814   [(set (match_operand:DI 0 "push_operand" "")
1815         (match_operand:DI 1 "immediate_operand" ""))]
1816   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1817    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1818   [(set (match_dup 0) (match_dup 1))
1819    (set (match_dup 2) (match_dup 3))]
1820   "split_di (operands + 1, 1, operands + 2, operands + 3);
1821    operands[1] = gen_lowpart (DImode, operands[2]);
1822    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1823                                                     GEN_INT (4)));
1824   ")
1825
1826 (define_split
1827   [(set (match_operand:DI 0 "push_operand" "")
1828         (match_operand:DI 1 "immediate_operand" ""))]
1829   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1830    && !symbolic_operand (operands[1], DImode)
1831    && !x86_64_immediate_operand (operands[1], DImode)"
1832   [(set (match_dup 0) (match_dup 1))
1833    (set (match_dup 2) (match_dup 3))]
1834   "split_di (operands + 1, 1, operands + 2, operands + 3);
1835    operands[1] = gen_lowpart (DImode, operands[2]);
1836    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1837                                                     GEN_INT (4)));
1838   ")
1839
1840 (define_insn "*pushdi2_prologue_rex64"
1841   [(set (match_operand:DI 0 "push_operand" "=<")
1842         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1843    (clobber (mem:BLK (scratch)))]
1844   "TARGET_64BIT"
1845   "push{q}\t%1"
1846   [(set_attr "type" "push")
1847    (set_attr "mode" "DI")])
1848
1849 (define_insn "*popdi1_epilogue_rex64"
1850   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1851         (mem:DI (reg:DI SP_REG)))
1852    (set (reg:DI SP_REG)
1853         (plus:DI (reg:DI SP_REG) (const_int 8)))
1854    (clobber (mem:BLK (scratch)))]
1855   "TARGET_64BIT"
1856   "pop{q}\t%0"
1857   [(set_attr "type" "pop")
1858    (set_attr "mode" "DI")])
1859
1860 (define_insn "popdi1"
1861   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1862         (mem:DI (reg:DI SP_REG)))
1863    (set (reg:DI SP_REG)
1864         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1865   "TARGET_64BIT"
1866   "pop{q}\t%0"
1867   [(set_attr "type" "pop")
1868    (set_attr "mode" "DI")])
1869
1870 (define_insn "*movdi_xor_rex64"
1871   [(set (match_operand:DI 0 "register_operand" "=r")
1872         (match_operand:DI 1 "const0_operand" "i"))
1873    (clobber (reg:CC FLAGS_REG))]
1874   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1875    && reload_completed"
1876   "xor{l}\t{%k0, %k0|%k0, %k0}"
1877   [(set_attr "type" "alu1")
1878    (set_attr "mode" "SI")
1879    (set_attr "length_immediate" "0")])
1880
1881 (define_insn "*movdi_or_rex64"
1882   [(set (match_operand:DI 0 "register_operand" "=r")
1883         (match_operand:DI 1 "const_int_operand" "i"))
1884    (clobber (reg:CC FLAGS_REG))]
1885   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1886    && reload_completed
1887    && operands[1] == constm1_rtx"
1888 {
1889   operands[1] = constm1_rtx;
1890   return "or{q}\t{%1, %0|%0, %1}";
1891 }
1892   [(set_attr "type" "alu1")
1893    (set_attr "mode" "DI")
1894    (set_attr "length_immediate" "1")])
1895
1896 (define_insn "*movdi_2"
1897   [(set (match_operand:DI 0 "nonimmediate_operand"
1898                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1899         (match_operand:DI 1 "general_operand"
1900                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1901   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1902   "@
1903    #
1904    #
1905    pxor\t%0, %0
1906    movq\t{%1, %0|%0, %1}
1907    movq\t{%1, %0|%0, %1}
1908    pxor\t%0, %0
1909    movq\t{%1, %0|%0, %1}
1910    movdqa\t{%1, %0|%0, %1}
1911    movq\t{%1, %0|%0, %1}
1912    xorps\t%0, %0
1913    movlps\t{%1, %0|%0, %1}
1914    movaps\t{%1, %0|%0, %1}
1915    movlps\t{%1, %0|%0, %1}"
1916   [(set_attr "type" "*,*,mmxadd,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1917    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1918
1919 (define_split
1920   [(set (match_operand:DI 0 "push_operand" "")
1921         (match_operand:DI 1 "general_operand" ""))]
1922   "!TARGET_64BIT && reload_completed
1923    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1924   [(const_int 0)]
1925   "ix86_split_long_move (operands); DONE;")
1926
1927 ;; %%% This multiword shite has got to go.
1928 (define_split
1929   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1930         (match_operand:DI 1 "general_operand" ""))]
1931   "!TARGET_64BIT && reload_completed
1932    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1933    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1934   [(const_int 0)]
1935   "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movdi_1_rex64"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1940         (match_operand:DI 1 "general_operand"
1941                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1942   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 {
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_SSECVT:
1947       if (which_alternative == 13)
1948         return "movq2dq\t{%1, %0|%0, %1}";
1949       else
1950         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953           return "movdqa\t{%1, %0|%0, %1}";
1954       /* FALLTHRU */
1955     case TYPE_MMXMOV:
1956       /* Moves from and into integer register is done using movd opcode with
1957          REX prefix.  */
1958       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959           return "movd\t{%1, %0|%0, %1}";
1960       return "movq\t{%1, %0|%0, %1}";
1961     case TYPE_SSELOG1:
1962     case TYPE_MMXADD:
1963       return "pxor\t%0, %0";
1964     case TYPE_MULTI:
1965       return "#";
1966     case TYPE_LEA:
1967       return "lea{q}\t{%a1, %0|%0, %a1}";
1968     default:
1969       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1970         abort ();
1971       if (get_attr_mode (insn) == MODE_SI)
1972         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1973       else if (which_alternative == 2)
1974         return "movabs{q}\t{%1, %0|%0, %1}";
1975       else
1976         return "mov{q}\t{%1, %0|%0, %1}";
1977     }
1978 }
1979   [(set (attr "type")
1980      (cond [(eq_attr "alternative" "5")
1981               (const_string "mmxadd")
1982             (eq_attr "alternative" "6,7,8")
1983               (const_string "mmxmov")
1984             (eq_attr "alternative" "9")
1985               (const_string "sselog1")
1986             (eq_attr "alternative" "10,11,12")
1987               (const_string "ssemov")
1988             (eq_attr "alternative" "13,14")
1989               (const_string "ssecvt")
1990             (eq_attr "alternative" "4")
1991               (const_string "multi")
1992             (and (ne (symbol_ref "flag_pic") (const_int 0))
1993                  (match_operand:DI 1 "symbolic_operand" ""))
1994               (const_string "lea")
1995            ]
1996            (const_string "imov")))
1997    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
1998    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
1999    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2000
2001 ;; Stores and loads of ax to arbitrary constant address.
2002 ;; We fake an second form of instruction to force reload to load address
2003 ;; into register when rax is not available
2004 (define_insn "*movabsdi_1_rex64"
2005   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2006         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2007   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2008   "@
2009    movabs{q}\t{%1, %P0|%P0, %1}
2010    mov{q}\t{%1, %a0|%a0, %1}"
2011   [(set_attr "type" "imov")
2012    (set_attr "modrm" "0,*")
2013    (set_attr "length_address" "8,0")
2014    (set_attr "length_immediate" "0,*")
2015    (set_attr "memory" "store")
2016    (set_attr "mode" "DI")])
2017
2018 (define_insn "*movabsdi_2_rex64"
2019   [(set (match_operand:DI 0 "register_operand" "=a,r")
2020         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2021   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2022   "@
2023    movabs{q}\t{%P1, %0|%0, %P1}
2024    mov{q}\t{%a1, %0|%0, %a1}"
2025   [(set_attr "type" "imov")
2026    (set_attr "modrm" "0,*")
2027    (set_attr "length_address" "8,0")
2028    (set_attr "length_immediate" "0")
2029    (set_attr "memory" "load")
2030    (set_attr "mode" "DI")])
2031
2032 ;; Convert impossible stores of immediate to existing instructions.
2033 ;; First try to get scratch register and go through it.  In case this
2034 ;; fails, move by 32bit parts.
2035 (define_peephole2
2036   [(match_scratch:DI 2 "r")
2037    (set (match_operand:DI 0 "memory_operand" "")
2038         (match_operand:DI 1 "immediate_operand" ""))]
2039   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2040    && !x86_64_immediate_operand (operands[1], DImode)"
2041   [(set (match_dup 2) (match_dup 1))
2042    (set (match_dup 0) (match_dup 2))]
2043   "")
2044
2045 ;; We need to define this as both peepholer and splitter for case
2046 ;; peephole2 pass is not run.
2047 ;; "&& 1" is needed to keep it from matching the previous pattern.
2048 (define_peephole2
2049   [(set (match_operand:DI 0 "memory_operand" "")
2050         (match_operand:DI 1 "immediate_operand" ""))]
2051   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2052    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2053   [(set (match_dup 2) (match_dup 3))
2054    (set (match_dup 4) (match_dup 5))]
2055   "split_di (operands, 2, operands + 2, operands + 4);")
2056
2057 (define_split
2058   [(set (match_operand:DI 0 "memory_operand" "")
2059         (match_operand:DI 1 "immediate_operand" ""))]
2060   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2061    && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode)"
2063   [(set (match_dup 2) (match_dup 3))
2064    (set (match_dup 4) (match_dup 5))]
2065   "split_di (operands, 2, operands + 2, operands + 4);")
2066
2067 (define_insn "*swapdi_rex64"
2068   [(set (match_operand:DI 0 "register_operand" "+r")
2069         (match_operand:DI 1 "register_operand" "+r"))
2070    (set (match_dup 1)
2071         (match_dup 0))]
2072   "TARGET_64BIT"
2073   "xchg{q}\t%1, %0"
2074   [(set_attr "type" "imov")
2075    (set_attr "mode" "DI")
2076    (set_attr "pent_pair" "np")
2077    (set_attr "athlon_decode" "vector")])
2078
2079 (define_expand "movti"
2080   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2081         (match_operand:TI 1 "nonimmediate_operand" ""))]
2082   "TARGET_SSE || TARGET_64BIT"
2083 {
2084   if (TARGET_64BIT)
2085     ix86_expand_move (TImode, operands);
2086   else
2087     ix86_expand_vector_move (TImode, operands);
2088   DONE;
2089 })
2090
2091 (define_insn "*movti_internal"
2092   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2093         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2094   "TARGET_SSE && !TARGET_64BIT
2095    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2096 {
2097   switch (which_alternative)
2098     {
2099     case 0:
2100       if (get_attr_mode (insn) == MODE_V4SF)
2101         return "xorps\t%0, %0";
2102       else
2103         return "pxor\t%0, %0";
2104     case 1:
2105     case 2:
2106       if (get_attr_mode (insn) == MODE_V4SF)
2107         return "movaps\t{%1, %0|%0, %1}";
2108       else
2109         return "movdqa\t{%1, %0|%0, %1}";
2110     default:
2111       abort ();
2112     }
2113 }
2114   [(set_attr "type" "ssemov,ssemov,ssemov")
2115    (set (attr "mode")
2116         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2117                  (const_string "V4SF")
2118
2119                (eq_attr "alternative" "0,1")
2120                  (if_then_else
2121                    (ne (symbol_ref "optimize_size")
2122                        (const_int 0))
2123                    (const_string "V4SF")
2124                    (const_string "TI"))
2125                (eq_attr "alternative" "2")
2126                  (if_then_else
2127                    (ne (symbol_ref "optimize_size")
2128                        (const_int 0))
2129                    (const_string "V4SF")
2130                    (const_string "TI"))]
2131                (const_string "TI")))])
2132
2133 (define_insn "*movti_rex64"
2134   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2135         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2136   "TARGET_64BIT
2137    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2138 {
2139   switch (which_alternative)
2140     {
2141     case 0:
2142     case 1:
2143       return "#";
2144     case 2:
2145       if (get_attr_mode (insn) == MODE_V4SF)
2146         return "xorps\t%0, %0";
2147       else
2148         return "pxor\t%0, %0";
2149     case 3:
2150     case 4:
2151       if (get_attr_mode (insn) == MODE_V4SF)
2152         return "movaps\t{%1, %0|%0, %1}";
2153       else
2154         return "movdqa\t{%1, %0|%0, %1}";
2155     default:
2156       abort ();
2157     }
2158 }
2159   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2160    (set (attr "mode")
2161         (cond [(eq_attr "alternative" "2,3")
2162                  (if_then_else
2163                    (ne (symbol_ref "optimize_size")
2164                        (const_int 0))
2165                    (const_string "V4SF")
2166                    (const_string "TI"))
2167                (eq_attr "alternative" "4")
2168                  (if_then_else
2169                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2170                             (const_int 0))
2171                         (ne (symbol_ref "optimize_size")
2172                             (const_int 0)))
2173                    (const_string "V4SF")
2174                    (const_string "TI"))]
2175                (const_string "DI")))])
2176
2177 (define_split
2178   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2179         (match_operand:TI 1 "general_operand" ""))]
2180   "reload_completed && !SSE_REG_P (operands[0])
2181    && !SSE_REG_P (operands[1])"
2182   [(const_int 0)]
2183   "ix86_split_long_move (operands); DONE;")
2184
2185 (define_expand "movsf"
2186   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2187         (match_operand:SF 1 "general_operand" ""))]
2188   ""
2189   "ix86_expand_move (SFmode, operands); DONE;")
2190
2191 (define_insn "*pushsf"
2192   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2193         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2194   "!TARGET_64BIT"
2195 {
2196   switch (which_alternative)
2197     {
2198     case 1:
2199       return "push{l}\t%1";
2200
2201     default:
2202       /* This insn should be already split before reg-stack.  */
2203       abort ();
2204     }
2205 }
2206   [(set_attr "type" "multi,push,multi")
2207    (set_attr "mode" "SF,SI,SF")])
2208
2209 (define_insn "*pushsf_rex64"
2210   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2211         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2212   "TARGET_64BIT"
2213 {
2214   switch (which_alternative)
2215     {
2216     case 1:
2217       return "push{q}\t%q1";
2218
2219     default:
2220       /* This insn should be already split before reg-stack.  */
2221       abort ();
2222     }
2223 }
2224   [(set_attr "type" "multi,push,multi")
2225    (set_attr "mode" "SF,DI,SF")])
2226
2227 (define_split
2228   [(set (match_operand:SF 0 "push_operand" "")
2229         (match_operand:SF 1 "memory_operand" ""))]
2230   "reload_completed
2231    && GET_CODE (operands[1]) == MEM
2232    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2233    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2234   [(set (match_dup 0)
2235         (match_dup 1))]
2236   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2237
2238
2239 ;; %%% Kill this when call knows how to work this out.
2240 (define_split
2241   [(set (match_operand:SF 0 "push_operand" "")
2242         (match_operand:SF 1 "any_fp_register_operand" ""))]
2243   "!TARGET_64BIT"
2244   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2245    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2246
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "any_fp_register_operand" ""))]
2250   "TARGET_64BIT"
2251   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2252    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2253
2254 (define_insn "*movsf_1"
2255   [(set (match_operand:SF 0 "nonimmediate_operand"
2256           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2257         (match_operand:SF 1 "general_operand"
2258           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2259   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2260    && (reload_in_progress || reload_completed
2261        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2262        || GET_CODE (operands[1]) != CONST_DOUBLE
2263        || memory_operand (operands[0], SFmode))" 
2264 {
2265   switch (which_alternative)
2266     {
2267     case 0:
2268       return output_387_reg_move (insn, operands);
2269
2270     case 1:
2271       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2272         return "fstp%z0\t%y0";
2273       else
2274         return "fst%z0\t%y0";
2275
2276     case 2:
2277       return standard_80387_constant_opcode (operands[1]);
2278
2279     case 3:
2280     case 4:
2281       return "mov{l}\t{%1, %0|%0, %1}";
2282     case 5:
2283       if (get_attr_mode (insn) == MODE_TI)
2284         return "pxor\t%0, %0";
2285       else
2286         return "xorps\t%0, %0";
2287     case 6:
2288       if (get_attr_mode (insn) == MODE_V4SF)
2289         return "movaps\t{%1, %0|%0, %1}";
2290       else
2291         return "movss\t{%1, %0|%0, %1}";
2292     case 7:
2293     case 8:
2294       return "movss\t{%1, %0|%0, %1}";
2295
2296     case 9:
2297     case 10:
2298       return "movd\t{%1, %0|%0, %1}";
2299
2300     case 11:
2301       return "movq\t{%1, %0|%0, %1}";
2302
2303     default:
2304       abort();
2305     }
2306 }
2307   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2308    (set (attr "mode")
2309         (cond [(eq_attr "alternative" "3,4,9,10")
2310                  (const_string "SI")
2311                (eq_attr "alternative" "5")
2312                  (if_then_else
2313                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2314                                  (const_int 0))
2315                              (ne (symbol_ref "TARGET_SSE2")
2316                                  (const_int 0)))
2317                         (eq (symbol_ref "optimize_size")
2318                             (const_int 0)))
2319                    (const_string "TI")
2320                    (const_string "V4SF"))
2321                /* For architectures resolving dependencies on
2322                   whole SSE registers use APS move to break dependency
2323                   chains, otherwise use short move to avoid extra work. 
2324
2325                   Do the same for architectures resolving dependencies on
2326                   the parts.  While in DF mode it is better to always handle
2327                   just register parts, the SF mode is different due to lack
2328                   of instructions to load just part of the register.  It is
2329                   better to maintain the whole registers in single format
2330                   to avoid problems on using packed logical operations.  */
2331                (eq_attr "alternative" "6")
2332                  (if_then_else
2333                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2334                             (const_int 0))
2335                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2336                             (const_int 0)))
2337                    (const_string "V4SF")
2338                    (const_string "SF"))
2339                (eq_attr "alternative" "11")
2340                  (const_string "DI")]
2341                (const_string "SF")))])
2342
2343 (define_insn "*swapsf"
2344   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2345         (match_operand:SF 1 "fp_register_operand" "+f"))
2346    (set (match_dup 1)
2347         (match_dup 0))]
2348   "reload_completed || TARGET_80387"
2349 {
2350   if (STACK_TOP_P (operands[0]))
2351     return "fxch\t%1";
2352   else
2353     return "fxch\t%0";
2354 }
2355   [(set_attr "type" "fxch")
2356    (set_attr "mode" "SF")])
2357
2358 (define_expand "movdf"
2359   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2360         (match_operand:DF 1 "general_operand" ""))]
2361   ""
2362   "ix86_expand_move (DFmode, operands); DONE;")
2363
2364 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2365 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2366 ;; On the average, pushdf using integers can be still shorter.  Allow this
2367 ;; pattern for optimize_size too.
2368
2369 (define_insn "*pushdf_nointeger"
2370   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2371         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2372   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2373 {
2374   /* This insn should be already split before reg-stack.  */
2375   abort ();
2376 }
2377   [(set_attr "type" "multi")
2378    (set_attr "mode" "DF,SI,SI,DF")])
2379
2380 (define_insn "*pushdf_integer"
2381   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2382         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2383   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2384 {
2385   /* This insn should be already split before reg-stack.  */
2386   abort ();
2387 }
2388   [(set_attr "type" "multi")
2389    (set_attr "mode" "DF,SI,DF")])
2390
2391 ;; %%% Kill this when call knows how to work this out.
2392 (define_split
2393   [(set (match_operand:DF 0 "push_operand" "")
2394         (match_operand:DF 1 "any_fp_register_operand" ""))]
2395   "!TARGET_64BIT && reload_completed"
2396   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2397    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2398   "")
2399
2400 (define_split
2401   [(set (match_operand:DF 0 "push_operand" "")
2402         (match_operand:DF 1 "any_fp_register_operand" ""))]
2403   "TARGET_64BIT && reload_completed"
2404   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2405    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2406   "")
2407
2408 (define_split
2409   [(set (match_operand:DF 0 "push_operand" "")
2410         (match_operand:DF 1 "general_operand" ""))]
2411   "reload_completed"
2412   [(const_int 0)]
2413   "ix86_split_long_move (operands); DONE;")
2414
2415 ;; Moving is usually shorter when only FP registers are used. This separate
2416 ;; movdf pattern avoids the use of integer registers for FP operations
2417 ;; when optimizing for size.
2418
2419 (define_insn "*movdf_nointeger"
2420   [(set (match_operand:DF 0 "nonimmediate_operand"
2421                         "=f#Y,m  ,f#Y,*r  ,o  ,Y#f*x,Y#f*x,Y#f*x  ,m    ")
2422         (match_operand:DF 1 "general_operand"
2423                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y#f*x,HmY#f*x,Y#f*x"))]
2424   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2425    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2426    && (reload_in_progress || reload_completed
2427        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2428        || GET_CODE (operands[1]) != CONST_DOUBLE
2429        || memory_operand (operands[0], DFmode))" 
2430 {
2431   switch (which_alternative)
2432     {
2433     case 0:
2434       return output_387_reg_move (insn, operands);
2435
2436     case 1:
2437       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2438         return "fstp%z0\t%y0";
2439       else
2440         return "fst%z0\t%y0";
2441
2442     case 2:
2443       return standard_80387_constant_opcode (operands[1]);
2444
2445     case 3:
2446     case 4:
2447       return "#";
2448     case 5:
2449       switch (get_attr_mode (insn))
2450         {
2451         case MODE_V4SF:
2452           return "xorps\t%0, %0";
2453         case MODE_V2DF:
2454           return "xorpd\t%0, %0";
2455         case MODE_TI:
2456           return "pxor\t%0, %0";
2457         default:
2458           abort ();
2459         }
2460     case 6:
2461     case 7:
2462     case 8:
2463       switch (get_attr_mode (insn))
2464         {
2465         case MODE_V4SF:
2466           return "movaps\t{%1, %0|%0, %1}";
2467         case MODE_V2DF:
2468           return "movapd\t{%1, %0|%0, %1}";
2469         case MODE_TI:
2470           return "movdqa\t{%1, %0|%0, %1}";
2471         case MODE_DI:
2472           return "movq\t{%1, %0|%0, %1}";
2473         case MODE_DF:
2474           return "movsd\t{%1, %0|%0, %1}";
2475         case MODE_V1DF:
2476           return "movlpd\t{%1, %0|%0, %1}";
2477         case MODE_V2SF:
2478           return "movlps\t{%1, %0|%0, %1}";
2479         default:
2480           abort ();
2481         }
2482
2483     default:
2484       abort();
2485     }
2486 }
2487   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488    (set (attr "mode")
2489         (cond [(eq_attr "alternative" "0,1,2")
2490                  (const_string "DF")
2491                (eq_attr "alternative" "3,4")
2492                  (const_string "SI")
2493
2494                /* For SSE1, we have many fewer alternatives.  */
2495                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2496                  (cond [(eq_attr "alternative" "5,6")
2497                           (const_string "V4SF")
2498                        ]
2499                    (const_string "V2SF"))
2500
2501                /* xorps is one byte shorter.  */
2502                (eq_attr "alternative" "5")
2503                  (cond [(ne (symbol_ref "optimize_size")
2504                             (const_int 0))
2505                           (const_string "V4SF")
2506                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2507                             (const_int 0))
2508                           (const_string "TI")
2509                        ]
2510                        (const_string "V2DF"))
2511
2512                /* For architectures resolving dependencies on
2513                   whole SSE registers use APD move to break dependency
2514                   chains, otherwise use short move to avoid extra work.
2515
2516                   movaps encodes one byte shorter.  */
2517                (eq_attr "alternative" "6")
2518                  (cond
2519                    [(ne (symbol_ref "optimize_size")
2520                         (const_int 0))
2521                       (const_string "V4SF")
2522                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2523                         (const_int 0))
2524                       (const_string "V2DF")
2525                    ]
2526                    (const_string "DF"))
2527                /* For architectures resolving dependencies on register
2528                   parts we may avoid extra work to zero out upper part
2529                   of register.  */
2530                (eq_attr "alternative" "7")
2531                  (if_then_else
2532                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2533                        (const_int 0))
2534                    (const_string "V1DF")
2535                    (const_string "DF"))
2536               ]
2537               (const_string "DF")))])
2538
2539 (define_insn "*movdf_integer"
2540   [(set (match_operand:DF 0 "nonimmediate_operand"
2541                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2542         (match_operand:DF 1 "general_operand"
2543                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y#rf*x,m     ,Y#rf*x"))]
2544   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2545    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2546    && (reload_in_progress || reload_completed
2547        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2548        || GET_CODE (operands[1]) != CONST_DOUBLE
2549        || memory_operand (operands[0], DFmode))" 
2550 {
2551   switch (which_alternative)
2552     {
2553     case 0:
2554       return output_387_reg_move (insn, operands);
2555
2556     case 1:
2557       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2558         return "fstp%z0\t%y0";
2559       else
2560         return "fst%z0\t%y0";
2561
2562     case 2:
2563       return standard_80387_constant_opcode (operands[1]);
2564
2565     case 3:
2566     case 4:
2567       return "#";
2568
2569     case 5:
2570       switch (get_attr_mode (insn))
2571         {
2572         case MODE_V4SF:
2573           return "xorps\t%0, %0";
2574         case MODE_V2DF:
2575           return "xorpd\t%0, %0";
2576         case MODE_TI:
2577           return "pxor\t%0, %0";
2578         default:
2579           abort ();
2580         }
2581     case 6:
2582     case 7:
2583     case 8:
2584       switch (get_attr_mode (insn))
2585         {
2586         case MODE_V4SF:
2587           return "movaps\t{%1, %0|%0, %1}";
2588         case MODE_V2DF:
2589           return "movapd\t{%1, %0|%0, %1}";
2590         case MODE_TI:
2591           return "movdqa\t{%1, %0|%0, %1}";
2592         case MODE_DI:
2593           return "movq\t{%1, %0|%0, %1}";
2594         case MODE_DF:
2595           return "movsd\t{%1, %0|%0, %1}";
2596         case MODE_V1DF:
2597           return "movlpd\t{%1, %0|%0, %1}";
2598         case MODE_V2SF:
2599           return "movlps\t{%1, %0|%0, %1}";
2600         default:
2601           abort ();
2602         }
2603
2604     default:
2605       abort();
2606     }
2607 }
2608   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2609    (set (attr "mode")
2610         (cond [(eq_attr "alternative" "0,1,2")
2611                  (const_string "DF")
2612                (eq_attr "alternative" "3,4")
2613                  (const_string "SI")
2614
2615                /* For SSE1, we have many fewer alternatives.  */
2616                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2617                  (cond [(eq_attr "alternative" "5,6")
2618                           (const_string "V4SF")
2619                        ]
2620                    (const_string "V2SF"))
2621
2622                /* xorps is one byte shorter.  */
2623                (eq_attr "alternative" "5")
2624                  (cond [(ne (symbol_ref "optimize_size")
2625                             (const_int 0))
2626                           (const_string "V4SF")
2627                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2628                             (const_int 0))
2629                           (const_string "TI")
2630                        ]
2631                        (const_string "V2DF"))
2632
2633                /* For architectures resolving dependencies on
2634                   whole SSE registers use APD move to break dependency
2635                   chains, otherwise use short move to avoid extra work.
2636
2637                   movaps encodes one byte shorter.  */
2638                (eq_attr "alternative" "6")
2639                  (cond
2640                    [(ne (symbol_ref "optimize_size")
2641                         (const_int 0))
2642                       (const_string "V4SF")
2643                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2644                         (const_int 0))
2645                       (const_string "V2DF")
2646                    ]
2647                    (const_string "DF"))
2648                /* For architectures resolving dependencies on register
2649                   parts we may avoid extra work to zero out upper part
2650                   of register.  */
2651                (eq_attr "alternative" "7")
2652                  (if_then_else
2653                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2654                        (const_int 0))
2655                    (const_string "V1DF")
2656                    (const_string "DF"))
2657               ]
2658               (const_string "DF")))])
2659
2660 (define_split
2661   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2662         (match_operand:DF 1 "general_operand" ""))]
2663   "reload_completed
2664    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2665    && ! (ANY_FP_REG_P (operands[0]) || 
2666          (GET_CODE (operands[0]) == SUBREG
2667           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2668    && ! (ANY_FP_REG_P (operands[1]) || 
2669          (GET_CODE (operands[1]) == SUBREG
2670           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2671   [(const_int 0)]
2672   "ix86_split_long_move (operands); DONE;")
2673
2674 (define_insn "*swapdf"
2675   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2676         (match_operand:DF 1 "fp_register_operand" "+f"))
2677    (set (match_dup 1)
2678         (match_dup 0))]
2679   "reload_completed || TARGET_80387"
2680 {
2681   if (STACK_TOP_P (operands[0]))
2682     return "fxch\t%1";
2683   else
2684     return "fxch\t%0";
2685 }
2686   [(set_attr "type" "fxch")
2687    (set_attr "mode" "DF")])
2688
2689 (define_expand "movxf"
2690   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2691         (match_operand:XF 1 "general_operand" ""))]
2692   ""
2693   "ix86_expand_move (XFmode, operands); DONE;")
2694
2695 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references.
2699 ;; (assuming that any given constant is pushed only once, but this ought to be
2700 ;;  handled elsewhere).
2701
2702 (define_insn "*pushxf_nointeger"
2703   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2704         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2705   "optimize_size"
2706 {
2707   /* This insn should be already split before reg-stack.  */
2708   abort ();
2709 }
2710   [(set_attr "type" "multi")
2711    (set_attr "mode" "XF,SI,SI")])
2712
2713 (define_insn "*pushxf_integer"
2714   [(set (match_operand:XF 0 "push_operand" "=<,<")
2715         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2716   "!optimize_size"
2717 {
2718   /* This insn should be already split before reg-stack.  */
2719   abort ();
2720 }
2721   [(set_attr "type" "multi")
2722    (set_attr "mode" "XF,SI")])
2723
2724 (define_split
2725   [(set (match_operand 0 "push_operand" "")
2726         (match_operand 1 "general_operand" ""))]
2727   "reload_completed
2728    && (GET_MODE (operands[0]) == XFmode
2729        || GET_MODE (operands[0]) == DFmode)
2730    && !ANY_FP_REG_P (operands[1])"
2731   [(const_int 0)]
2732   "ix86_split_long_move (operands); DONE;")
2733
2734 (define_split
2735   [(set (match_operand:XF 0 "push_operand" "")
2736         (match_operand:XF 1 "any_fp_register_operand" ""))]
2737   "!TARGET_64BIT"
2738   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2739    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2740   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2741
2742 (define_split
2743   [(set (match_operand:XF 0 "push_operand" "")
2744         (match_operand:XF 1 "any_fp_register_operand" ""))]
2745   "TARGET_64BIT"
2746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2747    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2748   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2749
2750 ;; Do not use integer registers when optimizing for size
2751 (define_insn "*movxf_nointeger"
2752   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2753         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2754   "optimize_size
2755    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756    && (reload_in_progress || reload_completed
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], XFmode))" 
2759 {
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2764
2765     case 1:
2766       /* There is no non-popping store to memory for XFmode.  So if
2767          we need one, follow the store with a load.  */
2768       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769         return "fstp%z0\t%y0\;fld%z0\t%y0";
2770       else
2771         return "fstp%z0\t%y0";
2772
2773     case 2:
2774       return standard_80387_constant_opcode (operands[1]);
2775
2776     case 3: case 4:
2777       return "#";
2778     }
2779   abort();
2780 }
2781   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782    (set_attr "mode" "XF,XF,XF,SI,SI")])
2783
2784 (define_insn "*movxf_integer"
2785   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2786         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2787   "!optimize_size
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && (reload_in_progress || reload_completed
2790        || GET_CODE (operands[1]) != CONST_DOUBLE
2791        || memory_operand (operands[0], XFmode))" 
2792 {
2793   switch (which_alternative)
2794     {
2795     case 0:
2796       return output_387_reg_move (insn, operands);
2797
2798     case 1:
2799       /* There is no non-popping store to memory for XFmode.  So if
2800          we need one, follow the store with a load.  */
2801       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802         return "fstp%z0\t%y0\;fld%z0\t%y0";
2803       else
2804         return "fstp%z0\t%y0";
2805
2806     case 2:
2807       return standard_80387_constant_opcode (operands[1]);
2808
2809     case 3: case 4:
2810       return "#";
2811     }
2812   abort();
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2815    (set_attr "mode" "XF,XF,XF,SI,SI")])
2816
2817 (define_split
2818   [(set (match_operand 0 "nonimmediate_operand" "")
2819         (match_operand 1 "general_operand" ""))]
2820   "reload_completed
2821    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2822    && GET_MODE (operands[0]) == XFmode
2823    && ! (ANY_FP_REG_P (operands[0]) || 
2824          (GET_CODE (operands[0]) == SUBREG
2825           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2826    && ! (ANY_FP_REG_P (operands[1]) || 
2827          (GET_CODE (operands[1]) == SUBREG
2828           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2829   [(const_int 0)]
2830   "ix86_split_long_move (operands); DONE;")
2831
2832 (define_split
2833   [(set (match_operand 0 "register_operand" "")
2834         (match_operand 1 "memory_operand" ""))]
2835   "reload_completed
2836    && GET_CODE (operands[1]) == MEM
2837    && (GET_MODE (operands[0]) == XFmode
2838        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2839    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2840    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2841   [(set (match_dup 0) (match_dup 1))]
2842 {
2843   rtx c = get_pool_constant (XEXP (operands[1], 0));
2844   rtx r = operands[0];
2845
2846   if (GET_CODE (r) == SUBREG)
2847     r = SUBREG_REG (r);
2848
2849   if (SSE_REG_P (r))
2850     {
2851       if (!standard_sse_constant_p (c))
2852         FAIL;
2853     }
2854   else if (FP_REG_P (r))
2855     {
2856       if (!standard_80387_constant_p (c))
2857         FAIL;
2858     }
2859   else if (MMX_REG_P (r))
2860     FAIL;
2861
2862   operands[1] = c;
2863 })
2864
2865 (define_insn "swapxf"
2866   [(set (match_operand:XF 0 "register_operand" "+f")
2867         (match_operand:XF 1 "register_operand" "+f"))
2868    (set (match_dup 1)
2869         (match_dup 0))]
2870   "TARGET_80387"
2871 {
2872   if (STACK_TOP_P (operands[0]))
2873     return "fxch\t%1";
2874   else
2875     return "fxch\t%0";
2876 }
2877   [(set_attr "type" "fxch")
2878    (set_attr "mode" "XF")])
2879
2880 (define_expand "movtf"
2881   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2882         (match_operand:TF 1 "nonimmediate_operand" ""))]
2883   "TARGET_64BIT"
2884 {
2885   ix86_expand_move (TFmode, operands);
2886   DONE;
2887 })
2888
2889 (define_insn "*movtf_internal"
2890   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2891         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2892   "TARGET_64BIT
2893    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2894 {
2895   switch (which_alternative)
2896     {
2897     case 0:
2898     case 1:
2899       return "#";
2900     case 2:
2901       if (get_attr_mode (insn) == MODE_V4SF)
2902         return "xorps\t%0, %0";
2903       else
2904         return "pxor\t%0, %0";
2905     case 3:
2906     case 4:
2907       if (get_attr_mode (insn) == MODE_V4SF)
2908         return "movaps\t{%1, %0|%0, %1}";
2909       else
2910         return "movdqa\t{%1, %0|%0, %1}";
2911     default:
2912       abort ();
2913     }
2914 }
2915   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2916    (set (attr "mode")
2917         (cond [(eq_attr "alternative" "2,3")
2918                  (if_then_else
2919                    (ne (symbol_ref "optimize_size")
2920                        (const_int 0))
2921                    (const_string "V4SF")
2922                    (const_string "TI"))
2923                (eq_attr "alternative" "4")
2924                  (if_then_else
2925                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2926                             (const_int 0))
2927                         (ne (symbol_ref "optimize_size")
2928                             (const_int 0)))
2929                    (const_string "V4SF")
2930                    (const_string "TI"))]
2931                (const_string "DI")))])
2932
2933 (define_split
2934   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2935         (match_operand:TF 1 "general_operand" ""))]
2936   "reload_completed && !SSE_REG_P (operands[0])
2937    && !SSE_REG_P (operands[1])"
2938   [(const_int 0)]
2939   "ix86_split_long_move (operands); DONE;")
2940 \f
2941 ;; Zero extension instructions
2942
2943 (define_expand "zero_extendhisi2"
2944   [(set (match_operand:SI 0 "register_operand" "")
2945      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2946   ""
2947 {
2948   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2949     {
2950       operands[1] = force_reg (HImode, operands[1]);
2951       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2952       DONE;
2953     }
2954 })
2955
2956 (define_insn "zero_extendhisi2_and"
2957   [(set (match_operand:SI 0 "register_operand" "=r")
2958      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2959    (clobber (reg:CC FLAGS_REG))]
2960   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2961   "#"
2962   [(set_attr "type" "alu1")
2963    (set_attr "mode" "SI")])
2964
2965 (define_split
2966   [(set (match_operand:SI 0 "register_operand" "")
2967         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2968    (clobber (reg:CC FLAGS_REG))]
2969   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2970   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2971               (clobber (reg:CC FLAGS_REG))])]
2972   "")
2973
2974 (define_insn "*zero_extendhisi2_movzwl"
2975   [(set (match_operand:SI 0 "register_operand" "=r")
2976      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2977   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2978   "movz{wl|x}\t{%1, %0|%0, %1}"
2979   [(set_attr "type" "imovx")
2980    (set_attr "mode" "SI")])
2981
2982 (define_expand "zero_extendqihi2"
2983   [(parallel
2984     [(set (match_operand:HI 0 "register_operand" "")
2985        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2986      (clobber (reg:CC FLAGS_REG))])]
2987   ""
2988   "")
2989
2990 (define_insn "*zero_extendqihi2_and"
2991   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2992      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2993    (clobber (reg:CC FLAGS_REG))]
2994   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2995   "#"
2996   [(set_attr "type" "alu1")
2997    (set_attr "mode" "HI")])
2998
2999 (define_insn "*zero_extendqihi2_movzbw_and"
3000   [(set (match_operand:HI 0 "register_operand" "=r,r")
3001      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3002    (clobber (reg:CC FLAGS_REG))]
3003   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004   "#"
3005   [(set_attr "type" "imovx,alu1")
3006    (set_attr "mode" "HI")])
3007
3008 (define_insn "*zero_extendqihi2_movzbw"
3009   [(set (match_operand:HI 0 "register_operand" "=r")
3010      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3011   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3012   "movz{bw|x}\t{%1, %0|%0, %1}"
3013   [(set_attr "type" "imovx")
3014    (set_attr "mode" "HI")])
3015
3016 ;; For the movzbw case strip only the clobber
3017 (define_split
3018   [(set (match_operand:HI 0 "register_operand" "")
3019         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "reload_completed 
3022    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3023    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3024   [(set (match_operand:HI 0 "register_operand" "")
3025         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3026
3027 ;; When source and destination does not overlap, clear destination
3028 ;; first and then do the movb
3029 (define_split
3030   [(set (match_operand:HI 0 "register_operand" "")
3031         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3032    (clobber (reg:CC FLAGS_REG))]
3033   "reload_completed
3034    && ANY_QI_REG_P (operands[0])
3035    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3036    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3037   [(set (match_dup 0) (const_int 0))
3038    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3039   "operands[2] = gen_lowpart (QImode, operands[0]);")
3040
3041 ;; Rest is handled by single and.
3042 (define_split
3043   [(set (match_operand:HI 0 "register_operand" "")
3044         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3045    (clobber (reg:CC FLAGS_REG))]
3046   "reload_completed
3047    && true_regnum (operands[0]) == true_regnum (operands[1])"
3048   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3049               (clobber (reg:CC FLAGS_REG))])]
3050   "")
3051
3052 (define_expand "zero_extendqisi2"
3053   [(parallel
3054     [(set (match_operand:SI 0 "register_operand" "")
3055        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3056      (clobber (reg:CC FLAGS_REG))])]
3057   ""
3058   "")
3059
3060 (define_insn "*zero_extendqisi2_and"
3061   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3062      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3063    (clobber (reg:CC FLAGS_REG))]
3064   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3065   "#"
3066   [(set_attr "type" "alu1")
3067    (set_attr "mode" "SI")])
3068
3069 (define_insn "*zero_extendqisi2_movzbw_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r,r")
3071      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3074   "#"
3075   [(set_attr "type" "imovx,alu1")
3076    (set_attr "mode" "SI")])
3077
3078 (define_insn "*zero_extendqisi2_movzbw"
3079   [(set (match_operand:SI 0 "register_operand" "=r")
3080      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3081   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3082   "movz{bl|x}\t{%1, %0|%0, %1}"
3083   [(set_attr "type" "imovx")
3084    (set_attr "mode" "SI")])
3085
3086 ;; For the movzbl case strip only the clobber
3087 (define_split
3088   [(set (match_operand:SI 0 "register_operand" "")
3089         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "reload_completed 
3092    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3093    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3094   [(set (match_dup 0)
3095         (zero_extend:SI (match_dup 1)))])
3096
3097 ;; When source and destination does not overlap, clear destination
3098 ;; first and then do the movb
3099 (define_split
3100   [(set (match_operand:SI 0 "register_operand" "")
3101         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3102    (clobber (reg:CC FLAGS_REG))]
3103   "reload_completed
3104    && ANY_QI_REG_P (operands[0])
3105    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3106    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3107    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3108   [(set (match_dup 0) (const_int 0))
3109    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3110   "operands[2] = gen_lowpart (QImode, operands[0]);")
3111
3112 ;; Rest is handled by single and.
3113 (define_split
3114   [(set (match_operand:SI 0 "register_operand" "")
3115         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3116    (clobber (reg:CC FLAGS_REG))]
3117   "reload_completed
3118    && true_regnum (operands[0]) == true_regnum (operands[1])"
3119   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3120               (clobber (reg:CC FLAGS_REG))])]
3121   "")
3122
3123 ;; %%% Kill me once multi-word ops are sane.
3124 (define_expand "zero_extendsidi2"
3125   [(set (match_operand:DI 0 "register_operand" "=r")
3126      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3127   ""
3128   "if (!TARGET_64BIT)
3129      {
3130        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3131        DONE;
3132      }
3133   ")
3134
3135 (define_insn "zero_extendsidi2_32"
3136   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3137         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3138    (clobber (reg:CC FLAGS_REG))]
3139   "!TARGET_64BIT"
3140   "@
3141    #
3142    #
3143    #
3144    movd\t{%1, %0|%0, %1}
3145    movd\t{%1, %0|%0, %1}"
3146   [(set_attr "mode" "SI,SI,SI,DI,TI")
3147    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3148
3149 (define_insn "zero_extendsidi2_rex64"
3150   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3151      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3152   "TARGET_64BIT"
3153   "@
3154    mov\t{%k1, %k0|%k0, %k1}
3155    #
3156    movd\t{%1, %0|%0, %1}
3157    movd\t{%1, %0|%0, %1}"
3158   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3159    (set_attr "mode" "SI,DI,SI,SI")])
3160
3161 (define_split
3162   [(set (match_operand:DI 0 "memory_operand" "")
3163      (zero_extend:DI (match_dup 0)))]
3164   "TARGET_64BIT"
3165   [(set (match_dup 4) (const_int 0))]
3166   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3167
3168 (define_split 
3169   [(set (match_operand:DI 0 "register_operand" "")
3170         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "!TARGET_64BIT && reload_completed
3173    && true_regnum (operands[0]) == true_regnum (operands[1])"
3174   [(set (match_dup 4) (const_int 0))]
3175   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3176
3177 (define_split 
3178   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3179         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3180    (clobber (reg:CC FLAGS_REG))]
3181   "!TARGET_64BIT && reload_completed
3182    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3183   [(set (match_dup 3) (match_dup 1))
3184    (set (match_dup 4) (const_int 0))]
3185   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3186
3187 (define_insn "zero_extendhidi2"
3188   [(set (match_operand:DI 0 "register_operand" "=r,r")
3189      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3190   "TARGET_64BIT"
3191   "@
3192    movz{wl|x}\t{%1, %k0|%k0, %1}
3193    movz{wq|x}\t{%1, %0|%0, %1}"
3194   [(set_attr "type" "imovx")
3195    (set_attr "mode" "SI,DI")])
3196
3197 (define_insn "zero_extendqidi2"
3198   [(set (match_operand:DI 0 "register_operand" "=r,r")
3199      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3200   "TARGET_64BIT"
3201   "@
3202    movz{bl|x}\t{%1, %k0|%k0, %1}
3203    movz{bq|x}\t{%1, %0|%0, %1}"
3204   [(set_attr "type" "imovx")
3205    (set_attr "mode" "SI,DI")])
3206 \f
3207 ;; Sign extension instructions
3208
3209 (define_expand "extendsidi2"
3210   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3211                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3212               (clobber (reg:CC FLAGS_REG))
3213               (clobber (match_scratch:SI 2 ""))])]
3214   ""
3215 {
3216   if (TARGET_64BIT)
3217     {
3218       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3219       DONE;
3220     }
3221 })
3222
3223 (define_insn "*extendsidi2_1"
3224   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3225         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3226    (clobber (reg:CC FLAGS_REG))
3227    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3228   "!TARGET_64BIT"
3229   "#")
3230
3231 (define_insn "extendsidi2_rex64"
3232   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3233         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3234   "TARGET_64BIT"
3235   "@
3236    {cltq|cdqe}
3237    movs{lq|x}\t{%1,%0|%0, %1}"
3238   [(set_attr "type" "imovx")
3239    (set_attr "mode" "DI")
3240    (set_attr "prefix_0f" "0")
3241    (set_attr "modrm" "0,1")])
3242
3243 (define_insn "extendhidi2"
3244   [(set (match_operand:DI 0 "register_operand" "=r")
3245         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3246   "TARGET_64BIT"
3247   "movs{wq|x}\t{%1,%0|%0, %1}"
3248   [(set_attr "type" "imovx")
3249    (set_attr "mode" "DI")])
3250
3251 (define_insn "extendqidi2"
3252   [(set (match_operand:DI 0 "register_operand" "=r")
3253         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3254   "TARGET_64BIT"
3255   "movs{bq|x}\t{%1,%0|%0, %1}"
3256    [(set_attr "type" "imovx")
3257     (set_attr "mode" "DI")])
3258
3259 ;; Extend to memory case when source register does die.
3260 (define_split 
3261   [(set (match_operand:DI 0 "memory_operand" "")
3262         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263    (clobber (reg:CC FLAGS_REG))
3264    (clobber (match_operand:SI 2 "register_operand" ""))]
3265   "(reload_completed
3266     && dead_or_set_p (insn, operands[1])
3267     && !reg_mentioned_p (operands[1], operands[0]))"
3268   [(set (match_dup 3) (match_dup 1))
3269    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3270               (clobber (reg:CC FLAGS_REG))])
3271    (set (match_dup 4) (match_dup 1))]
3272   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3273
3274 ;; Extend to memory case when source register does not die.
3275 (define_split 
3276   [(set (match_operand:DI 0 "memory_operand" "")
3277         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3278    (clobber (reg:CC FLAGS_REG))
3279    (clobber (match_operand:SI 2 "register_operand" ""))]
3280   "reload_completed"
3281   [(const_int 0)]
3282 {
3283   split_di (&operands[0], 1, &operands[3], &operands[4]);
3284
3285   emit_move_insn (operands[3], operands[1]);
3286
3287   /* Generate a cltd if possible and doing so it profitable.  */
3288   if (true_regnum (operands[1]) == 0
3289       && true_regnum (operands[2]) == 1
3290       && (optimize_size || TARGET_USE_CLTD))
3291     {
3292       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3293     }
3294   else
3295     {
3296       emit_move_insn (operands[2], operands[1]);
3297       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3298     }
3299   emit_move_insn (operands[4], operands[2]);
3300   DONE;
3301 })
3302
3303 ;; Extend to register case.  Optimize case where source and destination
3304 ;; registers match and cases where we can use cltd.
3305 (define_split 
3306   [(set (match_operand:DI 0 "register_operand" "")
3307         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3308    (clobber (reg:CC FLAGS_REG))
3309    (clobber (match_scratch:SI 2 ""))]
3310   "reload_completed"
3311   [(const_int 0)]
3312 {
3313   split_di (&operands[0], 1, &operands[3], &operands[4]);
3314
3315   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3316     emit_move_insn (operands[3], operands[1]);
3317
3318   /* Generate a cltd if possible and doing so it profitable.  */
3319   if (true_regnum (operands[3]) == 0
3320       && (optimize_size || TARGET_USE_CLTD))
3321     {
3322       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3323       DONE;
3324     }
3325
3326   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3327     emit_move_insn (operands[4], operands[1]);
3328
3329   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3330   DONE;
3331 })
3332
3333 (define_insn "extendhisi2"
3334   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3335         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3336   ""
3337 {
3338   switch (get_attr_prefix_0f (insn))
3339     {
3340     case 0:
3341       return "{cwtl|cwde}";
3342     default:
3343       return "movs{wl|x}\t{%1,%0|%0, %1}";
3344     }
3345 }
3346   [(set_attr "type" "imovx")
3347    (set_attr "mode" "SI")
3348    (set (attr "prefix_0f")
3349      ;; movsx is short decodable while cwtl is vector decoded.
3350      (if_then_else (and (eq_attr "cpu" "!k6")
3351                         (eq_attr "alternative" "0"))
3352         (const_string "0")
3353         (const_string "1")))
3354    (set (attr "modrm")
3355      (if_then_else (eq_attr "prefix_0f" "0")
3356         (const_string "0")
3357         (const_string "1")))])
3358
3359 (define_insn "*extendhisi2_zext"
3360   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3361         (zero_extend:DI
3362           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3363   "TARGET_64BIT"
3364 {
3365   switch (get_attr_prefix_0f (insn))
3366     {
3367     case 0:
3368       return "{cwtl|cwde}";
3369     default:
3370       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3371     }
3372 }
3373   [(set_attr "type" "imovx")
3374    (set_attr "mode" "SI")
3375    (set (attr "prefix_0f")
3376      ;; movsx is short decodable while cwtl is vector decoded.
3377      (if_then_else (and (eq_attr "cpu" "!k6")
3378                         (eq_attr "alternative" "0"))
3379         (const_string "0")
3380         (const_string "1")))
3381    (set (attr "modrm")
3382      (if_then_else (eq_attr "prefix_0f" "0")
3383         (const_string "0")
3384         (const_string "1")))])
3385
3386 (define_insn "extendqihi2"
3387   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3388         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3389   ""
3390 {
3391   switch (get_attr_prefix_0f (insn))
3392     {
3393     case 0:
3394       return "{cbtw|cbw}";
3395     default:
3396       return "movs{bw|x}\t{%1,%0|%0, %1}";
3397     }
3398 }
3399   [(set_attr "type" "imovx")
3400    (set_attr "mode" "HI")
3401    (set (attr "prefix_0f")
3402      ;; movsx is short decodable while cwtl is vector decoded.
3403      (if_then_else (and (eq_attr "cpu" "!k6")
3404                         (eq_attr "alternative" "0"))
3405         (const_string "0")
3406         (const_string "1")))
3407    (set (attr "modrm")
3408      (if_then_else (eq_attr "prefix_0f" "0")
3409         (const_string "0")
3410         (const_string "1")))])
3411
3412 (define_insn "extendqisi2"
3413   [(set (match_operand:SI 0 "register_operand" "=r")
3414         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3415   ""
3416   "movs{bl|x}\t{%1,%0|%0, %1}"
3417    [(set_attr "type" "imovx")
3418     (set_attr "mode" "SI")])
3419
3420 (define_insn "*extendqisi2_zext"
3421   [(set (match_operand:DI 0 "register_operand" "=r")
3422         (zero_extend:DI
3423           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3424   "TARGET_64BIT"
3425   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3426    [(set_attr "type" "imovx")
3427     (set_attr "mode" "SI")])
3428 \f
3429 ;; Conversions between float and double.
3430
3431 ;; These are all no-ops in the model used for the 80387.  So just
3432 ;; emit moves.
3433
3434 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3435 (define_insn "*dummy_extendsfdf2"
3436   [(set (match_operand:DF 0 "push_operand" "=<")
3437         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3438   "0"
3439   "#")
3440
3441 (define_split
3442   [(set (match_operand:DF 0 "push_operand" "")
3443         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3444   "!TARGET_64BIT"
3445   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3446    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3447
3448 (define_split
3449   [(set (match_operand:DF 0 "push_operand" "")
3450         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3451   "TARGET_64BIT"
3452   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3453    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3454
3455 (define_insn "*dummy_extendsfxf2"
3456   [(set (match_operand:XF 0 "push_operand" "=<")
3457         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3458   "0"
3459   "#")
3460
3461 (define_split
3462   [(set (match_operand:XF 0 "push_operand" "")
3463         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3464   ""
3465   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3466    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3467   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3468
3469 (define_split
3470   [(set (match_operand:XF 0 "push_operand" "")
3471         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3472   "TARGET_64BIT"
3473   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3474    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3475   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3476
3477 (define_split
3478   [(set (match_operand:XF 0 "push_operand" "")
3479         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3480   ""
3481   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3482    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3483   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3484
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3488   "TARGET_64BIT"
3489   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3490    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493 (define_expand "extendsfdf2"
3494   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3495         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3496   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3497 {
3498   /* ??? Needed for compress_float_constant since all fp constants
3499      are LEGITIMATE_CONSTANT_P.  */
3500   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3501     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3502   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3503     operands[1] = force_reg (SFmode, operands[1]);
3504 })
3505
3506 (define_insn "*extendsfdf2_mixed"
3507   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3508         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3509   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3510    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3511 {
3512   switch (which_alternative)
3513     {
3514     case 0:
3515       return output_387_reg_move (insn, operands);
3516
3517     case 1:
3518       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3519         return "fstp%z0\t%y0";
3520       else
3521         return "fst%z0\t%y0";
3522
3523     case 2:
3524       return "cvtss2sd\t{%1, %0|%0, %1}";
3525
3526     default:
3527       abort ();
3528     }
3529 }
3530   [(set_attr "type" "fmov,fmov,ssecvt")
3531    (set_attr "mode" "SF,XF,DF")])
3532
3533 (define_insn "*extendsfdf2_sse"
3534   [(set (match_operand:DF 0 "register_operand" "=Y")
3535         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3536   "TARGET_SSE2 && TARGET_SSE_MATH
3537    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3538   "cvtss2sd\t{%1, %0|%0, %1}"
3539   [(set_attr "type" "ssecvt")
3540    (set_attr "mode" "DF")])
3541
3542 (define_insn "*extendsfdf2_i387"
3543   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3544         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3545   "TARGET_80387
3546    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3547 {
3548   switch (which_alternative)
3549     {
3550     case 0:
3551       return output_387_reg_move (insn, operands);
3552
3553     case 1:
3554       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3555         return "fstp%z0\t%y0";
3556       else
3557         return "fst%z0\t%y0";
3558
3559     default:
3560       abort ();
3561     }
3562 }
3563   [(set_attr "type" "fmov")
3564    (set_attr "mode" "SF,XF")])
3565
3566 (define_expand "extendsfxf2"
3567   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3568         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569   "TARGET_80387"
3570 {
3571   /* ??? Needed for compress_float_constant since all fp constants
3572      are LEGITIMATE_CONSTANT_P.  */
3573   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3574     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3575   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3576     operands[1] = force_reg (SFmode, operands[1]);
3577 })
3578
3579 (define_insn "*extendsfxf2_i387"
3580   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3581         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3582   "TARGET_80387
3583    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3584 {
3585   switch (which_alternative)
3586     {
3587     case 0:
3588       return output_387_reg_move (insn, operands);
3589
3590     case 1:
3591       /* There is no non-popping store to memory for XFmode.  So if
3592          we need one, follow the store with a load.  */
3593       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3594         return "fstp%z0\t%y0";
3595       else
3596         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3597
3598     default:
3599       abort ();
3600     }
3601 }
3602   [(set_attr "type" "fmov")
3603    (set_attr "mode" "SF,XF")])
3604
3605 (define_expand "extenddfxf2"
3606   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3607         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3608   "TARGET_80387"
3609 {
3610   /* ??? Needed for compress_float_constant since all fp constants
3611      are LEGITIMATE_CONSTANT_P.  */
3612   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3613     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3614   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3615     operands[1] = force_reg (DFmode, operands[1]);
3616 })
3617
3618 (define_insn "*extenddfxf2_i387"
3619   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3620         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3621   "TARGET_80387
3622    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3623 {
3624   switch (which_alternative)
3625     {
3626     case 0:
3627       return output_387_reg_move (insn, operands);
3628
3629     case 1:
3630       /* There is no non-popping store to memory for XFmode.  So if
3631          we need one, follow the store with a load.  */
3632       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3633         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3634       else
3635         return "fstp%z0\t%y0";
3636
3637     default:
3638       abort ();
3639     }
3640 }
3641   [(set_attr "type" "fmov")
3642    (set_attr "mode" "DF,XF")])
3643
3644 ;; %%% This seems bad bad news.
3645 ;; This cannot output into an f-reg because there is no way to be sure
3646 ;; of truncating in that case.  Otherwise this is just like a simple move
3647 ;; insn.  So we pretend we can output to a reg in order to get better
3648 ;; register preferencing, but we really use a stack slot.
3649
3650 ;; Conversion from DFmode to SFmode.
3651
3652 (define_expand "truncdfsf2"
3653   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3654         (float_truncate:SF
3655           (match_operand:DF 1 "nonimmediate_operand" "")))]
3656   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3657 {
3658   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3659     operands[1] = force_reg (DFmode, operands[1]);
3660
3661   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3662     ;
3663   else if (flag_unsafe_math_optimizations)
3664     ;
3665   else
3666     {
3667       rtx temp = assign_386_stack_local (SFmode, 0);
3668       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3669       DONE;
3670     }
3671 })
3672
3673 (define_expand "truncdfsf2_with_temp"
3674   [(parallel [(set (match_operand:SF 0 "" "")
3675                    (float_truncate:SF (match_operand:DF 1 "" "")))
3676               (clobber (match_operand:SF 2 "" ""))])]
3677   "")
3678
3679 (define_insn "*truncdfsf_fast_mixed"
3680   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3681         (float_truncate:SF
3682           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3683   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3684 {
3685   switch (which_alternative)
3686     {
3687     case 0:
3688       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689         return "fstp%z0\t%y0";
3690       else
3691         return "fst%z0\t%y0";
3692     case 1:
3693       return output_387_reg_move (insn, operands);
3694     case 2:
3695       return "cvtsd2ss\t{%1, %0|%0, %1}";
3696     default:
3697       abort ();
3698     }
3699 }
3700   [(set_attr "type" "fmov,fmov,ssecvt")
3701    (set_attr "mode" "SF")])
3702
3703 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3704 ;; because nothing we do here is unsafe.
3705 (define_insn "*truncdfsf_fast_sse"
3706   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3707         (float_truncate:SF
3708           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3709   "TARGET_SSE2 && TARGET_SSE_MATH"
3710   "cvtsd2ss\t{%1, %0|%0, %1}"
3711   [(set_attr "type" "ssecvt")
3712    (set_attr "mode" "SF")])
3713
3714 (define_insn "*truncdfsf_fast_i387"
3715   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3716         (float_truncate:SF
3717           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3718   "TARGET_80387 && flag_unsafe_math_optimizations"
3719   "* return output_387_reg_move (insn, operands);"
3720   [(set_attr "type" "fmov")
3721    (set_attr "mode" "SF")])
3722
3723 (define_insn "*truncdfsf_mixed"
3724   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3727    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3728   "TARGET_MIX_SSE_I387"
3729 {
3730   switch (which_alternative)
3731     {
3732     case 0:
3733       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3734         return "fstp%z0\t%y0";
3735       else
3736         return "fst%z0\t%y0";
3737     case 1:
3738       return "#";
3739     case 2:
3740       return "cvtsd2ss\t{%1, %0|%0, %1}";
3741     default:
3742       abort ();
3743     }
3744 }
3745   [(set_attr "type" "fmov,multi,ssecvt")
3746    (set_attr "mode" "SF")])
3747
3748 (define_insn "*truncdfsf_i387"
3749   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3750         (float_truncate:SF
3751           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3752    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3753   "TARGET_80387"
3754 {
3755   switch (which_alternative)
3756     {
3757     case 0:
3758       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759         return "fstp%z0\t%y0";
3760       else
3761         return "fst%z0\t%y0";
3762     case 1:
3763       return "#";
3764     default:
3765       abort ();
3766     }
3767 }
3768   [(set_attr "type" "fmov,multi")
3769    (set_attr "mode" "SF")])
3770
3771 (define_split
3772   [(set (match_operand:SF 0 "register_operand" "")
3773         (float_truncate:SF
3774          (match_operand:DF 1 "fp_register_operand" "")))
3775    (clobber (match_operand 2 "" ""))]
3776   "reload_completed"
3777   [(set (match_dup 2) (match_dup 1))
3778    (set (match_dup 0) (match_dup 2))]
3779 {
3780   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3781 })
3782
3783 ;; Conversion from XFmode to SFmode.
3784
3785 (define_expand "truncxfsf2"
3786   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3787                    (float_truncate:SF
3788                     (match_operand:XF 1 "register_operand" "")))
3789               (clobber (match_dup 2))])]
3790   "TARGET_80387"
3791 {
3792   if (flag_unsafe_math_optimizations)
3793     {
3794       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3795       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3796       if (reg != operands[0])
3797         emit_move_insn (operands[0], reg);
3798       DONE;
3799     }
3800   else
3801     operands[2] = assign_386_stack_local (SFmode, 0);
3802 })
3803
3804 (define_insn "*truncxfsf2_mixed"
3805   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3806         (float_truncate:SF
3807          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3808    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3809   "TARGET_MIX_SSE_I387"
3810 {
3811   switch (which_alternative)
3812     {
3813     case 0:
3814       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3815         return "fstp%z0\t%y0";
3816       else
3817         return "fst%z0\t%y0";
3818     default:
3819       abort();
3820     }
3821 }
3822   [(set_attr "type" "fmov,multi,multi,multi")
3823    (set_attr "mode" "SF")])
3824
3825 (define_insn "truncxfsf2_i387_noop"
3826   [(set (match_operand:SF 0 "register_operand" "=f")
3827         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3828   "TARGET_80387 && flag_unsafe_math_optimizations"
3829 {
3830   return output_387_reg_move (insn, operands);
3831 }
3832   [(set_attr "type" "fmov")
3833    (set_attr "mode" "SF")])
3834
3835 (define_insn "*truncxfsf2_i387"
3836   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3837         (float_truncate:SF
3838          (match_operand:XF 1 "register_operand" "f,f,f")))
3839    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3840   "TARGET_80387"
3841 {
3842   switch (which_alternative)
3843     {
3844     case 0:
3845       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3846         return "fstp%z0\t%y0";
3847       else
3848         return "fst%z0\t%y0";
3849     default:
3850       abort ();
3851     }
3852 }
3853   [(set_attr "type" "fmov,multi,multi")
3854    (set_attr "mode" "SF")])
3855
3856 (define_insn "*truncxfsf2_i387_1"
3857   [(set (match_operand:SF 0 "memory_operand" "=m")
3858         (float_truncate:SF
3859          (match_operand:XF 1 "register_operand" "f")))]
3860   "TARGET_80387"
3861 {
3862   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3863     return "fstp%z0\t%y0";
3864   else
3865     return "fst%z0\t%y0";
3866 }
3867   [(set_attr "type" "fmov")
3868    (set_attr "mode" "SF")])
3869
3870 (define_split
3871   [(set (match_operand:SF 0 "register_operand" "")
3872         (float_truncate:SF
3873          (match_operand:XF 1 "register_operand" "")))
3874    (clobber (match_operand:SF 2 "memory_operand" ""))]
3875   "TARGET_80387 && reload_completed"
3876   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3877    (set (match_dup 0) (match_dup 2))]
3878   "")
3879
3880 (define_split
3881   [(set (match_operand:SF 0 "memory_operand" "")
3882         (float_truncate:SF
3883          (match_operand:XF 1 "register_operand" "")))
3884    (clobber (match_operand:SF 2 "memory_operand" ""))]
3885   "TARGET_80387"
3886   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3887   "")
3888
3889 ;; Conversion from XFmode to DFmode.
3890
3891 (define_expand "truncxfdf2"
3892   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3893                    (float_truncate:DF
3894                     (match_operand:XF 1 "register_operand" "")))
3895               (clobber (match_dup 2))])]
3896   "TARGET_80387"
3897 {
3898   if (flag_unsafe_math_optimizations)
3899     {
3900       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3901       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3902       if (reg != operands[0])
3903         emit_move_insn (operands[0], reg);
3904       DONE;
3905     }
3906   else
3907     operands[2] = assign_386_stack_local (DFmode, 0);
3908 })
3909
3910 (define_insn "*truncxfdf2_mixed"
3911   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3912         (float_truncate:DF
3913          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3914    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3915   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3916 {
3917   switch (which_alternative)
3918     {
3919     case 0:
3920       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0";
3922       else
3923         return "fst%z0\t%y0";
3924     default:
3925       abort();
3926     }
3927   abort ();
3928 }
3929   [(set_attr "type" "fmov,multi,multi,multi")
3930    (set_attr "mode" "DF")])
3931
3932 (define_insn "truncxfdf2_i387_noop"
3933   [(set (match_operand:DF 0 "register_operand" "=f")
3934         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3935   "TARGET_80387 && flag_unsafe_math_optimizations"
3936 {
3937   return output_387_reg_move (insn, operands);
3938 }
3939   [(set_attr "type" "fmov")
3940    (set_attr "mode" "DF")])
3941
3942 (define_insn "*truncxfdf2_i387"
3943   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3944         (float_truncate:DF
3945          (match_operand:XF 1 "register_operand" "f,f,f")))
3946    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3947   "TARGET_80387"
3948 {
3949   switch (which_alternative)
3950     {
3951     case 0:
3952       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3953         return "fstp%z0\t%y0";
3954       else
3955         return "fst%z0\t%y0";
3956     default:
3957       abort ();
3958     }
3959 }
3960   [(set_attr "type" "fmov,multi,multi")
3961    (set_attr "mode" "DF")])
3962
3963 (define_insn "*truncxfdf2_i387_1"
3964   [(set (match_operand:DF 0 "memory_operand" "=m")
3965         (float_truncate:DF
3966           (match_operand:XF 1 "register_operand" "f")))]
3967   "TARGET_80387"
3968 {
3969   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3970     return "fstp%z0\t%y0";
3971   else
3972     return "fst%z0\t%y0";
3973 }
3974   [(set_attr "type" "fmov")
3975    (set_attr "mode" "DF")])
3976
3977 (define_split
3978   [(set (match_operand:DF 0 "register_operand" "")
3979         (float_truncate:DF
3980          (match_operand:XF 1 "register_operand" "")))
3981    (clobber (match_operand:DF 2 "memory_operand" ""))]
3982   "TARGET_80387 && reload_completed"
3983   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3984    (set (match_dup 0) (match_dup 2))]
3985   "")
3986
3987 (define_split
3988   [(set (match_operand:DF 0 "memory_operand" "")
3989         (float_truncate:DF
3990          (match_operand:XF 1 "register_operand" "")))
3991    (clobber (match_operand:DF 2 "memory_operand" ""))]
3992   "TARGET_80387"
3993   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3994   "")
3995 \f
3996 ;; %%% Break up all these bad boys.
3997
3998 ;; Signed conversion to DImode.
3999
4000 (define_expand "fix_truncxfdi2"
4001   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4002                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4003               (clobber (reg:CC FLAGS_REG))])]
4004   "TARGET_80387"
4005   "")
4006
4007 (define_expand "fix_truncdfdi2"
4008   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4009                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4010               (clobber (reg:CC FLAGS_REG))])]
4011   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4012 {
4013   if (TARGET_64BIT && TARGET_SSE2)
4014    {
4015      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4016      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4017      if (out != operands[0])
4018         emit_move_insn (operands[0], out);
4019      DONE;
4020    }
4021 })
4022
4023 (define_expand "fix_truncsfdi2"
4024   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4025                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4026               (clobber (reg:CC FLAGS_REG))])] 
4027   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4028 {
4029   if (TARGET_64BIT && TARGET_SSE)
4030    {
4031      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4032      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4033      if (out != operands[0])
4034         emit_move_insn (operands[0], out);
4035      DONE;
4036    }
4037 })
4038
4039 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4040 ;; of the machinery.
4041 (define_insn_and_split "*fix_truncdi_i387"
4042   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4043         (fix:DI (match_operand 1 "register_operand" "f,f")))
4044    (clobber (reg:CC FLAGS_REG))]
4045   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4046    && !reload_completed && !reload_in_progress
4047    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4048   "#"
4049   "&& 1"
4050   [(const_int 0)]
4051 {
4052   ix86_optimize_mode_switching = 1;
4053   operands[2] = assign_386_stack_local (HImode, 1);
4054   operands[3] = assign_386_stack_local (HImode, 2);
4055   if (memory_operand (operands[0], VOIDmode))
4056     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4057                                        operands[2], operands[3]));
4058   else
4059     {
4060       operands[4] = assign_386_stack_local (DImode, 0);
4061       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4062                                            operands[2], operands[3],
4063                                            operands[4]));
4064     }
4065   DONE;
4066 }
4067   [(set_attr "type" "fistp")
4068    (set_attr "i387_cw" "trunc")
4069    (set_attr "mode" "DI")])
4070
4071 (define_insn "fix_truncdi_nomemory"
4072   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4073         (fix:DI (match_operand 1 "register_operand" "f,f")))
4074    (use (match_operand:HI 2 "memory_operand" "m,m"))
4075    (use (match_operand:HI 3 "memory_operand" "m,m"))
4076    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4077    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4078   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4079    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4080   "#"
4081   [(set_attr "type" "fistp")
4082    (set_attr "i387_cw" "trunc")
4083    (set_attr "mode" "DI")])
4084
4085 (define_insn "fix_truncdi_memory"
4086   [(set (match_operand:DI 0 "memory_operand" "=m")
4087         (fix:DI (match_operand 1 "register_operand" "f")))
4088    (use (match_operand:HI 2 "memory_operand" "m"))
4089    (use (match_operand:HI 3 "memory_operand" "m"))
4090    (clobber (match_scratch:DF 4 "=&1f"))]
4091   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4092    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4093   "* return output_fix_trunc (insn, operands);"
4094   [(set_attr "type" "fistp")
4095    (set_attr "i387_cw" "trunc")
4096    (set_attr "mode" "DI")])
4097
4098 (define_split 
4099   [(set (match_operand:DI 0 "register_operand" "")
4100         (fix:DI (match_operand 1 "register_operand" "")))
4101    (use (match_operand:HI 2 "memory_operand" ""))
4102    (use (match_operand:HI 3 "memory_operand" ""))
4103    (clobber (match_operand:DI 4 "memory_operand" ""))
4104    (clobber (match_scratch 5 ""))]
4105   "reload_completed"
4106   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4107               (use (match_dup 2))
4108               (use (match_dup 3))
4109               (clobber (match_dup 5))])
4110    (set (match_dup 0) (match_dup 4))]
4111   "")
4112
4113 (define_split 
4114   [(set (match_operand:DI 0 "memory_operand" "")
4115         (fix:DI (match_operand 1 "register_operand" "")))
4116    (use (match_operand:HI 2 "memory_operand" ""))
4117    (use (match_operand:HI 3 "memory_operand" ""))
4118    (clobber (match_operand:DI 4 "memory_operand" ""))
4119    (clobber (match_scratch 5 ""))]
4120   "reload_completed"
4121   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4122               (use (match_dup 2))
4123               (use (match_dup 3))
4124               (clobber (match_dup 5))])]
4125   "")
4126
4127 ;; When SSE available, it is always faster to use it!
4128 (define_insn "fix_truncsfdi_sse"
4129   [(set (match_operand:DI 0 "register_operand" "=r,r")
4130         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4131   "TARGET_64BIT && TARGET_SSE"
4132   "cvttss2si{q}\t{%1, %0|%0, %1}"
4133   [(set_attr "type" "sseicvt")
4134    (set_attr "mode" "SF")
4135    (set_attr "athlon_decode" "double,vector")])
4136
4137 ;; Avoid vector decoded form of the instruction.
4138 (define_peephole2
4139   [(match_scratch:SF 2 "x")
4140    (set (match_operand:DI 0 "register_operand" "")
4141         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4142   "TARGET_K8 && !optimize_size"
4143   [(set (match_dup 2) (match_dup 1))
4144    (set (match_dup 0) (fix:DI (match_dup 2)))]
4145   "")
4146
4147 (define_insn "fix_truncdfdi_sse"
4148   [(set (match_operand:DI 0 "register_operand" "=r,r")
4149         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4150   "TARGET_64BIT && TARGET_SSE2"
4151   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4152   [(set_attr "type" "sseicvt,sseicvt")
4153    (set_attr "mode" "DF")
4154    (set_attr "athlon_decode" "double,vector")])
4155
4156 ;; Avoid vector decoded form of the instruction.
4157 (define_peephole2
4158   [(match_scratch:DF 2 "Y")
4159    (set (match_operand:DI 0 "register_operand" "")
4160         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4161   "TARGET_K8 && !optimize_size"
4162   [(set (match_dup 2) (match_dup 1))
4163    (set (match_dup 0) (fix:DI (match_dup 2)))]
4164   "")
4165
4166 ;; Signed conversion to SImode.
4167
4168 (define_expand "fix_truncxfsi2"
4169   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4170                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4171               (clobber (reg:CC FLAGS_REG))])]
4172   "TARGET_80387"
4173   "")
4174
4175 (define_expand "fix_truncdfsi2"
4176   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4177                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4178               (clobber (reg:CC FLAGS_REG))])]
4179   "TARGET_80387 || TARGET_SSE2"
4180 {
4181   if (TARGET_SSE2)
4182    {
4183      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4184      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4185      if (out != operands[0])
4186         emit_move_insn (operands[0], out);
4187      DONE;
4188    }
4189 })
4190
4191 (define_expand "fix_truncsfsi2"
4192   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4194               (clobber (reg:CC FLAGS_REG))])] 
4195   "TARGET_80387 || TARGET_SSE"
4196 {
4197   if (TARGET_SSE)
4198    {
4199      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4200      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4201      if (out != operands[0])
4202         emit_move_insn (operands[0], out);
4203      DONE;
4204    }
4205 })
4206
4207 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4208 ;; of the machinery.
4209 (define_insn_and_split "*fix_truncsi_i387"
4210   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4211         (fix:SI (match_operand 1 "register_operand" "f,f")))
4212    (clobber (reg:CC FLAGS_REG))]
4213   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4214    && !reload_completed && !reload_in_progress
4215    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4216   "#"
4217   "&& 1"
4218   [(const_int 0)]
4219 {
4220   ix86_optimize_mode_switching = 1;
4221   operands[2] = assign_386_stack_local (HImode, 1);
4222   operands[3] = assign_386_stack_local (HImode, 2);
4223   if (memory_operand (operands[0], VOIDmode))
4224     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4225                                        operands[2], operands[3]));
4226   else
4227     {
4228       operands[4] = assign_386_stack_local (SImode, 0);
4229       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4230                                            operands[2], operands[3],
4231                                            operands[4]));
4232     }
4233   DONE;
4234 }
4235   [(set_attr "type" "fistp")
4236    (set_attr "i387_cw" "trunc")
4237    (set_attr "mode" "SI")])
4238
4239 (define_insn "fix_truncsi_nomemory"
4240   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4241         (fix:SI (match_operand 1 "register_operand" "f,f")))
4242    (use (match_operand:HI 2 "memory_operand" "m,m"))
4243    (use (match_operand:HI 3 "memory_operand" "m,m"))
4244    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4245   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4246    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4247   "#"
4248   [(set_attr "type" "fistp")
4249    (set_attr "i387_cw" "trunc")
4250    (set_attr "mode" "SI")])
4251
4252 (define_insn "fix_truncsi_memory"
4253   [(set (match_operand:SI 0 "memory_operand" "=m")
4254         (fix:SI (match_operand 1 "register_operand" "f")))
4255    (use (match_operand:HI 2 "memory_operand" "m"))
4256    (use (match_operand:HI 3 "memory_operand" "m"))]
4257   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4258    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4259   "* return output_fix_trunc (insn, operands);"
4260   [(set_attr "type" "fistp")
4261    (set_attr "i387_cw" "trunc")
4262    (set_attr "mode" "SI")])
4263
4264 ;; When SSE available, it is always faster to use it!
4265 (define_insn "fix_truncsfsi_sse"
4266   [(set (match_operand:SI 0 "register_operand" "=r,r")
4267         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4268   "TARGET_SSE"
4269   "cvttss2si\t{%1, %0|%0, %1}"
4270   [(set_attr "type" "sseicvt")
4271    (set_attr "mode" "DF")
4272    (set_attr "athlon_decode" "double,vector")])
4273
4274 ;; Avoid vector decoded form of the instruction.
4275 (define_peephole2
4276   [(match_scratch:SF 2 "x")
4277    (set (match_operand:SI 0 "register_operand" "")
4278         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4279   "TARGET_K8 && !optimize_size"
4280   [(set (match_dup 2) (match_dup 1))
4281    (set (match_dup 0) (fix:SI (match_dup 2)))]
4282   "")
4283
4284 (define_insn "fix_truncdfsi_sse"
4285   [(set (match_operand:SI 0 "register_operand" "=r,r")
4286         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4287   "TARGET_SSE2"
4288   "cvttsd2si\t{%1, %0|%0, %1}"
4289   [(set_attr "type" "sseicvt")
4290    (set_attr "mode" "DF")
4291    (set_attr "athlon_decode" "double,vector")])
4292
4293 ;; Avoid vector decoded form of the instruction.
4294 (define_peephole2
4295   [(match_scratch:DF 2 "Y")
4296    (set (match_operand:SI 0 "register_operand" "")
4297         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4298   "TARGET_K8 && !optimize_size"
4299   [(set (match_dup 2) (match_dup 1))
4300    (set (match_dup 0) (fix:SI (match_dup 2)))]
4301   "")
4302
4303 (define_split 
4304   [(set (match_operand:SI 0 "register_operand" "")
4305         (fix:SI (match_operand 1 "register_operand" "")))
4306    (use (match_operand:HI 2 "memory_operand" ""))
4307    (use (match_operand:HI 3 "memory_operand" ""))
4308    (clobber (match_operand:SI 4 "memory_operand" ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4311               (use (match_dup 2))
4312               (use (match_dup 3))])
4313    (set (match_dup 0) (match_dup 4))]
4314   "")
4315
4316 (define_split 
4317   [(set (match_operand:SI 0 "memory_operand" "")
4318         (fix:SI (match_operand 1 "register_operand" "")))
4319    (use (match_operand:HI 2 "memory_operand" ""))
4320    (use (match_operand:HI 3 "memory_operand" ""))
4321    (clobber (match_operand:SI 4 "memory_operand" ""))]
4322   "reload_completed"
4323   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4324               (use (match_dup 2))
4325               (use (match_dup 3))])]
4326   "")
4327
4328 ;; Signed conversion to HImode.
4329
4330 (define_expand "fix_truncxfhi2"
4331   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4332                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4333               (clobber (reg:CC FLAGS_REG))])] 
4334   "TARGET_80387"
4335   "")
4336
4337 (define_expand "fix_truncdfhi2"
4338   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4339                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4340               (clobber (reg:CC FLAGS_REG))])]
4341   "TARGET_80387 && !TARGET_SSE2"
4342   "")
4343
4344 (define_expand "fix_truncsfhi2"
4345   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4347                (clobber (reg:CC FLAGS_REG))])]
4348   "TARGET_80387 && !TARGET_SSE"
4349   "")
4350
4351 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4352 ;; of the machinery.
4353 (define_insn_and_split "*fix_trunchi_i387"
4354   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4355         (fix:HI (match_operand 1 "register_operand" "f,f")))
4356    (clobber (reg:CC FLAGS_REG))]
4357   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358    && !reload_completed && !reload_in_progress
4359    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360   "#"
4361   "&& 1"
4362   [(const_int 0)]
4363 {
4364   ix86_optimize_mode_switching = 1;
4365   operands[2] = assign_386_stack_local (HImode, 1);
4366   operands[3] = assign_386_stack_local (HImode, 2);
4367   if (memory_operand (operands[0], VOIDmode))
4368     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4369                                        operands[2], operands[3]));
4370   else
4371     {
4372       operands[4] = assign_386_stack_local (HImode, 0);
4373       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4374                                            operands[2], operands[3],
4375                                            operands[4]));
4376     }
4377   DONE;
4378 }
4379   [(set_attr "type" "fistp")
4380    (set_attr "i387_cw" "trunc")
4381    (set_attr "mode" "HI")])
4382
4383 (define_insn "fix_trunchi_nomemory"
4384   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4385         (fix:HI (match_operand 1 "register_operand" "f,f")))
4386    (use (match_operand:HI 2 "memory_operand" "m,m"))
4387    (use (match_operand:HI 3 "memory_operand" "m,m"))
4388    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4389   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4390    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4391   "#"
4392   [(set_attr "type" "fistp")
4393    (set_attr "i387_cw" "trunc")
4394    (set_attr "mode" "HI")])
4395
4396 (define_insn "fix_trunchi_memory"
4397   [(set (match_operand:HI 0 "memory_operand" "=m")
4398         (fix:HI (match_operand 1 "register_operand" "f")))
4399    (use (match_operand:HI 2 "memory_operand" "m"))
4400    (use (match_operand:HI 3 "memory_operand" "m"))]
4401   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4402    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403   "* return output_fix_trunc (insn, operands);"
4404   [(set_attr "type" "fistp")
4405    (set_attr "i387_cw" "trunc")
4406    (set_attr "mode" "HI")])
4407
4408 (define_split 
4409   [(set (match_operand:HI 0 "memory_operand" "")
4410         (fix:HI (match_operand 1 "register_operand" "")))
4411    (use (match_operand:HI 2 "memory_operand" ""))
4412    (use (match_operand:HI 3 "memory_operand" ""))
4413    (clobber (match_operand:HI 4 "memory_operand" ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))])]
4418   "")
4419
4420 (define_split 
4421   [(set (match_operand:HI 0 "register_operand" "")
4422         (fix:HI (match_operand 1 "register_operand" "")))
4423    (use (match_operand:HI 2 "memory_operand" ""))
4424    (use (match_operand:HI 3 "memory_operand" ""))
4425    (clobber (match_operand:HI 4 "memory_operand" ""))]
4426   "reload_completed"
4427   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4428               (use (match_dup 2))
4429               (use (match_dup 3))
4430               (clobber (match_dup 4))])
4431    (set (match_dup 0) (match_dup 4))]
4432   "")
4433
4434 (define_insn "x86_fnstcw_1"
4435   [(set (match_operand:HI 0 "memory_operand" "=m")
4436         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4437   "TARGET_80387"
4438   "fnstcw\t%0"
4439   [(set_attr "length" "2")
4440    (set_attr "mode" "HI")
4441    (set_attr "unit" "i387")])
4442
4443 (define_insn "x86_fldcw_1"
4444   [(set (reg:HI FPSR_REG)
4445         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4446   "TARGET_80387"
4447   "fldcw\t%0"
4448   [(set_attr "length" "2")
4449    (set_attr "mode" "HI")
4450    (set_attr "unit" "i387")
4451    (set_attr "athlon_decode" "vector")])
4452 \f
4453 ;; Conversion between fixed point and floating point.
4454
4455 ;; Even though we only accept memory inputs, the backend _really_
4456 ;; wants to be able to do this between registers.
4457
4458 (define_expand "floathisf2"
4459   [(set (match_operand:SF 0 "register_operand" "")
4460         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4461   "TARGET_80387 || TARGET_SSE_MATH"
4462 {
4463   if (TARGET_SSE_MATH)
4464     {
4465       emit_insn (gen_floatsisf2 (operands[0],
4466                                  convert_to_mode (SImode, operands[1], 0)));
4467       DONE;
4468     }
4469 })
4470
4471 (define_insn "*floathisf2_i387"
4472   [(set (match_operand:SF 0 "register_operand" "=f,f")
4473         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4474   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4475   "@
4476    fild%z1\t%1
4477    #"
4478   [(set_attr "type" "fmov,multi")
4479    (set_attr "mode" "SF")
4480    (set_attr "fp_int_src" "true")])
4481
4482 (define_expand "floatsisf2"
4483   [(set (match_operand:SF 0 "register_operand" "")
4484         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485   "TARGET_80387 || TARGET_SSE_MATH"
4486   "")
4487
4488 (define_insn "*floatsisf2_mixed"
4489   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491   "TARGET_MIX_SSE_I387"
4492   "@
4493    fild%z1\t%1
4494    #
4495    cvtsi2ss\t{%1, %0|%0, %1}
4496    cvtsi2ss\t{%1, %0|%0, %1}"
4497   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498    (set_attr "mode" "SF")
4499    (set_attr "athlon_decode" "*,*,vector,double")
4500    (set_attr "fp_int_src" "true")])
4501
4502 (define_insn "*floatsisf2_sse"
4503   [(set (match_operand:SF 0 "register_operand" "=x,x")
4504         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4505   "TARGET_SSE_MATH"
4506   "cvtsi2ss\t{%1, %0|%0, %1}"
4507   [(set_attr "type" "sseicvt")
4508    (set_attr "mode" "SF")
4509    (set_attr "athlon_decode" "vector,double")
4510    (set_attr "fp_int_src" "true")])
4511
4512 (define_insn "*floatsisf2_i387"
4513   [(set (match_operand:SF 0 "register_operand" "=f,f")
4514         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4515   "TARGET_80387"
4516   "@
4517    fild%z1\t%1
4518    #"
4519   [(set_attr "type" "fmov,multi")
4520    (set_attr "mode" "SF")
4521    (set_attr "fp_int_src" "true")])
4522
4523 (define_expand "floatdisf2"
4524   [(set (match_operand:SF 0 "register_operand" "")
4525         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4526   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4527   "")
4528
4529 (define_insn "*floatdisf2_mixed"
4530   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4531         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4532   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4533   "@
4534    fild%z1\t%1
4535    #
4536    cvtsi2ss{q}\t{%1, %0|%0, %1}
4537    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4538   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4539    (set_attr "mode" "SF")
4540    (set_attr "athlon_decode" "*,*,vector,double")
4541    (set_attr "fp_int_src" "true")])
4542
4543 (define_insn "*floatdisf2_sse"
4544   [(set (match_operand:SF 0 "register_operand" "=x,x")
4545         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4546   "TARGET_64BIT && TARGET_SSE_MATH"
4547   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4548   [(set_attr "type" "sseicvt")
4549    (set_attr "mode" "SF")
4550    (set_attr "athlon_decode" "vector,double")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_insn "*floatdisf2_i387"
4554   [(set (match_operand:SF 0 "register_operand" "=f,f")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4556   "TARGET_80387"
4557   "@
4558    fild%z1\t%1
4559    #"
4560   [(set_attr "type" "fmov,multi")
4561    (set_attr "mode" "SF")
4562    (set_attr "fp_int_src" "true")])
4563
4564 (define_expand "floathidf2"
4565   [(set (match_operand:DF 0 "register_operand" "")
4566         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4567   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4568 {
4569   if (TARGET_SSE2 && TARGET_SSE_MATH)
4570     {
4571       emit_insn (gen_floatsidf2 (operands[0],
4572                                  convert_to_mode (SImode, operands[1], 0)));
4573       DONE;
4574     }
4575 })
4576
4577 (define_insn "*floathidf2_i387"
4578   [(set (match_operand:DF 0 "register_operand" "=f,f")
4579         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4580   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4581   "@
4582    fild%z1\t%1
4583    #"
4584   [(set_attr "type" "fmov,multi")
4585    (set_attr "mode" "DF")
4586    (set_attr "fp_int_src" "true")])
4587
4588 (define_expand "floatsidf2"
4589   [(set (match_operand:DF 0 "register_operand" "")
4590         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4591   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4592   "")
4593
4594 (define_insn "*floatsidf2_mixed"
4595   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598   "@
4599    fild%z1\t%1
4600    #
4601    cvtsi2sd\t{%1, %0|%0, %1}
4602    cvtsi2sd\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "athlon_decode" "*,*,double,direct")
4606    (set_attr "fp_int_src" "true")])
4607
4608 (define_insn "*floatsidf2_sse"
4609   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4610         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4611   "TARGET_SSE2 && TARGET_SSE_MATH"
4612   "cvtsi2sd\t{%1, %0|%0, %1}"
4613   [(set_attr "type" "sseicvt")
4614    (set_attr "mode" "DF")
4615    (set_attr "athlon_decode" "double,direct")
4616    (set_attr "fp_int_src" "true")])
4617
4618 (define_insn "*floatsidf2_i387"
4619   [(set (match_operand:DF 0 "register_operand" "=f,f")
4620         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4621   "TARGET_80387"
4622   "@
4623    fild%z1\t%1
4624    #"
4625   [(set_attr "type" "fmov,multi")
4626    (set_attr "mode" "DF")
4627    (set_attr "fp_int_src" "true")])
4628
4629 (define_expand "floatdidf2"
4630   [(set (match_operand:DF 0 "register_operand" "")
4631         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4632   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4633   "")
4634
4635 (define_insn "*floatdidf2_mixed"
4636   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4637         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4638   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4639   "@
4640    fild%z1\t%1
4641    #
4642    cvtsi2sd{q}\t{%1, %0|%0, %1}
4643    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4644   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4645    (set_attr "mode" "DF")
4646    (set_attr "athlon_decode" "*,*,double,direct")
4647    (set_attr "fp_int_src" "true")])
4648
4649 (define_insn "*floatdidf2_sse"
4650   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4651         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4652   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4653   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4654   [(set_attr "type" "sseicvt")
4655    (set_attr "mode" "DF")
4656    (set_attr "athlon_decode" "double,direct")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_insn "*floatdidf2_i387"
4660   [(set (match_operand:DF 0 "register_operand" "=f,f")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "DF")
4668    (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "floathixf2"
4671   [(set (match_operand:XF 0 "register_operand" "=f,f")
4672         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4673   "TARGET_80387"
4674   "@
4675    fild%z1\t%1
4676    #"
4677   [(set_attr "type" "fmov,multi")
4678    (set_attr "mode" "XF")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "floatsixf2"
4682   [(set (match_operand:XF 0 "register_operand" "=f,f")
4683         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4684   "TARGET_80387"
4685   "@
4686    fild%z1\t%1
4687    #"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "XF")
4690    (set_attr "fp_int_src" "true")])
4691
4692 (define_insn "floatdixf2"
4693   [(set (match_operand:XF 0 "register_operand" "=f,f")
4694         (float:XF (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" "XF")
4701    (set_attr "fp_int_src" "true")])
4702
4703 ;; %%% Kill these when reload knows how to do it.
4704 (define_split
4705   [(set (match_operand 0 "fp_register_operand" "")
4706         (float (match_operand 1 "register_operand" "")))]
4707   "reload_completed
4708    && TARGET_80387
4709    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4710   [(const_int 0)]
4711 {
4712   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4713   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4714   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4715   ix86_free_from_memory (GET_MODE (operands[1]));
4716   DONE;
4717 })
4718
4719 (define_expand "floatunssisf2"
4720   [(use (match_operand:SF 0 "register_operand" ""))
4721    (use (match_operand:SI 1 "register_operand" ""))]
4722   "!TARGET_64BIT && TARGET_SSE_MATH"
4723   "x86_emit_floatuns (operands); DONE;")
4724
4725 (define_expand "floatunsdisf2"
4726   [(use (match_operand:SF 0 "register_operand" ""))
4727    (use (match_operand:DI 1 "register_operand" ""))]
4728   "TARGET_64BIT && TARGET_SSE_MATH"
4729   "x86_emit_floatuns (operands); DONE;")
4730
4731 (define_expand "floatunsdidf2"
4732   [(use (match_operand:DF 0 "register_operand" ""))
4733    (use (match_operand:DI 1 "register_operand" ""))]
4734   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4735   "x86_emit_floatuns (operands); DONE;")
4736 \f
4737 ;; SSE extract/set expanders
4738
4739 \f
4740 ;; Add instructions
4741
4742 ;; %%% splits for addsidi3
4743 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4746
4747 (define_expand "adddi3"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750                  (match_operand:DI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   ""
4753   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4754
4755 (define_insn "*adddi3_1"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4761   "#")
4762
4763 (define_split
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766                  (match_operand:DI 2 "general_operand" "")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "!TARGET_64BIT && reload_completed"
4769   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770                                           UNSPEC_ADD_CARRY))
4771               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_di (operands+0, 1, operands+0, operands+3);
4778    split_di (operands+1, 1, operands+1, operands+4);
4779    split_di (operands+2, 1, operands+2, operands+5);")
4780
4781 (define_insn "adddi3_carry_rex64"
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788   "adc{q}\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")
4790    (set_attr "pent_pair" "pu")
4791    (set_attr "mode" "DI")])
4792
4793 (define_insn "*adddi3_cc_rex64"
4794   [(set (reg:CC FLAGS_REG)
4795         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4797                    UNSPEC_ADD_CARRY))
4798    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799         (plus:DI (match_dup 1) (match_dup 2)))]
4800   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "add{q}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "mode" "DI")])
4804
4805 (define_insn "addqi3_carry"
4806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809                    (match_operand:QI 2 "general_operand" "qi,qm")))
4810    (clobber (reg:CC FLAGS_REG))]
4811   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812   "adc{b}\t{%2, %0|%0, %2}"
4813   [(set_attr "type" "alu")
4814    (set_attr "pent_pair" "pu")
4815    (set_attr "mode" "QI")])
4816
4817 (define_insn "addhi3_carry"
4818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821                    (match_operand:HI 2 "general_operand" "ri,rm")))
4822    (clobber (reg:CC FLAGS_REG))]
4823   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824   "adc{w}\t{%2, %0|%0, %2}"
4825   [(set_attr "type" "alu")
4826    (set_attr "pent_pair" "pu")
4827    (set_attr "mode" "HI")])
4828
4829 (define_insn "addsi3_carry"
4830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:SI 2 "general_operand" "ri,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836   "adc{l}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "SI")])
4840
4841 (define_insn "*addsi3_carry_zext"
4842   [(set (match_operand:DI 0 "register_operand" "=r")
4843           (zero_extend:DI 
4844             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846                      (match_operand:SI 2 "general_operand" "rim"))))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849   "adc{l}\t{%2, %k0|%k0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "pent_pair" "pu")
4852    (set_attr "mode" "SI")])
4853
4854 (define_insn "*addsi3_cc"
4855   [(set (reg:CC FLAGS_REG)
4856         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857                     (match_operand:SI 2 "general_operand" "ri,rm")]
4858                    UNSPEC_ADD_CARRY))
4859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860         (plus:SI (match_dup 1) (match_dup 2)))]
4861   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862   "add{l}\t{%2, %0|%0, %2}"
4863   [(set_attr "type" "alu")
4864    (set_attr "mode" "SI")])
4865
4866 (define_insn "addqi3_cc"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:QI 2 "general_operand" "qi,qm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872         (plus:QI (match_dup 1) (match_dup 2)))]
4873   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874   "add{b}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "QI")])
4877
4878 (define_expand "addsi3"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881                             (match_operand:SI 2 "general_operand" "")))
4882               (clobber (reg:CC FLAGS_REG))])]
4883   ""
4884   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4885
4886 (define_insn "*lea_1"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4889   "!TARGET_64BIT"
4890   "lea{l}\t{%a1, %0|%0, %a1}"
4891   [(set_attr "type" "lea")
4892    (set_attr "mode" "SI")])
4893
4894 (define_insn "*lea_1_rex64"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4897   "TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn "*lea_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %k0|%k0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4910
4911 (define_insn "*lea_2_rex64"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4914   "TARGET_64BIT"
4915   "lea{q}\t{%a1, %0|%0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "DI")])
4918
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4921
4922 (define_insn_and_split "*lea_general_1"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (plus (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "register_operand" "r"))
4926               (match_operand 3 "immediate_operand" "i")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4937 {
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[2] = gen_lowpart (Pmode, operands[2]);
4942   operands[3] = gen_lowpart (Pmode, operands[3]);
4943   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4944                       operands[3]);
4945   if (Pmode != SImode)
4946     pat = gen_rtx_SUBREG (SImode, pat, 0);
4947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948   DONE;
4949 }
4950   [(set_attr "type" "lea")
4951    (set_attr "mode" "SI")])
4952
4953 (define_insn_and_split "*lea_general_1_zext"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (zero_extend:DI
4956           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957                             (match_operand:SI 2 "register_operand" "r"))
4958                    (match_operand:SI 3 "immediate_operand" "i"))))]
4959   "TARGET_64BIT"
4960   "#"
4961   "&& reload_completed"
4962   [(set (match_dup 0)
4963         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4964                                                      (match_dup 2))
4965                                             (match_dup 3)) 0)))]
4966 {
4967   operands[1] = gen_lowpart (Pmode, operands[1]);
4968   operands[2] = gen_lowpart (Pmode, operands[2]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4970 }
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4973
4974 (define_insn_and_split "*lea_general_2"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (mult (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "const248_operand" "i"))
4978               (match_operand 3 "nonmemory_operand" "ri")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984        || GET_MODE (operands[3]) == VOIDmode)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4988 {
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4994                       operands[3]);
4995   if (Pmode != SImode)
4996     pat = gen_rtx_SUBREG (SImode, pat, 0);
4997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998   DONE;
4999 }
5000   [(set_attr "type" "lea")
5001    (set_attr "mode" "SI")])
5002
5003 (define_insn_and_split "*lea_general_2_zext"
5004   [(set (match_operand:DI 0 "register_operand" "=r")
5005         (zero_extend:DI
5006           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007                             (match_operand:SI 2 "const248_operand" "n"))
5008                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009   "TARGET_64BIT"
5010   "#"
5011   "&& reload_completed"
5012   [(set (match_dup 0)
5013         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5014                                                      (match_dup 2))
5015                                             (match_dup 3)) 0)))]
5016 {
5017   operands[1] = gen_lowpart (Pmode, operands[1]);
5018   operands[3] = gen_lowpart (Pmode, operands[3]);
5019 }
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5022
5023 (define_insn_and_split "*lea_general_3"
5024   [(set (match_operand 0 "register_operand" "=r")
5025         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026                           (match_operand 2 "const248_operand" "i"))
5027                     (match_operand 3 "register_operand" "r"))
5028               (match_operand 4 "immediate_operand" "i")))]
5029   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5034   "#"
5035   "&& reload_completed"
5036   [(const_int 0)]
5037 {
5038   rtx pat;
5039   operands[0] = gen_lowpart (SImode, operands[0]);
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[3] = gen_lowpart (Pmode, operands[3]);
5042   operands[4] = gen_lowpart (Pmode, operands[4]);
5043   pat = gen_rtx_PLUS (Pmode,
5044                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5045                                                          operands[2]),
5046                                     operands[3]),
5047                       operands[4]);
5048   if (Pmode != SImode)
5049     pat = gen_rtx_SUBREG (SImode, pat, 0);
5050   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051   DONE;
5052 }
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3_zext"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (zero_extend:DI
5059           (plus:SI (plus:SI (mult:SI
5060                               (match_operand:SI 1 "index_register_operand" "l")
5061                               (match_operand:SI 2 "const248_operand" "n"))
5062                             (match_operand:SI 3 "register_operand" "r"))
5063                    (match_operand:SI 4 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069                                                               (match_dup 2))
5070                                                      (match_dup 3))
5071                                             (match_dup 4)) 0)))]
5072 {
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076 }
5077   [(set_attr "type" "lea")
5078    (set_attr "mode" "SI")])
5079
5080 (define_insn "*adddi_1_rex64"
5081   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5086 {
5087   switch (get_attr_type (insn))
5088     {
5089     case TYPE_LEA:
5090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091       return "lea{q}\t{%a2, %0|%0, %a2}";
5092
5093     case TYPE_INCDEC:
5094       if (! rtx_equal_p (operands[0], operands[1]))
5095         abort ();
5096       if (operands[2] == const1_rtx)
5097         return "inc{q}\t%0";
5098       else if (operands[2] == constm1_rtx)
5099         return "dec{q}\t%0";
5100       else
5101         abort ();
5102
5103     default:
5104       if (! rtx_equal_p (operands[0], operands[1]))
5105         abort ();
5106
5107       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5108          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5109       if (GET_CODE (operands[2]) == CONST_INT
5110           /* Avoid overflows.  */
5111           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5112           && (INTVAL (operands[2]) == 128
5113               || (INTVAL (operands[2]) < 0
5114                   && INTVAL (operands[2]) != -128)))
5115         {
5116           operands[2] = GEN_INT (-INTVAL (operands[2]));
5117           return "sub{q}\t{%2, %0|%0, %2}";
5118         }
5119       return "add{q}\t{%2, %0|%0, %2}";
5120     }
5121 }
5122   [(set (attr "type")
5123      (cond [(eq_attr "alternative" "2")
5124               (const_string "lea")
5125             ; Current assemblers are broken and do not allow @GOTOFF in
5126             ; ought but a memory context.
5127             (match_operand:DI 2 "pic_symbolic_operand" "")
5128               (const_string "lea")
5129             (match_operand:DI 2 "incdec_operand" "")
5130               (const_string "incdec")
5131            ]
5132            (const_string "alu")))
5133    (set_attr "mode" "DI")])
5134
5135 ;; Convert lea to the lea pattern to avoid flags dependency.
5136 (define_split
5137   [(set (match_operand:DI 0 "register_operand" "")
5138         (plus:DI (match_operand:DI 1 "register_operand" "")
5139                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5140    (clobber (reg:CC FLAGS_REG))]
5141   "TARGET_64BIT && reload_completed
5142    && true_regnum (operands[0]) != true_regnum (operands[1])"
5143   [(set (match_dup 0)
5144         (plus:DI (match_dup 1)
5145                  (match_dup 2)))]
5146   "")
5147
5148 (define_insn "*adddi_2_rex64"
5149   [(set (reg FLAGS_REG)
5150         (compare
5151           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5152                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5153           (const_int 0)))                       
5154    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5155         (plus:DI (match_dup 1) (match_dup 2)))]
5156   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5157    && ix86_binary_operator_ok (PLUS, DImode, operands)
5158    /* Current assemblers are broken and do not allow @GOTOFF in
5159       ought but a memory context.  */
5160    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5161 {
5162   switch (get_attr_type (insn))
5163     {
5164     case TYPE_INCDEC:
5165       if (! rtx_equal_p (operands[0], operands[1]))
5166         abort ();
5167       if (operands[2] == const1_rtx)
5168         return "inc{q}\t%0";
5169       else if (operands[2] == constm1_rtx)
5170         return "dec{q}\t%0";
5171       else
5172         abort ();
5173
5174     default:
5175       if (! rtx_equal_p (operands[0], operands[1]))
5176         abort ();
5177       /* ???? We ought to handle there the 32bit case too
5178          - do we need new constraint?  */
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      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5196         (const_string "incdec")
5197         (const_string "alu")))
5198    (set_attr "mode" "DI")])
5199
5200 (define_insn "*adddi_3_rex64"
5201   [(set (reg FLAGS_REG)
5202         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5203                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5204    (clobber (match_scratch:DI 0 "=r"))]
5205   "TARGET_64BIT
5206    && ix86_match_ccmode (insn, CCZmode)
5207    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5208    /* Current assemblers are broken and do not allow @GOTOFF in
5209       ought but a memory context.  */
5210    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5211 {
5212   switch (get_attr_type (insn))
5213     {
5214     case TYPE_INCDEC:
5215       if (! rtx_equal_p (operands[0], operands[1]))
5216         abort ();
5217       if (operands[2] == const1_rtx)
5218         return "inc{q}\t%0";
5219       else if (operands[2] == constm1_rtx)
5220         return "dec{q}\t%0";
5221       else
5222         abort ();
5223
5224     default:
5225       if (! rtx_equal_p (operands[0], operands[1]))
5226         abort ();
5227       /* ???? We ought to handle there the 32bit case too
5228          - do we need new constraint?  */
5229       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5231       if (GET_CODE (operands[2]) == CONST_INT
5232           /* Avoid overflows.  */
5233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234           && (INTVAL (operands[2]) == 128
5235               || (INTVAL (operands[2]) < 0
5236                   && INTVAL (operands[2]) != -128)))
5237         {
5238           operands[2] = GEN_INT (-INTVAL (operands[2]));
5239           return "sub{q}\t{%2, %0|%0, %2}";
5240         }
5241       return "add{q}\t{%2, %0|%0, %2}";
5242     }
5243 }
5244   [(set (attr "type")
5245      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5246         (const_string "incdec")
5247         (const_string "alu")))
5248    (set_attr "mode" "DI")])
5249
5250 ; For comparisons against 1, -1 and 128, we may generate better code
5251 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5252 ; is matched then.  We can't accept general immediate, because for
5253 ; case of overflows,  the result is messed up.
5254 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5255 ; when negated.
5256 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5257 ; only for comparisons not depending on it.
5258 (define_insn "*adddi_4_rex64"
5259   [(set (reg FLAGS_REG)
5260         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5261                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5262    (clobber (match_scratch:DI 0 "=rm"))]
5263   "TARGET_64BIT
5264    &&  ix86_match_ccmode (insn, CCGCmode)"
5265 {
5266   switch (get_attr_type (insn))
5267     {
5268     case TYPE_INCDEC:
5269       if (operands[2] == constm1_rtx)
5270         return "inc{q}\t%0";
5271       else if (operands[2] == const1_rtx)
5272         return "dec{q}\t%0";
5273       else
5274         abort();
5275
5276     default:
5277       if (! rtx_equal_p (operands[0], operands[1]))
5278         abort ();
5279       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5280          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5281       if ((INTVAL (operands[2]) == -128
5282            || (INTVAL (operands[2]) > 0
5283                && INTVAL (operands[2]) != 128))
5284           /* Avoid overflows.  */
5285           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5286         return "sub{q}\t{%2, %0|%0, %2}";
5287       operands[2] = GEN_INT (-INTVAL (operands[2]));
5288       return "add{q}\t{%2, %0|%0, %2}";
5289     }
5290 }
5291   [(set (attr "type")
5292      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5293         (const_string "incdec")
5294         (const_string "alu")))
5295    (set_attr "mode" "DI")])
5296
5297 (define_insn "*adddi_5_rex64"
5298   [(set (reg FLAGS_REG)
5299         (compare
5300           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5301                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5302           (const_int 0)))                       
5303    (clobber (match_scratch:DI 0 "=r"))]
5304   "TARGET_64BIT
5305    && ix86_match_ccmode (insn, CCGOCmode)
5306    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5307    /* Current assemblers are broken and do not allow @GOTOFF in
5308       ought but a memory context.  */
5309    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5310 {
5311   switch (get_attr_type (insn))
5312     {
5313     case TYPE_INCDEC:
5314       if (! rtx_equal_p (operands[0], operands[1]))
5315         abort ();
5316       if (operands[2] == const1_rtx)
5317         return "inc{q}\t%0";
5318       else if (operands[2] == constm1_rtx)
5319         return "dec{q}\t%0";
5320       else
5321         abort();
5322
5323     default:
5324       if (! rtx_equal_p (operands[0], operands[1]))
5325         abort ();
5326       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5328       if (GET_CODE (operands[2]) == CONST_INT
5329           /* Avoid overflows.  */
5330           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331           && (INTVAL (operands[2]) == 128
5332               || (INTVAL (operands[2]) < 0
5333                   && INTVAL (operands[2]) != -128)))
5334         {
5335           operands[2] = GEN_INT (-INTVAL (operands[2]));
5336           return "sub{q}\t{%2, %0|%0, %2}";
5337         }
5338       return "add{q}\t{%2, %0|%0, %2}";
5339     }
5340 }
5341   [(set (attr "type")
5342      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343         (const_string "incdec")
5344         (const_string "alu")))
5345    (set_attr "mode" "DI")])
5346
5347
5348 (define_insn "*addsi_1"
5349   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352    (clobber (reg:CC FLAGS_REG))]
5353   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5354 {
5355   switch (get_attr_type (insn))
5356     {
5357     case TYPE_LEA:
5358       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359       return "lea{l}\t{%a2, %0|%0, %a2}";
5360
5361     case TYPE_INCDEC:
5362       if (! rtx_equal_p (operands[0], operands[1]))
5363         abort ();
5364       if (operands[2] == const1_rtx)
5365         return "inc{l}\t%0";
5366       else if (operands[2] == constm1_rtx)
5367         return "dec{l}\t%0";
5368       else
5369         abort();
5370
5371     default:
5372       if (! rtx_equal_p (operands[0], operands[1]))
5373         abort ();
5374
5375       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5376          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5377       if (GET_CODE (operands[2]) == CONST_INT
5378           && (INTVAL (operands[2]) == 128
5379               || (INTVAL (operands[2]) < 0
5380                   && INTVAL (operands[2]) != -128)))
5381         {
5382           operands[2] = GEN_INT (-INTVAL (operands[2]));
5383           return "sub{l}\t{%2, %0|%0, %2}";
5384         }
5385       return "add{l}\t{%2, %0|%0, %2}";
5386     }
5387 }
5388   [(set (attr "type")
5389      (cond [(eq_attr "alternative" "2")
5390               (const_string "lea")
5391             ; Current assemblers are broken and do not allow @GOTOFF in
5392             ; ought but a memory context.
5393             (match_operand:SI 2 "pic_symbolic_operand" "")
5394               (const_string "lea")
5395             (match_operand:SI 2 "incdec_operand" "")
5396               (const_string "incdec")
5397            ]
5398            (const_string "alu")))
5399    (set_attr "mode" "SI")])
5400
5401 ;; Convert lea to the lea pattern to avoid flags dependency.
5402 (define_split
5403   [(set (match_operand 0 "register_operand" "")
5404         (plus (match_operand 1 "register_operand" "")
5405               (match_operand 2 "nonmemory_operand" "")))
5406    (clobber (reg:CC FLAGS_REG))]
5407   "reload_completed
5408    && true_regnum (operands[0]) != true_regnum (operands[1])"
5409   [(const_int 0)]
5410 {
5411   rtx pat;
5412   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5413      may confuse gen_lowpart.  */
5414   if (GET_MODE (operands[0]) != Pmode)
5415     {
5416       operands[1] = gen_lowpart (Pmode, operands[1]);
5417       operands[2] = gen_lowpart (Pmode, operands[2]);
5418     }
5419   operands[0] = gen_lowpart (SImode, operands[0]);
5420   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5421   if (Pmode != SImode)
5422     pat = gen_rtx_SUBREG (SImode, pat, 0);
5423   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5424   DONE;
5425 })
5426
5427 ;; It may seem that nonimmediate operand is proper one for operand 1.
5428 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5429 ;; we take care in ix86_binary_operator_ok to not allow two memory
5430 ;; operands so proper swapping will be done in reload.  This allow
5431 ;; patterns constructed from addsi_1 to match.
5432 (define_insn "addsi_1_zext"
5433   [(set (match_operand:DI 0 "register_operand" "=r,r")
5434         (zero_extend:DI
5435           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5436                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5437    (clobber (reg:CC FLAGS_REG))]
5438   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5439 {
5440   switch (get_attr_type (insn))
5441     {
5442     case TYPE_LEA:
5443       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5444       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5445
5446     case TYPE_INCDEC:
5447       if (operands[2] == const1_rtx)
5448         return "inc{l}\t%k0";
5449       else if (operands[2] == constm1_rtx)
5450         return "dec{l}\t%k0";
5451       else
5452         abort();
5453
5454     default:
5455       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5457       if (GET_CODE (operands[2]) == CONST_INT
5458           && (INTVAL (operands[2]) == 128
5459               || (INTVAL (operands[2]) < 0
5460                   && INTVAL (operands[2]) != -128)))
5461         {
5462           operands[2] = GEN_INT (-INTVAL (operands[2]));
5463           return "sub{l}\t{%2, %k0|%k0, %2}";
5464         }
5465       return "add{l}\t{%2, %k0|%k0, %2}";
5466     }
5467 }
5468   [(set (attr "type")
5469      (cond [(eq_attr "alternative" "1")
5470               (const_string "lea")
5471             ; Current assemblers are broken and do not allow @GOTOFF in
5472             ; ought but a memory context.
5473             (match_operand:SI 2 "pic_symbolic_operand" "")
5474               (const_string "lea")
5475             (match_operand:SI 2 "incdec_operand" "")
5476               (const_string "incdec")
5477            ]
5478            (const_string "alu")))
5479    (set_attr "mode" "SI")])
5480
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 (define_split
5483   [(set (match_operand:DI 0 "register_operand" "")
5484         (zero_extend:DI
5485           (plus:SI (match_operand:SI 1 "register_operand" "")
5486                    (match_operand:SI 2 "nonmemory_operand" ""))))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "TARGET_64BIT && reload_completed
5489    && true_regnum (operands[0]) != true_regnum (operands[1])"
5490   [(set (match_dup 0)
5491         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5492 {
5493   operands[1] = gen_lowpart (Pmode, operands[1]);
5494   operands[2] = gen_lowpart (Pmode, operands[2]);
5495 })
5496
5497 (define_insn "*addsi_2"
5498   [(set (reg FLAGS_REG)
5499         (compare
5500           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5502           (const_int 0)))                       
5503    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504         (plus:SI (match_dup 1) (match_dup 2)))]
5505   "ix86_match_ccmode (insn, CCGOCmode)
5506    && ix86_binary_operator_ok (PLUS, SImode, operands)
5507    /* Current assemblers are broken and do not allow @GOTOFF in
5508       ought but a memory context.  */
5509    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 {
5511   switch (get_attr_type (insn))
5512     {
5513     case TYPE_INCDEC:
5514       if (! rtx_equal_p (operands[0], operands[1]))
5515         abort ();
5516       if (operands[2] == const1_rtx)
5517         return "inc{l}\t%0";
5518       else if (operands[2] == constm1_rtx)
5519         return "dec{l}\t%0";
5520       else
5521         abort();
5522
5523     default:
5524       if (! rtx_equal_p (operands[0], operands[1]))
5525         abort ();
5526       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5528       if (GET_CODE (operands[2]) == CONST_INT
5529           && (INTVAL (operands[2]) == 128
5530               || (INTVAL (operands[2]) < 0
5531                   && INTVAL (operands[2]) != -128)))
5532         {
5533           operands[2] = GEN_INT (-INTVAL (operands[2]));
5534           return "sub{l}\t{%2, %0|%0, %2}";
5535         }
5536       return "add{l}\t{%2, %0|%0, %2}";
5537     }
5538 }
5539   [(set (attr "type")
5540      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5541         (const_string "incdec")
5542         (const_string "alu")))
5543    (set_attr "mode" "SI")])
5544
5545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5546 (define_insn "*addsi_2_zext"
5547   [(set (reg FLAGS_REG)
5548         (compare
5549           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5550                    (match_operand:SI 2 "general_operand" "rmni"))
5551           (const_int 0)))                       
5552    (set (match_operand:DI 0 "register_operand" "=r")
5553         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5554   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5555    && ix86_binary_operator_ok (PLUS, SImode, operands)
5556    /* Current assemblers are broken and do not allow @GOTOFF in
5557       ought but a memory context.  */
5558    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5559 {
5560   switch (get_attr_type (insn))
5561     {
5562     case TYPE_INCDEC:
5563       if (operands[2] == const1_rtx)
5564         return "inc{l}\t%k0";
5565       else if (operands[2] == constm1_rtx)
5566         return "dec{l}\t%k0";
5567       else
5568         abort();
5569
5570     default:
5571       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5573       if (GET_CODE (operands[2]) == CONST_INT
5574           && (INTVAL (operands[2]) == 128
5575               || (INTVAL (operands[2]) < 0
5576                   && INTVAL (operands[2]) != -128)))
5577         {
5578           operands[2] = GEN_INT (-INTVAL (operands[2]));
5579           return "sub{l}\t{%2, %k0|%k0, %2}";
5580         }
5581       return "add{l}\t{%2, %k0|%k0, %2}";
5582     }
5583 }
5584   [(set (attr "type")
5585      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586         (const_string "incdec")
5587         (const_string "alu")))
5588    (set_attr "mode" "SI")])
5589
5590 (define_insn "*addsi_3"
5591   [(set (reg FLAGS_REG)
5592         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594    (clobber (match_scratch:SI 0 "=r"))]
5595   "ix86_match_ccmode (insn, CCZmode)
5596    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597    /* Current assemblers are broken and do not allow @GOTOFF in
5598       ought but a memory context.  */
5599    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5600 {
5601   switch (get_attr_type (insn))
5602     {
5603     case TYPE_INCDEC:
5604       if (! rtx_equal_p (operands[0], operands[1]))
5605         abort ();
5606       if (operands[2] == const1_rtx)
5607         return "inc{l}\t%0";
5608       else if (operands[2] == constm1_rtx)
5609         return "dec{l}\t%0";
5610       else
5611         abort();
5612
5613     default:
5614       if (! rtx_equal_p (operands[0], operands[1]))
5615         abort ();
5616       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5617          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5618       if (GET_CODE (operands[2]) == CONST_INT
5619           && (INTVAL (operands[2]) == 128
5620               || (INTVAL (operands[2]) < 0
5621                   && INTVAL (operands[2]) != -128)))
5622         {
5623           operands[2] = GEN_INT (-INTVAL (operands[2]));
5624           return "sub{l}\t{%2, %0|%0, %2}";
5625         }
5626       return "add{l}\t{%2, %0|%0, %2}";
5627     }
5628 }
5629   [(set (attr "type")
5630      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5631         (const_string "incdec")
5632         (const_string "alu")))
5633    (set_attr "mode" "SI")])
5634
5635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5636 (define_insn "*addsi_3_zext"
5637   [(set (reg FLAGS_REG)
5638         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5639                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5640    (set (match_operand:DI 0 "register_operand" "=r")
5641         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5642   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5643    && ix86_binary_operator_ok (PLUS, SImode, operands)
5644    /* Current assemblers are broken and do not allow @GOTOFF in
5645       ought but a memory context.  */
5646    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5647 {
5648   switch (get_attr_type (insn))
5649     {
5650     case TYPE_INCDEC:
5651       if (operands[2] == const1_rtx)
5652         return "inc{l}\t%k0";
5653       else if (operands[2] == constm1_rtx)
5654         return "dec{l}\t%k0";
5655       else
5656         abort();
5657
5658     default:
5659       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5661       if (GET_CODE (operands[2]) == CONST_INT
5662           && (INTVAL (operands[2]) == 128
5663               || (INTVAL (operands[2]) < 0
5664                   && INTVAL (operands[2]) != -128)))
5665         {
5666           operands[2] = GEN_INT (-INTVAL (operands[2]));
5667           return "sub{l}\t{%2, %k0|%k0, %2}";
5668         }
5669       return "add{l}\t{%2, %k0|%k0, %2}";
5670     }
5671 }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5677
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5680 ; is matched then.  We can't accept general immediate, because for
5681 ; case of overflows,  the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5683 ; when negated.
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687   [(set (reg FLAGS_REG)
5688         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689                  (match_operand:SI 2 "const_int_operand" "n")))
5690    (clobber (match_scratch:SI 0 "=rm"))]
5691   "ix86_match_ccmode (insn, CCGCmode)
5692    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5693 {
5694   switch (get_attr_type (insn))
5695     {
5696     case TYPE_INCDEC:
5697       if (operands[2] == constm1_rtx)
5698         return "inc{l}\t%0";
5699       else if (operands[2] == const1_rtx)
5700         return "dec{l}\t%0";
5701       else
5702         abort();
5703
5704     default:
5705       if (! rtx_equal_p (operands[0], operands[1]))
5706         abort ();
5707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5709       if ((INTVAL (operands[2]) == -128
5710            || (INTVAL (operands[2]) > 0
5711                && INTVAL (operands[2]) != 128)))
5712         return "sub{l}\t{%2, %0|%0, %2}";
5713       operands[2] = GEN_INT (-INTVAL (operands[2]));
5714       return "add{l}\t{%2, %0|%0, %2}";
5715     }
5716 }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set_attr "mode" "SI")])
5722
5723 (define_insn "*addsi_5"
5724   [(set (reg FLAGS_REG)
5725         (compare
5726           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727                    (match_operand:SI 2 "general_operand" "rmni"))
5728           (const_int 0)))                       
5729    (clobber (match_scratch:SI 0 "=r"))]
5730   "ix86_match_ccmode (insn, CCGOCmode)
5731    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732    /* Current assemblers are broken and do not allow @GOTOFF in
5733       ought but a memory context.  */
5734    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5735 {
5736   switch (get_attr_type (insn))
5737     {
5738     case TYPE_INCDEC:
5739       if (! rtx_equal_p (operands[0], operands[1]))
5740         abort ();
5741       if (operands[2] == const1_rtx)
5742         return "inc{l}\t%0";
5743       else if (operands[2] == constm1_rtx)
5744         return "dec{l}\t%0";
5745       else
5746         abort();
5747
5748     default:
5749       if (! rtx_equal_p (operands[0], operands[1]))
5750         abort ();
5751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5753       if (GET_CODE (operands[2]) == CONST_INT
5754           && (INTVAL (operands[2]) == 128
5755               || (INTVAL (operands[2]) < 0
5756                   && INTVAL (operands[2]) != -128)))
5757         {
5758           operands[2] = GEN_INT (-INTVAL (operands[2]));
5759           return "sub{l}\t{%2, %0|%0, %2}";
5760         }
5761       return "add{l}\t{%2, %0|%0, %2}";
5762     }
5763 }
5764   [(set (attr "type")
5765      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5766         (const_string "incdec")
5767         (const_string "alu")))
5768    (set_attr "mode" "SI")])
5769
5770 (define_expand "addhi3"
5771   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5772                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5773                             (match_operand:HI 2 "general_operand" "")))
5774               (clobber (reg:CC FLAGS_REG))])]
5775   "TARGET_HIMODE_MATH"
5776   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5777
5778 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5779 ;; type optimizations enabled by define-splits.  This is not important
5780 ;; for PII, and in fact harmful because of partial register stalls.
5781
5782 (define_insn "*addhi_1_lea"
5783   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5784         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5785                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5786    (clobber (reg:CC FLAGS_REG))]
5787   "!TARGET_PARTIAL_REG_STALL
5788    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5789 {
5790   switch (get_attr_type (insn))
5791     {
5792     case TYPE_LEA:
5793       return "#";
5794     case TYPE_INCDEC:
5795       if (operands[2] == const1_rtx)
5796         return "inc{w}\t%0";
5797       else if (operands[2] == constm1_rtx)
5798         return "dec{w}\t%0";
5799       abort();
5800
5801     default:
5802       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5803          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5804       if (GET_CODE (operands[2]) == CONST_INT
5805           && (INTVAL (operands[2]) == 128
5806               || (INTVAL (operands[2]) < 0
5807                   && INTVAL (operands[2]) != -128)))
5808         {
5809           operands[2] = GEN_INT (-INTVAL (operands[2]));
5810           return "sub{w}\t{%2, %0|%0, %2}";
5811         }
5812       return "add{w}\t{%2, %0|%0, %2}";
5813     }
5814 }
5815   [(set (attr "type")
5816      (if_then_else (eq_attr "alternative" "2")
5817         (const_string "lea")
5818         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5819            (const_string "incdec")
5820            (const_string "alu"))))
5821    (set_attr "mode" "HI,HI,SI")])
5822
5823 (define_insn "*addhi_1"
5824   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5825         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5826                  (match_operand:HI 2 "general_operand" "ri,rm")))
5827    (clobber (reg:CC FLAGS_REG))]
5828   "TARGET_PARTIAL_REG_STALL
5829    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5830 {
5831   switch (get_attr_type (insn))
5832     {
5833     case TYPE_INCDEC:
5834       if (operands[2] == const1_rtx)
5835         return "inc{w}\t%0";
5836       else if (operands[2] == constm1_rtx)
5837         return "dec{w}\t%0";
5838       abort();
5839
5840     default:
5841       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843       if (GET_CODE (operands[2]) == CONST_INT
5844           && (INTVAL (operands[2]) == 128
5845               || (INTVAL (operands[2]) < 0
5846                   && INTVAL (operands[2]) != -128)))
5847         {
5848           operands[2] = GEN_INT (-INTVAL (operands[2]));
5849           return "sub{w}\t{%2, %0|%0, %2}";
5850         }
5851       return "add{w}\t{%2, %0|%0, %2}";
5852     }
5853 }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "mode" "HI")])
5859
5860 (define_insn "*addhi_2"
5861   [(set (reg FLAGS_REG)
5862         (compare
5863           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5864                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5865           (const_int 0)))                       
5866    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5867         (plus:HI (match_dup 1) (match_dup 2)))]
5868   "ix86_match_ccmode (insn, CCGOCmode)
5869    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5870 {
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_INCDEC:
5874       if (operands[2] == const1_rtx)
5875         return "inc{w}\t%0";
5876       else if (operands[2] == constm1_rtx)
5877         return "dec{w}\t%0";
5878       abort();
5879
5880     default:
5881       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5882          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5883       if (GET_CODE (operands[2]) == CONST_INT
5884           && (INTVAL (operands[2]) == 128
5885               || (INTVAL (operands[2]) < 0
5886                   && INTVAL (operands[2]) != -128)))
5887         {
5888           operands[2] = GEN_INT (-INTVAL (operands[2]));
5889           return "sub{w}\t{%2, %0|%0, %2}";
5890         }
5891       return "add{w}\t{%2, %0|%0, %2}";
5892     }
5893 }
5894   [(set (attr "type")
5895      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5896         (const_string "incdec")
5897         (const_string "alu")))
5898    (set_attr "mode" "HI")])
5899
5900 (define_insn "*addhi_3"
5901   [(set (reg FLAGS_REG)
5902         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5903                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5904    (clobber (match_scratch:HI 0 "=r"))]
5905   "ix86_match_ccmode (insn, CCZmode)
5906    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5907 {
5908   switch (get_attr_type (insn))
5909     {
5910     case TYPE_INCDEC:
5911       if (operands[2] == const1_rtx)
5912         return "inc{w}\t%0";
5913       else if (operands[2] == constm1_rtx)
5914         return "dec{w}\t%0";
5915       abort();
5916
5917     default:
5918       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5919          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5920       if (GET_CODE (operands[2]) == CONST_INT
5921           && (INTVAL (operands[2]) == 128
5922               || (INTVAL (operands[2]) < 0
5923                   && INTVAL (operands[2]) != -128)))
5924         {
5925           operands[2] = GEN_INT (-INTVAL (operands[2]));
5926           return "sub{w}\t{%2, %0|%0, %2}";
5927         }
5928       return "add{w}\t{%2, %0|%0, %2}";
5929     }
5930 }
5931   [(set (attr "type")
5932      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5933         (const_string "incdec")
5934         (const_string "alu")))
5935    (set_attr "mode" "HI")])
5936
5937 ; See comments above addsi_4 for details.
5938 (define_insn "*addhi_4"
5939   [(set (reg FLAGS_REG)
5940         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5941                  (match_operand:HI 2 "const_int_operand" "n")))
5942    (clobber (match_scratch:HI 0 "=rm"))]
5943   "ix86_match_ccmode (insn, CCGCmode)
5944    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5945 {
5946   switch (get_attr_type (insn))
5947     {
5948     case TYPE_INCDEC:
5949       if (operands[2] == constm1_rtx)
5950         return "inc{w}\t%0";
5951       else if (operands[2] == const1_rtx)
5952         return "dec{w}\t%0";
5953       else
5954         abort();
5955
5956     default:
5957       if (! rtx_equal_p (operands[0], operands[1]))
5958         abort ();
5959       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5960          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5961       if ((INTVAL (operands[2]) == -128
5962            || (INTVAL (operands[2]) > 0
5963                && INTVAL (operands[2]) != 128)))
5964         return "sub{w}\t{%2, %0|%0, %2}";
5965       operands[2] = GEN_INT (-INTVAL (operands[2]));
5966       return "add{w}\t{%2, %0|%0, %2}";
5967     }
5968 }
5969   [(set (attr "type")
5970      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5971         (const_string "incdec")
5972         (const_string "alu")))
5973    (set_attr "mode" "SI")])
5974
5975
5976 (define_insn "*addhi_5"
5977   [(set (reg FLAGS_REG)
5978         (compare
5979           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5980                    (match_operand:HI 2 "general_operand" "rmni"))
5981           (const_int 0)))                       
5982    (clobber (match_scratch:HI 0 "=r"))]
5983   "ix86_match_ccmode (insn, CCGOCmode)
5984    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5985 {
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return "inc{w}\t%0";
5991       else if (operands[2] == constm1_rtx)
5992         return "dec{w}\t%0";
5993       abort();
5994
5995     default:
5996       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5997          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5998       if (GET_CODE (operands[2]) == CONST_INT
5999           && (INTVAL (operands[2]) == 128
6000               || (INTVAL (operands[2]) < 0
6001                   && INTVAL (operands[2]) != -128)))
6002         {
6003           operands[2] = GEN_INT (-INTVAL (operands[2]));
6004           return "sub{w}\t{%2, %0|%0, %2}";
6005         }
6006       return "add{w}\t{%2, %0|%0, %2}";
6007     }
6008 }
6009   [(set (attr "type")
6010      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6011         (const_string "incdec")
6012         (const_string "alu")))
6013    (set_attr "mode" "HI")])
6014
6015 (define_expand "addqi3"
6016   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6017                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6018                             (match_operand:QI 2 "general_operand" "")))
6019               (clobber (reg:CC FLAGS_REG))])]
6020   "TARGET_QIMODE_MATH"
6021   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6022
6023 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6024 (define_insn "*addqi_1_lea"
6025   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6026         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6027                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6028    (clobber (reg:CC FLAGS_REG))]
6029   "!TARGET_PARTIAL_REG_STALL
6030    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6031 {
6032   int widen = (which_alternative == 2);
6033   switch (get_attr_type (insn))
6034     {
6035     case TYPE_LEA:
6036       return "#";
6037     case TYPE_INCDEC:
6038       if (operands[2] == const1_rtx)
6039         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6040       else if (operands[2] == constm1_rtx)
6041         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6042       abort();
6043
6044     default:
6045       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6047       if (GET_CODE (operands[2]) == CONST_INT
6048           && (INTVAL (operands[2]) == 128
6049               || (INTVAL (operands[2]) < 0
6050                   && INTVAL (operands[2]) != -128)))
6051         {
6052           operands[2] = GEN_INT (-INTVAL (operands[2]));
6053           if (widen)
6054             return "sub{l}\t{%2, %k0|%k0, %2}";
6055           else
6056             return "sub{b}\t{%2, %0|%0, %2}";
6057         }
6058       if (widen)
6059         return "add{l}\t{%k2, %k0|%k0, %k2}";
6060       else
6061         return "add{b}\t{%2, %0|%0, %2}";
6062     }
6063 }
6064   [(set (attr "type")
6065      (if_then_else (eq_attr "alternative" "3")
6066         (const_string "lea")
6067         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6068            (const_string "incdec")
6069            (const_string "alu"))))
6070    (set_attr "mode" "QI,QI,SI,SI")])
6071
6072 (define_insn "*addqi_1"
6073   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6074         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6075                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6076    (clobber (reg:CC FLAGS_REG))]
6077   "TARGET_PARTIAL_REG_STALL
6078    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6079 {
6080   int widen = (which_alternative == 2);
6081   switch (get_attr_type (insn))
6082     {
6083     case TYPE_INCDEC:
6084       if (operands[2] == const1_rtx)
6085         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6086       else if (operands[2] == constm1_rtx)
6087         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6088       abort();
6089
6090     default:
6091       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6092          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6093       if (GET_CODE (operands[2]) == CONST_INT
6094           && (INTVAL (operands[2]) == 128
6095               || (INTVAL (operands[2]) < 0
6096                   && INTVAL (operands[2]) != -128)))
6097         {
6098           operands[2] = GEN_INT (-INTVAL (operands[2]));
6099           if (widen)
6100             return "sub{l}\t{%2, %k0|%k0, %2}";
6101           else
6102             return "sub{b}\t{%2, %0|%0, %2}";
6103         }
6104       if (widen)
6105         return "add{l}\t{%k2, %k0|%k0, %k2}";
6106       else
6107         return "add{b}\t{%2, %0|%0, %2}";
6108     }
6109 }
6110   [(set (attr "type")
6111      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6112         (const_string "incdec")
6113         (const_string "alu")))
6114    (set_attr "mode" "QI,QI,SI")])
6115
6116 (define_insn "*addqi_1_slp"
6117   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6118         (plus:QI (match_dup 0)
6119                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6120    (clobber (reg:CC FLAGS_REG))]
6121   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6122    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6123 {
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_INCDEC:
6127       if (operands[1] == const1_rtx)
6128         return "inc{b}\t%0";
6129       else if (operands[1] == constm1_rtx)
6130         return "dec{b}\t%0";
6131       abort();
6132
6133     default:
6134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6135       if (GET_CODE (operands[1]) == CONST_INT
6136           && INTVAL (operands[1]) < 0)
6137         {
6138           operands[1] = GEN_INT (-INTVAL (operands[1]));
6139           return "sub{b}\t{%1, %0|%0, %1}";
6140         }
6141       return "add{b}\t{%1, %0|%0, %1}";
6142     }
6143 }
6144   [(set (attr "type")
6145      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6146         (const_string "incdec")
6147         (const_string "alu1")))
6148    (set (attr "memory")
6149      (if_then_else (match_operand 1 "memory_operand" "")
6150         (const_string "load")
6151         (const_string "none")))
6152    (set_attr "mode" "QI")])
6153
6154 (define_insn "*addqi_2"
6155   [(set (reg FLAGS_REG)
6156         (compare
6157           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6158                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6159           (const_int 0)))
6160    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6161         (plus:QI (match_dup 1) (match_dup 2)))]
6162   "ix86_match_ccmode (insn, CCGOCmode)
6163    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6164 {
6165   switch (get_attr_type (insn))
6166     {
6167     case TYPE_INCDEC:
6168       if (operands[2] == const1_rtx)
6169         return "inc{b}\t%0";
6170       else if (operands[2] == constm1_rtx
6171                || (GET_CODE (operands[2]) == CONST_INT
6172                    && INTVAL (operands[2]) == 255))
6173         return "dec{b}\t%0";
6174       abort();
6175
6176     default:
6177       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6178       if (GET_CODE (operands[2]) == CONST_INT
6179           && INTVAL (operands[2]) < 0)
6180         {
6181           operands[2] = GEN_INT (-INTVAL (operands[2]));
6182           return "sub{b}\t{%2, %0|%0, %2}";
6183         }
6184       return "add{b}\t{%2, %0|%0, %2}";
6185     }
6186 }
6187   [(set (attr "type")
6188      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6189         (const_string "incdec")
6190         (const_string "alu")))
6191    (set_attr "mode" "QI")])
6192
6193 (define_insn "*addqi_3"
6194   [(set (reg FLAGS_REG)
6195         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6196                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6197    (clobber (match_scratch:QI 0 "=q"))]
6198   "ix86_match_ccmode (insn, CCZmode)
6199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6200 {
6201   switch (get_attr_type (insn))
6202     {
6203     case TYPE_INCDEC:
6204       if (operands[2] == const1_rtx)
6205         return "inc{b}\t%0";
6206       else if (operands[2] == constm1_rtx
6207                || (GET_CODE (operands[2]) == CONST_INT
6208                    && INTVAL (operands[2]) == 255))
6209         return "dec{b}\t%0";
6210       abort();
6211
6212     default:
6213       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6214       if (GET_CODE (operands[2]) == CONST_INT
6215           && INTVAL (operands[2]) < 0)
6216         {
6217           operands[2] = GEN_INT (-INTVAL (operands[2]));
6218           return "sub{b}\t{%2, %0|%0, %2}";
6219         }
6220       return "add{b}\t{%2, %0|%0, %2}";
6221     }
6222 }
6223   [(set (attr "type")
6224      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6225         (const_string "incdec")
6226         (const_string "alu")))
6227    (set_attr "mode" "QI")])
6228
6229 ; See comments above addsi_4 for details.
6230 (define_insn "*addqi_4"
6231   [(set (reg FLAGS_REG)
6232         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6233                  (match_operand:QI 2 "const_int_operand" "n")))
6234    (clobber (match_scratch:QI 0 "=qm"))]
6235   "ix86_match_ccmode (insn, CCGCmode)
6236    && (INTVAL (operands[2]) & 0xff) != 0x80"
6237 {
6238   switch (get_attr_type (insn))
6239     {
6240     case TYPE_INCDEC:
6241       if (operands[2] == constm1_rtx
6242           || (GET_CODE (operands[2]) == CONST_INT
6243               && INTVAL (operands[2]) == 255))
6244         return "inc{b}\t%0";
6245       else if (operands[2] == const1_rtx)
6246         return "dec{b}\t%0";
6247       else
6248         abort();
6249
6250     default:
6251       if (! rtx_equal_p (operands[0], operands[1]))
6252         abort ();
6253       if (INTVAL (operands[2]) < 0)
6254         {
6255           operands[2] = GEN_INT (-INTVAL (operands[2]));
6256           return "add{b}\t{%2, %0|%0, %2}";
6257         }
6258       return "sub{b}\t{%2, %0|%0, %2}";
6259     }
6260 }
6261   [(set (attr "type")
6262      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6263         (const_string "incdec")
6264         (const_string "alu")))
6265    (set_attr "mode" "QI")])
6266
6267
6268 (define_insn "*addqi_5"
6269   [(set (reg FLAGS_REG)
6270         (compare
6271           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6272                    (match_operand:QI 2 "general_operand" "qmni"))
6273           (const_int 0)))
6274    (clobber (match_scratch:QI 0 "=q"))]
6275   "ix86_match_ccmode (insn, CCGOCmode)
6276    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6277 {
6278   switch (get_attr_type (insn))
6279     {
6280     case TYPE_INCDEC:
6281       if (operands[2] == const1_rtx)
6282         return "inc{b}\t%0";
6283       else if (operands[2] == constm1_rtx
6284                || (GET_CODE (operands[2]) == CONST_INT
6285                    && INTVAL (operands[2]) == 255))
6286         return "dec{b}\t%0";
6287       abort();
6288
6289     default:
6290       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6291       if (GET_CODE (operands[2]) == CONST_INT
6292           && INTVAL (operands[2]) < 0)
6293         {
6294           operands[2] = GEN_INT (-INTVAL (operands[2]));
6295           return "sub{b}\t{%2, %0|%0, %2}";
6296         }
6297       return "add{b}\t{%2, %0|%0, %2}";
6298     }
6299 }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu")))
6304    (set_attr "mode" "QI")])
6305
6306
6307 (define_insn "addqi_ext_1"
6308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6309                          (const_int 8)
6310                          (const_int 8))
6311         (plus:SI
6312           (zero_extract:SI
6313             (match_operand 1 "ext_register_operand" "0")
6314             (const_int 8)
6315             (const_int 8))
6316           (match_operand:QI 2 "general_operand" "Qmn")))
6317    (clobber (reg:CC FLAGS_REG))]
6318   "!TARGET_64BIT"
6319 {
6320   switch (get_attr_type (insn))
6321     {
6322     case TYPE_INCDEC:
6323       if (operands[2] == const1_rtx)
6324         return "inc{b}\t%h0";
6325       else if (operands[2] == constm1_rtx
6326                || (GET_CODE (operands[2]) == CONST_INT
6327                    && INTVAL (operands[2]) == 255))
6328         return "dec{b}\t%h0";
6329       abort();
6330
6331     default:
6332       return "add{b}\t{%2, %h0|%h0, %2}";
6333     }
6334 }
6335   [(set (attr "type")
6336      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6337         (const_string "incdec")
6338         (const_string "alu")))
6339    (set_attr "mode" "QI")])
6340
6341 (define_insn "*addqi_ext_1_rex64"
6342   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6343                          (const_int 8)
6344                          (const_int 8))
6345         (plus:SI
6346           (zero_extract:SI
6347             (match_operand 1 "ext_register_operand" "0")
6348             (const_int 8)
6349             (const_int 8))
6350           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6351    (clobber (reg:CC FLAGS_REG))]
6352   "TARGET_64BIT"
6353 {
6354   switch (get_attr_type (insn))
6355     {
6356     case TYPE_INCDEC:
6357       if (operands[2] == const1_rtx)
6358         return "inc{b}\t%h0";
6359       else if (operands[2] == constm1_rtx
6360                || (GET_CODE (operands[2]) == CONST_INT
6361                    && INTVAL (operands[2]) == 255))
6362         return "dec{b}\t%h0";
6363       abort();
6364
6365     default:
6366       return "add{b}\t{%2, %h0|%h0, %2}";
6367     }
6368 }
6369   [(set (attr "type")
6370      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371         (const_string "incdec")
6372         (const_string "alu")))
6373    (set_attr "mode" "QI")])
6374
6375 (define_insn "*addqi_ext_2"
6376   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6377                          (const_int 8)
6378                          (const_int 8))
6379         (plus:SI
6380           (zero_extract:SI
6381             (match_operand 1 "ext_register_operand" "%0")
6382             (const_int 8)
6383             (const_int 8))
6384           (zero_extract:SI
6385             (match_operand 2 "ext_register_operand" "Q")
6386             (const_int 8)
6387             (const_int 8))))
6388    (clobber (reg:CC FLAGS_REG))]
6389   ""
6390   "add{b}\t{%h2, %h0|%h0, %h2}"
6391   [(set_attr "type" "alu")
6392    (set_attr "mode" "QI")])
6393
6394 ;; The patterns that match these are at the end of this file.
6395
6396 (define_expand "addxf3"
6397   [(set (match_operand:XF 0 "register_operand" "")
6398         (plus:XF (match_operand:XF 1 "register_operand" "")
6399                  (match_operand:XF 2 "register_operand" "")))]
6400   "TARGET_80387"
6401   "")
6402
6403 (define_expand "adddf3"
6404   [(set (match_operand:DF 0 "register_operand" "")
6405         (plus:DF (match_operand:DF 1 "register_operand" "")
6406                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6407   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6408   "")
6409
6410 (define_expand "addsf3"
6411   [(set (match_operand:SF 0 "register_operand" "")
6412         (plus:SF (match_operand:SF 1 "register_operand" "")
6413                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6414   "TARGET_80387 || TARGET_SSE_MATH"
6415   "")
6416 \f
6417 ;; Subtract instructions
6418
6419 ;; %%% splits for subsidi3
6420
6421 (define_expand "subdi3"
6422   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6423                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6424                              (match_operand:DI 2 "x86_64_general_operand" "")))
6425               (clobber (reg:CC FLAGS_REG))])]
6426   ""
6427   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6428
6429 (define_insn "*subdi3_1"
6430   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6431         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6432                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6433    (clobber (reg:CC FLAGS_REG))]
6434   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6435   "#")
6436
6437 (define_split
6438   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6439         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6440                   (match_operand:DI 2 "general_operand" "")))
6441    (clobber (reg:CC FLAGS_REG))]
6442   "!TARGET_64BIT && reload_completed"
6443   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6444               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6445    (parallel [(set (match_dup 3)
6446                    (minus:SI (match_dup 4)
6447                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6448                                       (match_dup 5))))
6449               (clobber (reg:CC FLAGS_REG))])]
6450   "split_di (operands+0, 1, operands+0, operands+3);
6451    split_di (operands+1, 1, operands+1, operands+4);
6452    split_di (operands+2, 1, operands+2, operands+5);")
6453
6454 (define_insn "subdi3_carry_rex64"
6455   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6456           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6457             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6458                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6459    (clobber (reg:CC FLAGS_REG))]
6460   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6461   "sbb{q}\t{%2, %0|%0, %2}"
6462   [(set_attr "type" "alu")
6463    (set_attr "pent_pair" "pu")
6464    (set_attr "mode" "DI")])
6465
6466 (define_insn "*subdi_1_rex64"
6467   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6468         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6469                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6470    (clobber (reg:CC FLAGS_REG))]
6471   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6472   "sub{q}\t{%2, %0|%0, %2}"
6473   [(set_attr "type" "alu")
6474    (set_attr "mode" "DI")])
6475
6476 (define_insn "*subdi_2_rex64"
6477   [(set (reg FLAGS_REG)
6478         (compare
6479           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6480                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6481           (const_int 0)))
6482    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6483         (minus:DI (match_dup 1) (match_dup 2)))]
6484   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6485    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6486   "sub{q}\t{%2, %0|%0, %2}"
6487   [(set_attr "type" "alu")
6488    (set_attr "mode" "DI")])
6489
6490 (define_insn "*subdi_3_rex63"
6491   [(set (reg FLAGS_REG)
6492         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6493                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6494    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6495         (minus:DI (match_dup 1) (match_dup 2)))]
6496   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6497    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6498   "sub{q}\t{%2, %0|%0, %2}"
6499   [(set_attr "type" "alu")
6500    (set_attr "mode" "DI")])
6501
6502 (define_insn "subqi3_carry"
6503   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6504           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6505             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6506                (match_operand:QI 2 "general_operand" "qi,qm"))))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6509   "sbb{b}\t{%2, %0|%0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "pent_pair" "pu")
6512    (set_attr "mode" "QI")])
6513
6514 (define_insn "subhi3_carry"
6515   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6516           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6517             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6518                (match_operand:HI 2 "general_operand" "ri,rm"))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6521   "sbb{w}\t{%2, %0|%0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "pent_pair" "pu")
6524    (set_attr "mode" "HI")])
6525
6526 (define_insn "subsi3_carry"
6527   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6528           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6529             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6530                (match_operand:SI 2 "general_operand" "ri,rm"))))
6531    (clobber (reg:CC FLAGS_REG))]
6532   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6533   "sbb{l}\t{%2, %0|%0, %2}"
6534   [(set_attr "type" "alu")
6535    (set_attr "pent_pair" "pu")
6536    (set_attr "mode" "SI")])
6537
6538 (define_insn "subsi3_carry_zext"
6539   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6540           (zero_extend:DI
6541             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6542               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6543                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6544    (clobber (reg:CC FLAGS_REG))]
6545   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546   "sbb{l}\t{%2, %k0|%k0, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "pent_pair" "pu")
6549    (set_attr "mode" "SI")])
6550
6551 (define_expand "subsi3"
6552   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6553                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6554                              (match_operand:SI 2 "general_operand" "")))
6555               (clobber (reg:CC FLAGS_REG))])]
6556   ""
6557   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6558
6559 (define_insn "*subsi_1"
6560   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6561         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6562                   (match_operand:SI 2 "general_operand" "ri,rm")))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6565   "sub{l}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "mode" "SI")])
6568
6569 (define_insn "*subsi_1_zext"
6570   [(set (match_operand:DI 0 "register_operand" "=r")
6571         (zero_extend:DI
6572           (minus:SI (match_operand:SI 1 "register_operand" "0")
6573                     (match_operand:SI 2 "general_operand" "rim"))))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6576   "sub{l}\t{%2, %k0|%k0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "SI")])
6579
6580 (define_insn "*subsi_2"
6581   [(set (reg FLAGS_REG)
6582         (compare
6583           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6584                     (match_operand:SI 2 "general_operand" "ri,rm"))
6585           (const_int 0)))
6586    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6587         (minus:SI (match_dup 1) (match_dup 2)))]
6588   "ix86_match_ccmode (insn, CCGOCmode)
6589    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6590   "sub{l}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "mode" "SI")])
6593
6594 (define_insn "*subsi_2_zext"
6595   [(set (reg FLAGS_REG)
6596         (compare
6597           (minus:SI (match_operand:SI 1 "register_operand" "0")
6598                     (match_operand:SI 2 "general_operand" "rim"))
6599           (const_int 0)))
6600    (set (match_operand:DI 0 "register_operand" "=r")
6601         (zero_extend:DI
6602           (minus:SI (match_dup 1)
6603                     (match_dup 2))))]
6604   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6605    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606   "sub{l}\t{%2, %k0|%k0, %2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "mode" "SI")])
6609
6610 (define_insn "*subsi_3"
6611   [(set (reg FLAGS_REG)
6612         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6613                  (match_operand:SI 2 "general_operand" "ri,rm")))
6614    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6615         (minus:SI (match_dup 1) (match_dup 2)))]
6616   "ix86_match_ccmode (insn, CCmode)
6617    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6618   "sub{l}\t{%2, %0|%0, %2}"
6619   [(set_attr "type" "alu")
6620    (set_attr "mode" "SI")])
6621
6622 (define_insn "*subsi_3_zext"
6623   [(set (reg FLAGS_REG)
6624         (compare (match_operand:SI 1 "register_operand" "0")
6625                  (match_operand:SI 2 "general_operand" "rim")))
6626    (set (match_operand:DI 0 "register_operand" "=r")
6627         (zero_extend:DI
6628           (minus:SI (match_dup 1)
6629                     (match_dup 2))))]
6630   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6631    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632   "sub{q}\t{%2, %0|%0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "DI")])
6635
6636 (define_expand "subhi3"
6637   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6638                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6639                              (match_operand:HI 2 "general_operand" "")))
6640               (clobber (reg:CC FLAGS_REG))])]
6641   "TARGET_HIMODE_MATH"
6642   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6643
6644 (define_insn "*subhi_1"
6645   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6646         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6647                   (match_operand:HI 2 "general_operand" "ri,rm")))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650   "sub{w}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "HI")])
6653
6654 (define_insn "*subhi_2"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6658                     (match_operand:HI 2 "general_operand" "ri,rm"))
6659           (const_int 0)))
6660    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6661         (minus:HI (match_dup 1) (match_dup 2)))]
6662   "ix86_match_ccmode (insn, CCGOCmode)
6663    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6664   "sub{w}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "HI")])
6667
6668 (define_insn "*subhi_3"
6669   [(set (reg FLAGS_REG)
6670         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6671                  (match_operand:HI 2 "general_operand" "ri,rm")))
6672    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6673         (minus:HI (match_dup 1) (match_dup 2)))]
6674   "ix86_match_ccmode (insn, CCmode)
6675    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6676   "sub{w}\t{%2, %0|%0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "mode" "HI")])
6679
6680 (define_expand "subqi3"
6681   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6682                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6683                              (match_operand:QI 2 "general_operand" "")))
6684               (clobber (reg:CC FLAGS_REG))])]
6685   "TARGET_QIMODE_MATH"
6686   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6687
6688 (define_insn "*subqi_1"
6689   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6690         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6691                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6692    (clobber (reg:CC FLAGS_REG))]
6693   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6694   "sub{b}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "QI")])
6697
6698 (define_insn "*subqi_1_slp"
6699   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6700         (minus:QI (match_dup 0)
6701                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6702    (clobber (reg:CC FLAGS_REG))]
6703   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6704    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6705   "sub{b}\t{%1, %0|%0, %1}"
6706   [(set_attr "type" "alu1")
6707    (set_attr "mode" "QI")])
6708
6709 (define_insn "*subqi_2"
6710   [(set (reg FLAGS_REG)
6711         (compare
6712           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6713                     (match_operand:QI 2 "general_operand" "qi,qm"))
6714           (const_int 0)))
6715    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6716         (minus:HI (match_dup 1) (match_dup 2)))]
6717   "ix86_match_ccmode (insn, CCGOCmode)
6718    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6719   "sub{b}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "QI")])
6722
6723 (define_insn "*subqi_3"
6724   [(set (reg FLAGS_REG)
6725         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6726                  (match_operand:QI 2 "general_operand" "qi,qm")))
6727    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6728         (minus:HI (match_dup 1) (match_dup 2)))]
6729   "ix86_match_ccmode (insn, CCmode)
6730    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6731   "sub{b}\t{%2, %0|%0, %2}"
6732   [(set_attr "type" "alu")
6733    (set_attr "mode" "QI")])
6734
6735 ;; The patterns that match these are at the end of this file.
6736
6737 (define_expand "subxf3"
6738   [(set (match_operand:XF 0 "register_operand" "")
6739         (minus:XF (match_operand:XF 1 "register_operand" "")
6740                   (match_operand:XF 2 "register_operand" "")))]
6741   "TARGET_80387"
6742   "")
6743
6744 (define_expand "subdf3"
6745   [(set (match_operand:DF 0 "register_operand" "")
6746         (minus:DF (match_operand:DF 1 "register_operand" "")
6747                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6748   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6749   "")
6750
6751 (define_expand "subsf3"
6752   [(set (match_operand:SF 0 "register_operand" "")
6753         (minus:SF (match_operand:SF 1 "register_operand" "")
6754                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6755   "TARGET_80387 || TARGET_SSE_MATH"
6756   "")
6757 \f
6758 ;; Multiply instructions
6759
6760 (define_expand "muldi3"
6761   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6762                    (mult:DI (match_operand:DI 1 "register_operand" "")
6763                             (match_operand:DI 2 "x86_64_general_operand" "")))
6764               (clobber (reg:CC FLAGS_REG))])]
6765   "TARGET_64BIT"
6766   "")
6767
6768 (define_insn "*muldi3_1_rex64"
6769   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6770         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6771                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6772    (clobber (reg:CC FLAGS_REG))]
6773   "TARGET_64BIT
6774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6775   "@
6776    imul{q}\t{%2, %1, %0|%0, %1, %2}
6777    imul{q}\t{%2, %1, %0|%0, %1, %2}
6778    imul{q}\t{%2, %0|%0, %2}"
6779   [(set_attr "type" "imul")
6780    (set_attr "prefix_0f" "0,0,1")
6781    (set (attr "athlon_decode")
6782         (cond [(eq_attr "cpu" "athlon")
6783                   (const_string "vector")
6784                (eq_attr "alternative" "1")
6785                   (const_string "vector")
6786                (and (eq_attr "alternative" "2")
6787                     (match_operand 1 "memory_operand" ""))
6788                   (const_string "vector")]
6789               (const_string "direct")))
6790    (set_attr "mode" "DI")])
6791
6792 (define_expand "mulsi3"
6793   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6794                    (mult:SI (match_operand:SI 1 "register_operand" "")
6795                             (match_operand:SI 2 "general_operand" "")))
6796               (clobber (reg:CC FLAGS_REG))])]
6797   ""
6798   "")
6799
6800 (define_insn "*mulsi3_1"
6801   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6802         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6803                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6804    (clobber (reg:CC FLAGS_REG))]
6805   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6806   "@
6807    imul{l}\t{%2, %1, %0|%0, %1, %2}
6808    imul{l}\t{%2, %1, %0|%0, %1, %2}
6809    imul{l}\t{%2, %0|%0, %2}"
6810   [(set_attr "type" "imul")
6811    (set_attr "prefix_0f" "0,0,1")
6812    (set (attr "athlon_decode")
6813         (cond [(eq_attr "cpu" "athlon")
6814                   (const_string "vector")
6815                (eq_attr "alternative" "1")
6816                   (const_string "vector")
6817                (and (eq_attr "alternative" "2")
6818                     (match_operand 1 "memory_operand" ""))
6819                   (const_string "vector")]
6820               (const_string "direct")))
6821    (set_attr "mode" "SI")])
6822
6823 (define_insn "*mulsi3_1_zext"
6824   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6825         (zero_extend:DI
6826           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6827                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_64BIT
6830    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6831   "@
6832    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6833    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6834    imul{l}\t{%2, %k0|%k0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1")
6841                   (const_string "vector")
6842                (and (eq_attr "alternative" "2")
6843                     (match_operand 1 "memory_operand" ""))
6844                   (const_string "vector")]
6845               (const_string "direct")))
6846    (set_attr "mode" "SI")])
6847
6848 (define_expand "mulhi3"
6849   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6850                    (mult:HI (match_operand:HI 1 "register_operand" "")
6851                             (match_operand:HI 2 "general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   "TARGET_HIMODE_MATH"
6854   "")
6855
6856 (define_insn "*mulhi3_1"
6857   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6858         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6862   "@
6863    imul{w}\t{%2, %1, %0|%0, %1, %2}
6864    imul{w}\t{%2, %1, %0|%0, %1, %2}
6865    imul{w}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "imul")
6867    (set_attr "prefix_0f" "0,0,1")
6868    (set (attr "athlon_decode")
6869         (cond [(eq_attr "cpu" "athlon")
6870                   (const_string "vector")
6871                (eq_attr "alternative" "1,2")
6872                   (const_string "vector")]
6873               (const_string "direct")))
6874    (set_attr "mode" "HI")])
6875
6876 (define_expand "mulqi3"
6877   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6878                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6879                             (match_operand:QI 2 "register_operand" "")))
6880               (clobber (reg:CC FLAGS_REG))])]
6881   "TARGET_QIMODE_MATH"
6882   "")
6883
6884 (define_insn "*mulqi3_1"
6885   [(set (match_operand:QI 0 "register_operand" "=a")
6886         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6887                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "TARGET_QIMODE_MATH
6890    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6891   "mul{b}\t%2"
6892   [(set_attr "type" "imul")
6893    (set_attr "length_immediate" "0")
6894    (set (attr "athlon_decode")
6895      (if_then_else (eq_attr "cpu" "athlon")
6896         (const_string "vector")
6897         (const_string "direct")))
6898    (set_attr "mode" "QI")])
6899
6900 (define_expand "umulqihi3"
6901   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6902                    (mult:HI (zero_extend:HI
6903                               (match_operand:QI 1 "nonimmediate_operand" ""))
6904                             (zero_extend:HI
6905                               (match_operand:QI 2 "register_operand" ""))))
6906               (clobber (reg:CC FLAGS_REG))])]
6907   "TARGET_QIMODE_MATH"
6908   "")
6909
6910 (define_insn "*umulqihi3_1"
6911   [(set (match_operand:HI 0 "register_operand" "=a")
6912         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6913                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_QIMODE_MATH
6916    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6917   "mul{b}\t%2"
6918   [(set_attr "type" "imul")
6919    (set_attr "length_immediate" "0")
6920    (set (attr "athlon_decode")
6921      (if_then_else (eq_attr "cpu" "athlon")
6922         (const_string "vector")
6923         (const_string "direct")))
6924    (set_attr "mode" "QI")])
6925
6926 (define_expand "mulqihi3"
6927   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6928                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6929                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6930               (clobber (reg:CC FLAGS_REG))])]
6931   "TARGET_QIMODE_MATH"
6932   "")
6933
6934 (define_insn "*mulqihi3_insn"
6935   [(set (match_operand:HI 0 "register_operand" "=a")
6936         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6937                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6938    (clobber (reg:CC FLAGS_REG))]
6939   "TARGET_QIMODE_MATH
6940    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6941   "imul{b}\t%2"
6942   [(set_attr "type" "imul")
6943    (set_attr "length_immediate" "0")
6944    (set (attr "athlon_decode")
6945      (if_then_else (eq_attr "cpu" "athlon")
6946         (const_string "vector")
6947         (const_string "direct")))
6948    (set_attr "mode" "QI")])
6949
6950 (define_expand "umulditi3"
6951   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6952                    (mult:TI (zero_extend:TI
6953                               (match_operand:DI 1 "nonimmediate_operand" ""))
6954                             (zero_extend:TI
6955                               (match_operand:DI 2 "register_operand" ""))))
6956               (clobber (reg:CC FLAGS_REG))])]
6957   "TARGET_64BIT"
6958   "")
6959
6960 (define_insn "*umulditi3_insn"
6961   [(set (match_operand:TI 0 "register_operand" "=A")
6962         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6963                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6964    (clobber (reg:CC FLAGS_REG))]
6965   "TARGET_64BIT
6966    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6967   "mul{q}\t%2"
6968   [(set_attr "type" "imul")
6969    (set_attr "length_immediate" "0")
6970    (set (attr "athlon_decode")
6971      (if_then_else (eq_attr "cpu" "athlon")
6972         (const_string "vector")
6973         (const_string "double")))
6974    (set_attr "mode" "DI")])
6975
6976 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6977 (define_expand "umulsidi3"
6978   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6979                    (mult:DI (zero_extend:DI
6980                               (match_operand:SI 1 "nonimmediate_operand" ""))
6981                             (zero_extend:DI
6982                               (match_operand:SI 2 "register_operand" ""))))
6983               (clobber (reg:CC FLAGS_REG))])]
6984   "!TARGET_64BIT"
6985   "")
6986
6987 (define_insn "*umulsidi3_insn"
6988   [(set (match_operand:DI 0 "register_operand" "=A")
6989         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6990                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6991    (clobber (reg:CC FLAGS_REG))]
6992   "!TARGET_64BIT
6993    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6994   "mul{l}\t%2"
6995   [(set_attr "type" "imul")
6996    (set_attr "length_immediate" "0")
6997    (set (attr "athlon_decode")
6998      (if_then_else (eq_attr "cpu" "athlon")
6999         (const_string "vector")
7000         (const_string "double")))
7001    (set_attr "mode" "SI")])
7002
7003 (define_expand "mulditi3"
7004   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7005                    (mult:TI (sign_extend:TI
7006                               (match_operand:DI 1 "nonimmediate_operand" ""))
7007                             (sign_extend:TI
7008                               (match_operand:DI 2 "register_operand" ""))))
7009               (clobber (reg:CC FLAGS_REG))])]
7010   "TARGET_64BIT"
7011   "")
7012
7013 (define_insn "*mulditi3_insn"
7014   [(set (match_operand:TI 0 "register_operand" "=A")
7015         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7016                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7017    (clobber (reg:CC FLAGS_REG))]
7018   "TARGET_64BIT
7019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7020   "imul{q}\t%2"
7021   [(set_attr "type" "imul")
7022    (set_attr "length_immediate" "0")
7023    (set (attr "athlon_decode")
7024      (if_then_else (eq_attr "cpu" "athlon")
7025         (const_string "vector")
7026         (const_string "double")))
7027    (set_attr "mode" "DI")])
7028
7029 (define_expand "mulsidi3"
7030   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7031                    (mult:DI (sign_extend:DI
7032                               (match_operand:SI 1 "nonimmediate_operand" ""))
7033                             (sign_extend:DI
7034                               (match_operand:SI 2 "register_operand" ""))))
7035               (clobber (reg:CC FLAGS_REG))])]
7036   "!TARGET_64BIT"
7037   "")
7038
7039 (define_insn "*mulsidi3_insn"
7040   [(set (match_operand:DI 0 "register_operand" "=A")
7041         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7042                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7043    (clobber (reg:CC FLAGS_REG))]
7044   "!TARGET_64BIT
7045    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7046   "imul{l}\t%2"
7047   [(set_attr "type" "imul")
7048    (set_attr "length_immediate" "0")
7049    (set (attr "athlon_decode")
7050      (if_then_else (eq_attr "cpu" "athlon")
7051         (const_string "vector")
7052         (const_string "double")))
7053    (set_attr "mode" "SI")])
7054
7055 (define_expand "umuldi3_highpart"
7056   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7057                    (truncate:DI
7058                      (lshiftrt:TI
7059                        (mult:TI (zero_extend:TI
7060                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7061                                 (zero_extend:TI
7062                                   (match_operand:DI 2 "register_operand" "")))
7063                        (const_int 64))))
7064               (clobber (match_scratch:DI 3 ""))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   "TARGET_64BIT"
7067   "")
7068
7069 (define_insn "*umuldi3_highpart_rex64"
7070   [(set (match_operand:DI 0 "register_operand" "=d")
7071         (truncate:DI
7072           (lshiftrt:TI
7073             (mult:TI (zero_extend:TI
7074                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7075                      (zero_extend:TI
7076                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7077             (const_int 64))))
7078    (clobber (match_scratch:DI 3 "=1"))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "TARGET_64BIT
7081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082   "mul{q}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "double")))
7089    (set_attr "mode" "DI")])
7090
7091 (define_expand "umulsi3_highpart"
7092   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7093                    (truncate:SI
7094                      (lshiftrt:DI
7095                        (mult:DI (zero_extend:DI
7096                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7097                                 (zero_extend:DI
7098                                   (match_operand:SI 2 "register_operand" "")))
7099                        (const_int 32))))
7100               (clobber (match_scratch:SI 3 ""))
7101               (clobber (reg:CC FLAGS_REG))])]
7102   ""
7103   "")
7104
7105 (define_insn "*umulsi3_highpart_insn"
7106   [(set (match_operand:SI 0 "register_operand" "=d")
7107         (truncate:SI
7108           (lshiftrt:DI
7109             (mult:DI (zero_extend:DI
7110                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7111                      (zero_extend:DI
7112                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7113             (const_int 32))))
7114    (clobber (match_scratch:SI 3 "=1"))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7117   "mul{l}\t%2"
7118   [(set_attr "type" "imul")
7119    (set_attr "length_immediate" "0")
7120    (set (attr "athlon_decode")
7121      (if_then_else (eq_attr "cpu" "athlon")
7122         (const_string "vector")
7123         (const_string "double")))
7124    (set_attr "mode" "SI")])
7125
7126 (define_insn "*umulsi3_highpart_zext"
7127   [(set (match_operand:DI 0 "register_operand" "=d")
7128         (zero_extend:DI (truncate:SI
7129           (lshiftrt:DI
7130             (mult:DI (zero_extend:DI
7131                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7132                      (zero_extend:DI
7133                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7134             (const_int 32)))))
7135    (clobber (match_scratch:SI 3 "=1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT
7138    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139   "mul{l}\t%2"
7140   [(set_attr "type" "imul")
7141    (set_attr "length_immediate" "0")
7142    (set (attr "athlon_decode")
7143      (if_then_else (eq_attr "cpu" "athlon")
7144         (const_string "vector")
7145         (const_string "double")))
7146    (set_attr "mode" "SI")])
7147
7148 (define_expand "smuldi3_highpart"
7149   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7150                    (truncate:DI
7151                      (lshiftrt:TI
7152                        (mult:TI (sign_extend:TI
7153                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7154                                 (sign_extend:TI
7155                                   (match_operand:DI 2 "register_operand" "")))
7156                        (const_int 64))))
7157               (clobber (match_scratch:DI 3 ""))
7158               (clobber (reg:CC FLAGS_REG))])]
7159   "TARGET_64BIT"
7160   "")
7161
7162 (define_insn "*smuldi3_highpart_rex64"
7163   [(set (match_operand:DI 0 "register_operand" "=d")
7164         (truncate:DI
7165           (lshiftrt:TI
7166             (mult:TI (sign_extend:TI
7167                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7168                      (sign_extend:TI
7169                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7170             (const_int 64))))
7171    (clobber (match_scratch:DI 3 "=1"))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "TARGET_64BIT
7174    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7175   "imul{q}\t%2"
7176   [(set_attr "type" "imul")
7177    (set (attr "athlon_decode")
7178      (if_then_else (eq_attr "cpu" "athlon")
7179         (const_string "vector")
7180         (const_string "double")))
7181    (set_attr "mode" "DI")])
7182
7183 (define_expand "smulsi3_highpart"
7184   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7185                    (truncate:SI
7186                      (lshiftrt:DI
7187                        (mult:DI (sign_extend:DI
7188                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7189                                 (sign_extend:DI
7190                                   (match_operand:SI 2 "register_operand" "")))
7191                        (const_int 32))))
7192               (clobber (match_scratch:SI 3 ""))
7193               (clobber (reg:CC FLAGS_REG))])]
7194   ""
7195   "")
7196
7197 (define_insn "*smulsi3_highpart_insn"
7198   [(set (match_operand:SI 0 "register_operand" "=d")
7199         (truncate:SI
7200           (lshiftrt:DI
7201             (mult:DI (sign_extend:DI
7202                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7203                      (sign_extend:DI
7204                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7205             (const_int 32))))
7206    (clobber (match_scratch:SI 3 "=1"))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7209   "imul{l}\t%2"
7210   [(set_attr "type" "imul")
7211    (set (attr "athlon_decode")
7212      (if_then_else (eq_attr "cpu" "athlon")
7213         (const_string "vector")
7214         (const_string "double")))
7215    (set_attr "mode" "SI")])
7216
7217 (define_insn "*smulsi3_highpart_zext"
7218   [(set (match_operand:DI 0 "register_operand" "=d")
7219         (zero_extend:DI (truncate:SI
7220           (lshiftrt:DI
7221             (mult:DI (sign_extend:DI
7222                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7223                      (sign_extend:DI
7224                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7225             (const_int 32)))))
7226    (clobber (match_scratch:SI 3 "=1"))
7227    (clobber (reg:CC FLAGS_REG))]
7228   "TARGET_64BIT
7229    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7230   "imul{l}\t%2"
7231   [(set_attr "type" "imul")
7232    (set (attr "athlon_decode")
7233      (if_then_else (eq_attr "cpu" "athlon")
7234         (const_string "vector")
7235         (const_string "double")))
7236    (set_attr "mode" "SI")])
7237
7238 ;; The patterns that match these are at the end of this file.
7239
7240 (define_expand "mulxf3"
7241   [(set (match_operand:XF 0 "register_operand" "")
7242         (mult:XF (match_operand:XF 1 "register_operand" "")
7243                  (match_operand:XF 2 "register_operand" "")))]
7244   "TARGET_80387"
7245   "")
7246
7247 (define_expand "muldf3"
7248   [(set (match_operand:DF 0 "register_operand" "")
7249         (mult:DF (match_operand:DF 1 "register_operand" "")
7250                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7251   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7252   "")
7253
7254 (define_expand "mulsf3"
7255   [(set (match_operand:SF 0 "register_operand" "")
7256         (mult:SF (match_operand:SF 1 "register_operand" "")
7257                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7258   "TARGET_80387 || TARGET_SSE_MATH"
7259   "")
7260 \f
7261 ;; Divide instructions
7262
7263 (define_insn "divqi3"
7264   [(set (match_operand:QI 0 "register_operand" "=a")
7265         (div:QI (match_operand:HI 1 "register_operand" "0")
7266                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "TARGET_QIMODE_MATH"
7269   "idiv{b}\t%2"
7270   [(set_attr "type" "idiv")
7271    (set_attr "mode" "QI")])
7272
7273 (define_insn "udivqi3"
7274   [(set (match_operand:QI 0 "register_operand" "=a")
7275         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7276                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_QIMODE_MATH"
7279   "div{b}\t%2"
7280   [(set_attr "type" "idiv")
7281    (set_attr "mode" "QI")])
7282
7283 ;; The patterns that match these are at the end of this file.
7284
7285 (define_expand "divxf3"
7286   [(set (match_operand:XF 0 "register_operand" "")
7287         (div:XF (match_operand:XF 1 "register_operand" "")
7288                 (match_operand:XF 2 "register_operand" "")))]
7289   "TARGET_80387"
7290   "")
7291
7292 (define_expand "divdf3"
7293   [(set (match_operand:DF 0 "register_operand" "")
7294         (div:DF (match_operand:DF 1 "register_operand" "")
7295                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7296    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7297    "")
7298  
7299 (define_expand "divsf3"
7300   [(set (match_operand:SF 0 "register_operand" "")
7301         (div:SF (match_operand:SF 1 "register_operand" "")
7302                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7303   "TARGET_80387 || TARGET_SSE_MATH"
7304   "")
7305 \f
7306 ;; Remainder instructions.
7307
7308 (define_expand "divmoddi4"
7309   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7310                    (div:DI (match_operand:DI 1 "register_operand" "")
7311                            (match_operand:DI 2 "nonimmediate_operand" "")))
7312               (set (match_operand:DI 3 "register_operand" "")
7313                    (mod:DI (match_dup 1) (match_dup 2)))
7314               (clobber (reg:CC FLAGS_REG))])]
7315   "TARGET_64BIT"
7316   "")
7317
7318 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7319 ;; Penalize eax case slightly because it results in worse scheduling
7320 ;; of code.
7321 (define_insn "*divmoddi4_nocltd_rex64"
7322   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7323         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7324                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7325    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7326         (mod:DI (match_dup 2) (match_dup 3)))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7329   "#"
7330   [(set_attr "type" "multi")])
7331
7332 (define_insn "*divmoddi4_cltd_rex64"
7333   [(set (match_operand:DI 0 "register_operand" "=a")
7334         (div:DI (match_operand:DI 2 "register_operand" "a")
7335                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7336    (set (match_operand:DI 1 "register_operand" "=&d")
7337         (mod:DI (match_dup 2) (match_dup 3)))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7340   "#"
7341   [(set_attr "type" "multi")])
7342
7343 (define_insn "*divmoddi_noext_rex64"
7344   [(set (match_operand:DI 0 "register_operand" "=a")
7345         (div:DI (match_operand:DI 1 "register_operand" "0")
7346                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7347    (set (match_operand:DI 3 "register_operand" "=d")
7348         (mod:DI (match_dup 1) (match_dup 2)))
7349    (use (match_operand:DI 4 "register_operand" "3"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "TARGET_64BIT"
7352   "idiv{q}\t%2"
7353   [(set_attr "type" "idiv")
7354    (set_attr "mode" "DI")])
7355
7356 (define_split
7357   [(set (match_operand:DI 0 "register_operand" "")
7358         (div:DI (match_operand:DI 1 "register_operand" "")
7359                 (match_operand:DI 2 "nonimmediate_operand" "")))
7360    (set (match_operand:DI 3 "register_operand" "")
7361         (mod:DI (match_dup 1) (match_dup 2)))
7362    (clobber (reg:CC FLAGS_REG))]
7363   "TARGET_64BIT && reload_completed"
7364   [(parallel [(set (match_dup 3)
7365                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7366               (clobber (reg:CC FLAGS_REG))])
7367    (parallel [(set (match_dup 0)
7368                    (div:DI (reg:DI 0) (match_dup 2)))
7369               (set (match_dup 3)
7370                    (mod:DI (reg:DI 0) (match_dup 2)))
7371               (use (match_dup 3))
7372               (clobber (reg:CC FLAGS_REG))])]
7373 {
7374   /* Avoid use of cltd in favor of a mov+shift.  */
7375   if (!TARGET_USE_CLTD && !optimize_size)
7376     {
7377       if (true_regnum (operands[1]))
7378         emit_move_insn (operands[0], operands[1]);
7379       else
7380         emit_move_insn (operands[3], operands[1]);
7381       operands[4] = operands[3];
7382     }
7383   else
7384     {
7385       if (true_regnum (operands[1]))
7386         abort();
7387       operands[4] = operands[1];
7388     }
7389 })
7390
7391
7392 (define_expand "divmodsi4"
7393   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7394                    (div:SI (match_operand:SI 1 "register_operand" "")
7395                            (match_operand:SI 2 "nonimmediate_operand" "")))
7396               (set (match_operand:SI 3 "register_operand" "")
7397                    (mod:SI (match_dup 1) (match_dup 2)))
7398               (clobber (reg:CC FLAGS_REG))])]
7399   ""
7400   "")
7401
7402 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7403 ;; Penalize eax case slightly because it results in worse scheduling
7404 ;; of code.
7405 (define_insn "*divmodsi4_nocltd"
7406   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7407         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7408                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7409    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7410         (mod:SI (match_dup 2) (match_dup 3)))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "!optimize_size && !TARGET_USE_CLTD"
7413   "#"
7414   [(set_attr "type" "multi")])
7415
7416 (define_insn "*divmodsi4_cltd"
7417   [(set (match_operand:SI 0 "register_operand" "=a")
7418         (div:SI (match_operand:SI 2 "register_operand" "a")
7419                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7420    (set (match_operand:SI 1 "register_operand" "=&d")
7421         (mod:SI (match_dup 2) (match_dup 3)))
7422    (clobber (reg:CC FLAGS_REG))]
7423   "optimize_size || TARGET_USE_CLTD"
7424   "#"
7425   [(set_attr "type" "multi")])
7426
7427 (define_insn "*divmodsi_noext"
7428   [(set (match_operand:SI 0 "register_operand" "=a")
7429         (div:SI (match_operand:SI 1 "register_operand" "0")
7430                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7431    (set (match_operand:SI 3 "register_operand" "=d")
7432         (mod:SI (match_dup 1) (match_dup 2)))
7433    (use (match_operand:SI 4 "register_operand" "3"))
7434    (clobber (reg:CC FLAGS_REG))]
7435   ""
7436   "idiv{l}\t%2"
7437   [(set_attr "type" "idiv")
7438    (set_attr "mode" "SI")])
7439
7440 (define_split
7441   [(set (match_operand:SI 0 "register_operand" "")
7442         (div:SI (match_operand:SI 1 "register_operand" "")
7443                 (match_operand:SI 2 "nonimmediate_operand" "")))
7444    (set (match_operand:SI 3 "register_operand" "")
7445         (mod:SI (match_dup 1) (match_dup 2)))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "reload_completed"
7448   [(parallel [(set (match_dup 3)
7449                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7450               (clobber (reg:CC FLAGS_REG))])
7451    (parallel [(set (match_dup 0)
7452                    (div:SI (reg:SI 0) (match_dup 2)))
7453               (set (match_dup 3)
7454                    (mod:SI (reg:SI 0) (match_dup 2)))
7455               (use (match_dup 3))
7456               (clobber (reg:CC FLAGS_REG))])]
7457 {
7458   /* Avoid use of cltd in favor of a mov+shift.  */
7459   if (!TARGET_USE_CLTD && !optimize_size)
7460     {
7461       if (true_regnum (operands[1]))
7462         emit_move_insn (operands[0], operands[1]);
7463       else
7464         emit_move_insn (operands[3], operands[1]);
7465       operands[4] = operands[3];
7466     }
7467   else
7468     {
7469       if (true_regnum (operands[1]))
7470         abort();
7471       operands[4] = operands[1];
7472     }
7473 })
7474 ;; %%% Split me.
7475 (define_insn "divmodhi4"
7476   [(set (match_operand:HI 0 "register_operand" "=a")
7477         (div:HI (match_operand:HI 1 "register_operand" "0")
7478                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7479    (set (match_operand:HI 3 "register_operand" "=&d")
7480         (mod:HI (match_dup 1) (match_dup 2)))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "TARGET_HIMODE_MATH"
7483   "cwtd\;idiv{w}\t%2"
7484   [(set_attr "type" "multi")
7485    (set_attr "length_immediate" "0")
7486    (set_attr "mode" "SI")])
7487
7488 (define_insn "udivmoddi4"
7489   [(set (match_operand:DI 0 "register_operand" "=a")
7490         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7491                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7492    (set (match_operand:DI 3 "register_operand" "=&d")
7493         (umod:DI (match_dup 1) (match_dup 2)))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT"
7496   "xor{q}\t%3, %3\;div{q}\t%2"
7497   [(set_attr "type" "multi")
7498    (set_attr "length_immediate" "0")
7499    (set_attr "mode" "DI")])
7500
7501 (define_insn "*udivmoddi4_noext"
7502   [(set (match_operand:DI 0 "register_operand" "=a")
7503         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7504                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7505    (set (match_operand:DI 3 "register_operand" "=d")
7506         (umod:DI (match_dup 1) (match_dup 2)))
7507    (use (match_dup 3))
7508    (clobber (reg:CC FLAGS_REG))]
7509   "TARGET_64BIT"
7510   "div{q}\t%2"
7511   [(set_attr "type" "idiv")
7512    (set_attr "mode" "DI")])
7513
7514 (define_split
7515   [(set (match_operand:DI 0 "register_operand" "")
7516         (udiv:DI (match_operand:DI 1 "register_operand" "")
7517                  (match_operand:DI 2 "nonimmediate_operand" "")))
7518    (set (match_operand:DI 3 "register_operand" "")
7519         (umod:DI (match_dup 1) (match_dup 2)))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "TARGET_64BIT && reload_completed"
7522   [(set (match_dup 3) (const_int 0))
7523    (parallel [(set (match_dup 0)
7524                    (udiv:DI (match_dup 1) (match_dup 2)))
7525               (set (match_dup 3)
7526                    (umod:DI (match_dup 1) (match_dup 2)))
7527               (use (match_dup 3))
7528               (clobber (reg:CC FLAGS_REG))])]
7529   "")
7530
7531 (define_insn "udivmodsi4"
7532   [(set (match_operand:SI 0 "register_operand" "=a")
7533         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7534                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7535    (set (match_operand:SI 3 "register_operand" "=&d")
7536         (umod:SI (match_dup 1) (match_dup 2)))
7537    (clobber (reg:CC FLAGS_REG))]
7538   ""
7539   "xor{l}\t%3, %3\;div{l}\t%2"
7540   [(set_attr "type" "multi")
7541    (set_attr "length_immediate" "0")
7542    (set_attr "mode" "SI")])
7543
7544 (define_insn "*udivmodsi4_noext"
7545   [(set (match_operand:SI 0 "register_operand" "=a")
7546         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7547                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7548    (set (match_operand:SI 3 "register_operand" "=d")
7549         (umod:SI (match_dup 1) (match_dup 2)))
7550    (use (match_dup 3))
7551    (clobber (reg:CC FLAGS_REG))]
7552   ""
7553   "div{l}\t%2"
7554   [(set_attr "type" "idiv")
7555    (set_attr "mode" "SI")])
7556
7557 (define_split
7558   [(set (match_operand:SI 0 "register_operand" "")
7559         (udiv:SI (match_operand:SI 1 "register_operand" "")
7560                  (match_operand:SI 2 "nonimmediate_operand" "")))
7561    (set (match_operand:SI 3 "register_operand" "")
7562         (umod:SI (match_dup 1) (match_dup 2)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "reload_completed"
7565   [(set (match_dup 3) (const_int 0))
7566    (parallel [(set (match_dup 0)
7567                    (udiv:SI (match_dup 1) (match_dup 2)))
7568               (set (match_dup 3)
7569                    (umod:SI (match_dup 1) (match_dup 2)))
7570               (use (match_dup 3))
7571               (clobber (reg:CC FLAGS_REG))])]
7572   "")
7573
7574 (define_expand "udivmodhi4"
7575   [(set (match_dup 4) (const_int 0))
7576    (parallel [(set (match_operand:HI 0 "register_operand" "")
7577                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7578                             (match_operand:HI 2 "nonimmediate_operand" "")))
7579               (set (match_operand:HI 3 "register_operand" "")
7580                    (umod:HI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 4))
7582               (clobber (reg:CC FLAGS_REG))])]
7583   "TARGET_HIMODE_MATH"
7584   "operands[4] = gen_reg_rtx (HImode);")
7585
7586 (define_insn "*udivmodhi_noext"
7587   [(set (match_operand:HI 0 "register_operand" "=a")
7588         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7589                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7590    (set (match_operand:HI 3 "register_operand" "=d")
7591         (umod:HI (match_dup 1) (match_dup 2)))
7592    (use (match_operand:HI 4 "register_operand" "3"))
7593    (clobber (reg:CC FLAGS_REG))]
7594   ""
7595   "div{w}\t%2"
7596   [(set_attr "type" "idiv")
7597    (set_attr "mode" "HI")])
7598
7599 ;; We cannot use div/idiv for double division, because it causes
7600 ;; "division by zero" on the overflow and that's not what we expect
7601 ;; from truncate.  Because true (non truncating) double division is
7602 ;; never generated, we can't create this insn anyway.
7603 ;
7604 ;(define_insn ""
7605 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7606 ;       (truncate:SI
7607 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7608 ;                  (zero_extend:DI
7609 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7610 ;   (set (match_operand:SI 3 "register_operand" "=d")
7611 ;       (truncate:SI
7612 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7613 ;   (clobber (reg:CC FLAGS_REG))]
7614 ;  ""
7615 ;  "div{l}\t{%2, %0|%0, %2}"
7616 ;  [(set_attr "type" "idiv")])
7617 \f
7618 ;;- Logical AND instructions
7619
7620 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7621 ;; Note that this excludes ah.
7622
7623 (define_insn "*testdi_1_rex64"
7624   [(set (reg FLAGS_REG)
7625         (compare
7626           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7627                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7628           (const_int 0)))]
7629   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7630    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7631   "@
7632    test{l}\t{%k1, %k0|%k0, %k1}
7633    test{l}\t{%k1, %k0|%k0, %k1}
7634    test{q}\t{%1, %0|%0, %1}
7635    test{q}\t{%1, %0|%0, %1}
7636    test{q}\t{%1, %0|%0, %1}"
7637   [(set_attr "type" "test")
7638    (set_attr "modrm" "0,1,0,1,1")
7639    (set_attr "mode" "SI,SI,DI,DI,DI")
7640    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7641
7642 (define_insn "testsi_1"
7643   [(set (reg FLAGS_REG)
7644         (compare
7645           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7646                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7647           (const_int 0)))]
7648   "ix86_match_ccmode (insn, CCNOmode)
7649    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7650   "test{l}\t{%1, %0|%0, %1}"
7651   [(set_attr "type" "test")
7652    (set_attr "modrm" "0,1,1")
7653    (set_attr "mode" "SI")
7654    (set_attr "pent_pair" "uv,np,uv")])
7655
7656 (define_expand "testsi_ccno_1"
7657   [(set (reg:CCNO FLAGS_REG)
7658         (compare:CCNO
7659           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7660                   (match_operand:SI 1 "nonmemory_operand" ""))
7661           (const_int 0)))]
7662   ""
7663   "")
7664
7665 (define_insn "*testhi_1"
7666   [(set (reg FLAGS_REG)
7667         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7668                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7669                  (const_int 0)))]
7670   "ix86_match_ccmode (insn, CCNOmode)
7671    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7672   "test{w}\t{%1, %0|%0, %1}"
7673   [(set_attr "type" "test")
7674    (set_attr "modrm" "0,1,1")
7675    (set_attr "mode" "HI")
7676    (set_attr "pent_pair" "uv,np,uv")])
7677
7678 (define_expand "testqi_ccz_1"
7679   [(set (reg:CCZ FLAGS_REG)
7680         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7681                              (match_operand:QI 1 "nonmemory_operand" ""))
7682                  (const_int 0)))]
7683   ""
7684   "")
7685
7686 (define_insn "*testqi_1_maybe_si"
7687   [(set (reg FLAGS_REG)
7688         (compare
7689           (and:QI
7690             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7691             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7692           (const_int 0)))]
7693    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7694     && ix86_match_ccmode (insn,
7695                          GET_CODE (operands[1]) == CONST_INT
7696                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7697 {
7698   if (which_alternative == 3)
7699     {
7700       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7701         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7702       return "test{l}\t{%1, %k0|%k0, %1}";
7703     }
7704   return "test{b}\t{%1, %0|%0, %1}";
7705 }
7706   [(set_attr "type" "test")
7707    (set_attr "modrm" "0,1,1,1")
7708    (set_attr "mode" "QI,QI,QI,SI")
7709    (set_attr "pent_pair" "uv,np,uv,np")])
7710
7711 (define_insn "*testqi_1"
7712   [(set (reg FLAGS_REG)
7713         (compare
7714           (and:QI
7715             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7716             (match_operand:QI 1 "general_operand" "n,n,qn"))
7717           (const_int 0)))]
7718   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7719    && ix86_match_ccmode (insn, CCNOmode)"
7720   "test{b}\t{%1, %0|%0, %1}"
7721   [(set_attr "type" "test")
7722    (set_attr "modrm" "0,1,1")
7723    (set_attr "mode" "QI")
7724    (set_attr "pent_pair" "uv,np,uv")])
7725
7726 (define_expand "testqi_ext_ccno_0"
7727   [(set (reg:CCNO FLAGS_REG)
7728         (compare:CCNO
7729           (and:SI
7730             (zero_extract:SI
7731               (match_operand 0 "ext_register_operand" "")
7732               (const_int 8)
7733               (const_int 8))
7734             (match_operand 1 "const_int_operand" ""))
7735           (const_int 0)))]
7736   ""
7737   "")
7738
7739 (define_insn "*testqi_ext_0"
7740   [(set (reg FLAGS_REG)
7741         (compare
7742           (and:SI
7743             (zero_extract:SI
7744               (match_operand 0 "ext_register_operand" "Q")
7745               (const_int 8)
7746               (const_int 8))
7747             (match_operand 1 "const_int_operand" "n"))
7748           (const_int 0)))]
7749   "ix86_match_ccmode (insn, CCNOmode)"
7750   "test{b}\t{%1, %h0|%h0, %1}"
7751   [(set_attr "type" "test")
7752    (set_attr "mode" "QI")
7753    (set_attr "length_immediate" "1")
7754    (set_attr "pent_pair" "np")])
7755
7756 (define_insn "*testqi_ext_1"
7757   [(set (reg FLAGS_REG)
7758         (compare
7759           (and:SI
7760             (zero_extract:SI
7761               (match_operand 0 "ext_register_operand" "Q")
7762               (const_int 8)
7763               (const_int 8))
7764             (zero_extend:SI
7765               (match_operand:QI 1 "general_operand" "Qm")))
7766           (const_int 0)))]
7767   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7768    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7769   "test{b}\t{%1, %h0|%h0, %1}"
7770   [(set_attr "type" "test")
7771    (set_attr "mode" "QI")])
7772
7773 (define_insn "*testqi_ext_1_rex64"
7774   [(set (reg FLAGS_REG)
7775         (compare
7776           (and:SI
7777             (zero_extract:SI
7778               (match_operand 0 "ext_register_operand" "Q")
7779               (const_int 8)
7780               (const_int 8))
7781             (zero_extend:SI
7782               (match_operand:QI 1 "register_operand" "Q")))
7783           (const_int 0)))]
7784   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7785   "test{b}\t{%1, %h0|%h0, %1}"
7786   [(set_attr "type" "test")
7787    (set_attr "mode" "QI")])
7788
7789 (define_insn "*testqi_ext_2"
7790   [(set (reg FLAGS_REG)
7791         (compare
7792           (and:SI
7793             (zero_extract:SI
7794               (match_operand 0 "ext_register_operand" "Q")
7795               (const_int 8)
7796               (const_int 8))
7797             (zero_extract:SI
7798               (match_operand 1 "ext_register_operand" "Q")
7799               (const_int 8)
7800               (const_int 8)))
7801           (const_int 0)))]
7802   "ix86_match_ccmode (insn, CCNOmode)"
7803   "test{b}\t{%h1, %h0|%h0, %h1}"
7804   [(set_attr "type" "test")
7805    (set_attr "mode" "QI")])
7806
7807 ;; Combine likes to form bit extractions for some tests.  Humor it.
7808 (define_insn "*testqi_ext_3"
7809   [(set (reg FLAGS_REG)
7810         (compare (zero_extract:SI
7811                    (match_operand 0 "nonimmediate_operand" "rm")
7812                    (match_operand:SI 1 "const_int_operand" "")
7813                    (match_operand:SI 2 "const_int_operand" ""))
7814                  (const_int 0)))]
7815   "ix86_match_ccmode (insn, CCNOmode)
7816    && (GET_MODE (operands[0]) == SImode
7817        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7818        || GET_MODE (operands[0]) == HImode
7819        || GET_MODE (operands[0]) == QImode)"
7820   "#")
7821
7822 (define_insn "*testqi_ext_3_rex64"
7823   [(set (reg FLAGS_REG)
7824         (compare (zero_extract:DI
7825                    (match_operand 0 "nonimmediate_operand" "rm")
7826                    (match_operand:DI 1 "const_int_operand" "")
7827                    (match_operand:DI 2 "const_int_operand" ""))
7828                  (const_int 0)))]
7829   "TARGET_64BIT
7830    && ix86_match_ccmode (insn, CCNOmode)
7831    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7832    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7833    /* Ensure that resulting mask is zero or sign extended operand.  */
7834    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7835        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7836            && INTVAL (operands[1]) > 32))
7837    && (GET_MODE (operands[0]) == SImode
7838        || GET_MODE (operands[0]) == DImode
7839        || GET_MODE (operands[0]) == HImode
7840        || GET_MODE (operands[0]) == QImode)"
7841   "#")
7842
7843 (define_split
7844   [(set (match_operand 0 "flags_reg_operand" "")
7845         (match_operator 1 "compare_operator"
7846           [(zero_extract
7847              (match_operand 2 "nonimmediate_operand" "")
7848              (match_operand 3 "const_int_operand" "")
7849              (match_operand 4 "const_int_operand" ""))
7850            (const_int 0)]))]
7851   "ix86_match_ccmode (insn, CCNOmode)"
7852   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7853 {
7854   rtx val = operands[2];
7855   HOST_WIDE_INT len = INTVAL (operands[3]);
7856   HOST_WIDE_INT pos = INTVAL (operands[4]);
7857   HOST_WIDE_INT mask;
7858   enum machine_mode mode, submode;
7859
7860   mode = GET_MODE (val);
7861   if (GET_CODE (val) == MEM)
7862     {
7863       /* ??? Combine likes to put non-volatile mem extractions in QImode
7864          no matter the size of the test.  So find a mode that works.  */
7865       if (! MEM_VOLATILE_P (val))
7866         {
7867           mode = smallest_mode_for_size (pos + len, MODE_INT);
7868           val = adjust_address (val, mode, 0);
7869         }
7870     }
7871   else if (GET_CODE (val) == SUBREG
7872            && (submode = GET_MODE (SUBREG_REG (val)),
7873                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7874            && pos + len <= GET_MODE_BITSIZE (submode))
7875     {
7876       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7877       mode = submode;
7878       val = SUBREG_REG (val);
7879     }
7880   else if (mode == HImode && pos + len <= 8)
7881     {
7882       /* Small HImode tests can be converted to QImode.  */
7883       mode = QImode;
7884       val = gen_lowpart (QImode, val);
7885     }
7886
7887   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7888   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7889
7890   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7891 })
7892
7893 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7894 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7895 ;; this is relatively important trick.
7896 ;; Do the conversion only post-reload to avoid limiting of the register class
7897 ;; to QI regs.
7898 (define_split
7899   [(set (match_operand 0 "flags_reg_operand" "")
7900         (match_operator 1 "compare_operator"
7901           [(and (match_operand 2 "register_operand" "")
7902                 (match_operand 3 "const_int_operand" ""))
7903            (const_int 0)]))]
7904    "reload_completed
7905     && QI_REG_P (operands[2])
7906     && GET_MODE (operands[2]) != QImode
7907     && ((ix86_match_ccmode (insn, CCZmode)
7908          && !(INTVAL (operands[3]) & ~(255 << 8)))
7909         || (ix86_match_ccmode (insn, CCNOmode)
7910             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7911   [(set (match_dup 0)
7912         (match_op_dup 1
7913           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7914                    (match_dup 3))
7915            (const_int 0)]))]
7916   "operands[2] = gen_lowpart (SImode, operands[2]);
7917    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7918
7919 (define_split
7920   [(set (match_operand 0 "flags_reg_operand" "")
7921         (match_operator 1 "compare_operator"
7922           [(and (match_operand 2 "nonimmediate_operand" "")
7923                 (match_operand 3 "const_int_operand" ""))
7924            (const_int 0)]))]
7925    "reload_completed
7926     && GET_MODE (operands[2]) != QImode
7927     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7928     && ((ix86_match_ccmode (insn, CCZmode)
7929          && !(INTVAL (operands[3]) & ~255))
7930         || (ix86_match_ccmode (insn, CCNOmode)
7931             && !(INTVAL (operands[3]) & ~127)))"
7932   [(set (match_dup 0)
7933         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7934                          (const_int 0)]))]
7935   "operands[2] = gen_lowpart (QImode, operands[2]);
7936    operands[3] = gen_lowpart (QImode, operands[3]);")
7937
7938
7939 ;; %%% This used to optimize known byte-wide and operations to memory,
7940 ;; and sometimes to QImode registers.  If this is considered useful,
7941 ;; it should be done with splitters.
7942
7943 (define_expand "anddi3"
7944   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7945         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7946                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7947    (clobber (reg:CC FLAGS_REG))]
7948   "TARGET_64BIT"
7949   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7950
7951 (define_insn "*anddi_1_rex64"
7952   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7953         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7954                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7955    (clobber (reg:CC FLAGS_REG))]
7956   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7957 {
7958   switch (get_attr_type (insn))
7959     {
7960     case TYPE_IMOVX:
7961       {
7962         enum machine_mode mode;
7963
7964         if (GET_CODE (operands[2]) != CONST_INT)
7965           abort ();
7966         if (INTVAL (operands[2]) == 0xff)
7967           mode = QImode;
7968         else if (INTVAL (operands[2]) == 0xffff)
7969           mode = HImode;
7970         else
7971           abort ();
7972         
7973         operands[1] = gen_lowpart (mode, operands[1]);
7974         if (mode == QImode)
7975           return "movz{bq|x}\t{%1,%0|%0, %1}";
7976         else
7977           return "movz{wq|x}\t{%1,%0|%0, %1}";
7978       }
7979
7980     default:
7981       if (! rtx_equal_p (operands[0], operands[1]))
7982         abort ();
7983       if (get_attr_mode (insn) == MODE_SI)
7984         return "and{l}\t{%k2, %k0|%k0, %k2}";
7985       else
7986         return "and{q}\t{%2, %0|%0, %2}";
7987     }
7988 }
7989   [(set_attr "type" "alu,alu,alu,imovx")
7990    (set_attr "length_immediate" "*,*,*,0")
7991    (set_attr "mode" "SI,DI,DI,DI")])
7992
7993 (define_insn "*anddi_2"
7994   [(set (reg FLAGS_REG)
7995         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7996                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7997                  (const_int 0)))
7998    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7999         (and:DI (match_dup 1) (match_dup 2)))]
8000   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8001    && ix86_binary_operator_ok (AND, DImode, operands)"
8002   "@
8003    and{l}\t{%k2, %k0|%k0, %k2}
8004    and{q}\t{%2, %0|%0, %2}
8005    and{q}\t{%2, %0|%0, %2}"
8006   [(set_attr "type" "alu")
8007    (set_attr "mode" "SI,DI,DI")])
8008
8009 (define_expand "andsi3"
8010   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8011         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8012                 (match_operand:SI 2 "general_operand" "")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   ""
8015   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8016
8017 (define_insn "*andsi_1"
8018   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8019         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8020                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8021    (clobber (reg:CC FLAGS_REG))]
8022   "ix86_binary_operator_ok (AND, SImode, operands)"
8023 {
8024   switch (get_attr_type (insn))
8025     {
8026     case TYPE_IMOVX:
8027       {
8028         enum machine_mode mode;
8029
8030         if (GET_CODE (operands[2]) != CONST_INT)
8031           abort ();
8032         if (INTVAL (operands[2]) == 0xff)
8033           mode = QImode;
8034         else if (INTVAL (operands[2]) == 0xffff)
8035           mode = HImode;
8036         else
8037           abort ();
8038         
8039         operands[1] = gen_lowpart (mode, operands[1]);
8040         if (mode == QImode)
8041           return "movz{bl|x}\t{%1,%0|%0, %1}";
8042         else
8043           return "movz{wl|x}\t{%1,%0|%0, %1}";
8044       }
8045
8046     default:
8047       if (! rtx_equal_p (operands[0], operands[1]))
8048         abort ();
8049       return "and{l}\t{%2, %0|%0, %2}";
8050     }
8051 }
8052   [(set_attr "type" "alu,alu,imovx")
8053    (set_attr "length_immediate" "*,*,0")
8054    (set_attr "mode" "SI")])
8055
8056 (define_split
8057   [(set (match_operand 0 "register_operand" "")
8058         (and (match_dup 0)
8059              (const_int -65536)))
8060    (clobber (reg:CC FLAGS_REG))]
8061   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8062   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8063   "operands[1] = gen_lowpart (HImode, operands[0]);")
8064
8065 (define_split
8066   [(set (match_operand 0 "ext_register_operand" "")
8067         (and (match_dup 0)
8068              (const_int -256)))
8069    (clobber (reg:CC FLAGS_REG))]
8070   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8071   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8072   "operands[1] = gen_lowpart (QImode, operands[0]);")
8073
8074 (define_split
8075   [(set (match_operand 0 "ext_register_operand" "")
8076         (and (match_dup 0)
8077              (const_int -65281)))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8080   [(parallel [(set (zero_extract:SI (match_dup 0)
8081                                     (const_int 8)
8082                                     (const_int 8))
8083                    (xor:SI 
8084                      (zero_extract:SI (match_dup 0)
8085                                       (const_int 8)
8086                                       (const_int 8))
8087                      (zero_extract:SI (match_dup 0)
8088                                       (const_int 8)
8089                                       (const_int 8))))
8090               (clobber (reg:CC FLAGS_REG))])]
8091   "operands[0] = gen_lowpart (SImode, operands[0]);")
8092
8093 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8094 (define_insn "*andsi_1_zext"
8095   [(set (match_operand:DI 0 "register_operand" "=r")
8096         (zero_extend:DI
8097           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8098                   (match_operand:SI 2 "general_operand" "rim"))))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8101   "and{l}\t{%2, %k0|%k0, %2}"
8102   [(set_attr "type" "alu")
8103    (set_attr "mode" "SI")])
8104
8105 (define_insn "*andsi_2"
8106   [(set (reg FLAGS_REG)
8107         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8108                          (match_operand:SI 2 "general_operand" "rim,ri"))
8109                  (const_int 0)))
8110    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8111         (and:SI (match_dup 1) (match_dup 2)))]
8112   "ix86_match_ccmode (insn, CCNOmode)
8113    && ix86_binary_operator_ok (AND, SImode, operands)"
8114   "and{l}\t{%2, %0|%0, %2}"
8115   [(set_attr "type" "alu")
8116    (set_attr "mode" "SI")])
8117
8118 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8119 (define_insn "*andsi_2_zext"
8120   [(set (reg FLAGS_REG)
8121         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8122                          (match_operand:SI 2 "general_operand" "rim"))
8123                  (const_int 0)))
8124    (set (match_operand:DI 0 "register_operand" "=r")
8125         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8126   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8127    && ix86_binary_operator_ok (AND, SImode, operands)"
8128   "and{l}\t{%2, %k0|%k0, %2}"
8129   [(set_attr "type" "alu")
8130    (set_attr "mode" "SI")])
8131
8132 (define_expand "andhi3"
8133   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8134         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8135                 (match_operand:HI 2 "general_operand" "")))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "TARGET_HIMODE_MATH"
8138   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8139
8140 (define_insn "*andhi_1"
8141   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8142         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8143                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8144    (clobber (reg:CC FLAGS_REG))]
8145   "ix86_binary_operator_ok (AND, HImode, operands)"
8146 {
8147   switch (get_attr_type (insn))
8148     {
8149     case TYPE_IMOVX:
8150       if (GET_CODE (operands[2]) != CONST_INT)
8151         abort ();
8152       if (INTVAL (operands[2]) == 0xff)
8153         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8154       abort ();
8155
8156     default:
8157       if (! rtx_equal_p (operands[0], operands[1]))
8158         abort ();
8159
8160       return "and{w}\t{%2, %0|%0, %2}";
8161     }
8162 }
8163   [(set_attr "type" "alu,alu,imovx")
8164    (set_attr "length_immediate" "*,*,0")
8165    (set_attr "mode" "HI,HI,SI")])
8166
8167 (define_insn "*andhi_2"
8168   [(set (reg FLAGS_REG)
8169         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8170                          (match_operand:HI 2 "general_operand" "rim,ri"))
8171                  (const_int 0)))
8172    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8173         (and:HI (match_dup 1) (match_dup 2)))]
8174   "ix86_match_ccmode (insn, CCNOmode)
8175    && ix86_binary_operator_ok (AND, HImode, operands)"
8176   "and{w}\t{%2, %0|%0, %2}"
8177   [(set_attr "type" "alu")
8178    (set_attr "mode" "HI")])
8179
8180 (define_expand "andqi3"
8181   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8182         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8183                 (match_operand:QI 2 "general_operand" "")))
8184    (clobber (reg:CC FLAGS_REG))]
8185   "TARGET_QIMODE_MATH"
8186   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8187
8188 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8189 (define_insn "*andqi_1"
8190   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8191         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8192                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8193    (clobber (reg:CC FLAGS_REG))]
8194   "ix86_binary_operator_ok (AND, QImode, operands)"
8195   "@
8196    and{b}\t{%2, %0|%0, %2}
8197    and{b}\t{%2, %0|%0, %2}
8198    and{l}\t{%k2, %k0|%k0, %k2}"
8199   [(set_attr "type" "alu")
8200    (set_attr "mode" "QI,QI,SI")])
8201
8202 (define_insn "*andqi_1_slp"
8203   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8204         (and:QI (match_dup 0)
8205                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8208    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8209   "and{b}\t{%1, %0|%0, %1}"
8210   [(set_attr "type" "alu1")
8211    (set_attr "mode" "QI")])
8212
8213 (define_insn "*andqi_2_maybe_si"
8214   [(set (reg FLAGS_REG)
8215         (compare (and:QI
8216                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8217                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8218                  (const_int 0)))
8219    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8220         (and:QI (match_dup 1) (match_dup 2)))]
8221   "ix86_binary_operator_ok (AND, QImode, operands)
8222    && ix86_match_ccmode (insn,
8223                          GET_CODE (operands[2]) == CONST_INT
8224                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8225 {
8226   if (which_alternative == 2)
8227     {
8228       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8229         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8230       return "and{l}\t{%2, %k0|%k0, %2}";
8231     }
8232   return "and{b}\t{%2, %0|%0, %2}";
8233 }
8234   [(set_attr "type" "alu")
8235    (set_attr "mode" "QI,QI,SI")])
8236
8237 (define_insn "*andqi_2"
8238   [(set (reg FLAGS_REG)
8239         (compare (and:QI
8240                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8241                    (match_operand:QI 2 "general_operand" "qim,qi"))
8242                  (const_int 0)))
8243    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8244         (and:QI (match_dup 1) (match_dup 2)))]
8245   "ix86_match_ccmode (insn, CCNOmode)
8246    && ix86_binary_operator_ok (AND, QImode, operands)"
8247   "and{b}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "QI")])
8250
8251 (define_insn "*andqi_2_slp"
8252   [(set (reg FLAGS_REG)
8253         (compare (and:QI
8254                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8255                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8256                  (const_int 0)))
8257    (set (strict_low_part (match_dup 0))
8258         (and:QI (match_dup 0) (match_dup 1)))]
8259   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8260    && ix86_match_ccmode (insn, CCNOmode)
8261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262   "and{b}\t{%1, %0|%0, %1}"
8263   [(set_attr "type" "alu1")
8264    (set_attr "mode" "QI")])
8265
8266 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8267 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8268 ;; for a QImode operand, which of course failed.
8269
8270 (define_insn "andqi_ext_0"
8271   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272                          (const_int 8)
8273                          (const_int 8))
8274         (and:SI 
8275           (zero_extract:SI
8276             (match_operand 1 "ext_register_operand" "0")
8277             (const_int 8)
8278             (const_int 8))
8279           (match_operand 2 "const_int_operand" "n")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   ""
8282   "and{b}\t{%2, %h0|%h0, %2}"
8283   [(set_attr "type" "alu")
8284    (set_attr "length_immediate" "1")
8285    (set_attr "mode" "QI")])
8286
8287 ;; Generated by peephole translating test to and.  This shows up
8288 ;; often in fp comparisons.
8289
8290 (define_insn "*andqi_ext_0_cc"
8291   [(set (reg FLAGS_REG)
8292         (compare
8293           (and:SI
8294             (zero_extract:SI
8295               (match_operand 1 "ext_register_operand" "0")
8296               (const_int 8)
8297               (const_int 8))
8298             (match_operand 2 "const_int_operand" "n"))
8299           (const_int 0)))
8300    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8301                          (const_int 8)
8302                          (const_int 8))
8303         (and:SI 
8304           (zero_extract:SI
8305             (match_dup 1)
8306             (const_int 8)
8307             (const_int 8))
8308           (match_dup 2)))]
8309   "ix86_match_ccmode (insn, CCNOmode)"
8310   "and{b}\t{%2, %h0|%h0, %2}"
8311   [(set_attr "type" "alu")
8312    (set_attr "length_immediate" "1")
8313    (set_attr "mode" "QI")])
8314
8315 (define_insn "*andqi_ext_1"
8316   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8317                          (const_int 8)
8318                          (const_int 8))
8319         (and:SI 
8320           (zero_extract:SI
8321             (match_operand 1 "ext_register_operand" "0")
8322             (const_int 8)
8323             (const_int 8))
8324           (zero_extend:SI
8325             (match_operand:QI 2 "general_operand" "Qm"))))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "!TARGET_64BIT"
8328   "and{b}\t{%2, %h0|%h0, %2}"
8329   [(set_attr "type" "alu")
8330    (set_attr "length_immediate" "0")
8331    (set_attr "mode" "QI")])
8332
8333 (define_insn "*andqi_ext_1_rex64"
8334   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8335                          (const_int 8)
8336                          (const_int 8))
8337         (and:SI 
8338           (zero_extract:SI
8339             (match_operand 1 "ext_register_operand" "0")
8340             (const_int 8)
8341             (const_int 8))
8342           (zero_extend:SI
8343             (match_operand 2 "ext_register_operand" "Q"))))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "TARGET_64BIT"
8346   "and{b}\t{%2, %h0|%h0, %2}"
8347   [(set_attr "type" "alu")
8348    (set_attr "length_immediate" "0")
8349    (set_attr "mode" "QI")])
8350
8351 (define_insn "*andqi_ext_2"
8352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8353                          (const_int 8)
8354                          (const_int 8))
8355         (and:SI
8356           (zero_extract:SI
8357             (match_operand 1 "ext_register_operand" "%0")
8358             (const_int 8)
8359             (const_int 8))
8360           (zero_extract:SI
8361             (match_operand 2 "ext_register_operand" "Q")
8362             (const_int 8)
8363             (const_int 8))))
8364    (clobber (reg:CC FLAGS_REG))]
8365   ""
8366   "and{b}\t{%h2, %h0|%h0, %h2}"
8367   [(set_attr "type" "alu")
8368    (set_attr "length_immediate" "0")
8369    (set_attr "mode" "QI")])
8370
8371 ;; Convert wide AND instructions with immediate operand to shorter QImode
8372 ;; equivalents when possible.
8373 ;; Don't do the splitting with memory operands, since it introduces risk
8374 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8375 ;; for size, but that can (should?) be handled by generic code instead.
8376 (define_split
8377   [(set (match_operand 0 "register_operand" "")
8378         (and (match_operand 1 "register_operand" "")
8379              (match_operand 2 "const_int_operand" "")))
8380    (clobber (reg:CC FLAGS_REG))]
8381    "reload_completed
8382     && QI_REG_P (operands[0])
8383     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8384     && !(~INTVAL (operands[2]) & ~(255 << 8))
8385     && GET_MODE (operands[0]) != QImode"
8386   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8387                    (and:SI (zero_extract:SI (match_dup 1)
8388                                             (const_int 8) (const_int 8))
8389                            (match_dup 2)))
8390               (clobber (reg:CC FLAGS_REG))])]
8391   "operands[0] = gen_lowpart (SImode, operands[0]);
8392    operands[1] = gen_lowpart (SImode, operands[1]);
8393    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8394
8395 ;; Since AND can be encoded with sign extended immediate, this is only
8396 ;; profitable when 7th bit is not set.
8397 (define_split
8398   [(set (match_operand 0 "register_operand" "")
8399         (and (match_operand 1 "general_operand" "")
8400              (match_operand 2 "const_int_operand" "")))
8401    (clobber (reg:CC FLAGS_REG))]
8402    "reload_completed
8403     && ANY_QI_REG_P (operands[0])
8404     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8405     && !(~INTVAL (operands[2]) & ~255)
8406     && !(INTVAL (operands[2]) & 128)
8407     && GET_MODE (operands[0]) != QImode"
8408   [(parallel [(set (strict_low_part (match_dup 0))
8409                    (and:QI (match_dup 1)
8410                            (match_dup 2)))
8411               (clobber (reg:CC FLAGS_REG))])]
8412   "operands[0] = gen_lowpart (QImode, operands[0]);
8413    operands[1] = gen_lowpart (QImode, operands[1]);
8414    operands[2] = gen_lowpart (QImode, operands[2]);")
8415 \f
8416 ;; Logical inclusive OR instructions
8417
8418 ;; %%% This used to optimize known byte-wide and operations to memory.
8419 ;; If this is considered useful, it should be done with splitters.
8420
8421 (define_expand "iordi3"
8422   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8423         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8424                 (match_operand:DI 2 "x86_64_general_operand" "")))
8425    (clobber (reg:CC FLAGS_REG))]
8426   "TARGET_64BIT"
8427   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8428
8429 (define_insn "*iordi_1_rex64"
8430   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8431         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8432                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8433    (clobber (reg:CC FLAGS_REG))]
8434   "TARGET_64BIT
8435    && ix86_binary_operator_ok (IOR, DImode, operands)"
8436   "or{q}\t{%2, %0|%0, %2}"
8437   [(set_attr "type" "alu")
8438    (set_attr "mode" "DI")])
8439
8440 (define_insn "*iordi_2_rex64"
8441   [(set (reg FLAGS_REG)
8442         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8443                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8444                  (const_int 0)))
8445    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8446         (ior:DI (match_dup 1) (match_dup 2)))]
8447   "TARGET_64BIT
8448    && ix86_match_ccmode (insn, CCNOmode)
8449    && ix86_binary_operator_ok (IOR, DImode, operands)"
8450   "or{q}\t{%2, %0|%0, %2}"
8451   [(set_attr "type" "alu")
8452    (set_attr "mode" "DI")])
8453
8454 (define_insn "*iordi_3_rex64"
8455   [(set (reg FLAGS_REG)
8456         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8457                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8458                  (const_int 0)))
8459    (clobber (match_scratch:DI 0 "=r"))]
8460   "TARGET_64BIT
8461    && ix86_match_ccmode (insn, CCNOmode)
8462    && ix86_binary_operator_ok (IOR, DImode, operands)"
8463   "or{q}\t{%2, %0|%0, %2}"
8464   [(set_attr "type" "alu")
8465    (set_attr "mode" "DI")])
8466
8467
8468 (define_expand "iorsi3"
8469   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8470         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8471                 (match_operand:SI 2 "general_operand" "")))
8472    (clobber (reg:CC FLAGS_REG))]
8473   ""
8474   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8475
8476 (define_insn "*iorsi_1"
8477   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8478         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8479                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "ix86_binary_operator_ok (IOR, SImode, operands)"
8482   "or{l}\t{%2, %0|%0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "mode" "SI")])
8485
8486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8487 (define_insn "*iorsi_1_zext"
8488   [(set (match_operand:DI 0 "register_operand" "=rm")
8489         (zero_extend:DI
8490           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8491                   (match_operand:SI 2 "general_operand" "rim"))))
8492    (clobber (reg:CC FLAGS_REG))]
8493   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8494   "or{l}\t{%2, %k0|%k0, %2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "mode" "SI")])
8497
8498 (define_insn "*iorsi_1_zext_imm"
8499   [(set (match_operand:DI 0 "register_operand" "=rm")
8500         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8501                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "TARGET_64BIT"
8504   "or{l}\t{%2, %k0|%k0, %2}"
8505   [(set_attr "type" "alu")
8506    (set_attr "mode" "SI")])
8507
8508 (define_insn "*iorsi_2"
8509   [(set (reg FLAGS_REG)
8510         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8511                          (match_operand:SI 2 "general_operand" "rim,ri"))
8512                  (const_int 0)))
8513    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8514         (ior:SI (match_dup 1) (match_dup 2)))]
8515   "ix86_match_ccmode (insn, CCNOmode)
8516    && ix86_binary_operator_ok (IOR, SImode, operands)"
8517   "or{l}\t{%2, %0|%0, %2}"
8518   [(set_attr "type" "alu")
8519    (set_attr "mode" "SI")])
8520
8521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8522 ;; ??? Special case for immediate operand is missing - it is tricky.
8523 (define_insn "*iorsi_2_zext"
8524   [(set (reg FLAGS_REG)
8525         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8526                          (match_operand:SI 2 "general_operand" "rim"))
8527                  (const_int 0)))
8528    (set (match_operand:DI 0 "register_operand" "=r")
8529         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8530   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8531    && ix86_binary_operator_ok (IOR, SImode, operands)"
8532   "or{l}\t{%2, %k0|%k0, %2}"
8533   [(set_attr "type" "alu")
8534    (set_attr "mode" "SI")])
8535
8536 (define_insn "*iorsi_2_zext_imm"
8537   [(set (reg FLAGS_REG)
8538         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8539                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8540                  (const_int 0)))
8541    (set (match_operand:DI 0 "register_operand" "=r")
8542         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8543   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8544    && ix86_binary_operator_ok (IOR, SImode, operands)"
8545   "or{l}\t{%2, %k0|%k0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "mode" "SI")])
8548
8549 (define_insn "*iorsi_3"
8550   [(set (reg FLAGS_REG)
8551         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8552                          (match_operand:SI 2 "general_operand" "rim"))
8553                  (const_int 0)))
8554    (clobber (match_scratch:SI 0 "=r"))]
8555   "ix86_match_ccmode (insn, CCNOmode)
8556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8557   "or{l}\t{%2, %0|%0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "SI")])
8560
8561 (define_expand "iorhi3"
8562   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8563         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8564                 (match_operand:HI 2 "general_operand" "")))
8565    (clobber (reg:CC FLAGS_REG))]
8566   "TARGET_HIMODE_MATH"
8567   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8568
8569 (define_insn "*iorhi_1"
8570   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8571         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8572                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8573    (clobber (reg:CC FLAGS_REG))]
8574   "ix86_binary_operator_ok (IOR, HImode, operands)"
8575   "or{w}\t{%2, %0|%0, %2}"
8576   [(set_attr "type" "alu")
8577    (set_attr "mode" "HI")])
8578
8579 (define_insn "*iorhi_2"
8580   [(set (reg FLAGS_REG)
8581         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8582                          (match_operand:HI 2 "general_operand" "rim,ri"))
8583                  (const_int 0)))
8584    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8585         (ior:HI (match_dup 1) (match_dup 2)))]
8586   "ix86_match_ccmode (insn, CCNOmode)
8587    && ix86_binary_operator_ok (IOR, HImode, operands)"
8588   "or{w}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "HI")])
8591
8592 (define_insn "*iorhi_3"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8595                          (match_operand:HI 2 "general_operand" "rim"))
8596                  (const_int 0)))
8597    (clobber (match_scratch:HI 0 "=r"))]
8598   "ix86_match_ccmode (insn, CCNOmode)
8599    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8600   "or{w}\t{%2, %0|%0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "HI")])
8603
8604 (define_expand "iorqi3"
8605   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8606         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8607                 (match_operand:QI 2 "general_operand" "")))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "TARGET_QIMODE_MATH"
8610   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8611
8612 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8613 (define_insn "*iorqi_1"
8614   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8615         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8616                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8617    (clobber (reg:CC FLAGS_REG))]
8618   "ix86_binary_operator_ok (IOR, QImode, operands)"
8619   "@
8620    or{b}\t{%2, %0|%0, %2}
8621    or{b}\t{%2, %0|%0, %2}
8622    or{l}\t{%k2, %k0|%k0, %k2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "QI,QI,SI")])
8625
8626 (define_insn "*iorqi_1_slp"
8627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8628         (ior:QI (match_dup 0)
8629                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8632    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8633   "or{b}\t{%1, %0|%0, %1}"
8634   [(set_attr "type" "alu1")
8635    (set_attr "mode" "QI")])
8636
8637 (define_insn "*iorqi_2"
8638   [(set (reg FLAGS_REG)
8639         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8640                          (match_operand:QI 2 "general_operand" "qim,qi"))
8641                  (const_int 0)))
8642    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8643         (ior:QI (match_dup 1) (match_dup 2)))]
8644   "ix86_match_ccmode (insn, CCNOmode)
8645    && ix86_binary_operator_ok (IOR, QImode, operands)"
8646   "or{b}\t{%2, %0|%0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "QI")])
8649
8650 (define_insn "*iorqi_2_slp"
8651   [(set (reg FLAGS_REG)
8652         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8653                          (match_operand:QI 1 "general_operand" "qim,qi"))
8654                  (const_int 0)))
8655    (set (strict_low_part (match_dup 0))
8656         (ior:QI (match_dup 0) (match_dup 1)))]
8657   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8658    && ix86_match_ccmode (insn, CCNOmode)
8659    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8660   "or{b}\t{%1, %0|%0, %1}"
8661   [(set_attr "type" "alu1")
8662    (set_attr "mode" "QI")])
8663
8664 (define_insn "*iorqi_3"
8665   [(set (reg FLAGS_REG)
8666         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8667                          (match_operand:QI 2 "general_operand" "qim"))
8668                  (const_int 0)))
8669    (clobber (match_scratch:QI 0 "=q"))]
8670   "ix86_match_ccmode (insn, CCNOmode)
8671    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8672   "or{b}\t{%2, %0|%0, %2}"
8673   [(set_attr "type" "alu")
8674    (set_attr "mode" "QI")])
8675
8676 (define_insn "iorqi_ext_0"
8677   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8678                          (const_int 8)
8679                          (const_int 8))
8680         (ior:SI 
8681           (zero_extract:SI
8682             (match_operand 1 "ext_register_operand" "0")
8683             (const_int 8)
8684             (const_int 8))
8685           (match_operand 2 "const_int_operand" "n")))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8688   "or{b}\t{%2, %h0|%h0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "length_immediate" "1")
8691    (set_attr "mode" "QI")])
8692
8693 (define_insn "*iorqi_ext_1"
8694   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8695                          (const_int 8)
8696                          (const_int 8))
8697         (ior:SI 
8698           (zero_extract:SI
8699             (match_operand 1 "ext_register_operand" "0")
8700             (const_int 8)
8701             (const_int 8))
8702           (zero_extend:SI
8703             (match_operand:QI 2 "general_operand" "Qm"))))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "!TARGET_64BIT
8706    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8707   "or{b}\t{%2, %h0|%h0, %2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "length_immediate" "0")
8710    (set_attr "mode" "QI")])
8711
8712 (define_insn "*iorqi_ext_1_rex64"
8713   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8714                          (const_int 8)
8715                          (const_int 8))
8716         (ior:SI 
8717           (zero_extract:SI
8718             (match_operand 1 "ext_register_operand" "0")
8719             (const_int 8)
8720             (const_int 8))
8721           (zero_extend:SI
8722             (match_operand 2 "ext_register_operand" "Q"))))
8723    (clobber (reg:CC FLAGS_REG))]
8724   "TARGET_64BIT
8725    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8726   "or{b}\t{%2, %h0|%h0, %2}"
8727   [(set_attr "type" "alu")
8728    (set_attr "length_immediate" "0")
8729    (set_attr "mode" "QI")])
8730
8731 (define_insn "*iorqi_ext_2"
8732   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8733                          (const_int 8)
8734                          (const_int 8))
8735         (ior:SI 
8736           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8737                            (const_int 8)
8738                            (const_int 8))
8739           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8740                            (const_int 8)
8741                            (const_int 8))))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8744   "ior{b}\t{%h2, %h0|%h0, %h2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "length_immediate" "0")
8747    (set_attr "mode" "QI")])
8748
8749 (define_split
8750   [(set (match_operand 0 "register_operand" "")
8751         (ior (match_operand 1 "register_operand" "")
8752              (match_operand 2 "const_int_operand" "")))
8753    (clobber (reg:CC FLAGS_REG))]
8754    "reload_completed
8755     && QI_REG_P (operands[0])
8756     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8757     && !(INTVAL (operands[2]) & ~(255 << 8))
8758     && GET_MODE (operands[0]) != QImode"
8759   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8760                    (ior:SI (zero_extract:SI (match_dup 1)
8761                                             (const_int 8) (const_int 8))
8762                            (match_dup 2)))
8763               (clobber (reg:CC FLAGS_REG))])]
8764   "operands[0] = gen_lowpart (SImode, operands[0]);
8765    operands[1] = gen_lowpart (SImode, operands[1]);
8766    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8767
8768 ;; Since OR can be encoded with sign extended immediate, this is only
8769 ;; profitable when 7th bit is set.
8770 (define_split
8771   [(set (match_operand 0 "register_operand" "")
8772         (ior (match_operand 1 "general_operand" "")
8773              (match_operand 2 "const_int_operand" "")))
8774    (clobber (reg:CC FLAGS_REG))]
8775    "reload_completed
8776     && ANY_QI_REG_P (operands[0])
8777     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8778     && !(INTVAL (operands[2]) & ~255)
8779     && (INTVAL (operands[2]) & 128)
8780     && GET_MODE (operands[0]) != QImode"
8781   [(parallel [(set (strict_low_part (match_dup 0))
8782                    (ior:QI (match_dup 1)
8783                            (match_dup 2)))
8784               (clobber (reg:CC FLAGS_REG))])]
8785   "operands[0] = gen_lowpart (QImode, operands[0]);
8786    operands[1] = gen_lowpart (QImode, operands[1]);
8787    operands[2] = gen_lowpart (QImode, operands[2]);")
8788 \f
8789 ;; Logical XOR instructions
8790
8791 ;; %%% This used to optimize known byte-wide and operations to memory.
8792 ;; If this is considered useful, it should be done with splitters.
8793
8794 (define_expand "xordi3"
8795   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8796         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8797                 (match_operand:DI 2 "x86_64_general_operand" "")))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "TARGET_64BIT"
8800   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8801
8802 (define_insn "*xordi_1_rex64"
8803   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8804         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8805                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8806    (clobber (reg:CC FLAGS_REG))]
8807   "TARGET_64BIT
8808    && ix86_binary_operator_ok (XOR, DImode, operands)"
8809   "@
8810    xor{q}\t{%2, %0|%0, %2}
8811    xor{q}\t{%2, %0|%0, %2}"
8812   [(set_attr "type" "alu")
8813    (set_attr "mode" "DI,DI")])
8814
8815 (define_insn "*xordi_2_rex64"
8816   [(set (reg FLAGS_REG)
8817         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8818                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8819                  (const_int 0)))
8820    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8821         (xor:DI (match_dup 1) (match_dup 2)))]
8822   "TARGET_64BIT
8823    && ix86_match_ccmode (insn, CCNOmode)
8824    && ix86_binary_operator_ok (XOR, DImode, operands)"
8825   "@
8826    xor{q}\t{%2, %0|%0, %2}
8827    xor{q}\t{%2, %0|%0, %2}"
8828   [(set_attr "type" "alu")
8829    (set_attr "mode" "DI,DI")])
8830
8831 (define_insn "*xordi_3_rex64"
8832   [(set (reg FLAGS_REG)
8833         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8834                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8835                  (const_int 0)))
8836    (clobber (match_scratch:DI 0 "=r"))]
8837   "TARGET_64BIT
8838    && ix86_match_ccmode (insn, CCNOmode)
8839    && ix86_binary_operator_ok (XOR, DImode, operands)"
8840   "xor{q}\t{%2, %0|%0, %2}"
8841   [(set_attr "type" "alu")
8842    (set_attr "mode" "DI")])
8843
8844 (define_expand "xorsi3"
8845   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8846         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8847                 (match_operand:SI 2 "general_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849   ""
8850   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8851
8852 (define_insn "*xorsi_1"
8853   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8854         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8855                 (match_operand:SI 2 "general_operand" "ri,rm")))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "ix86_binary_operator_ok (XOR, SImode, operands)"
8858   "xor{l}\t{%2, %0|%0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "SI")])
8861
8862 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8863 ;; Add speccase for immediates
8864 (define_insn "*xorsi_1_zext"
8865   [(set (match_operand:DI 0 "register_operand" "=r")
8866         (zero_extend:DI
8867           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8868                   (match_operand:SI 2 "general_operand" "rim"))))
8869    (clobber (reg:CC FLAGS_REG))]
8870   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8871   "xor{l}\t{%2, %k0|%k0, %2}"
8872   [(set_attr "type" "alu")
8873    (set_attr "mode" "SI")])
8874
8875 (define_insn "*xorsi_1_zext_imm"
8876   [(set (match_operand:DI 0 "register_operand" "=r")
8877         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8878                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8879    (clobber (reg:CC FLAGS_REG))]
8880   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8881   "xor{l}\t{%2, %k0|%k0, %2}"
8882   [(set_attr "type" "alu")
8883    (set_attr "mode" "SI")])
8884
8885 (define_insn "*xorsi_2"
8886   [(set (reg FLAGS_REG)
8887         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8888                          (match_operand:SI 2 "general_operand" "rim,ri"))
8889                  (const_int 0)))
8890    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8891         (xor:SI (match_dup 1) (match_dup 2)))]
8892   "ix86_match_ccmode (insn, CCNOmode)
8893    && ix86_binary_operator_ok (XOR, SImode, operands)"
8894   "xor{l}\t{%2, %0|%0, %2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "mode" "SI")])
8897
8898 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8899 ;; ??? Special case for immediate operand is missing - it is tricky.
8900 (define_insn "*xorsi_2_zext"
8901   [(set (reg FLAGS_REG)
8902         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8903                          (match_operand:SI 2 "general_operand" "rim"))
8904                  (const_int 0)))
8905    (set (match_operand:DI 0 "register_operand" "=r")
8906         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8907   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8908    && ix86_binary_operator_ok (XOR, SImode, operands)"
8909   "xor{l}\t{%2, %k0|%k0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "SI")])
8912
8913 (define_insn "*xorsi_2_zext_imm"
8914   [(set (reg FLAGS_REG)
8915         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8916                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8917                  (const_int 0)))
8918    (set (match_operand:DI 0 "register_operand" "=r")
8919         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8920   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8921    && ix86_binary_operator_ok (XOR, SImode, operands)"
8922   "xor{l}\t{%2, %k0|%k0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "mode" "SI")])
8925
8926 (define_insn "*xorsi_3"
8927   [(set (reg FLAGS_REG)
8928         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8929                          (match_operand:SI 2 "general_operand" "rim"))
8930                  (const_int 0)))
8931    (clobber (match_scratch:SI 0 "=r"))]
8932   "ix86_match_ccmode (insn, CCNOmode)
8933    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8934   "xor{l}\t{%2, %0|%0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "SI")])
8937
8938 (define_expand "xorhi3"
8939   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8940         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8941                 (match_operand:HI 2 "general_operand" "")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "TARGET_HIMODE_MATH"
8944   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8945
8946 (define_insn "*xorhi_1"
8947   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8948         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8949                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "ix86_binary_operator_ok (XOR, HImode, operands)"
8952   "xor{w}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "HI")])
8955
8956 (define_insn "*xorhi_2"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8959                          (match_operand:HI 2 "general_operand" "rim,ri"))
8960                  (const_int 0)))
8961    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8962         (xor:HI (match_dup 1) (match_dup 2)))]
8963   "ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (XOR, HImode, operands)"
8965   "xor{w}\t{%2, %0|%0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "HI")])
8968
8969 (define_insn "*xorhi_3"
8970   [(set (reg FLAGS_REG)
8971         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8972                          (match_operand:HI 2 "general_operand" "rim"))
8973                  (const_int 0)))
8974    (clobber (match_scratch:HI 0 "=r"))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8977   "xor{w}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "HI")])
8980
8981 (define_expand "xorqi3"
8982   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8983         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8984                 (match_operand:QI 2 "general_operand" "")))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_QIMODE_MATH"
8987   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8988
8989 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8990 (define_insn "*xorqi_1"
8991   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8992         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8993                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8994    (clobber (reg:CC FLAGS_REG))]
8995   "ix86_binary_operator_ok (XOR, QImode, operands)"
8996   "@
8997    xor{b}\t{%2, %0|%0, %2}
8998    xor{b}\t{%2, %0|%0, %2}
8999    xor{l}\t{%k2, %k0|%k0, %k2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "QI,QI,SI")])
9002
9003 (define_insn "*xorqi_1_slp"
9004   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9005         (xor:QI (match_dup 0)
9006                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9009    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9010   "xor{b}\t{%1, %0|%0, %1}"
9011   [(set_attr "type" "alu1")
9012    (set_attr "mode" "QI")])
9013
9014 (define_insn "xorqi_ext_0"
9015   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9016                          (const_int 8)
9017                          (const_int 8))
9018         (xor:SI 
9019           (zero_extract:SI
9020             (match_operand 1 "ext_register_operand" "0")
9021             (const_int 8)
9022             (const_int 8))
9023           (match_operand 2 "const_int_operand" "n")))
9024    (clobber (reg:CC FLAGS_REG))]
9025   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9026   "xor{b}\t{%2, %h0|%h0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "length_immediate" "1")
9029    (set_attr "mode" "QI")])
9030
9031 (define_insn "*xorqi_ext_1"
9032   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9033                          (const_int 8)
9034                          (const_int 8))
9035         (xor:SI 
9036           (zero_extract:SI
9037             (match_operand 1 "ext_register_operand" "0")
9038             (const_int 8)
9039             (const_int 8))
9040           (zero_extend:SI
9041             (match_operand:QI 2 "general_operand" "Qm"))))
9042    (clobber (reg:CC FLAGS_REG))]
9043   "!TARGET_64BIT
9044    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9045   "xor{b}\t{%2, %h0|%h0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "length_immediate" "0")
9048    (set_attr "mode" "QI")])
9049
9050 (define_insn "*xorqi_ext_1_rex64"
9051   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9052                          (const_int 8)
9053                          (const_int 8))
9054         (xor:SI 
9055           (zero_extract:SI
9056             (match_operand 1 "ext_register_operand" "0")
9057             (const_int 8)
9058             (const_int 8))
9059           (zero_extend:SI
9060             (match_operand 2 "ext_register_operand" "Q"))))
9061    (clobber (reg:CC FLAGS_REG))]
9062   "TARGET_64BIT
9063    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9064   "xor{b}\t{%2, %h0|%h0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "length_immediate" "0")
9067    (set_attr "mode" "QI")])
9068
9069 (define_insn "*xorqi_ext_2"
9070   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071                          (const_int 8)
9072                          (const_int 8))
9073         (xor:SI 
9074           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9075                            (const_int 8)
9076                            (const_int 8))
9077           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9078                            (const_int 8)
9079                            (const_int 8))))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9082   "xor{b}\t{%h2, %h0|%h0, %h2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "length_immediate" "0")
9085    (set_attr "mode" "QI")])
9086
9087 (define_insn "*xorqi_cc_1"
9088   [(set (reg FLAGS_REG)
9089         (compare
9090           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9091                   (match_operand:QI 2 "general_operand" "qim,qi"))
9092           (const_int 0)))
9093    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9094         (xor:QI (match_dup 1) (match_dup 2)))]
9095   "ix86_match_ccmode (insn, CCNOmode)
9096    && ix86_binary_operator_ok (XOR, QImode, operands)"
9097   "xor{b}\t{%2, %0|%0, %2}"
9098   [(set_attr "type" "alu")
9099    (set_attr "mode" "QI")])
9100
9101 (define_insn "*xorqi_2_slp"
9102   [(set (reg FLAGS_REG)
9103         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9104                          (match_operand:QI 1 "general_operand" "qim,qi"))
9105                  (const_int 0)))
9106    (set (strict_low_part (match_dup 0))
9107         (xor:QI (match_dup 0) (match_dup 1)))]
9108   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109    && ix86_match_ccmode (insn, CCNOmode)
9110    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9111   "xor{b}\t{%1, %0|%0, %1}"
9112   [(set_attr "type" "alu1")
9113    (set_attr "mode" "QI")])
9114
9115 (define_insn "*xorqi_cc_2"
9116   [(set (reg FLAGS_REG)
9117         (compare
9118           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9119                   (match_operand:QI 2 "general_operand" "qim"))
9120           (const_int 0)))
9121    (clobber (match_scratch:QI 0 "=q"))]
9122   "ix86_match_ccmode (insn, CCNOmode)
9123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9124   "xor{b}\t{%2, %0|%0, %2}"
9125   [(set_attr "type" "alu")
9126    (set_attr "mode" "QI")])
9127
9128 (define_insn "*xorqi_cc_ext_1"
9129   [(set (reg FLAGS_REG)
9130         (compare
9131           (xor:SI
9132             (zero_extract:SI
9133               (match_operand 1 "ext_register_operand" "0")
9134               (const_int 8)
9135               (const_int 8))
9136             (match_operand:QI 2 "general_operand" "qmn"))
9137           (const_int 0)))
9138    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9139                          (const_int 8)
9140                          (const_int 8))
9141         (xor:SI 
9142           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9143           (match_dup 2)))]
9144   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9145   "xor{b}\t{%2, %h0|%h0, %2}"
9146   [(set_attr "type" "alu")
9147    (set_attr "mode" "QI")])
9148
9149 (define_insn "*xorqi_cc_ext_1_rex64"
9150   [(set (reg FLAGS_REG)
9151         (compare
9152           (xor:SI
9153             (zero_extract:SI
9154               (match_operand 1 "ext_register_operand" "0")
9155               (const_int 8)
9156               (const_int 8))
9157             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9158           (const_int 0)))
9159    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160                          (const_int 8)
9161                          (const_int 8))
9162         (xor:SI 
9163           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9164           (match_dup 2)))]
9165   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9166   "xor{b}\t{%2, %h0|%h0, %2}"
9167   [(set_attr "type" "alu")
9168    (set_attr "mode" "QI")])
9169
9170 (define_expand "xorqi_cc_ext_1"
9171   [(parallel [
9172      (set (reg:CCNO FLAGS_REG)
9173           (compare:CCNO
9174             (xor:SI
9175               (zero_extract:SI
9176                 (match_operand 1 "ext_register_operand" "")
9177                 (const_int 8)
9178                 (const_int 8))
9179               (match_operand:QI 2 "general_operand" ""))
9180             (const_int 0)))
9181      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9182                            (const_int 8)
9183                            (const_int 8))
9184           (xor:SI 
9185             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9186             (match_dup 2)))])]
9187   ""
9188   "")
9189
9190 (define_split
9191   [(set (match_operand 0 "register_operand" "")
9192         (xor (match_operand 1 "register_operand" "")
9193              (match_operand 2 "const_int_operand" "")))
9194    (clobber (reg:CC FLAGS_REG))]
9195    "reload_completed
9196     && QI_REG_P (operands[0])
9197     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9198     && !(INTVAL (operands[2]) & ~(255 << 8))
9199     && GET_MODE (operands[0]) != QImode"
9200   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9201                    (xor:SI (zero_extract:SI (match_dup 1)
9202                                             (const_int 8) (const_int 8))
9203                            (match_dup 2)))
9204               (clobber (reg:CC FLAGS_REG))])]
9205   "operands[0] = gen_lowpart (SImode, operands[0]);
9206    operands[1] = gen_lowpart (SImode, operands[1]);
9207    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9208
9209 ;; Since XOR can be encoded with sign extended immediate, this is only
9210 ;; profitable when 7th bit is set.
9211 (define_split
9212   [(set (match_operand 0 "register_operand" "")
9213         (xor (match_operand 1 "general_operand" "")
9214              (match_operand 2 "const_int_operand" "")))
9215    (clobber (reg:CC FLAGS_REG))]
9216    "reload_completed
9217     && ANY_QI_REG_P (operands[0])
9218     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9219     && !(INTVAL (operands[2]) & ~255)
9220     && (INTVAL (operands[2]) & 128)
9221     && GET_MODE (operands[0]) != QImode"
9222   [(parallel [(set (strict_low_part (match_dup 0))
9223                    (xor:QI (match_dup 1)
9224                            (match_dup 2)))
9225               (clobber (reg:CC FLAGS_REG))])]
9226   "operands[0] = gen_lowpart (QImode, operands[0]);
9227    operands[1] = gen_lowpart (QImode, operands[1]);
9228    operands[2] = gen_lowpart (QImode, operands[2]);")
9229 \f
9230 ;; Negation instructions
9231
9232 (define_expand "negdi2"
9233   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9234                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9235               (clobber (reg:CC FLAGS_REG))])]
9236   ""
9237   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9238
9239 (define_insn "*negdi2_1"
9240   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9241         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9242    (clobber (reg:CC FLAGS_REG))]
9243   "!TARGET_64BIT
9244    && ix86_unary_operator_ok (NEG, DImode, operands)"
9245   "#")
9246
9247 (define_split
9248   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9249         (neg:DI (match_operand:DI 1 "general_operand" "")))
9250    (clobber (reg:CC FLAGS_REG))]
9251   "!TARGET_64BIT && reload_completed"
9252   [(parallel
9253     [(set (reg:CCZ FLAGS_REG)
9254           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9255      (set (match_dup 0) (neg:SI (match_dup 2)))])
9256    (parallel
9257     [(set (match_dup 1)
9258           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9259                             (match_dup 3))
9260                    (const_int 0)))
9261      (clobber (reg:CC FLAGS_REG))])
9262    (parallel
9263     [(set (match_dup 1)
9264           (neg:SI (match_dup 1)))
9265      (clobber (reg:CC FLAGS_REG))])]
9266   "split_di (operands+1, 1, operands+2, operands+3);
9267    split_di (operands+0, 1, operands+0, operands+1);")
9268
9269 (define_insn "*negdi2_1_rex64"
9270   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9271         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9272    (clobber (reg:CC FLAGS_REG))]
9273   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9274   "neg{q}\t%0"
9275   [(set_attr "type" "negnot")
9276    (set_attr "mode" "DI")])
9277
9278 ;; The problem with neg is that it does not perform (compare x 0),
9279 ;; it really performs (compare 0 x), which leaves us with the zero
9280 ;; flag being the only useful item.
9281
9282 (define_insn "*negdi2_cmpz_rex64"
9283   [(set (reg:CCZ FLAGS_REG)
9284         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9285                      (const_int 0)))
9286    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9287         (neg:DI (match_dup 1)))]
9288   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9289   "neg{q}\t%0"
9290   [(set_attr "type" "negnot")
9291    (set_attr "mode" "DI")])
9292
9293
9294 (define_expand "negsi2"
9295   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9296                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9297               (clobber (reg:CC FLAGS_REG))])]
9298   ""
9299   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9300
9301 (define_insn "*negsi2_1"
9302   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9303         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9304    (clobber (reg:CC FLAGS_REG))]
9305   "ix86_unary_operator_ok (NEG, SImode, operands)"
9306   "neg{l}\t%0"
9307   [(set_attr "type" "negnot")
9308    (set_attr "mode" "SI")])
9309
9310 ;; Combine is quite creative about this pattern.
9311 (define_insn "*negsi2_1_zext"
9312   [(set (match_operand:DI 0 "register_operand" "=r")
9313         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9314                                         (const_int 32)))
9315                      (const_int 32)))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9318   "neg{l}\t%k0"
9319   [(set_attr "type" "negnot")
9320    (set_attr "mode" "SI")])
9321
9322 ;; The problem with neg is that it does not perform (compare x 0),
9323 ;; it really performs (compare 0 x), which leaves us with the zero
9324 ;; flag being the only useful item.
9325
9326 (define_insn "*negsi2_cmpz"
9327   [(set (reg:CCZ FLAGS_REG)
9328         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9329                      (const_int 0)))
9330    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9331         (neg:SI (match_dup 1)))]
9332   "ix86_unary_operator_ok (NEG, SImode, operands)"
9333   "neg{l}\t%0"
9334   [(set_attr "type" "negnot")
9335    (set_attr "mode" "SI")])
9336
9337 (define_insn "*negsi2_cmpz_zext"
9338   [(set (reg:CCZ FLAGS_REG)
9339         (compare:CCZ (lshiftrt:DI
9340                        (neg:DI (ashift:DI
9341                                  (match_operand:DI 1 "register_operand" "0")
9342                                  (const_int 32)))
9343                        (const_int 32))
9344                      (const_int 0)))
9345    (set (match_operand:DI 0 "register_operand" "=r")
9346         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9347                                         (const_int 32)))
9348                      (const_int 32)))]
9349   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9350   "neg{l}\t%k0"
9351   [(set_attr "type" "negnot")
9352    (set_attr "mode" "SI")])
9353
9354 (define_expand "neghi2"
9355   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9356                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9357               (clobber (reg:CC FLAGS_REG))])]
9358   "TARGET_HIMODE_MATH"
9359   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9360
9361 (define_insn "*neghi2_1"
9362   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9363         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "ix86_unary_operator_ok (NEG, HImode, operands)"
9366   "neg{w}\t%0"
9367   [(set_attr "type" "negnot")
9368    (set_attr "mode" "HI")])
9369
9370 (define_insn "*neghi2_cmpz"
9371   [(set (reg:CCZ FLAGS_REG)
9372         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9373                      (const_int 0)))
9374    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9375         (neg:HI (match_dup 1)))]
9376   "ix86_unary_operator_ok (NEG, HImode, operands)"
9377   "neg{w}\t%0"
9378   [(set_attr "type" "negnot")
9379    (set_attr "mode" "HI")])
9380
9381 (define_expand "negqi2"
9382   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9383                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9384               (clobber (reg:CC FLAGS_REG))])]
9385   "TARGET_QIMODE_MATH"
9386   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9387
9388 (define_insn "*negqi2_1"
9389   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9390         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9391    (clobber (reg:CC FLAGS_REG))]
9392   "ix86_unary_operator_ok (NEG, QImode, operands)"
9393   "neg{b}\t%0"
9394   [(set_attr "type" "negnot")
9395    (set_attr "mode" "QI")])
9396
9397 (define_insn "*negqi2_cmpz"
9398   [(set (reg:CCZ FLAGS_REG)
9399         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9400                      (const_int 0)))
9401    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9402         (neg:QI (match_dup 1)))]
9403   "ix86_unary_operator_ok (NEG, QImode, operands)"
9404   "neg{b}\t%0"
9405   [(set_attr "type" "negnot")
9406    (set_attr "mode" "QI")])
9407
9408 ;; Changing of sign for FP values is doable using integer unit too.
9409
9410 (define_expand "negsf2"
9411   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9412         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9413   "TARGET_80387 || TARGET_SSE_MATH"
9414   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9415
9416 (define_expand "abssf2"
9417   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9418         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9419   "TARGET_80387 || TARGET_SSE_MATH"
9420   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9421
9422 (define_insn "*absnegsf2_mixed"
9423   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9424         (match_operator:SF 3 "absneg_operator"
9425           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9426    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9429    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9430   "#")
9431
9432 (define_insn "*absnegsf2_sse"
9433   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9434         (match_operator:SF 3 "absneg_operator"
9435           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9436    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_SSE_MATH
9439    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9440   "#")
9441
9442 (define_insn "*absnegsf2_i387"
9443   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9444         (match_operator:SF 3 "absneg_operator"
9445           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9446    (use (match_operand 2 "" ""))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "TARGET_80387 && !TARGET_SSE_MATH
9449    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9450   "#")
9451
9452 (define_expand "negdf2"
9453   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9454         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9455   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9456   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9457
9458 (define_expand "absdf2"
9459   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9460         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9461   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9462   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9463
9464 (define_insn "*absnegdf2_mixed"
9465   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9466         (match_operator:DF 3 "absneg_operator"
9467           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9468    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9469    (clobber (reg:CC FLAGS_REG))]
9470   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9471    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9472   "#")
9473
9474 (define_insn "*absnegdf2_sse"
9475   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9476         (match_operator:DF 3 "absneg_operator"
9477           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9478    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9479    (clobber (reg:CC FLAGS_REG))]
9480   "TARGET_SSE2 && TARGET_SSE_MATH
9481    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9482   "#")
9483
9484 (define_insn "*absnegdf2_i387"
9485   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9486         (match_operator:DF 3 "absneg_operator"
9487           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9488    (use (match_operand 2 "" ""))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9491    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9492   "#")
9493
9494 (define_expand "negxf2"
9495   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9496         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9497   "TARGET_80387"
9498   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9499
9500 (define_expand "absxf2"
9501   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9502         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9503   "TARGET_80387"
9504   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9505
9506 (define_insn "*absnegxf2_i387"
9507   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9508         (match_operator:XF 3 "absneg_operator"
9509           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9510    (use (match_operand 2 "" ""))
9511    (clobber (reg:CC FLAGS_REG))]
9512   "TARGET_80387
9513    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9514   "#")
9515
9516 ;; Splitters for fp abs and neg.
9517
9518 (define_split
9519   [(set (match_operand 0 "fp_register_operand" "")
9520         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9521    (use (match_operand 2 "" ""))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "reload_completed"
9524   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9525
9526 (define_split
9527   [(set (match_operand 0 "register_operand" "")
9528         (match_operator 3 "absneg_operator"
9529           [(match_operand 1 "register_operand" "")]))
9530    (use (match_operand 2 "nonimmediate_operand" ""))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "reload_completed && SSE_REG_P (operands[0])"
9533   [(set (match_dup 0) (match_dup 3))]
9534 {
9535   enum machine_mode mode = GET_MODE (operands[0]);
9536   enum machine_mode vmode = GET_MODE (operands[2]);
9537   rtx tmp;
9538   
9539   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9540   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9541   if (operands_match_p (operands[0], operands[2]))
9542     {
9543       tmp = operands[1];
9544       operands[1] = operands[2];
9545       operands[2] = tmp;
9546     }
9547   if (GET_CODE (operands[3]) == ABS)
9548     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9549   else
9550     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9551   operands[3] = tmp;
9552 })
9553
9554 (define_split
9555   [(set (match_operand:SF 0 "register_operand" "")
9556         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9557    (use (match_operand:V4SF 2 "" ""))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "reload_completed"
9560   [(parallel [(set (match_dup 0) (match_dup 1))
9561               (clobber (reg:CC FLAGS_REG))])]
9562
9563   rtx tmp;
9564   operands[0] = gen_lowpart (SImode, operands[0]);
9565   if (GET_CODE (operands[1]) == ABS)
9566     {
9567       tmp = gen_int_mode (0x7fffffff, SImode);
9568       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9569     }
9570   else
9571     {
9572       tmp = gen_int_mode (0x80000000, SImode);
9573       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9574     }
9575   operands[1] = tmp;
9576 })
9577
9578 (define_split
9579   [(set (match_operand:DF 0 "register_operand" "")
9580         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9581    (use (match_operand 2 "" ""))
9582    (clobber (reg:CC FLAGS_REG))]
9583   "reload_completed"
9584   [(parallel [(set (match_dup 0) (match_dup 1))
9585               (clobber (reg:CC FLAGS_REG))])]
9586 {
9587   rtx tmp;
9588   if (TARGET_64BIT)
9589     {
9590       tmp = gen_lowpart (DImode, operands[0]);
9591       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9592       operands[0] = tmp;
9593
9594       if (GET_CODE (operands[1]) == ABS)
9595         tmp = const0_rtx;
9596       else
9597         tmp = gen_rtx_NOT (DImode, tmp);
9598     }
9599   else
9600     {
9601       operands[0] = gen_highpart (SImode, operands[0]);
9602       if (GET_CODE (operands[1]) == ABS)
9603         {
9604           tmp = gen_int_mode (0x7fffffff, SImode);
9605           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9606         }
9607       else
9608         {
9609           tmp = gen_int_mode (0x80000000, SImode);
9610           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9611         }
9612     }
9613   operands[1] = tmp;
9614 })
9615
9616 (define_split
9617   [(set (match_operand:XF 0 "register_operand" "")
9618         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9619    (use (match_operand 2 "" ""))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "reload_completed"
9622   [(parallel [(set (match_dup 0) (match_dup 1))
9623               (clobber (reg:CC FLAGS_REG))])]
9624 {
9625   rtx tmp;
9626   operands[0] = gen_rtx_REG (SImode,
9627                              true_regnum (operands[0])
9628                              + (TARGET_64BIT ? 1 : 2));
9629   if (GET_CODE (operands[1]) == ABS)
9630     {
9631       tmp = GEN_INT (0x7fff);
9632       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9633     }
9634   else
9635     {
9636       tmp = GEN_INT (0x8000);
9637       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9638     }
9639   operands[1] = tmp;
9640 })
9641
9642 (define_split
9643   [(set (match_operand 0 "memory_operand" "")
9644         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9645    (use (match_operand 2 "" ""))
9646    (clobber (reg:CC FLAGS_REG))]
9647   "reload_completed"
9648   [(parallel [(set (match_dup 0) (match_dup 1))
9649               (clobber (reg:CC FLAGS_REG))])]
9650 {
9651   enum machine_mode mode = GET_MODE (operands[0]);
9652   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9653   rtx tmp;
9654
9655   operands[0] = adjust_address (operands[0], QImode, size - 1);
9656   if (GET_CODE (operands[1]) == ABS)
9657     {
9658       tmp = gen_int_mode (0x7f, QImode);
9659       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9660     }
9661   else
9662     {
9663       tmp = gen_int_mode (0x80, QImode);
9664       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9665     }
9666   operands[1] = tmp;
9667 })
9668
9669 ;; Conditionalize these after reload. If they match before reload, we 
9670 ;; lose the clobber and ability to use integer instructions.
9671
9672 (define_insn "*negsf2_1"
9673   [(set (match_operand:SF 0 "register_operand" "=f")
9674         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9675   "TARGET_80387 && reload_completed"
9676   "fchs"
9677   [(set_attr "type" "fsgn")
9678    (set_attr "mode" "SF")])
9679
9680 (define_insn "*negdf2_1"
9681   [(set (match_operand:DF 0 "register_operand" "=f")
9682         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9683   "TARGET_80387 && reload_completed"
9684   "fchs"
9685   [(set_attr "type" "fsgn")
9686    (set_attr "mode" "DF")])
9687
9688 (define_insn "*negxf2_1"
9689   [(set (match_operand:XF 0 "register_operand" "=f")
9690         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9691   "TARGET_80387 && reload_completed"
9692   "fchs"
9693   [(set_attr "type" "fsgn")
9694    (set_attr "mode" "XF")])
9695
9696 (define_insn "*abssf2_1"
9697   [(set (match_operand:SF 0 "register_operand" "=f")
9698         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9699   "TARGET_80387 && reload_completed"
9700   "fabs"
9701   [(set_attr "type" "fsgn")
9702    (set_attr "mode" "SF")])
9703
9704 (define_insn "*absdf2_1"
9705   [(set (match_operand:DF 0 "register_operand" "=f")
9706         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9707   "TARGET_80387 && reload_completed"
9708   "fabs"
9709   [(set_attr "type" "fsgn")
9710    (set_attr "mode" "DF")])
9711
9712 (define_insn "*absxf2_1"
9713   [(set (match_operand:XF 0 "register_operand" "=f")
9714         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9715   "TARGET_80387 && reload_completed"
9716   "fabs"
9717   [(set_attr "type" "fsgn")
9718    (set_attr "mode" "DF")])
9719
9720 (define_insn "*negextendsfdf2"
9721   [(set (match_operand:DF 0 "register_operand" "=f")
9722         (neg:DF (float_extend:DF
9723                   (match_operand:SF 1 "register_operand" "0"))))]
9724   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9725   "fchs"
9726   [(set_attr "type" "fsgn")
9727    (set_attr "mode" "DF")])
9728
9729 (define_insn "*negextenddfxf2"
9730   [(set (match_operand:XF 0 "register_operand" "=f")
9731         (neg:XF (float_extend:XF
9732                   (match_operand:DF 1 "register_operand" "0"))))]
9733   "TARGET_80387"
9734   "fchs"
9735   [(set_attr "type" "fsgn")
9736    (set_attr "mode" "XF")])
9737
9738 (define_insn "*negextendsfxf2"
9739   [(set (match_operand:XF 0 "register_operand" "=f")
9740         (neg:XF (float_extend:XF
9741                   (match_operand:SF 1 "register_operand" "0"))))]
9742   "TARGET_80387"
9743   "fchs"
9744   [(set_attr "type" "fsgn")
9745    (set_attr "mode" "XF")])
9746
9747 (define_insn "*absextendsfdf2"
9748   [(set (match_operand:DF 0 "register_operand" "=f")
9749         (abs:DF (float_extend:DF
9750                   (match_operand:SF 1 "register_operand" "0"))))]
9751   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9752   "fabs"
9753   [(set_attr "type" "fsgn")
9754    (set_attr "mode" "DF")])
9755
9756 (define_insn "*absextenddfxf2"
9757   [(set (match_operand:XF 0 "register_operand" "=f")
9758         (abs:XF (float_extend:XF
9759           (match_operand:DF 1 "register_operand" "0"))))]
9760   "TARGET_80387"
9761   "fabs"
9762   [(set_attr "type" "fsgn")
9763    (set_attr "mode" "XF")])
9764
9765 (define_insn "*absextendsfxf2"
9766   [(set (match_operand:XF 0 "register_operand" "=f")
9767         (abs:XF (float_extend:XF
9768           (match_operand:SF 1 "register_operand" "0"))))]
9769   "TARGET_80387"
9770   "fabs"
9771   [(set_attr "type" "fsgn")
9772    (set_attr "mode" "XF")])
9773 \f
9774 ;; One complement instructions
9775
9776 (define_expand "one_cmpldi2"
9777   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9778         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9779   "TARGET_64BIT"
9780   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9781
9782 (define_insn "*one_cmpldi2_1_rex64"
9783   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9784         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9785   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9786   "not{q}\t%0"
9787   [(set_attr "type" "negnot")
9788    (set_attr "mode" "DI")])
9789
9790 (define_insn "*one_cmpldi2_2_rex64"
9791   [(set (reg FLAGS_REG)
9792         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9793                  (const_int 0)))
9794    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9795         (not:DI (match_dup 1)))]
9796   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9797    && ix86_unary_operator_ok (NOT, DImode, operands)"
9798   "#"
9799   [(set_attr "type" "alu1")
9800    (set_attr "mode" "DI")])
9801
9802 (define_split
9803   [(set (match_operand 0 "flags_reg_operand" "")
9804         (match_operator 2 "compare_operator"
9805           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9806            (const_int 0)]))
9807    (set (match_operand:DI 1 "nonimmediate_operand" "")
9808         (not:DI (match_dup 3)))]
9809   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9810   [(parallel [(set (match_dup 0)
9811                    (match_op_dup 2
9812                      [(xor:DI (match_dup 3) (const_int -1))
9813                       (const_int 0)]))
9814               (set (match_dup 1)
9815                    (xor:DI (match_dup 3) (const_int -1)))])]
9816   "")
9817
9818 (define_expand "one_cmplsi2"
9819   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9820         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9821   ""
9822   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9823
9824 (define_insn "*one_cmplsi2_1"
9825   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9826         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9827   "ix86_unary_operator_ok (NOT, SImode, operands)"
9828   "not{l}\t%0"
9829   [(set_attr "type" "negnot")
9830    (set_attr "mode" "SI")])
9831
9832 ;; ??? Currently never generated - xor is used instead.
9833 (define_insn "*one_cmplsi2_1_zext"
9834   [(set (match_operand:DI 0 "register_operand" "=r")
9835         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9836   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9837   "not{l}\t%k0"
9838   [(set_attr "type" "negnot")
9839    (set_attr "mode" "SI")])
9840
9841 (define_insn "*one_cmplsi2_2"
9842   [(set (reg FLAGS_REG)
9843         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9844                  (const_int 0)))
9845    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9846         (not:SI (match_dup 1)))]
9847   "ix86_match_ccmode (insn, CCNOmode)
9848    && ix86_unary_operator_ok (NOT, SImode, operands)"
9849   "#"
9850   [(set_attr "type" "alu1")
9851    (set_attr "mode" "SI")])
9852
9853 (define_split
9854   [(set (match_operand 0 "flags_reg_operand" "")
9855         (match_operator 2 "compare_operator"
9856           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9857            (const_int 0)]))
9858    (set (match_operand:SI 1 "nonimmediate_operand" "")
9859         (not:SI (match_dup 3)))]
9860   "ix86_match_ccmode (insn, CCNOmode)"
9861   [(parallel [(set (match_dup 0)
9862                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9863                                     (const_int 0)]))
9864               (set (match_dup 1)
9865                    (xor:SI (match_dup 3) (const_int -1)))])]
9866   "")
9867
9868 ;; ??? Currently never generated - xor is used instead.
9869 (define_insn "*one_cmplsi2_2_zext"
9870   [(set (reg FLAGS_REG)
9871         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9872                  (const_int 0)))
9873    (set (match_operand:DI 0 "register_operand" "=r")
9874         (zero_extend:DI (not:SI (match_dup 1))))]
9875   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9876    && ix86_unary_operator_ok (NOT, SImode, operands)"
9877   "#"
9878   [(set_attr "type" "alu1")
9879    (set_attr "mode" "SI")])
9880
9881 (define_split
9882   [(set (match_operand 0 "flags_reg_operand" "")
9883         (match_operator 2 "compare_operator"
9884           [(not:SI (match_operand:SI 3 "register_operand" ""))
9885            (const_int 0)]))
9886    (set (match_operand:DI 1 "register_operand" "")
9887         (zero_extend:DI (not:SI (match_dup 3))))]
9888   "ix86_match_ccmode (insn, CCNOmode)"
9889   [(parallel [(set (match_dup 0)
9890                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9891                                     (const_int 0)]))
9892               (set (match_dup 1)
9893                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9894   "")
9895
9896 (define_expand "one_cmplhi2"
9897   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9898         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9899   "TARGET_HIMODE_MATH"
9900   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9901
9902 (define_insn "*one_cmplhi2_1"
9903   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9904         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9905   "ix86_unary_operator_ok (NOT, HImode, operands)"
9906   "not{w}\t%0"
9907   [(set_attr "type" "negnot")
9908    (set_attr "mode" "HI")])
9909
9910 (define_insn "*one_cmplhi2_2"
9911   [(set (reg FLAGS_REG)
9912         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9913                  (const_int 0)))
9914    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9915         (not:HI (match_dup 1)))]
9916   "ix86_match_ccmode (insn, CCNOmode)
9917    && ix86_unary_operator_ok (NEG, HImode, operands)"
9918   "#"
9919   [(set_attr "type" "alu1")
9920    (set_attr "mode" "HI")])
9921
9922 (define_split
9923   [(set (match_operand 0 "flags_reg_operand" "")
9924         (match_operator 2 "compare_operator"
9925           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9926            (const_int 0)]))
9927    (set (match_operand:HI 1 "nonimmediate_operand" "")
9928         (not:HI (match_dup 3)))]
9929   "ix86_match_ccmode (insn, CCNOmode)"
9930   [(parallel [(set (match_dup 0)
9931                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9932                                     (const_int 0)]))
9933               (set (match_dup 1)
9934                    (xor:HI (match_dup 3) (const_int -1)))])]
9935   "")
9936
9937 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9938 (define_expand "one_cmplqi2"
9939   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9940         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9941   "TARGET_QIMODE_MATH"
9942   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
9943
9944 (define_insn "*one_cmplqi2_1"
9945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9946         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9947   "ix86_unary_operator_ok (NOT, QImode, operands)"
9948   "@
9949    not{b}\t%0
9950    not{l}\t%k0"
9951   [(set_attr "type" "negnot")
9952    (set_attr "mode" "QI,SI")])
9953
9954 (define_insn "*one_cmplqi2_2"
9955   [(set (reg FLAGS_REG)
9956         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9957                  (const_int 0)))
9958    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9959         (not:QI (match_dup 1)))]
9960   "ix86_match_ccmode (insn, CCNOmode)
9961    && ix86_unary_operator_ok (NOT, QImode, operands)"
9962   "#"
9963   [(set_attr "type" "alu1")
9964    (set_attr "mode" "QI")])
9965
9966 (define_split
9967   [(set (match_operand 0 "flags_reg_operand" "")
9968         (match_operator 2 "compare_operator"
9969           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
9970            (const_int 0)]))
9971    (set (match_operand:QI 1 "nonimmediate_operand" "")
9972         (not:QI (match_dup 3)))]
9973   "ix86_match_ccmode (insn, CCNOmode)"
9974   [(parallel [(set (match_dup 0)
9975                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
9976                                     (const_int 0)]))
9977               (set (match_dup 1)
9978                    (xor:QI (match_dup 3) (const_int -1)))])]
9979   "")
9980 \f
9981 ;; Arithmetic shift instructions
9982
9983 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9984 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9985 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9986 ;; from the assembler input.
9987 ;;
9988 ;; This instruction shifts the target reg/mem as usual, but instead of
9989 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9990 ;; is a left shift double, bits are taken from the high order bits of
9991 ;; reg, else if the insn is a shift right double, bits are taken from the
9992 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9993 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9994 ;;
9995 ;; Since sh[lr]d does not change the `reg' operand, that is done
9996 ;; separately, making all shifts emit pairs of shift double and normal
9997 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9998 ;; support a 63 bit shift, each shift where the count is in a reg expands
9999 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10000 ;;
10001 ;; If the shift count is a constant, we need never emit more than one
10002 ;; shift pair, instead using moves and sign extension for counts greater
10003 ;; than 31.
10004
10005 (define_expand "ashldi3"
10006   [(set (match_operand:DI 0 "shiftdi_operand" "")
10007         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10008                    (match_operand:QI 2 "nonmemory_operand" "")))]
10009   ""
10010   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10011
10012 (define_insn "*ashldi3_1_rex64"
10013   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10014         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10015                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10016    (clobber (reg:CC FLAGS_REG))]
10017   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10018 {
10019   switch (get_attr_type (insn))
10020     {
10021     case TYPE_ALU:
10022       if (operands[2] != const1_rtx)
10023         abort ();
10024       if (!rtx_equal_p (operands[0], operands[1]))
10025         abort ();
10026       return "add{q}\t{%0, %0|%0, %0}";
10027
10028     case TYPE_LEA:
10029       if (GET_CODE (operands[2]) != CONST_INT
10030           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10031         abort ();
10032       operands[1] = gen_rtx_MULT (DImode, operands[1],
10033                                   GEN_INT (1 << INTVAL (operands[2])));
10034       return "lea{q}\t{%a1, %0|%0, %a1}";
10035
10036     default:
10037       if (REG_P (operands[2]))
10038         return "sal{q}\t{%b2, %0|%0, %b2}";
10039       else if (operands[2] == const1_rtx
10040                && (TARGET_SHIFT1 || optimize_size))
10041         return "sal{q}\t%0";
10042       else
10043         return "sal{q}\t{%2, %0|%0, %2}";
10044     }
10045 }
10046   [(set (attr "type")
10047      (cond [(eq_attr "alternative" "1")
10048               (const_string "lea")
10049             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10050                           (const_int 0))
10051                       (match_operand 0 "register_operand" ""))
10052                  (match_operand 2 "const1_operand" ""))
10053               (const_string "alu")
10054            ]
10055            (const_string "ishift")))
10056    (set_attr "mode" "DI")])
10057
10058 ;; Convert lea to the lea pattern to avoid flags dependency.
10059 (define_split
10060   [(set (match_operand:DI 0 "register_operand" "")
10061         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10062                    (match_operand:QI 2 "immediate_operand" "")))
10063    (clobber (reg:CC FLAGS_REG))]
10064   "TARGET_64BIT && reload_completed
10065    && true_regnum (operands[0]) != true_regnum (operands[1])"
10066   [(set (match_dup 0)
10067         (mult:DI (match_dup 1)
10068                  (match_dup 2)))]
10069   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10070
10071 ;; This pattern can't accept a variable shift count, since shifts by
10072 ;; zero don't affect the flags.  We assume that shifts by constant
10073 ;; zero are optimized away.
10074 (define_insn "*ashldi3_cmp_rex64"
10075   [(set (reg FLAGS_REG)
10076         (compare
10077           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10078                      (match_operand:QI 2 "immediate_operand" "e"))
10079           (const_int 0)))
10080    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10081         (ashift:DI (match_dup 1) (match_dup 2)))]
10082   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10083    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10084 {
10085   switch (get_attr_type (insn))
10086     {
10087     case TYPE_ALU:
10088       if (operands[2] != const1_rtx)
10089         abort ();
10090       return "add{q}\t{%0, %0|%0, %0}";
10091
10092     default:
10093       if (REG_P (operands[2]))
10094         return "sal{q}\t{%b2, %0|%0, %b2}";
10095       else if (operands[2] == const1_rtx
10096                && (TARGET_SHIFT1 || optimize_size))
10097         return "sal{q}\t%0";
10098       else
10099         return "sal{q}\t{%2, %0|%0, %2}";
10100     }
10101 }
10102   [(set (attr "type")
10103      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10104                           (const_int 0))
10105                       (match_operand 0 "register_operand" ""))
10106                  (match_operand 2 "const1_operand" ""))
10107               (const_string "alu")
10108            ]
10109            (const_string "ishift")))
10110    (set_attr "mode" "DI")])
10111
10112 (define_insn "*ashldi3_1"
10113   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10114         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10115                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "!TARGET_64BIT"
10118   "#"
10119   [(set_attr "type" "multi")])
10120
10121 ;; By default we don't ask for a scratch register, because when DImode
10122 ;; values are manipulated, registers are already at a premium.  But if
10123 ;; we have one handy, we won't turn it away.
10124 (define_peephole2
10125   [(match_scratch:SI 3 "r")
10126    (parallel [(set (match_operand:DI 0 "register_operand" "")
10127                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10128                               (match_operand:QI 2 "nonmemory_operand" "")))
10129               (clobber (reg:CC FLAGS_REG))])
10130    (match_dup 3)]
10131   "!TARGET_64BIT && TARGET_CMOVE"
10132   [(const_int 0)]
10133   "ix86_split_ashldi (operands, operands[3]); DONE;")
10134
10135 (define_split
10136   [(set (match_operand:DI 0 "register_operand" "")
10137         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10138                    (match_operand:QI 2 "nonmemory_operand" "")))
10139    (clobber (reg:CC FLAGS_REG))]
10140   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10141   [(const_int 0)]
10142   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10143
10144 (define_insn "x86_shld_1"
10145   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10146         (ior:SI (ashift:SI (match_dup 0)
10147                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10148                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10149                   (minus:QI (const_int 32) (match_dup 2)))))
10150    (clobber (reg:CC FLAGS_REG))]
10151   ""
10152   "@
10153    shld{l}\t{%2, %1, %0|%0, %1, %2}
10154    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10155   [(set_attr "type" "ishift")
10156    (set_attr "prefix_0f" "1")
10157    (set_attr "mode" "SI")
10158    (set_attr "pent_pair" "np")
10159    (set_attr "athlon_decode" "vector")])
10160
10161 (define_expand "x86_shift_adj_1"
10162   [(set (reg:CCZ FLAGS_REG)
10163         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10164                              (const_int 32))
10165                      (const_int 0)))
10166    (set (match_operand:SI 0 "register_operand" "")
10167         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10168                          (match_operand:SI 1 "register_operand" "")
10169                          (match_dup 0)))
10170    (set (match_dup 1)
10171         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10172                          (match_operand:SI 3 "register_operand" "r")
10173                          (match_dup 1)))]
10174   "TARGET_CMOVE"
10175   "")
10176
10177 (define_expand "x86_shift_adj_2"
10178   [(use (match_operand:SI 0 "register_operand" ""))
10179    (use (match_operand:SI 1 "register_operand" ""))
10180    (use (match_operand:QI 2 "register_operand" ""))]
10181   ""
10182 {
10183   rtx label = gen_label_rtx ();
10184   rtx tmp;
10185
10186   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10187
10188   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10189   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10190   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10191                               gen_rtx_LABEL_REF (VOIDmode, label),
10192                               pc_rtx);
10193   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10194   JUMP_LABEL (tmp) = label;
10195
10196   emit_move_insn (operands[0], operands[1]);
10197   ix86_expand_clear (operands[1]);
10198
10199   emit_label (label);
10200   LABEL_NUSES (label) = 1;
10201
10202   DONE;
10203 })
10204
10205 (define_expand "ashlsi3"
10206   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10207         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10208                    (match_operand:QI 2 "nonmemory_operand" "")))
10209    (clobber (reg:CC FLAGS_REG))]
10210   ""
10211   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10212
10213 (define_insn "*ashlsi3_1"
10214   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10215         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10216                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10217    (clobber (reg:CC FLAGS_REG))]
10218   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10219 {
10220   switch (get_attr_type (insn))
10221     {
10222     case TYPE_ALU:
10223       if (operands[2] != const1_rtx)
10224         abort ();
10225       if (!rtx_equal_p (operands[0], operands[1]))
10226         abort ();
10227       return "add{l}\t{%0, %0|%0, %0}";
10228
10229     case TYPE_LEA:
10230       return "#";
10231
10232     default:
10233       if (REG_P (operands[2]))
10234         return "sal{l}\t{%b2, %0|%0, %b2}";
10235       else if (operands[2] == const1_rtx
10236                && (TARGET_SHIFT1 || optimize_size))
10237         return "sal{l}\t%0";
10238       else
10239         return "sal{l}\t{%2, %0|%0, %2}";
10240     }
10241 }
10242   [(set (attr "type")
10243      (cond [(eq_attr "alternative" "1")
10244               (const_string "lea")
10245             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10246                           (const_int 0))
10247                       (match_operand 0 "register_operand" ""))
10248                  (match_operand 2 "const1_operand" ""))
10249               (const_string "alu")
10250            ]
10251            (const_string "ishift")))
10252    (set_attr "mode" "SI")])
10253
10254 ;; Convert lea to the lea pattern to avoid flags dependency.
10255 (define_split
10256   [(set (match_operand 0 "register_operand" "")
10257         (ashift (match_operand 1 "index_register_operand" "")
10258                 (match_operand:QI 2 "const_int_operand" "")))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "reload_completed
10261    && true_regnum (operands[0]) != true_regnum (operands[1])
10262    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10263   [(const_int 0)]
10264 {
10265   rtx pat;
10266   enum machine_mode mode = GET_MODE (operands[0]);
10267
10268   if (GET_MODE_SIZE (mode) < 4)
10269     operands[0] = gen_lowpart (SImode, operands[0]);
10270   if (mode != Pmode)
10271     operands[1] = gen_lowpart (Pmode, operands[1]);
10272   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10273
10274   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10275   if (Pmode != SImode)
10276     pat = gen_rtx_SUBREG (SImode, pat, 0);
10277   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10278   DONE;
10279 })
10280
10281 ;; Rare case of shifting RSP is handled by generating move and shift
10282 (define_split
10283   [(set (match_operand 0 "register_operand" "")
10284         (ashift (match_operand 1 "register_operand" "")
10285                 (match_operand:QI 2 "const_int_operand" "")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "reload_completed
10288    && true_regnum (operands[0]) != true_regnum (operands[1])"
10289   [(const_int 0)]
10290 {
10291   rtx pat, clob;
10292   emit_move_insn (operands[1], operands[0]);
10293   pat = gen_rtx_SET (VOIDmode, operands[0],
10294                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10295                                      operands[0], operands[2]));
10296   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10297   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10298   DONE;
10299 })
10300
10301 (define_insn "*ashlsi3_1_zext"
10302   [(set (match_operand:DI 0 "register_operand" "=r,r")
10303         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10304                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10305    (clobber (reg:CC FLAGS_REG))]
10306   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10307 {
10308   switch (get_attr_type (insn))
10309     {
10310     case TYPE_ALU:
10311       if (operands[2] != const1_rtx)
10312         abort ();
10313       return "add{l}\t{%k0, %k0|%k0, %k0}";
10314
10315     case TYPE_LEA:
10316       return "#";
10317
10318     default:
10319       if (REG_P (operands[2]))
10320         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10321       else if (operands[2] == const1_rtx
10322                && (TARGET_SHIFT1 || optimize_size))
10323         return "sal{l}\t%k0";
10324       else
10325         return "sal{l}\t{%2, %k0|%k0, %2}";
10326     }
10327 }
10328   [(set (attr "type")
10329      (cond [(eq_attr "alternative" "1")
10330               (const_string "lea")
10331             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10332                      (const_int 0))
10333                  (match_operand 2 "const1_operand" ""))
10334               (const_string "alu")
10335            ]
10336            (const_string "ishift")))
10337    (set_attr "mode" "SI")])
10338
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10340 (define_split
10341   [(set (match_operand:DI 0 "register_operand" "")
10342         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10343                                 (match_operand:QI 2 "const_int_operand" ""))))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_64BIT && reload_completed
10346    && true_regnum (operands[0]) != true_regnum (operands[1])"
10347   [(set (match_dup 0) (zero_extend:DI
10348                         (subreg:SI (mult:SI (match_dup 1)
10349                                             (match_dup 2)) 0)))]
10350 {
10351   operands[1] = gen_lowpart (Pmode, operands[1]);
10352   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10353 })
10354
10355 ;; This pattern can't accept a variable shift count, since shifts by
10356 ;; zero don't affect the flags.  We assume that shifts by constant
10357 ;; zero are optimized away.
10358 (define_insn "*ashlsi3_cmp"
10359   [(set (reg FLAGS_REG)
10360         (compare
10361           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10362                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10363           (const_int 0)))
10364    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10365         (ashift:SI (match_dup 1) (match_dup 2)))]
10366   "ix86_match_ccmode (insn, CCGOCmode)
10367    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10368 {
10369   switch (get_attr_type (insn))
10370     {
10371     case TYPE_ALU:
10372       if (operands[2] != const1_rtx)
10373         abort ();
10374       return "add{l}\t{%0, %0|%0, %0}";
10375
10376     default:
10377       if (REG_P (operands[2]))
10378         return "sal{l}\t{%b2, %0|%0, %b2}";
10379       else if (operands[2] == const1_rtx
10380                && (TARGET_SHIFT1 || optimize_size))
10381         return "sal{l}\t%0";
10382       else
10383         return "sal{l}\t{%2, %0|%0, %2}";
10384     }
10385 }
10386   [(set (attr "type")
10387      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10388                           (const_int 0))
10389                       (match_operand 0 "register_operand" ""))
10390                  (match_operand 2 "const1_operand" ""))
10391               (const_string "alu")
10392            ]
10393            (const_string "ishift")))
10394    (set_attr "mode" "SI")])
10395
10396 (define_insn "*ashlsi3_cmp_zext"
10397   [(set (reg FLAGS_REG)
10398         (compare
10399           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10400                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10401           (const_int 0)))
10402    (set (match_operand:DI 0 "register_operand" "=r")
10403         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10404   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10405    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10406 {
10407   switch (get_attr_type (insn))
10408     {
10409     case TYPE_ALU:
10410       if (operands[2] != const1_rtx)
10411         abort ();
10412       return "add{l}\t{%k0, %k0|%k0, %k0}";
10413
10414     default:
10415       if (REG_P (operands[2]))
10416         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10417       else if (operands[2] == const1_rtx
10418                && (TARGET_SHIFT1 || optimize_size))
10419         return "sal{l}\t%k0";
10420       else
10421         return "sal{l}\t{%2, %k0|%k0, %2}";
10422     }
10423 }
10424   [(set (attr "type")
10425      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10426                      (const_int 0))
10427                  (match_operand 2 "const1_operand" ""))
10428               (const_string "alu")
10429            ]
10430            (const_string "ishift")))
10431    (set_attr "mode" "SI")])
10432
10433 (define_expand "ashlhi3"
10434   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10435         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10436                    (match_operand:QI 2 "nonmemory_operand" "")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "TARGET_HIMODE_MATH"
10439   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10440
10441 (define_insn "*ashlhi3_1_lea"
10442   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10443         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10444                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10445    (clobber (reg:CC FLAGS_REG))]
10446   "!TARGET_PARTIAL_REG_STALL
10447    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10448 {
10449   switch (get_attr_type (insn))
10450     {
10451     case TYPE_LEA:
10452       return "#";
10453     case TYPE_ALU:
10454       if (operands[2] != const1_rtx)
10455         abort ();
10456       return "add{w}\t{%0, %0|%0, %0}";
10457
10458     default:
10459       if (REG_P (operands[2]))
10460         return "sal{w}\t{%b2, %0|%0, %b2}";
10461       else if (operands[2] == const1_rtx
10462                && (TARGET_SHIFT1 || optimize_size))
10463         return "sal{w}\t%0";
10464       else
10465         return "sal{w}\t{%2, %0|%0, %2}";
10466     }
10467 }
10468   [(set (attr "type")
10469      (cond [(eq_attr "alternative" "1")
10470               (const_string "lea")
10471             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10472                           (const_int 0))
10473                       (match_operand 0 "register_operand" ""))
10474                  (match_operand 2 "const1_operand" ""))
10475               (const_string "alu")
10476            ]
10477            (const_string "ishift")))
10478    (set_attr "mode" "HI,SI")])
10479
10480 (define_insn "*ashlhi3_1"
10481   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10483                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10484    (clobber (reg:CC FLAGS_REG))]
10485   "TARGET_PARTIAL_REG_STALL
10486    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10487 {
10488   switch (get_attr_type (insn))
10489     {
10490     case TYPE_ALU:
10491       if (operands[2] != const1_rtx)
10492         abort ();
10493       return "add{w}\t{%0, %0|%0, %0}";
10494
10495     default:
10496       if (REG_P (operands[2]))
10497         return "sal{w}\t{%b2, %0|%0, %b2}";
10498       else if (operands[2] == const1_rtx
10499                && (TARGET_SHIFT1 || optimize_size))
10500         return "sal{w}\t%0";
10501       else
10502         return "sal{w}\t{%2, %0|%0, %2}";
10503     }
10504 }
10505   [(set (attr "type")
10506      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10507                           (const_int 0))
10508                       (match_operand 0 "register_operand" ""))
10509                  (match_operand 2 "const1_operand" ""))
10510               (const_string "alu")
10511            ]
10512            (const_string "ishift")))
10513    (set_attr "mode" "HI")])
10514
10515 ;; This pattern can't accept a variable shift count, since shifts by
10516 ;; zero don't affect the flags.  We assume that shifts by constant
10517 ;; zero are optimized away.
10518 (define_insn "*ashlhi3_cmp"
10519   [(set (reg FLAGS_REG)
10520         (compare
10521           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10522                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10523           (const_int 0)))
10524    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10525         (ashift:HI (match_dup 1) (match_dup 2)))]
10526   "ix86_match_ccmode (insn, CCGOCmode)
10527    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10528 {
10529   switch (get_attr_type (insn))
10530     {
10531     case TYPE_ALU:
10532       if (operands[2] != const1_rtx)
10533         abort ();
10534       return "add{w}\t{%0, %0|%0, %0}";
10535
10536     default:
10537       if (REG_P (operands[2]))
10538         return "sal{w}\t{%b2, %0|%0, %b2}";
10539       else if (operands[2] == const1_rtx
10540                && (TARGET_SHIFT1 || optimize_size))
10541         return "sal{w}\t%0";
10542       else
10543         return "sal{w}\t{%2, %0|%0, %2}";
10544     }
10545 }
10546   [(set (attr "type")
10547      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10548                           (const_int 0))
10549                       (match_operand 0 "register_operand" ""))
10550                  (match_operand 2 "const1_operand" ""))
10551               (const_string "alu")
10552            ]
10553            (const_string "ishift")))
10554    (set_attr "mode" "HI")])
10555
10556 (define_expand "ashlqi3"
10557   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10558         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10559                    (match_operand:QI 2 "nonmemory_operand" "")))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "TARGET_QIMODE_MATH"
10562   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10563
10564 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10565
10566 (define_insn "*ashlqi3_1_lea"
10567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10568         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10569                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10570    (clobber (reg:CC FLAGS_REG))]
10571   "!TARGET_PARTIAL_REG_STALL
10572    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10573 {
10574   switch (get_attr_type (insn))
10575     {
10576     case TYPE_LEA:
10577       return "#";
10578     case TYPE_ALU:
10579       if (operands[2] != const1_rtx)
10580         abort ();
10581       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10582         return "add{l}\t{%k0, %k0|%k0, %k0}";
10583       else
10584         return "add{b}\t{%0, %0|%0, %0}";
10585
10586     default:
10587       if (REG_P (operands[2]))
10588         {
10589           if (get_attr_mode (insn) == MODE_SI)
10590             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10591           else
10592             return "sal{b}\t{%b2, %0|%0, %b2}";
10593         }
10594       else if (operands[2] == const1_rtx
10595                && (TARGET_SHIFT1 || optimize_size))
10596         {
10597           if (get_attr_mode (insn) == MODE_SI)
10598             return "sal{l}\t%0";
10599           else
10600             return "sal{b}\t%0";
10601         }
10602       else
10603         {
10604           if (get_attr_mode (insn) == MODE_SI)
10605             return "sal{l}\t{%2, %k0|%k0, %2}";
10606           else
10607             return "sal{b}\t{%2, %0|%0, %2}";
10608         }
10609     }
10610 }
10611   [(set (attr "type")
10612      (cond [(eq_attr "alternative" "2")
10613               (const_string "lea")
10614             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10615                           (const_int 0))
10616                       (match_operand 0 "register_operand" ""))
10617                  (match_operand 2 "const1_operand" ""))
10618               (const_string "alu")
10619            ]
10620            (const_string "ishift")))
10621    (set_attr "mode" "QI,SI,SI")])
10622
10623 (define_insn "*ashlqi3_1"
10624   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10625         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10626                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10627    (clobber (reg:CC FLAGS_REG))]
10628   "TARGET_PARTIAL_REG_STALL
10629    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10630 {
10631   switch (get_attr_type (insn))
10632     {
10633     case TYPE_ALU:
10634       if (operands[2] != const1_rtx)
10635         abort ();
10636       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10637         return "add{l}\t{%k0, %k0|%k0, %k0}";
10638       else
10639         return "add{b}\t{%0, %0|%0, %0}";
10640
10641     default:
10642       if (REG_P (operands[2]))
10643         {
10644           if (get_attr_mode (insn) == MODE_SI)
10645             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10646           else
10647             return "sal{b}\t{%b2, %0|%0, %b2}";
10648         }
10649       else if (operands[2] == const1_rtx
10650                && (TARGET_SHIFT1 || optimize_size))
10651         {
10652           if (get_attr_mode (insn) == MODE_SI)
10653             return "sal{l}\t%0";
10654           else
10655             return "sal{b}\t%0";
10656         }
10657       else
10658         {
10659           if (get_attr_mode (insn) == MODE_SI)
10660             return "sal{l}\t{%2, %k0|%k0, %2}";
10661           else
10662             return "sal{b}\t{%2, %0|%0, %2}";
10663         }
10664     }
10665 }
10666   [(set (attr "type")
10667      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10668                           (const_int 0))
10669                       (match_operand 0 "register_operand" ""))
10670                  (match_operand 2 "const1_operand" ""))
10671               (const_string "alu")
10672            ]
10673            (const_string "ishift")))
10674    (set_attr "mode" "QI,SI")])
10675
10676 ;; This pattern can't accept a variable shift count, since shifts by
10677 ;; zero don't affect the flags.  We assume that shifts by constant
10678 ;; zero are optimized away.
10679 (define_insn "*ashlqi3_cmp"
10680   [(set (reg FLAGS_REG)
10681         (compare
10682           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10683                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10684           (const_int 0)))
10685    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10686         (ashift:QI (match_dup 1) (match_dup 2)))]
10687   "ix86_match_ccmode (insn, CCGOCmode)
10688    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10689 {
10690   switch (get_attr_type (insn))
10691     {
10692     case TYPE_ALU:
10693       if (operands[2] != const1_rtx)
10694         abort ();
10695       return "add{b}\t{%0, %0|%0, %0}";
10696
10697     default:
10698       if (REG_P (operands[2]))
10699         return "sal{b}\t{%b2, %0|%0, %b2}";
10700       else if (operands[2] == const1_rtx
10701                && (TARGET_SHIFT1 || optimize_size))
10702         return "sal{b}\t%0";
10703       else
10704         return "sal{b}\t{%2, %0|%0, %2}";
10705     }
10706 }
10707   [(set (attr "type")
10708      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709                           (const_int 0))
10710                       (match_operand 0 "register_operand" ""))
10711                  (match_operand 2 "const1_operand" ""))
10712               (const_string "alu")
10713            ]
10714            (const_string "ishift")))
10715    (set_attr "mode" "QI")])
10716
10717 ;; See comment above `ashldi3' about how this works.
10718
10719 (define_expand "ashrdi3"
10720   [(set (match_operand:DI 0 "shiftdi_operand" "")
10721         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10722                      (match_operand:QI 2 "nonmemory_operand" "")))]
10723   ""
10724   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10725
10726 (define_insn "*ashrdi3_63_rex64"
10727   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10728         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10729                      (match_operand:DI 2 "const_int_operand" "i,i")))
10730    (clobber (reg:CC FLAGS_REG))]
10731   "TARGET_64BIT && INTVAL (operands[2]) == 63
10732    && (TARGET_USE_CLTD || optimize_size)
10733    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10734   "@
10735    {cqto|cqo}
10736    sar{q}\t{%2, %0|%0, %2}"
10737   [(set_attr "type" "imovx,ishift")
10738    (set_attr "prefix_0f" "0,*")
10739    (set_attr "length_immediate" "0,*")
10740    (set_attr "modrm" "0,1")
10741    (set_attr "mode" "DI")])
10742
10743 (define_insn "*ashrdi3_1_one_bit_rex64"
10744   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10745         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10746                      (match_operand:QI 2 "const1_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10749    && (TARGET_SHIFT1 || optimize_size)"
10750   "sar{q}\t%0"
10751   [(set_attr "type" "ishift")
10752    (set (attr "length") 
10753      (if_then_else (match_operand:DI 0 "register_operand" "") 
10754         (const_string "2")
10755         (const_string "*")))])
10756
10757 (define_insn "*ashrdi3_1_rex64"
10758   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10759         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10760                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10761    (clobber (reg:CC FLAGS_REG))]
10762   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10763   "@
10764    sar{q}\t{%2, %0|%0, %2}
10765    sar{q}\t{%b2, %0|%0, %b2}"
10766   [(set_attr "type" "ishift")
10767    (set_attr "mode" "DI")])
10768
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags.  We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10773   [(set (reg FLAGS_REG)
10774         (compare
10775           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10776                        (match_operand:QI 2 "const1_operand" ""))
10777           (const_int 0)))
10778    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10779         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10780   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10781    && (TARGET_SHIFT1 || optimize_size)
10782    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10783   "sar{q}\t%0"
10784   [(set_attr "type" "ishift")
10785    (set (attr "length") 
10786      (if_then_else (match_operand:DI 0 "register_operand" "") 
10787         (const_string "2")
10788         (const_string "*")))])
10789
10790 ;; This pattern can't accept a variable shift count, since shifts by
10791 ;; zero don't affect the flags.  We assume that shifts by constant
10792 ;; zero are optimized away.
10793 (define_insn "*ashrdi3_cmp_rex64"
10794   [(set (reg FLAGS_REG)
10795         (compare
10796           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10797                        (match_operand:QI 2 "const_int_operand" "n"))
10798           (const_int 0)))
10799    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10800         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10801   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10802    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10803   "sar{q}\t{%2, %0|%0, %2}"
10804   [(set_attr "type" "ishift")
10805    (set_attr "mode" "DI")])
10806
10807 (define_insn "*ashrdi3_1"
10808   [(set (match_operand:DI 0 "register_operand" "=r")
10809         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10810                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10811    (clobber (reg:CC FLAGS_REG))]
10812   "!TARGET_64BIT"
10813   "#"
10814   [(set_attr "type" "multi")])
10815
10816 ;; By default we don't ask for a scratch register, because when DImode
10817 ;; values are manipulated, registers are already at a premium.  But if
10818 ;; we have one handy, we won't turn it away.
10819 (define_peephole2
10820   [(match_scratch:SI 3 "r")
10821    (parallel [(set (match_operand:DI 0 "register_operand" "")
10822                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10823                                 (match_operand:QI 2 "nonmemory_operand" "")))
10824               (clobber (reg:CC FLAGS_REG))])
10825    (match_dup 3)]
10826   "!TARGET_64BIT && TARGET_CMOVE"
10827   [(const_int 0)]
10828   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10829
10830 (define_split
10831   [(set (match_operand:DI 0 "register_operand" "")
10832         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10833                      (match_operand:QI 2 "nonmemory_operand" "")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10836   [(const_int 0)]
10837   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10838
10839 (define_insn "x86_shrd_1"
10840   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10841         (ior:SI (ashiftrt:SI (match_dup 0)
10842                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10843                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10844                   (minus:QI (const_int 32) (match_dup 2)))))
10845    (clobber (reg:CC FLAGS_REG))]
10846   ""
10847   "@
10848    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10849    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10850   [(set_attr "type" "ishift")
10851    (set_attr "prefix_0f" "1")
10852    (set_attr "pent_pair" "np")
10853    (set_attr "mode" "SI")])
10854
10855 (define_expand "x86_shift_adj_3"
10856   [(use (match_operand:SI 0 "register_operand" ""))
10857    (use (match_operand:SI 1 "register_operand" ""))
10858    (use (match_operand:QI 2 "register_operand" ""))]
10859   ""
10860 {
10861   rtx label = gen_label_rtx ();
10862   rtx tmp;
10863
10864   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10865
10866   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10867   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10868   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10869                               gen_rtx_LABEL_REF (VOIDmode, label),
10870                               pc_rtx);
10871   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10872   JUMP_LABEL (tmp) = label;
10873
10874   emit_move_insn (operands[0], operands[1]);
10875   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10876
10877   emit_label (label);
10878   LABEL_NUSES (label) = 1;
10879
10880   DONE;
10881 })
10882
10883 (define_insn "ashrsi3_31"
10884   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10885         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10886                      (match_operand:SI 2 "const_int_operand" "i,i")))
10887    (clobber (reg:CC FLAGS_REG))]
10888   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10889    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10890   "@
10891    {cltd|cdq}
10892    sar{l}\t{%2, %0|%0, %2}"
10893   [(set_attr "type" "imovx,ishift")
10894    (set_attr "prefix_0f" "0,*")
10895    (set_attr "length_immediate" "0,*")
10896    (set_attr "modrm" "0,1")
10897    (set_attr "mode" "SI")])
10898
10899 (define_insn "*ashrsi3_31_zext"
10900   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10901         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10902                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10905    && INTVAL (operands[2]) == 31
10906    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10907   "@
10908    {cltd|cdq}
10909    sar{l}\t{%2, %k0|%k0, %2}"
10910   [(set_attr "type" "imovx,ishift")
10911    (set_attr "prefix_0f" "0,*")
10912    (set_attr "length_immediate" "0,*")
10913    (set_attr "modrm" "0,1")
10914    (set_attr "mode" "SI")])
10915
10916 (define_expand "ashrsi3"
10917   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10918         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10919                      (match_operand:QI 2 "nonmemory_operand" "")))
10920    (clobber (reg:CC FLAGS_REG))]
10921   ""
10922   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10923
10924 (define_insn "*ashrsi3_1_one_bit"
10925   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10926         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10927                      (match_operand:QI 2 "const1_operand" "")))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10930    && (TARGET_SHIFT1 || optimize_size)"
10931   "sar{l}\t%0"
10932   [(set_attr "type" "ishift")
10933    (set (attr "length") 
10934      (if_then_else (match_operand:SI 0 "register_operand" "") 
10935         (const_string "2")
10936         (const_string "*")))])
10937
10938 (define_insn "*ashrsi3_1_one_bit_zext"
10939   [(set (match_operand:DI 0 "register_operand" "=r")
10940         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10941                                      (match_operand:QI 2 "const1_operand" ""))))
10942    (clobber (reg:CC FLAGS_REG))]
10943   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10944    && (TARGET_SHIFT1 || optimize_size)"
10945   "sar{l}\t%k0"
10946   [(set_attr "type" "ishift")
10947    (set_attr "length" "2")])
10948
10949 (define_insn "*ashrsi3_1"
10950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10951         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10952                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10955   "@
10956    sar{l}\t{%2, %0|%0, %2}
10957    sar{l}\t{%b2, %0|%0, %b2}"
10958   [(set_attr "type" "ishift")
10959    (set_attr "mode" "SI")])
10960
10961 (define_insn "*ashrsi3_1_zext"
10962   [(set (match_operand:DI 0 "register_operand" "=r,r")
10963         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
10964                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10965    (clobber (reg:CC FLAGS_REG))]
10966   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10967   "@
10968    sar{l}\t{%2, %k0|%k0, %2}
10969    sar{l}\t{%b2, %k0|%k0, %b2}"
10970   [(set_attr "type" "ishift")
10971    (set_attr "mode" "SI")])
10972
10973 ;; This pattern can't accept a variable shift count, since shifts by
10974 ;; zero don't affect the flags.  We assume that shifts by constant
10975 ;; zero are optimized away.
10976 (define_insn "*ashrsi3_one_bit_cmp"
10977   [(set (reg FLAGS_REG)
10978         (compare
10979           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10980                        (match_operand:QI 2 "const1_operand" ""))
10981           (const_int 0)))
10982    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10983         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
10984   "ix86_match_ccmode (insn, CCGOCmode)
10985    && (TARGET_SHIFT1 || optimize_size)
10986    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10987   "sar{l}\t%0"
10988   [(set_attr "type" "ishift")
10989    (set (attr "length") 
10990      (if_then_else (match_operand:SI 0 "register_operand" "") 
10991         (const_string "2")
10992         (const_string "*")))])
10993
10994 (define_insn "*ashrsi3_one_bit_cmp_zext"
10995   [(set (reg FLAGS_REG)
10996         (compare
10997           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10998                        (match_operand:QI 2 "const1_operand" ""))
10999           (const_int 0)))
11000    (set (match_operand:DI 0 "register_operand" "=r")
11001         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11002   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11003    && (TARGET_SHIFT1 || optimize_size)
11004    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11005   "sar{l}\t%k0"
11006   [(set_attr "type" "ishift")
11007    (set_attr "length" "2")])
11008
11009 ;; This pattern can't accept a variable shift count, since shifts by
11010 ;; zero don't affect the flags.  We assume that shifts by constant
11011 ;; zero are optimized away.
11012 (define_insn "*ashrsi3_cmp"
11013   [(set (reg FLAGS_REG)
11014         (compare
11015           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11016                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11017           (const_int 0)))
11018    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11019         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11020   "ix86_match_ccmode (insn, CCGOCmode)
11021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11022   "sar{l}\t{%2, %0|%0, %2}"
11023   [(set_attr "type" "ishift")
11024    (set_attr "mode" "SI")])
11025
11026 (define_insn "*ashrsi3_cmp_zext"
11027   [(set (reg FLAGS_REG)
11028         (compare
11029           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11030                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11031           (const_int 0)))
11032    (set (match_operand:DI 0 "register_operand" "=r")
11033         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11034   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11035    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11036   "sar{l}\t{%2, %k0|%k0, %2}"
11037   [(set_attr "type" "ishift")
11038    (set_attr "mode" "SI")])
11039
11040 (define_expand "ashrhi3"
11041   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11042         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11043                      (match_operand:QI 2 "nonmemory_operand" "")))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_HIMODE_MATH"
11046   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11047
11048 (define_insn "*ashrhi3_1_one_bit"
11049   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11050         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11051                      (match_operand:QI 2 "const1_operand" "")))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11054    && (TARGET_SHIFT1 || optimize_size)"
11055   "sar{w}\t%0"
11056   [(set_attr "type" "ishift")
11057    (set (attr "length") 
11058      (if_then_else (match_operand 0 "register_operand" "") 
11059         (const_string "2")
11060         (const_string "*")))])
11061
11062 (define_insn "*ashrhi3_1"
11063   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11064         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11065                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11068   "@
11069    sar{w}\t{%2, %0|%0, %2}
11070    sar{w}\t{%b2, %0|%0, %b2}"
11071   [(set_attr "type" "ishift")
11072    (set_attr "mode" "HI")])
11073
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags.  We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashrhi3_one_bit_cmp"
11078   [(set (reg FLAGS_REG)
11079         (compare
11080           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11081                        (match_operand:QI 2 "const1_operand" ""))
11082           (const_int 0)))
11083    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11084         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11085   "ix86_match_ccmode (insn, CCGOCmode)
11086    && (TARGET_SHIFT1 || optimize_size)
11087    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11088   "sar{w}\t%0"
11089   [(set_attr "type" "ishift")
11090    (set (attr "length") 
11091      (if_then_else (match_operand 0 "register_operand" "") 
11092         (const_string "2")
11093         (const_string "*")))])
11094
11095 ;; This pattern can't accept a variable shift count, since shifts by
11096 ;; zero don't affect the flags.  We assume that shifts by constant
11097 ;; zero are optimized away.
11098 (define_insn "*ashrhi3_cmp"
11099   [(set (reg FLAGS_REG)
11100         (compare
11101           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11102                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11103           (const_int 0)))
11104    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11105         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11106   "ix86_match_ccmode (insn, CCGOCmode)
11107    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11108   "sar{w}\t{%2, %0|%0, %2}"
11109   [(set_attr "type" "ishift")
11110    (set_attr "mode" "HI")])
11111
11112 (define_expand "ashrqi3"
11113   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11114         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11115                      (match_operand:QI 2 "nonmemory_operand" "")))
11116    (clobber (reg:CC FLAGS_REG))]
11117   "TARGET_QIMODE_MATH"
11118   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11119
11120 (define_insn "*ashrqi3_1_one_bit"
11121   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11122         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11123                      (match_operand:QI 2 "const1_operand" "")))
11124    (clobber (reg:CC FLAGS_REG))]
11125   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11126    && (TARGET_SHIFT1 || optimize_size)"
11127   "sar{b}\t%0"
11128   [(set_attr "type" "ishift")
11129    (set (attr "length") 
11130      (if_then_else (match_operand 0 "register_operand" "") 
11131         (const_string "2")
11132         (const_string "*")))])
11133
11134 (define_insn "*ashrqi3_1_one_bit_slp"
11135   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11136         (ashiftrt:QI (match_dup 0)
11137                      (match_operand:QI 1 "const1_operand" "")))
11138    (clobber (reg:CC FLAGS_REG))]
11139   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11140    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11141    && (TARGET_SHIFT1 || optimize_size)"
11142   "sar{b}\t%0"
11143   [(set_attr "type" "ishift1")
11144    (set (attr "length") 
11145      (if_then_else (match_operand 0 "register_operand" "") 
11146         (const_string "2")
11147         (const_string "*")))])
11148
11149 (define_insn "*ashrqi3_1"
11150   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11151         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11152                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11155   "@
11156    sar{b}\t{%2, %0|%0, %2}
11157    sar{b}\t{%b2, %0|%0, %b2}"
11158   [(set_attr "type" "ishift")
11159    (set_attr "mode" "QI")])
11160
11161 (define_insn "*ashrqi3_1_slp"
11162   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11163         (ashiftrt:QI (match_dup 0)
11164                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11165    (clobber (reg:CC FLAGS_REG))]
11166   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11168   "@
11169    sar{b}\t{%1, %0|%0, %1}
11170    sar{b}\t{%b1, %0|%0, %b1}"
11171   [(set_attr "type" "ishift1")
11172    (set_attr "mode" "QI")])
11173
11174 ;; This pattern can't accept a variable shift count, since shifts by
11175 ;; zero don't affect the flags.  We assume that shifts by constant
11176 ;; zero are optimized away.
11177 (define_insn "*ashrqi3_one_bit_cmp"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11181                        (match_operand:QI 2 "const1_operand" "I"))
11182           (const_int 0)))
11183    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11184         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11185   "ix86_match_ccmode (insn, CCGOCmode)
11186    && (TARGET_SHIFT1 || optimize_size)
11187    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11188   "sar{b}\t%0"
11189   [(set_attr "type" "ishift")
11190    (set (attr "length") 
11191      (if_then_else (match_operand 0 "register_operand" "") 
11192         (const_string "2")
11193         (const_string "*")))])
11194
11195 ;; This pattern can't accept a variable shift count, since shifts by
11196 ;; zero don't affect the flags.  We assume that shifts by constant
11197 ;; zero are optimized away.
11198 (define_insn "*ashrqi3_cmp"
11199   [(set (reg FLAGS_REG)
11200         (compare
11201           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11202                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11203           (const_int 0)))
11204    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11205         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11206   "ix86_match_ccmode (insn, CCGOCmode)
11207    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11208   "sar{b}\t{%2, %0|%0, %2}"
11209   [(set_attr "type" "ishift")
11210    (set_attr "mode" "QI")])
11211 \f
11212 ;; Logical shift instructions
11213
11214 ;; See comment above `ashldi3' about how this works.
11215
11216 (define_expand "lshrdi3"
11217   [(set (match_operand:DI 0 "shiftdi_operand" "")
11218         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11219                      (match_operand:QI 2 "nonmemory_operand" "")))]
11220   ""
11221   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11222
11223 (define_insn "*lshrdi3_1_one_bit_rex64"
11224   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11225         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11226                      (match_operand:QI 2 "const1_operand" "")))
11227    (clobber (reg:CC FLAGS_REG))]
11228   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11229    && (TARGET_SHIFT1 || optimize_size)"
11230   "shr{q}\t%0"
11231   [(set_attr "type" "ishift")
11232    (set (attr "length") 
11233      (if_then_else (match_operand:DI 0 "register_operand" "") 
11234         (const_string "2")
11235         (const_string "*")))])
11236
11237 (define_insn "*lshrdi3_1_rex64"
11238   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11239         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11240                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11241    (clobber (reg:CC FLAGS_REG))]
11242   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11243   "@
11244    shr{q}\t{%2, %0|%0, %2}
11245    shr{q}\t{%b2, %0|%0, %b2}"
11246   [(set_attr "type" "ishift")
11247    (set_attr "mode" "DI")])
11248
11249 ;; This pattern can't accept a variable shift count, since shifts by
11250 ;; zero don't affect the flags.  We assume that shifts by constant
11251 ;; zero are optimized away.
11252 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11253   [(set (reg FLAGS_REG)
11254         (compare
11255           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11256                        (match_operand:QI 2 "const1_operand" ""))
11257           (const_int 0)))
11258    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11259         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11260   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11261    && (TARGET_SHIFT1 || optimize_size)
11262    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11263   "shr{q}\t%0"
11264   [(set_attr "type" "ishift")
11265    (set (attr "length") 
11266      (if_then_else (match_operand:DI 0 "register_operand" "") 
11267         (const_string "2")
11268         (const_string "*")))])
11269
11270 ;; This pattern can't accept a variable shift count, since shifts by
11271 ;; zero don't affect the flags.  We assume that shifts by constant
11272 ;; zero are optimized away.
11273 (define_insn "*lshrdi3_cmp_rex64"
11274   [(set (reg FLAGS_REG)
11275         (compare
11276           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11277                        (match_operand:QI 2 "const_int_operand" "e"))
11278           (const_int 0)))
11279    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11280         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11281   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11282    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11283   "shr{q}\t{%2, %0|%0, %2}"
11284   [(set_attr "type" "ishift")
11285    (set_attr "mode" "DI")])
11286
11287 (define_insn "*lshrdi3_1"
11288   [(set (match_operand:DI 0 "register_operand" "=r")
11289         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11290                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   "!TARGET_64BIT"
11293   "#"
11294   [(set_attr "type" "multi")])
11295
11296 ;; By default we don't ask for a scratch register, because when DImode
11297 ;; values are manipulated, registers are already at a premium.  But if
11298 ;; we have one handy, we won't turn it away.
11299 (define_peephole2
11300   [(match_scratch:SI 3 "r")
11301    (parallel [(set (match_operand:DI 0 "register_operand" "")
11302                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11303                                 (match_operand:QI 2 "nonmemory_operand" "")))
11304               (clobber (reg:CC FLAGS_REG))])
11305    (match_dup 3)]
11306   "!TARGET_64BIT && TARGET_CMOVE"
11307   [(const_int 0)]
11308   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11309
11310 (define_split 
11311   [(set (match_operand:DI 0 "register_operand" "")
11312         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11313                      (match_operand:QI 2 "nonmemory_operand" "")))
11314    (clobber (reg:CC FLAGS_REG))]
11315   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11316   [(const_int 0)]
11317   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11318
11319 (define_expand "lshrsi3"
11320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11321         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11322                      (match_operand:QI 2 "nonmemory_operand" "")))
11323    (clobber (reg:CC FLAGS_REG))]
11324   ""
11325   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11326
11327 (define_insn "*lshrsi3_1_one_bit"
11328   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11329         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11330                      (match_operand:QI 2 "const1_operand" "")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11333    && (TARGET_SHIFT1 || optimize_size)"
11334   "shr{l}\t%0"
11335   [(set_attr "type" "ishift")
11336    (set (attr "length") 
11337      (if_then_else (match_operand:SI 0 "register_operand" "") 
11338         (const_string "2")
11339         (const_string "*")))])
11340
11341 (define_insn "*lshrsi3_1_one_bit_zext"
11342   [(set (match_operand:DI 0 "register_operand" "=r")
11343         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11344                      (match_operand:QI 2 "const1_operand" "")))
11345    (clobber (reg:CC FLAGS_REG))]
11346   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11347    && (TARGET_SHIFT1 || optimize_size)"
11348   "shr{l}\t%k0"
11349   [(set_attr "type" "ishift")
11350    (set_attr "length" "2")])
11351
11352 (define_insn "*lshrsi3_1"
11353   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11354         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11355                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11356    (clobber (reg:CC FLAGS_REG))]
11357   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11358   "@
11359    shr{l}\t{%2, %0|%0, %2}
11360    shr{l}\t{%b2, %0|%0, %b2}"
11361   [(set_attr "type" "ishift")
11362    (set_attr "mode" "SI")])
11363
11364 (define_insn "*lshrsi3_1_zext"
11365   [(set (match_operand:DI 0 "register_operand" "=r,r")
11366         (zero_extend:DI
11367           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11368                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11369    (clobber (reg:CC FLAGS_REG))]
11370   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11371   "@
11372    shr{l}\t{%2, %k0|%k0, %2}
11373    shr{l}\t{%b2, %k0|%k0, %b2}"
11374   [(set_attr "type" "ishift")
11375    (set_attr "mode" "SI")])
11376
11377 ;; This pattern can't accept a variable shift count, since shifts by
11378 ;; zero don't affect the flags.  We assume that shifts by constant
11379 ;; zero are optimized away.
11380 (define_insn "*lshrsi3_one_bit_cmp"
11381   [(set (reg FLAGS_REG)
11382         (compare
11383           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11384                        (match_operand:QI 2 "const1_operand" ""))
11385           (const_int 0)))
11386    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11387         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11388   "ix86_match_ccmode (insn, CCGOCmode)
11389    && (TARGET_SHIFT1 || optimize_size)
11390    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11391   "shr{l}\t%0"
11392   [(set_attr "type" "ishift")
11393    (set (attr "length") 
11394      (if_then_else (match_operand:SI 0 "register_operand" "") 
11395         (const_string "2")
11396         (const_string "*")))])
11397
11398 (define_insn "*lshrsi3_cmp_one_bit_zext"
11399   [(set (reg FLAGS_REG)
11400         (compare
11401           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11402                        (match_operand:QI 2 "const1_operand" ""))
11403           (const_int 0)))
11404    (set (match_operand:DI 0 "register_operand" "=r")
11405         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11406   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11407    && (TARGET_SHIFT1 || optimize_size)
11408    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409   "shr{l}\t%k0"
11410   [(set_attr "type" "ishift")
11411    (set_attr "length" "2")])
11412
11413 ;; This pattern can't accept a variable shift count, since shifts by
11414 ;; zero don't affect the flags.  We assume that shifts by constant
11415 ;; zero are optimized away.
11416 (define_insn "*lshrsi3_cmp"
11417   [(set (reg FLAGS_REG)
11418         (compare
11419           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11420                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11421           (const_int 0)))
11422    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11423         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11424   "ix86_match_ccmode (insn, CCGOCmode)
11425    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11426   "shr{l}\t{%2, %0|%0, %2}"
11427   [(set_attr "type" "ishift")
11428    (set_attr "mode" "SI")])
11429
11430 (define_insn "*lshrsi3_cmp_zext"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11434                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "register_operand" "=r")
11437         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11440   "shr{l}\t{%2, %k0|%k0, %2}"
11441   [(set_attr "type" "ishift")
11442    (set_attr "mode" "SI")])
11443
11444 (define_expand "lshrhi3"
11445   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11446         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11447                      (match_operand:QI 2 "nonmemory_operand" "")))
11448    (clobber (reg:CC FLAGS_REG))]
11449   "TARGET_HIMODE_MATH"
11450   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11451
11452 (define_insn "*lshrhi3_1_one_bit"
11453   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11454         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11455                      (match_operand:QI 2 "const1_operand" "")))
11456    (clobber (reg:CC FLAGS_REG))]
11457   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11458    && (TARGET_SHIFT1 || optimize_size)"
11459   "shr{w}\t%0"
11460   [(set_attr "type" "ishift")
11461    (set (attr "length") 
11462      (if_then_else (match_operand 0 "register_operand" "") 
11463         (const_string "2")
11464         (const_string "*")))])
11465
11466 (define_insn "*lshrhi3_1"
11467   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11468         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11469                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11470    (clobber (reg:CC FLAGS_REG))]
11471   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11472   "@
11473    shr{w}\t{%2, %0|%0, %2}
11474    shr{w}\t{%b2, %0|%0, %b2}"
11475   [(set_attr "type" "ishift")
11476    (set_attr "mode" "HI")])
11477
11478 ;; This pattern can't accept a variable shift count, since shifts by
11479 ;; zero don't affect the flags.  We assume that shifts by constant
11480 ;; zero are optimized away.
11481 (define_insn "*lshrhi3_one_bit_cmp"
11482   [(set (reg FLAGS_REG)
11483         (compare
11484           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11485                        (match_operand:QI 2 "const1_operand" ""))
11486           (const_int 0)))
11487    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11488         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11489   "ix86_match_ccmode (insn, CCGOCmode)
11490    && (TARGET_SHIFT1 || optimize_size)
11491    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11492   "shr{w}\t%0"
11493   [(set_attr "type" "ishift")
11494    (set (attr "length") 
11495      (if_then_else (match_operand:SI 0 "register_operand" "") 
11496         (const_string "2")
11497         (const_string "*")))])
11498
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags.  We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*lshrhi3_cmp"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11506                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11507           (const_int 0)))
11508    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11509         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11510   "ix86_match_ccmode (insn, CCGOCmode)
11511    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11512   "shr{w}\t{%2, %0|%0, %2}"
11513   [(set_attr "type" "ishift")
11514    (set_attr "mode" "HI")])
11515
11516 (define_expand "lshrqi3"
11517   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11518         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11519                      (match_operand:QI 2 "nonmemory_operand" "")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "TARGET_QIMODE_MATH"
11522   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11523
11524 (define_insn "*lshrqi3_1_one_bit"
11525   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11526         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11527                      (match_operand:QI 2 "const1_operand" "")))
11528    (clobber (reg:CC FLAGS_REG))]
11529   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11530    && (TARGET_SHIFT1 || optimize_size)"
11531   "shr{b}\t%0"
11532   [(set_attr "type" "ishift")
11533    (set (attr "length") 
11534      (if_then_else (match_operand 0 "register_operand" "") 
11535         (const_string "2")
11536         (const_string "*")))])
11537
11538 (define_insn "*lshrqi3_1_one_bit_slp"
11539   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11540         (lshiftrt:QI (match_dup 0)
11541                      (match_operand:QI 1 "const1_operand" "")))
11542    (clobber (reg:CC FLAGS_REG))]
11543   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11544    && (TARGET_SHIFT1 || optimize_size)"
11545   "shr{b}\t%0"
11546   [(set_attr "type" "ishift1")
11547    (set (attr "length") 
11548      (if_then_else (match_operand 0 "register_operand" "") 
11549         (const_string "2")
11550         (const_string "*")))])
11551
11552 (define_insn "*lshrqi3_1"
11553   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11554         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11555                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11558   "@
11559    shr{b}\t{%2, %0|%0, %2}
11560    shr{b}\t{%b2, %0|%0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "QI")])
11563
11564 (define_insn "*lshrqi3_1_slp"
11565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11566         (lshiftrt:QI (match_dup 0)
11567                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11568    (clobber (reg:CC FLAGS_REG))]
11569   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11570    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11571   "@
11572    shr{b}\t{%1, %0|%0, %1}
11573    shr{b}\t{%b1, %0|%0, %b1}"
11574   [(set_attr "type" "ishift1")
11575    (set_attr "mode" "QI")])
11576
11577 ;; This pattern can't accept a variable shift count, since shifts by
11578 ;; zero don't affect the flags.  We assume that shifts by constant
11579 ;; zero are optimized away.
11580 (define_insn "*lshrqi2_one_bit_cmp"
11581   [(set (reg FLAGS_REG)
11582         (compare
11583           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11584                        (match_operand:QI 2 "const1_operand" ""))
11585           (const_int 0)))
11586    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11587         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11588   "ix86_match_ccmode (insn, CCGOCmode)
11589    && (TARGET_SHIFT1 || optimize_size)
11590    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11591   "shr{b}\t%0"
11592   [(set_attr "type" "ishift")
11593    (set (attr "length") 
11594      (if_then_else (match_operand:SI 0 "register_operand" "") 
11595         (const_string "2")
11596         (const_string "*")))])
11597
11598 ;; This pattern can't accept a variable shift count, since shifts by
11599 ;; zero don't affect the flags.  We assume that shifts by constant
11600 ;; zero are optimized away.
11601 (define_insn "*lshrqi2_cmp"
11602   [(set (reg FLAGS_REG)
11603         (compare
11604           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11605                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606           (const_int 0)))
11607    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11608         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11609   "ix86_match_ccmode (insn, CCGOCmode)
11610    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11611   "shr{b}\t{%2, %0|%0, %2}"
11612   [(set_attr "type" "ishift")
11613    (set_attr "mode" "QI")])
11614 \f
11615 ;; Rotate instructions
11616
11617 (define_expand "rotldi3"
11618   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11619         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11620                    (match_operand:QI 2 "nonmemory_operand" "")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "TARGET_64BIT"
11623   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11624
11625 (define_insn "*rotlsi3_1_one_bit_rex64"
11626   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11627         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11628                    (match_operand:QI 2 "const1_operand" "")))
11629    (clobber (reg:CC FLAGS_REG))]
11630   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11631    && (TARGET_SHIFT1 || optimize_size)"
11632   "rol{q}\t%0"
11633   [(set_attr "type" "rotate")
11634    (set (attr "length") 
11635      (if_then_else (match_operand:DI 0 "register_operand" "") 
11636         (const_string "2")
11637         (const_string "*")))])
11638
11639 (define_insn "*rotldi3_1_rex64"
11640   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11641         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11642                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11643    (clobber (reg:CC FLAGS_REG))]
11644   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11645   "@
11646    rol{q}\t{%2, %0|%0, %2}
11647    rol{q}\t{%b2, %0|%0, %b2}"
11648   [(set_attr "type" "rotate")
11649    (set_attr "mode" "DI")])
11650
11651 (define_expand "rotlsi3"
11652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11653         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11654                    (match_operand:QI 2 "nonmemory_operand" "")))
11655    (clobber (reg:CC FLAGS_REG))]
11656   ""
11657   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11658
11659 (define_insn "*rotlsi3_1_one_bit"
11660   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11661         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11662                    (match_operand:QI 2 "const1_operand" "")))
11663    (clobber (reg:CC FLAGS_REG))]
11664   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11665    && (TARGET_SHIFT1 || optimize_size)"
11666   "rol{l}\t%0"
11667   [(set_attr "type" "rotate")
11668    (set (attr "length") 
11669      (if_then_else (match_operand:SI 0 "register_operand" "") 
11670         (const_string "2")
11671         (const_string "*")))])
11672
11673 (define_insn "*rotlsi3_1_one_bit_zext"
11674   [(set (match_operand:DI 0 "register_operand" "=r")
11675         (zero_extend:DI
11676           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11677                      (match_operand:QI 2 "const1_operand" ""))))
11678    (clobber (reg:CC FLAGS_REG))]
11679   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11680    && (TARGET_SHIFT1 || optimize_size)"
11681   "rol{l}\t%k0"
11682   [(set_attr "type" "rotate")
11683    (set_attr "length" "2")])
11684
11685 (define_insn "*rotlsi3_1"
11686   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11687         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11688                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11689    (clobber (reg:CC FLAGS_REG))]
11690   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11691   "@
11692    rol{l}\t{%2, %0|%0, %2}
11693    rol{l}\t{%b2, %0|%0, %b2}"
11694   [(set_attr "type" "rotate")
11695    (set_attr "mode" "SI")])
11696
11697 (define_insn "*rotlsi3_1_zext"
11698   [(set (match_operand:DI 0 "register_operand" "=r,r")
11699         (zero_extend:DI
11700           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11701                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11704   "@
11705    rol{l}\t{%2, %k0|%k0, %2}
11706    rol{l}\t{%b2, %k0|%k0, %b2}"
11707   [(set_attr "type" "rotate")
11708    (set_attr "mode" "SI")])
11709
11710 (define_expand "rotlhi3"
11711   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11712         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11713                    (match_operand:QI 2 "nonmemory_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "TARGET_HIMODE_MATH"
11716   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11717
11718 (define_insn "*rotlhi3_1_one_bit"
11719   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11721                    (match_operand:QI 2 "const1_operand" "")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11724    && (TARGET_SHIFT1 || optimize_size)"
11725   "rol{w}\t%0"
11726   [(set_attr "type" "rotate")
11727    (set (attr "length") 
11728      (if_then_else (match_operand 0 "register_operand" "") 
11729         (const_string "2")
11730         (const_string "*")))])
11731
11732 (define_insn "*rotlhi3_1"
11733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11734         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11735                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11738   "@
11739    rol{w}\t{%2, %0|%0, %2}
11740    rol{w}\t{%b2, %0|%0, %b2}"
11741   [(set_attr "type" "rotate")
11742    (set_attr "mode" "HI")])
11743
11744 (define_expand "rotlqi3"
11745   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11746         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11747                    (match_operand:QI 2 "nonmemory_operand" "")))
11748    (clobber (reg:CC FLAGS_REG))]
11749   "TARGET_QIMODE_MATH"
11750   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11751
11752 (define_insn "*rotlqi3_1_one_bit_slp"
11753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11754         (rotate:QI (match_dup 0)
11755                    (match_operand:QI 1 "const1_operand" "")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11758    && (TARGET_SHIFT1 || optimize_size)"
11759   "rol{b}\t%0"
11760   [(set_attr "type" "rotate1")
11761    (set (attr "length") 
11762      (if_then_else (match_operand 0 "register_operand" "") 
11763         (const_string "2")
11764         (const_string "*")))])
11765
11766 (define_insn "*rotlqi3_1_one_bit"
11767   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11768         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11769                    (match_operand:QI 2 "const1_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11772    && (TARGET_SHIFT1 || optimize_size)"
11773   "rol{b}\t%0"
11774   [(set_attr "type" "rotate")
11775    (set (attr "length") 
11776      (if_then_else (match_operand 0 "register_operand" "") 
11777         (const_string "2")
11778         (const_string "*")))])
11779
11780 (define_insn "*rotlqi3_1_slp"
11781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11782         (rotate:QI (match_dup 0)
11783                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11787   "@
11788    rol{b}\t{%1, %0|%0, %1}
11789    rol{b}\t{%b1, %0|%0, %b1}"
11790   [(set_attr "type" "rotate1")
11791    (set_attr "mode" "QI")])
11792
11793 (define_insn "*rotlqi3_1"
11794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11795         (rotate:QI (match_operand:QI 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 (ROTATE, QImode, operands)"
11799   "@
11800    rol{b}\t{%2, %0|%0, %2}
11801    rol{b}\t{%b2, %0|%0, %b2}"
11802   [(set_attr "type" "rotate")
11803    (set_attr "mode" "QI")])
11804
11805 (define_expand "rotrdi3"
11806   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11807         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11808                      (match_operand:QI 2 "nonmemory_operand" "")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "TARGET_64BIT"
11811   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11812
11813 (define_insn "*rotrdi3_1_one_bit_rex64"
11814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11815         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11816                      (match_operand:QI 2 "const1_operand" "")))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11819    && (TARGET_SHIFT1 || optimize_size)"
11820   "ror{q}\t%0"
11821   [(set_attr "type" "rotate")
11822    (set (attr "length") 
11823      (if_then_else (match_operand:DI 0 "register_operand" "") 
11824         (const_string "2")
11825         (const_string "*")))])
11826
11827 (define_insn "*rotrdi3_1_rex64"
11828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11829         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11833   "@
11834    ror{q}\t{%2, %0|%0, %2}
11835    ror{q}\t{%b2, %0|%0, %b2}"
11836   [(set_attr "type" "rotate")
11837    (set_attr "mode" "DI")])
11838
11839 (define_expand "rotrsi3"
11840   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11841         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11842                      (match_operand:QI 2 "nonmemory_operand" "")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   ""
11845   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11846
11847 (define_insn "*rotrsi3_1_one_bit"
11848   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11849         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11850                      (match_operand:QI 2 "const1_operand" "")))
11851    (clobber (reg:CC FLAGS_REG))]
11852   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11853    && (TARGET_SHIFT1 || optimize_size)"
11854   "ror{l}\t%0"
11855   [(set_attr "type" "rotate")
11856    (set (attr "length") 
11857      (if_then_else (match_operand:SI 0 "register_operand" "") 
11858         (const_string "2")
11859         (const_string "*")))])
11860
11861 (define_insn "*rotrsi3_1_one_bit_zext"
11862   [(set (match_operand:DI 0 "register_operand" "=r")
11863         (zero_extend:DI
11864           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11865                        (match_operand:QI 2 "const1_operand" ""))))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11868    && (TARGET_SHIFT1 || optimize_size)"
11869   "ror{l}\t%k0"
11870   [(set_attr "type" "rotate")
11871    (set (attr "length") 
11872      (if_then_else (match_operand:SI 0 "register_operand" "") 
11873         (const_string "2")
11874         (const_string "*")))])
11875
11876 (define_insn "*rotrsi3_1"
11877   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11878         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11879                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11882   "@
11883    ror{l}\t{%2, %0|%0, %2}
11884    ror{l}\t{%b2, %0|%0, %b2}"
11885   [(set_attr "type" "rotate")
11886    (set_attr "mode" "SI")])
11887
11888 (define_insn "*rotrsi3_1_zext"
11889   [(set (match_operand:DI 0 "register_operand" "=r,r")
11890         (zero_extend:DI
11891           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11892                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11893    (clobber (reg:CC FLAGS_REG))]
11894   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11895   "@
11896    ror{l}\t{%2, %k0|%k0, %2}
11897    ror{l}\t{%b2, %k0|%k0, %b2}"
11898   [(set_attr "type" "rotate")
11899    (set_attr "mode" "SI")])
11900
11901 (define_expand "rotrhi3"
11902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11903         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11904                      (match_operand:QI 2 "nonmemory_operand" "")))
11905    (clobber (reg:CC FLAGS_REG))]
11906   "TARGET_HIMODE_MATH"
11907   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11908
11909 (define_insn "*rotrhi3_one_bit"
11910   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11911         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11912                      (match_operand:QI 2 "const1_operand" "")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11915    && (TARGET_SHIFT1 || optimize_size)"
11916   "ror{w}\t%0"
11917   [(set_attr "type" "rotate")
11918    (set (attr "length") 
11919      (if_then_else (match_operand 0 "register_operand" "") 
11920         (const_string "2")
11921         (const_string "*")))])
11922
11923 (define_insn "*rotrhi3"
11924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11925         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11929   "@
11930    ror{w}\t{%2, %0|%0, %2}
11931    ror{w}\t{%b2, %0|%0, %b2}"
11932   [(set_attr "type" "rotate")
11933    (set_attr "mode" "HI")])
11934
11935 (define_expand "rotrqi3"
11936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11937         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11938                      (match_operand:QI 2 "nonmemory_operand" "")))
11939    (clobber (reg:CC FLAGS_REG))]
11940   "TARGET_QIMODE_MATH"
11941   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11942
11943 (define_insn "*rotrqi3_1_one_bit"
11944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11945         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11946                      (match_operand:QI 2 "const1_operand" "")))
11947    (clobber (reg:CC FLAGS_REG))]
11948   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
11949    && (TARGET_SHIFT1 || optimize_size)"
11950   "ror{b}\t%0"
11951   [(set_attr "type" "rotate")
11952    (set (attr "length") 
11953      (if_then_else (match_operand 0 "register_operand" "") 
11954         (const_string "2")
11955         (const_string "*")))])
11956
11957 (define_insn "*rotrqi3_1_one_bit_slp"
11958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11959         (rotatert:QI (match_dup 0)
11960                      (match_operand:QI 1 "const1_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11963    && (TARGET_SHIFT1 || optimize_size)"
11964   "ror{b}\t%0"
11965   [(set_attr "type" "rotate1")
11966    (set (attr "length") 
11967      (if_then_else (match_operand 0 "register_operand" "") 
11968         (const_string "2")
11969         (const_string "*")))])
11970
11971 (define_insn "*rotrqi3_1"
11972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11973         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11974                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11977   "@
11978    ror{b}\t{%2, %0|%0, %2}
11979    ror{b}\t{%b2, %0|%0, %b2}"
11980   [(set_attr "type" "rotate")
11981    (set_attr "mode" "QI")])
11982
11983 (define_insn "*rotrqi3_1_slp"
11984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11985         (rotatert:QI (match_dup 0)
11986                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11989    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11990   "@
11991    ror{b}\t{%1, %0|%0, %1}
11992    ror{b}\t{%b1, %0|%0, %b1}"
11993   [(set_attr "type" "rotate1")
11994    (set_attr "mode" "QI")])
11995 \f
11996 ;; Bit set / bit test instructions
11997
11998 (define_expand "extv"
11999   [(set (match_operand:SI 0 "register_operand" "")
12000         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12001                          (match_operand:SI 2 "immediate_operand" "")
12002                          (match_operand:SI 3 "immediate_operand" "")))]
12003   ""
12004 {
12005   /* Handle extractions from %ah et al.  */
12006   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12007     FAIL;
12008
12009   /* From mips.md: extract_bit_field doesn't verify that our source
12010      matches the predicate, so check it again here.  */
12011   if (! ext_register_operand (operands[1], VOIDmode))
12012     FAIL;
12013 })
12014
12015 (define_expand "extzv"
12016   [(set (match_operand:SI 0 "register_operand" "")
12017         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12018                          (match_operand:SI 2 "immediate_operand" "")
12019                          (match_operand:SI 3 "immediate_operand" "")))]
12020   ""
12021 {
12022   /* Handle extractions from %ah et al.  */
12023   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12024     FAIL;
12025
12026   /* From mips.md: extract_bit_field doesn't verify that our source
12027      matches the predicate, so check it again here.  */
12028   if (! ext_register_operand (operands[1], VOIDmode))
12029     FAIL;
12030 })
12031
12032 (define_expand "insv"
12033   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12034                       (match_operand 1 "immediate_operand" "")
12035                       (match_operand 2 "immediate_operand" ""))
12036         (match_operand 3 "register_operand" ""))]
12037   ""
12038 {
12039   /* Handle extractions from %ah et al.  */
12040   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12041     FAIL;
12042
12043   /* From mips.md: insert_bit_field doesn't verify that our source
12044      matches the predicate, so check it again here.  */
12045   if (! ext_register_operand (operands[0], VOIDmode))
12046     FAIL;
12047
12048   if (TARGET_64BIT)
12049     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12050   else
12051     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12052
12053   DONE;
12054 })
12055
12056 ;; %%% bts, btr, btc, bt.
12057 ;; In general these instructions are *slow* when applied to memory,
12058 ;; since they enforce atomic operation.  When applied to registers,
12059 ;; it depends on the cpu implementation.  They're never faster than
12060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12061 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12062 ;; within the instruction itself, so operating on bits in the high
12063 ;; 32-bits of a register becomes easier.
12064 ;;
12065 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12067 ;; negdf respectively, so they can never be disabled entirely.
12068
12069 (define_insn "*btsq"
12070   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12071                          (const_int 1)
12072                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12073         (const_int 1))
12074    (clobber (reg:CC FLAGS_REG))]
12075   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12076   "bts{q} %1,%0"
12077   [(set_attr "type" "alu1")])
12078
12079 (define_insn "*btrq"
12080   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12081                          (const_int 1)
12082                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12083         (const_int 0))
12084    (clobber (reg:CC FLAGS_REG))]
12085   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12086   "btr{q} %1,%0"
12087   [(set_attr "type" "alu1")])
12088
12089 (define_insn "*btcq"
12090   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12091                          (const_int 1)
12092                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12093         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12096   "btc{q} %1,%0"
12097   [(set_attr "type" "alu1")])
12098
12099 ;; Allow Nocona to avoid these instructions if a register is available.
12100
12101 (define_peephole2
12102   [(match_scratch:DI 2 "r")
12103    (parallel [(set (zero_extract:DI
12104                      (match_operand:DI 0 "register_operand" "")
12105                      (const_int 1)
12106                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12107                    (const_int 1))
12108               (clobber (reg:CC FLAGS_REG))])]
12109   "TARGET_64BIT && !TARGET_USE_BT"
12110   [(const_int 0)]
12111 {
12112   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12113   rtx op1;
12114
12115   if (HOST_BITS_PER_WIDE_INT >= 64)
12116     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12117   else if (i < HOST_BITS_PER_WIDE_INT)
12118     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12119   else
12120     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12121
12122   op1 = immed_double_const (lo, hi, DImode);
12123   if (i >= 31)
12124     {
12125       emit_move_insn (operands[2], op1);
12126       op1 = operands[2];
12127     }
12128
12129   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12130   DONE;
12131 })
12132
12133 (define_peephole2
12134   [(match_scratch:DI 2 "r")
12135    (parallel [(set (zero_extract:DI
12136                      (match_operand:DI 0 "register_operand" "")
12137                      (const_int 1)
12138                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12139                    (const_int 0))
12140               (clobber (reg:CC FLAGS_REG))])]
12141   "TARGET_64BIT && !TARGET_USE_BT"
12142   [(const_int 0)]
12143 {
12144   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12145   rtx op1;
12146
12147   if (HOST_BITS_PER_WIDE_INT >= 64)
12148     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12149   else if (i < HOST_BITS_PER_WIDE_INT)
12150     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12151   else
12152     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12153
12154   op1 = immed_double_const (~lo, ~hi, DImode);
12155   if (i >= 32)
12156     {
12157       emit_move_insn (operands[2], op1);
12158       op1 = operands[2];
12159     }
12160
12161   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12162   DONE;
12163 })
12164
12165 (define_peephole2
12166   [(match_scratch:DI 2 "r")
12167    (parallel [(set (zero_extract:DI
12168                      (match_operand:DI 0 "register_operand" "")
12169                      (const_int 1)
12170                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12171               (not:DI (zero_extract:DI
12172                         (match_dup 0) (const_int 1) (match_dup 1))))
12173               (clobber (reg:CC FLAGS_REG))])]
12174   "TARGET_64BIT && !TARGET_USE_BT"
12175   [(const_int 0)]
12176 {
12177   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12178   rtx op1;
12179
12180   if (HOST_BITS_PER_WIDE_INT >= 64)
12181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12182   else if (i < HOST_BITS_PER_WIDE_INT)
12183     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12184   else
12185     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12186
12187   op1 = immed_double_const (lo, hi, DImode);
12188   if (i >= 31)
12189     {
12190       emit_move_insn (operands[2], op1);
12191       op1 = operands[2];
12192     }
12193
12194   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12195   DONE;
12196 })
12197 \f
12198 ;; Store-flag instructions.
12199
12200 ;; For all sCOND expanders, also expand the compare or test insn that
12201 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12202
12203 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12204 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12205 ;; way, which can later delete the movzx if only QImode is needed.
12206
12207 (define_expand "seq"
12208   [(set (match_operand:QI 0 "register_operand" "")
12209         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12210   ""
12211   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12212
12213 (define_expand "sne"
12214   [(set (match_operand:QI 0 "register_operand" "")
12215         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12216   ""
12217   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12218
12219 (define_expand "sgt"
12220   [(set (match_operand:QI 0 "register_operand" "")
12221         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12222   ""
12223   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12224
12225 (define_expand "sgtu"
12226   [(set (match_operand:QI 0 "register_operand" "")
12227         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12228   ""
12229   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12230
12231 (define_expand "slt"
12232   [(set (match_operand:QI 0 "register_operand" "")
12233         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12234   ""
12235   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12236
12237 (define_expand "sltu"
12238   [(set (match_operand:QI 0 "register_operand" "")
12239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12240   ""
12241   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12242
12243 (define_expand "sge"
12244   [(set (match_operand:QI 0 "register_operand" "")
12245         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12246   ""
12247   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12248
12249 (define_expand "sgeu"
12250   [(set (match_operand:QI 0 "register_operand" "")
12251         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12252   ""
12253   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12254
12255 (define_expand "sle"
12256   [(set (match_operand:QI 0 "register_operand" "")
12257         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12258   ""
12259   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12260
12261 (define_expand "sleu"
12262   [(set (match_operand:QI 0 "register_operand" "")
12263         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12264   ""
12265   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12266
12267 (define_expand "sunordered"
12268   [(set (match_operand:QI 0 "register_operand" "")
12269         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12270   "TARGET_80387 || TARGET_SSE"
12271   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12272
12273 (define_expand "sordered"
12274   [(set (match_operand:QI 0 "register_operand" "")
12275         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12276   "TARGET_80387"
12277   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12278
12279 (define_expand "suneq"
12280   [(set (match_operand:QI 0 "register_operand" "")
12281         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12282   "TARGET_80387 || TARGET_SSE"
12283   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12284
12285 (define_expand "sunge"
12286   [(set (match_operand:QI 0 "register_operand" "")
12287         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12288   "TARGET_80387 || TARGET_SSE"
12289   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12290
12291 (define_expand "sungt"
12292   [(set (match_operand:QI 0 "register_operand" "")
12293         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12294   "TARGET_80387 || TARGET_SSE"
12295   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12296
12297 (define_expand "sunle"
12298   [(set (match_operand:QI 0 "register_operand" "")
12299         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12300   "TARGET_80387 || TARGET_SSE"
12301   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12302
12303 (define_expand "sunlt"
12304   [(set (match_operand:QI 0 "register_operand" "")
12305         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12306   "TARGET_80387 || TARGET_SSE"
12307   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12308
12309 (define_expand "sltgt"
12310   [(set (match_operand:QI 0 "register_operand" "")
12311         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12312   "TARGET_80387 || TARGET_SSE"
12313   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12314
12315 (define_insn "*setcc_1"
12316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12317         (match_operator:QI 1 "ix86_comparison_operator"
12318           [(reg FLAGS_REG) (const_int 0)]))]
12319   ""
12320   "set%C1\t%0"
12321   [(set_attr "type" "setcc")
12322    (set_attr "mode" "QI")])
12323
12324 (define_insn "*setcc_2"
12325   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12326         (match_operator:QI 1 "ix86_comparison_operator"
12327           [(reg FLAGS_REG) (const_int 0)]))]
12328   ""
12329   "set%C1\t%0"
12330   [(set_attr "type" "setcc")
12331    (set_attr "mode" "QI")])
12332
12333 ;; In general it is not safe to assume too much about CCmode registers,
12334 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12335 ;; conditions this is safe on x86, so help combine not create
12336 ;;
12337 ;;      seta    %al
12338 ;;      testb   %al, %al
12339 ;;      sete    %al
12340
12341 (define_split 
12342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12343         (ne:QI (match_operator 1 "ix86_comparison_operator"
12344                  [(reg FLAGS_REG) (const_int 0)])
12345             (const_int 0)))]
12346   ""
12347   [(set (match_dup 0) (match_dup 1))]
12348 {
12349   PUT_MODE (operands[1], QImode);
12350 })
12351
12352 (define_split 
12353   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12354         (ne:QI (match_operator 1 "ix86_comparison_operator"
12355                  [(reg FLAGS_REG) (const_int 0)])
12356             (const_int 0)))]
12357   ""
12358   [(set (match_dup 0) (match_dup 1))]
12359 {
12360   PUT_MODE (operands[1], QImode);
12361 })
12362
12363 (define_split 
12364   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12365         (eq:QI (match_operator 1 "ix86_comparison_operator"
12366                  [(reg FLAGS_REG) (const_int 0)])
12367             (const_int 0)))]
12368   ""
12369   [(set (match_dup 0) (match_dup 1))]
12370 {
12371   rtx new_op1 = copy_rtx (operands[1]);
12372   operands[1] = new_op1;
12373   PUT_MODE (new_op1, QImode);
12374   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12375                                              GET_MODE (XEXP (new_op1, 0))));
12376
12377   /* Make sure that (a) the CCmode we have for the flags is strong
12378      enough for the reversed compare or (b) we have a valid FP compare.  */
12379   if (! ix86_comparison_operator (new_op1, VOIDmode))
12380     FAIL;
12381 })
12382
12383 (define_split 
12384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12385         (eq:QI (match_operator 1 "ix86_comparison_operator"
12386                  [(reg FLAGS_REG) (const_int 0)])
12387             (const_int 0)))]
12388   ""
12389   [(set (match_dup 0) (match_dup 1))]
12390 {
12391   rtx new_op1 = copy_rtx (operands[1]);
12392   operands[1] = new_op1;
12393   PUT_MODE (new_op1, QImode);
12394   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12395                                              GET_MODE (XEXP (new_op1, 0))));
12396
12397   /* Make sure that (a) the CCmode we have for the flags is strong
12398      enough for the reversed compare or (b) we have a valid FP compare.  */
12399   if (! ix86_comparison_operator (new_op1, VOIDmode))
12400     FAIL;
12401 })
12402
12403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12404 ;; subsequent logical operations are used to imitate conditional moves.
12405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12406 ;; it directly.  Further holding this value in pseudo register might bring
12407 ;; problem in implicit normalization in spill code.
12408 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12409 ;; instructions after reload by splitting the conditional move patterns.
12410
12411 (define_insn "*sse_setccsf"
12412   [(set (match_operand:SF 0 "register_operand" "=x")
12413         (match_operator:SF 1 "sse_comparison_operator"
12414           [(match_operand:SF 2 "register_operand" "0")
12415            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12416   "TARGET_SSE && reload_completed"
12417   "cmp%D1ss\t{%3, %0|%0, %3}"
12418   [(set_attr "type" "ssecmp")
12419    (set_attr "mode" "SF")])
12420
12421 (define_insn "*sse_setccdf"
12422   [(set (match_operand:DF 0 "register_operand" "=Y")
12423         (match_operator:DF 1 "sse_comparison_operator"
12424           [(match_operand:DF 2 "register_operand" "0")
12425            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12426   "TARGET_SSE2 && reload_completed"
12427   "cmp%D1sd\t{%3, %0|%0, %3}"
12428   [(set_attr "type" "ssecmp")
12429    (set_attr "mode" "DF")])
12430 \f
12431 ;; Basic conditional jump instructions.
12432 ;; We ignore the overflow flag for signed branch instructions.
12433
12434 ;; For all bCOND expanders, also expand the compare or test insn that
12435 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12436
12437 (define_expand "beq"
12438   [(set (pc)
12439         (if_then_else (match_dup 1)
12440                       (label_ref (match_operand 0 "" ""))
12441                       (pc)))]
12442   ""
12443   "ix86_expand_branch (EQ, operands[0]); DONE;")
12444
12445 (define_expand "bne"
12446   [(set (pc)
12447         (if_then_else (match_dup 1)
12448                       (label_ref (match_operand 0 "" ""))
12449                       (pc)))]
12450   ""
12451   "ix86_expand_branch (NE, operands[0]); DONE;")
12452
12453 (define_expand "bgt"
12454   [(set (pc)
12455         (if_then_else (match_dup 1)
12456                       (label_ref (match_operand 0 "" ""))
12457                       (pc)))]
12458   ""
12459   "ix86_expand_branch (GT, operands[0]); DONE;")
12460
12461 (define_expand "bgtu"
12462   [(set (pc)
12463         (if_then_else (match_dup 1)
12464                       (label_ref (match_operand 0 "" ""))
12465                       (pc)))]
12466   ""
12467   "ix86_expand_branch (GTU, operands[0]); DONE;")
12468
12469 (define_expand "blt"
12470   [(set (pc)
12471         (if_then_else (match_dup 1)
12472                       (label_ref (match_operand 0 "" ""))
12473                       (pc)))]
12474   ""
12475   "ix86_expand_branch (LT, operands[0]); DONE;")
12476
12477 (define_expand "bltu"
12478   [(set (pc)
12479         (if_then_else (match_dup 1)
12480                       (label_ref (match_operand 0 "" ""))
12481                       (pc)))]
12482   ""
12483   "ix86_expand_branch (LTU, operands[0]); DONE;")
12484
12485 (define_expand "bge"
12486   [(set (pc)
12487         (if_then_else (match_dup 1)
12488                       (label_ref (match_operand 0 "" ""))
12489                       (pc)))]
12490   ""
12491   "ix86_expand_branch (GE, operands[0]); DONE;")
12492
12493 (define_expand "bgeu"
12494   [(set (pc)
12495         (if_then_else (match_dup 1)
12496                       (label_ref (match_operand 0 "" ""))
12497                       (pc)))]
12498   ""
12499   "ix86_expand_branch (GEU, operands[0]); DONE;")
12500
12501 (define_expand "ble"
12502   [(set (pc)
12503         (if_then_else (match_dup 1)
12504                       (label_ref (match_operand 0 "" ""))
12505                       (pc)))]
12506   ""
12507   "ix86_expand_branch (LE, operands[0]); DONE;")
12508
12509 (define_expand "bleu"
12510   [(set (pc)
12511         (if_then_else (match_dup 1)
12512                       (label_ref (match_operand 0 "" ""))
12513                       (pc)))]
12514   ""
12515   "ix86_expand_branch (LEU, operands[0]); DONE;")
12516
12517 (define_expand "bunordered"
12518   [(set (pc)
12519         (if_then_else (match_dup 1)
12520                       (label_ref (match_operand 0 "" ""))
12521                       (pc)))]
12522   "TARGET_80387 || TARGET_SSE_MATH"
12523   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12524
12525 (define_expand "bordered"
12526   [(set (pc)
12527         (if_then_else (match_dup 1)
12528                       (label_ref (match_operand 0 "" ""))
12529                       (pc)))]
12530   "TARGET_80387 || TARGET_SSE_MATH"
12531   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12532
12533 (define_expand "buneq"
12534   [(set (pc)
12535         (if_then_else (match_dup 1)
12536                       (label_ref (match_operand 0 "" ""))
12537                       (pc)))]
12538   "TARGET_80387 || TARGET_SSE_MATH"
12539   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12540
12541 (define_expand "bunge"
12542   [(set (pc)
12543         (if_then_else (match_dup 1)
12544                       (label_ref (match_operand 0 "" ""))
12545                       (pc)))]
12546   "TARGET_80387 || TARGET_SSE_MATH"
12547   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12548
12549 (define_expand "bungt"
12550   [(set (pc)
12551         (if_then_else (match_dup 1)
12552                       (label_ref (match_operand 0 "" ""))
12553                       (pc)))]
12554   "TARGET_80387 || TARGET_SSE_MATH"
12555   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12556
12557 (define_expand "bunle"
12558   [(set (pc)
12559         (if_then_else (match_dup 1)
12560                       (label_ref (match_operand 0 "" ""))
12561                       (pc)))]
12562   "TARGET_80387 || TARGET_SSE_MATH"
12563   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12564
12565 (define_expand "bunlt"
12566   [(set (pc)
12567         (if_then_else (match_dup 1)
12568                       (label_ref (match_operand 0 "" ""))
12569                       (pc)))]
12570   "TARGET_80387 || TARGET_SSE_MATH"
12571   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12572
12573 (define_expand "bltgt"
12574   [(set (pc)
12575         (if_then_else (match_dup 1)
12576                       (label_ref (match_operand 0 "" ""))
12577                       (pc)))]
12578   "TARGET_80387 || TARGET_SSE_MATH"
12579   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12580
12581 (define_insn "*jcc_1"
12582   [(set (pc)
12583         (if_then_else (match_operator 1 "ix86_comparison_operator"
12584                                       [(reg FLAGS_REG) (const_int 0)])
12585                       (label_ref (match_operand 0 "" ""))
12586                       (pc)))]
12587   ""
12588   "%+j%C1\t%l0"
12589   [(set_attr "type" "ibr")
12590    (set_attr "modrm" "0")
12591    (set (attr "length")
12592            (if_then_else (and (ge (minus (match_dup 0) (pc))
12593                                   (const_int -126))
12594                               (lt (minus (match_dup 0) (pc))
12595                                   (const_int 128)))
12596              (const_int 2)
12597              (const_int 6)))])
12598
12599 (define_insn "*jcc_2"
12600   [(set (pc)
12601         (if_then_else (match_operator 1 "ix86_comparison_operator"
12602                                       [(reg FLAGS_REG) (const_int 0)])
12603                       (pc)
12604                       (label_ref (match_operand 0 "" ""))))]
12605   ""
12606   "%+j%c1\t%l0"
12607   [(set_attr "type" "ibr")
12608    (set_attr "modrm" "0")
12609    (set (attr "length")
12610            (if_then_else (and (ge (minus (match_dup 0) (pc))
12611                                   (const_int -126))
12612                               (lt (minus (match_dup 0) (pc))
12613                                   (const_int 128)))
12614              (const_int 2)
12615              (const_int 6)))])
12616
12617 ;; In general it is not safe to assume too much about CCmode registers,
12618 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12619 ;; conditions this is safe on x86, so help combine not create
12620 ;;
12621 ;;      seta    %al
12622 ;;      testb   %al, %al
12623 ;;      je      Lfoo
12624
12625 (define_split 
12626   [(set (pc)
12627         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12628                                       [(reg FLAGS_REG) (const_int 0)])
12629                           (const_int 0))
12630                       (label_ref (match_operand 1 "" ""))
12631                       (pc)))]
12632   ""
12633   [(set (pc)
12634         (if_then_else (match_dup 0)
12635                       (label_ref (match_dup 1))
12636                       (pc)))]
12637 {
12638   PUT_MODE (operands[0], VOIDmode);
12639 })
12640   
12641 (define_split 
12642   [(set (pc)
12643         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12644                                       [(reg FLAGS_REG) (const_int 0)])
12645                           (const_int 0))
12646                       (label_ref (match_operand 1 "" ""))
12647                       (pc)))]
12648   ""
12649   [(set (pc)
12650         (if_then_else (match_dup 0)
12651                       (label_ref (match_dup 1))
12652                       (pc)))]
12653 {
12654   rtx new_op0 = copy_rtx (operands[0]);
12655   operands[0] = new_op0;
12656   PUT_MODE (new_op0, VOIDmode);
12657   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12658                                              GET_MODE (XEXP (new_op0, 0))));
12659
12660   /* Make sure that (a) the CCmode we have for the flags is strong
12661      enough for the reversed compare or (b) we have a valid FP compare.  */
12662   if (! ix86_comparison_operator (new_op0, VOIDmode))
12663     FAIL;
12664 })
12665
12666 ;; Define combination compare-and-branch fp compare instructions to use
12667 ;; during early optimization.  Splitting the operation apart early makes
12668 ;; for bad code when we want to reverse the operation.
12669
12670 (define_insn "*fp_jcc_1_mixed"
12671   [(set (pc)
12672         (if_then_else (match_operator 0 "comparison_operator"
12673                         [(match_operand 1 "register_operand" "f#x,x#f")
12674                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12675           (label_ref (match_operand 3 "" ""))
12676           (pc)))
12677    (clobber (reg:CCFP FPSR_REG))
12678    (clobber (reg:CCFP FLAGS_REG))]
12679   "TARGET_MIX_SSE_I387
12680    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12681    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12682    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12683   "#")
12684
12685 (define_insn "*fp_jcc_1_sse"
12686   [(set (pc)
12687         (if_then_else (match_operator 0 "comparison_operator"
12688                         [(match_operand 1 "register_operand" "x")
12689                          (match_operand 2 "nonimmediate_operand" "xm")])
12690           (label_ref (match_operand 3 "" ""))
12691           (pc)))
12692    (clobber (reg:CCFP FPSR_REG))
12693    (clobber (reg:CCFP FLAGS_REG))]
12694   "TARGET_SSE_MATH
12695    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12696    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12697    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12698   "#")
12699
12700 (define_insn "*fp_jcc_1_387"
12701   [(set (pc)
12702         (if_then_else (match_operator 0 "comparison_operator"
12703                         [(match_operand 1 "register_operand" "f")
12704                          (match_operand 2 "register_operand" "f")])
12705           (label_ref (match_operand 3 "" ""))
12706           (pc)))
12707    (clobber (reg:CCFP FPSR_REG))
12708    (clobber (reg:CCFP FLAGS_REG))]
12709   "TARGET_CMOVE && TARGET_80387
12710    && FLOAT_MODE_P (GET_MODE (operands[1]))
12711    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12712    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12713   "#")
12714
12715 (define_insn "*fp_jcc_2_mixed"
12716   [(set (pc)
12717         (if_then_else (match_operator 0 "comparison_operator"
12718                         [(match_operand 1 "register_operand" "f#x,x#f")
12719                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12720           (pc)
12721           (label_ref (match_operand 3 "" ""))))
12722    (clobber (reg:CCFP FPSR_REG))
12723    (clobber (reg:CCFP FLAGS_REG))]
12724   "TARGET_MIX_SSE_I387
12725    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12726    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12727    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12728   "#")
12729
12730 (define_insn "*fp_jcc_2_sse"
12731   [(set (pc)
12732         (if_then_else (match_operator 0 "comparison_operator"
12733                         [(match_operand 1 "register_operand" "x")
12734                          (match_operand 2 "nonimmediate_operand" "xm")])
12735           (pc)
12736           (label_ref (match_operand 3 "" ""))))
12737    (clobber (reg:CCFP FPSR_REG))
12738    (clobber (reg:CCFP FLAGS_REG))]
12739   "TARGET_SSE_MATH
12740    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12741    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12742    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12743   "#")
12744
12745 (define_insn "*fp_jcc_2_387"
12746   [(set (pc)
12747         (if_then_else (match_operator 0 "comparison_operator"
12748                         [(match_operand 1 "register_operand" "f")
12749                          (match_operand 2 "register_operand" "f")])
12750           (pc)
12751           (label_ref (match_operand 3 "" ""))))
12752    (clobber (reg:CCFP FPSR_REG))
12753    (clobber (reg:CCFP FLAGS_REG))]
12754   "TARGET_CMOVE && TARGET_80387
12755    && FLOAT_MODE_P (GET_MODE (operands[1]))
12756    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12757    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12758   "#")
12759
12760 (define_insn "*fp_jcc_3_387"
12761   [(set (pc)
12762         (if_then_else (match_operator 0 "comparison_operator"
12763                         [(match_operand 1 "register_operand" "f")
12764                          (match_operand 2 "nonimmediate_operand" "fm")])
12765           (label_ref (match_operand 3 "" ""))
12766           (pc)))
12767    (clobber (reg:CCFP FPSR_REG))
12768    (clobber (reg:CCFP FLAGS_REG))
12769    (clobber (match_scratch:HI 4 "=a"))]
12770   "TARGET_80387
12771    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12772    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12773    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12774    && SELECT_CC_MODE (GET_CODE (operands[0]),
12775                       operands[1], operands[2]) == CCFPmode
12776    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12777   "#")
12778
12779 (define_insn "*fp_jcc_4_387"
12780   [(set (pc)
12781         (if_then_else (match_operator 0 "comparison_operator"
12782                         [(match_operand 1 "register_operand" "f")
12783                          (match_operand 2 "nonimmediate_operand" "fm")])
12784           (pc)
12785           (label_ref (match_operand 3 "" ""))))
12786    (clobber (reg:CCFP FPSR_REG))
12787    (clobber (reg:CCFP FLAGS_REG))
12788    (clobber (match_scratch:HI 4 "=a"))]
12789   "TARGET_80387
12790    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12791    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12792    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12793    && SELECT_CC_MODE (GET_CODE (operands[0]),
12794                       operands[1], operands[2]) == CCFPmode
12795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12796   "#")
12797
12798 (define_insn "*fp_jcc_5_387"
12799   [(set (pc)
12800         (if_then_else (match_operator 0 "comparison_operator"
12801                         [(match_operand 1 "register_operand" "f")
12802                          (match_operand 2 "register_operand" "f")])
12803           (label_ref (match_operand 3 "" ""))
12804           (pc)))
12805    (clobber (reg:CCFP FPSR_REG))
12806    (clobber (reg:CCFP FLAGS_REG))
12807    (clobber (match_scratch:HI 4 "=a"))]
12808   "TARGET_80387
12809    && FLOAT_MODE_P (GET_MODE (operands[1]))
12810    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12811    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12812   "#")
12813
12814 (define_insn "*fp_jcc_6_387"
12815   [(set (pc)
12816         (if_then_else (match_operator 0 "comparison_operator"
12817                         [(match_operand 1 "register_operand" "f")
12818                          (match_operand 2 "register_operand" "f")])
12819           (pc)
12820           (label_ref (match_operand 3 "" ""))))
12821    (clobber (reg:CCFP FPSR_REG))
12822    (clobber (reg:CCFP FLAGS_REG))
12823    (clobber (match_scratch:HI 4 "=a"))]
12824   "TARGET_80387
12825    && FLOAT_MODE_P (GET_MODE (operands[1]))
12826    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12827    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12828   "#")
12829
12830 (define_insn "*fp_jcc_7_387"
12831   [(set (pc)
12832         (if_then_else (match_operator 0 "comparison_operator"
12833                         [(match_operand 1 "register_operand" "f")
12834                          (match_operand 2 "const_double_operand" "C")])
12835           (label_ref (match_operand 3 "" ""))
12836           (pc)))
12837    (clobber (reg:CCFP FPSR_REG))
12838    (clobber (reg:CCFP FLAGS_REG))
12839    (clobber (match_scratch:HI 4 "=a"))]
12840   "TARGET_80387
12841    && FLOAT_MODE_P (GET_MODE (operands[1]))
12842    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
12843    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12844    && SELECT_CC_MODE (GET_CODE (operands[0]),
12845                       operands[1], operands[2]) == CCFPmode
12846    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12847   "#")
12848
12849 ;; The order of operands in *fp_jcc_8 is forced by combine in
12850 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12851 ;; with a precedence over other operators and is always put in the first
12852 ;; place. Swap condition and operands to match ficom instruction.
12853
12854 (define_insn "*fp_jcc_8_387"
12855   [(set (pc)
12856         (if_then_else (match_operator 0 "comparison_operator"
12857                         [(match_operator 1 "float_operator"
12858                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
12859                            (match_operand 3 "register_operand" "f,f")])
12860           (label_ref (match_operand 4 "" ""))
12861           (pc)))
12862    (clobber (reg:CCFP FPSR_REG))
12863    (clobber (reg:CCFP FLAGS_REG))
12864    (clobber (match_scratch:HI 5 "=a,a"))]
12865   "TARGET_80387 && TARGET_USE_FIOP
12866    && FLOAT_MODE_P (GET_MODE (operands[3]))
12867    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12868    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12869    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12870    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12871   "#")
12872
12873 (define_split
12874   [(set (pc)
12875         (if_then_else (match_operator 0 "comparison_operator"
12876                         [(match_operand 1 "register_operand" "")
12877                          (match_operand 2 "nonimmediate_operand" "")])
12878           (match_operand 3 "" "")
12879           (match_operand 4 "" "")))
12880    (clobber (reg:CCFP FPSR_REG))
12881    (clobber (reg:CCFP FLAGS_REG))]
12882   "reload_completed"
12883   [(const_int 0)]
12884 {
12885   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12886                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12887   DONE;
12888 })
12889
12890 (define_split
12891   [(set (pc)
12892         (if_then_else (match_operator 0 "comparison_operator"
12893                         [(match_operand 1 "register_operand" "")
12894                          (match_operand 2 "general_operand" "")])
12895           (match_operand 3 "" "")
12896           (match_operand 4 "" "")))
12897    (clobber (reg:CCFP FPSR_REG))
12898    (clobber (reg:CCFP FLAGS_REG))
12899    (clobber (match_scratch:HI 5 "=a"))]
12900   "reload_completed"
12901   [(const_int 0)]
12902 {
12903   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12904                         operands[3], operands[4], operands[5], NULL_RTX);
12905   DONE;
12906 })
12907
12908 (define_split
12909   [(set (pc)
12910         (if_then_else (match_operator 0 "comparison_operator"
12911                         [(match_operator 1 "float_operator"
12912                            [(match_operand:SI 2 "memory_operand" "")])
12913                            (match_operand 3 "register_operand" "")])
12914           (match_operand 4 "" "")
12915           (match_operand 5 "" "")))
12916    (clobber (reg:CCFP FPSR_REG))
12917    (clobber (reg:CCFP FLAGS_REG))
12918    (clobber (match_scratch:HI 6 "=a"))]
12919   "reload_completed"
12920   [(const_int 0)]
12921 {
12922   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12923   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12924                         operands[3], operands[7],
12925                         operands[4], operands[5], operands[6], NULL_RTX);
12926   DONE;
12927 })
12928
12929 ;; %%% Kill this when reload knows how to do it.
12930 (define_split
12931   [(set (pc)
12932         (if_then_else (match_operator 0 "comparison_operator"
12933                         [(match_operator 1 "float_operator"
12934                            [(match_operand:SI 2 "register_operand" "")])
12935                            (match_operand 3 "register_operand" "")])
12936           (match_operand 4 "" "")
12937           (match_operand 5 "" "")))
12938    (clobber (reg:CCFP FPSR_REG))
12939    (clobber (reg:CCFP FLAGS_REG))
12940    (clobber (match_scratch:HI 6 "=a"))]
12941   "reload_completed"
12942   [(const_int 0)]
12943 {
12944   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12945   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12946   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12947                         operands[3], operands[7],
12948                         operands[4], operands[5], operands[6], operands[2]);
12949   DONE;
12950 })
12951 \f
12952 ;; Unconditional and other jump instructions
12953
12954 (define_insn "jump"
12955   [(set (pc)
12956         (label_ref (match_operand 0 "" "")))]
12957   ""
12958   "jmp\t%l0"
12959   [(set_attr "type" "ibr")
12960    (set (attr "length")
12961            (if_then_else (and (ge (minus (match_dup 0) (pc))
12962                                   (const_int -126))
12963                               (lt (minus (match_dup 0) (pc))
12964                                   (const_int 128)))
12965              (const_int 2)
12966              (const_int 5)))
12967    (set_attr "modrm" "0")])
12968
12969 (define_expand "indirect_jump"
12970   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
12971   ""
12972   "")
12973
12974 (define_insn "*indirect_jump"
12975   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12976   "!TARGET_64BIT"
12977   "jmp\t%A0"
12978   [(set_attr "type" "ibr")
12979    (set_attr "length_immediate" "0")])
12980
12981 (define_insn "*indirect_jump_rtx64"
12982   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
12983   "TARGET_64BIT"
12984   "jmp\t%A0"
12985   [(set_attr "type" "ibr")
12986    (set_attr "length_immediate" "0")])
12987
12988 (define_expand "tablejump"
12989   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
12990               (use (label_ref (match_operand 1 "" "")))])]
12991   ""
12992 {
12993   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12994      relative.  Convert the relative address to an absolute address.  */
12995   if (flag_pic)
12996     {
12997       rtx op0, op1;
12998       enum rtx_code code;
12999
13000       if (TARGET_64BIT)
13001         {
13002           code = PLUS;
13003           op0 = operands[0];
13004           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13005         }
13006       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13007         {
13008           code = PLUS;
13009           op0 = operands[0];
13010           op1 = pic_offset_table_rtx;
13011         }
13012       else
13013         {
13014           code = MINUS;
13015           op0 = pic_offset_table_rtx;
13016           op1 = operands[0];
13017         }
13018
13019       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13020                                          OPTAB_DIRECT);
13021     }
13022 })
13023
13024 (define_insn "*tablejump_1"
13025   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13026    (use (label_ref (match_operand 1 "" "")))]
13027   "!TARGET_64BIT"
13028   "jmp\t%A0"
13029   [(set_attr "type" "ibr")
13030    (set_attr "length_immediate" "0")])
13031
13032 (define_insn "*tablejump_1_rtx64"
13033   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13034    (use (label_ref (match_operand 1 "" "")))]
13035   "TARGET_64BIT"
13036   "jmp\t%A0"
13037   [(set_attr "type" "ibr")
13038    (set_attr "length_immediate" "0")])
13039 \f
13040 ;; Loop instruction
13041 ;;
13042 ;; This is all complicated by the fact that since this is a jump insn
13043 ;; we must handle our own reloads.
13044
13045 (define_expand "doloop_end"
13046   [(use (match_operand 0 "" ""))        ; loop pseudo
13047    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13048    (use (match_operand 2 "" ""))        ; max iterations
13049    (use (match_operand 3 "" ""))        ; loop level 
13050    (use (match_operand 4 "" ""))]       ; label
13051   "!TARGET_64BIT && TARGET_USE_LOOP"
13052   "                                 
13053 {
13054   /* Only use cloop on innermost loops.  */
13055   if (INTVAL (operands[3]) > 1)
13056     FAIL;
13057   if (GET_MODE (operands[0]) != SImode)
13058     FAIL;
13059   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13060                                            operands[0]));
13061   DONE;
13062 }")
13063
13064 (define_insn "doloop_end_internal"
13065   [(set (pc)
13066         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13067                           (const_int 1))
13068                       (label_ref (match_operand 0 "" ""))
13069                       (pc)))
13070    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13071         (plus:SI (match_dup 1)
13072                  (const_int -1)))
13073    (clobber (match_scratch:SI 3 "=X,X,r"))
13074    (clobber (reg:CC FLAGS_REG))]
13075   "!TARGET_64BIT && TARGET_USE_LOOP
13076    && (reload_in_progress || reload_completed
13077        || register_operand (operands[2], VOIDmode))"
13078 {
13079   if (which_alternative != 0)
13080     return "#";
13081   if (get_attr_length (insn) == 2)
13082     return "%+loop\t%l0";
13083   else
13084     return "dec{l}\t%1\;%+jne\t%l0";
13085 }
13086   [(set (attr "length")
13087         (if_then_else (and (eq_attr "alternative" "0")
13088                            (and (ge (minus (match_dup 0) (pc))
13089                                     (const_int -126))
13090                                 (lt (minus (match_dup 0) (pc))
13091                                     (const_int 128))))
13092                       (const_int 2)
13093                       (const_int 16)))
13094    ;; We don't know the type before shorten branches.  Optimistically expect
13095    ;; the loop instruction to match.
13096    (set (attr "type") (const_string "ibr"))])
13097
13098 (define_split
13099   [(set (pc)
13100         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13101                           (const_int 1))
13102                       (match_operand 0 "" "")
13103                       (pc)))
13104    (set (match_dup 1)
13105         (plus:SI (match_dup 1)
13106                  (const_int -1)))
13107    (clobber (match_scratch:SI 2 ""))
13108    (clobber (reg:CC FLAGS_REG))]
13109   "!TARGET_64BIT && TARGET_USE_LOOP
13110    && reload_completed
13111    && REGNO (operands[1]) != 2"
13112   [(parallel [(set (reg:CCZ FLAGS_REG)
13113                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13114                                  (const_int 0)))
13115               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13116    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13117                            (match_dup 0)
13118                            (pc)))]
13119   "")
13120   
13121 (define_split
13122   [(set (pc)
13123         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13124                           (const_int 1))
13125                       (match_operand 0 "" "")
13126                       (pc)))
13127    (set (match_operand:SI 2 "nonimmediate_operand" "")
13128         (plus:SI (match_dup 1)
13129                  (const_int -1)))
13130    (clobber (match_scratch:SI 3 ""))
13131    (clobber (reg:CC FLAGS_REG))]
13132   "!TARGET_64BIT && TARGET_USE_LOOP
13133    && reload_completed
13134    && (! REG_P (operands[2])
13135        || ! rtx_equal_p (operands[1], operands[2]))"
13136   [(set (match_dup 3) (match_dup 1))
13137    (parallel [(set (reg:CCZ FLAGS_REG)
13138                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13139                                 (const_int 0)))
13140               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13141    (set (match_dup 2) (match_dup 3))
13142    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13143                            (match_dup 0)
13144                            (pc)))]
13145   "")
13146
13147 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13148
13149 (define_peephole2
13150   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13151    (set (match_operand:QI 1 "register_operand" "")
13152         (match_operator:QI 2 "ix86_comparison_operator"
13153           [(reg FLAGS_REG) (const_int 0)]))
13154    (set (match_operand 3 "q_regs_operand" "")
13155         (zero_extend (match_dup 1)))]
13156   "(peep2_reg_dead_p (3, operands[1])
13157     || operands_match_p (operands[1], operands[3]))
13158    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13159   [(set (match_dup 4) (match_dup 0))
13160    (set (strict_low_part (match_dup 5))
13161         (match_dup 2))]
13162 {
13163   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13164   operands[5] = gen_lowpart (QImode, operands[3]);
13165   ix86_expand_clear (operands[3]);
13166 })
13167
13168 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13169
13170 (define_peephole2
13171   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13172    (set (match_operand:QI 1 "register_operand" "")
13173         (match_operator:QI 2 "ix86_comparison_operator"
13174           [(reg FLAGS_REG) (const_int 0)]))
13175    (parallel [(set (match_operand 3 "q_regs_operand" "")
13176                    (zero_extend (match_dup 1)))
13177               (clobber (reg:CC FLAGS_REG))])]
13178   "(peep2_reg_dead_p (3, operands[1])
13179     || operands_match_p (operands[1], operands[3]))
13180    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13181   [(set (match_dup 4) (match_dup 0))
13182    (set (strict_low_part (match_dup 5))
13183         (match_dup 2))]
13184 {
13185   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13186   operands[5] = gen_lowpart (QImode, operands[3]);
13187   ix86_expand_clear (operands[3]);
13188 })
13189 \f
13190 ;; Call instructions.
13191
13192 ;; The predicates normally associated with named expanders are not properly
13193 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13194 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13195
13196 ;; Call subroutine returning no value.
13197
13198 (define_expand "call_pop"
13199   [(parallel [(call (match_operand:QI 0 "" "")
13200                     (match_operand:SI 1 "" ""))
13201               (set (reg:SI SP_REG)
13202                    (plus:SI (reg:SI SP_REG)
13203                             (match_operand:SI 3 "" "")))])]
13204   "!TARGET_64BIT"
13205 {
13206   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13207   DONE;
13208 })
13209
13210 (define_insn "*call_pop_0"
13211   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13212          (match_operand:SI 1 "" ""))
13213    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13214                             (match_operand:SI 2 "immediate_operand" "")))]
13215   "!TARGET_64BIT"
13216 {
13217   if (SIBLING_CALL_P (insn))
13218     return "jmp\t%P0";
13219   else
13220     return "call\t%P0";
13221 }
13222   [(set_attr "type" "call")])
13223   
13224 (define_insn "*call_pop_1"
13225   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13226          (match_operand:SI 1 "" ""))
13227    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13228                             (match_operand:SI 2 "immediate_operand" "i")))]
13229   "!TARGET_64BIT"
13230 {
13231   if (constant_call_address_operand (operands[0], Pmode))
13232     {
13233       if (SIBLING_CALL_P (insn))
13234         return "jmp\t%P0";
13235       else
13236         return "call\t%P0";
13237     }
13238   if (SIBLING_CALL_P (insn))
13239     return "jmp\t%A0";
13240   else
13241     return "call\t%A0";
13242 }
13243   [(set_attr "type" "call")])
13244
13245 (define_expand "call"
13246   [(call (match_operand:QI 0 "" "")
13247          (match_operand 1 "" ""))
13248    (use (match_operand 2 "" ""))]
13249   ""
13250 {
13251   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13252   DONE;
13253 })
13254
13255 (define_expand "sibcall"
13256   [(call (match_operand:QI 0 "" "")
13257          (match_operand 1 "" ""))
13258    (use (match_operand 2 "" ""))]
13259   ""
13260 {
13261   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13262   DONE;
13263 })
13264
13265 (define_insn "*call_0"
13266   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13267          (match_operand 1 "" ""))]
13268   ""
13269 {
13270   if (SIBLING_CALL_P (insn))
13271     return "jmp\t%P0";
13272   else
13273     return "call\t%P0";
13274 }
13275   [(set_attr "type" "call")])
13276
13277 (define_insn "*call_1"
13278   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13279          (match_operand 1 "" ""))]
13280   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13281 {
13282   if (constant_call_address_operand (operands[0], Pmode))
13283     return "call\t%P0";
13284   return "call\t%A0";
13285 }
13286   [(set_attr "type" "call")])
13287
13288 (define_insn "*sibcall_1"
13289   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13290          (match_operand 1 "" ""))]
13291   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13292 {
13293   if (constant_call_address_operand (operands[0], Pmode))
13294     return "jmp\t%P0";
13295   return "jmp\t%A0";
13296 }
13297   [(set_attr "type" "call")])
13298
13299 (define_insn "*call_1_rex64"
13300   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13301          (match_operand 1 "" ""))]
13302   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13303 {
13304   if (constant_call_address_operand (operands[0], Pmode))
13305     return "call\t%P0";
13306   return "call\t%A0";
13307 }
13308   [(set_attr "type" "call")])
13309
13310 (define_insn "*sibcall_1_rex64"
13311   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13312          (match_operand 1 "" ""))]
13313   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13314   "jmp\t%P0"
13315   [(set_attr "type" "call")])
13316
13317 (define_insn "*sibcall_1_rex64_v"
13318   [(call (mem:QI (reg:DI 40))
13319          (match_operand 0 "" ""))]
13320   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13321   "jmp\t*%%r11"
13322   [(set_attr "type" "call")])
13323
13324
13325 ;; Call subroutine, returning value in operand 0
13326
13327 (define_expand "call_value_pop"
13328   [(parallel [(set (match_operand 0 "" "")
13329                    (call (match_operand:QI 1 "" "")
13330                          (match_operand:SI 2 "" "")))
13331               (set (reg:SI SP_REG)
13332                    (plus:SI (reg:SI SP_REG)
13333                             (match_operand:SI 4 "" "")))])]
13334   "!TARGET_64BIT"
13335 {
13336   ix86_expand_call (operands[0], operands[1], operands[2],
13337                     operands[3], operands[4], 0);
13338   DONE;
13339 })
13340
13341 (define_expand "call_value"
13342   [(set (match_operand 0 "" "")
13343         (call (match_operand:QI 1 "" "")
13344               (match_operand:SI 2 "" "")))
13345    (use (match_operand:SI 3 "" ""))]
13346   ;; Operand 2 not used on the i386.
13347   ""
13348 {
13349   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13350   DONE;
13351 })
13352
13353 (define_expand "sibcall_value"
13354   [(set (match_operand 0 "" "")
13355         (call (match_operand:QI 1 "" "")
13356               (match_operand:SI 2 "" "")))
13357    (use (match_operand:SI 3 "" ""))]
13358   ;; Operand 2 not used on the i386.
13359   ""
13360 {
13361   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13362   DONE;
13363 })
13364
13365 ;; Call subroutine returning any type.
13366
13367 (define_expand "untyped_call"
13368   [(parallel [(call (match_operand 0 "" "")
13369                     (const_int 0))
13370               (match_operand 1 "" "")
13371               (match_operand 2 "" "")])]
13372   ""
13373 {
13374   int i;
13375
13376   /* In order to give reg-stack an easier job in validating two
13377      coprocessor registers as containing a possible return value,
13378      simply pretend the untyped call returns a complex long double
13379      value.  */
13380
13381   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13382                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13383                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13384                     NULL, 0);
13385
13386   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13387     {
13388       rtx set = XVECEXP (operands[2], 0, i);
13389       emit_move_insn (SET_DEST (set), SET_SRC (set));
13390     }
13391
13392   /* The optimizer does not know that the call sets the function value
13393      registers we stored in the result block.  We avoid problems by
13394      claiming that all hard registers are used and clobbered at this
13395      point.  */
13396   emit_insn (gen_blockage (const0_rtx));
13397
13398   DONE;
13399 })
13400 \f
13401 ;; Prologue and epilogue instructions
13402
13403 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13404 ;; all of memory.  This blocks insns from being moved across this point.
13405
13406 (define_insn "blockage"
13407   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13408   ""
13409   ""
13410   [(set_attr "length" "0")])
13411
13412 ;; Insn emitted into the body of a function to return from a function.
13413 ;; This is only done if the function's epilogue is known to be simple.
13414 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13415
13416 (define_expand "return"
13417   [(return)]
13418   "ix86_can_use_return_insn_p ()"
13419 {
13420   if (current_function_pops_args)
13421     {
13422       rtx popc = GEN_INT (current_function_pops_args);
13423       emit_jump_insn (gen_return_pop_internal (popc));
13424       DONE;
13425     }
13426 })
13427
13428 (define_insn "return_internal"
13429   [(return)]
13430   "reload_completed"
13431   "ret"
13432   [(set_attr "length" "1")
13433    (set_attr "length_immediate" "0")
13434    (set_attr "modrm" "0")])
13435
13436 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13437 ;; instruction Athlon and K8 have.
13438
13439 (define_insn "return_internal_long"
13440   [(return)
13441    (unspec [(const_int 0)] UNSPEC_REP)]
13442   "reload_completed"
13443   "rep {;} ret"
13444   [(set_attr "length" "1")
13445    (set_attr "length_immediate" "0")
13446    (set_attr "prefix_rep" "1")
13447    (set_attr "modrm" "0")])
13448
13449 (define_insn "return_pop_internal"
13450   [(return)
13451    (use (match_operand:SI 0 "const_int_operand" ""))]
13452   "reload_completed"
13453   "ret\t%0"
13454   [(set_attr "length" "3")
13455    (set_attr "length_immediate" "2")
13456    (set_attr "modrm" "0")])
13457
13458 (define_insn "return_indirect_internal"
13459   [(return)
13460    (use (match_operand:SI 0 "register_operand" "r"))]
13461   "reload_completed"
13462   "jmp\t%A0"
13463   [(set_attr "type" "ibr")
13464    (set_attr "length_immediate" "0")])
13465
13466 (define_insn "nop"
13467   [(const_int 0)]
13468   ""
13469   "nop"
13470   [(set_attr "length" "1")
13471    (set_attr "length_immediate" "0")
13472    (set_attr "modrm" "0")])
13473
13474 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13475 ;; branch prediction penalty for the third jump in a 16-byte
13476 ;; block on K8.
13477
13478 (define_insn "align"
13479   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13480   ""
13481 {
13482 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13483   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13484 #else
13485   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13486      The align insn is used to avoid 3 jump instructions in the row to improve
13487      branch prediction and the benefits hardly outweight the cost of extra 8
13488      nops on the average inserted by full alignment pseudo operation.  */
13489 #endif
13490   return "";
13491 }
13492   [(set_attr "length" "16")])
13493
13494 (define_expand "prologue"
13495   [(const_int 1)]
13496   ""
13497   "ix86_expand_prologue (); DONE;")
13498
13499 (define_insn "set_got"
13500   [(set (match_operand:SI 0 "register_operand" "=r")
13501         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13502    (clobber (reg:CC FLAGS_REG))]
13503   "!TARGET_64BIT"
13504   { return output_set_got (operands[0]); }
13505   [(set_attr "type" "multi")
13506    (set_attr "length" "12")])
13507
13508 (define_expand "epilogue"
13509   [(const_int 1)]
13510   ""
13511   "ix86_expand_epilogue (1); DONE;")
13512
13513 (define_expand "sibcall_epilogue"
13514   [(const_int 1)]
13515   ""
13516   "ix86_expand_epilogue (0); DONE;")
13517
13518 (define_expand "eh_return"
13519   [(use (match_operand 0 "register_operand" ""))]
13520   ""
13521 {
13522   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13523
13524   /* Tricky bit: we write the address of the handler to which we will
13525      be returning into someone else's stack frame, one word below the
13526      stack address we wish to restore.  */
13527   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13528   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13529   tmp = gen_rtx_MEM (Pmode, tmp);
13530   emit_move_insn (tmp, ra);
13531
13532   if (Pmode == SImode)
13533     emit_jump_insn (gen_eh_return_si (sa));
13534   else
13535     emit_jump_insn (gen_eh_return_di (sa));
13536   emit_barrier ();
13537   DONE;
13538 })
13539
13540 (define_insn_and_split "eh_return_si"
13541   [(set (pc) 
13542         (unspec [(match_operand:SI 0 "register_operand" "c")]
13543                  UNSPEC_EH_RETURN))]
13544   "!TARGET_64BIT"
13545   "#"
13546   "reload_completed"
13547   [(const_int 1)]
13548   "ix86_expand_epilogue (2); DONE;")
13549
13550 (define_insn_and_split "eh_return_di"
13551   [(set (pc) 
13552         (unspec [(match_operand:DI 0 "register_operand" "c")]
13553                  UNSPEC_EH_RETURN))]
13554   "TARGET_64BIT"
13555   "#"
13556   "reload_completed"
13557   [(const_int 1)]
13558   "ix86_expand_epilogue (2); DONE;")
13559
13560 (define_insn "leave"
13561   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13562    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13563    (clobber (mem:BLK (scratch)))]
13564   "!TARGET_64BIT"
13565   "leave"
13566   [(set_attr "type" "leave")])
13567
13568 (define_insn "leave_rex64"
13569   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13570    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13571    (clobber (mem:BLK (scratch)))]
13572   "TARGET_64BIT"
13573   "leave"
13574   [(set_attr "type" "leave")])
13575 \f
13576 (define_expand "ffssi2"
13577   [(parallel
13578      [(set (match_operand:SI 0 "register_operand" "") 
13579            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13580       (clobber (match_scratch:SI 2 ""))
13581       (clobber (reg:CC FLAGS_REG))])]
13582   ""
13583   "")
13584
13585 (define_insn_and_split "*ffs_cmove"
13586   [(set (match_operand:SI 0 "register_operand" "=r") 
13587         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13588    (clobber (match_scratch:SI 2 "=&r"))
13589    (clobber (reg:CC FLAGS_REG))]
13590   "TARGET_CMOVE"
13591   "#"
13592   "&& reload_completed"
13593   [(set (match_dup 2) (const_int -1))
13594    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13595               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13596    (set (match_dup 0) (if_then_else:SI
13597                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13598                         (match_dup 2)
13599                         (match_dup 0)))
13600    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13601               (clobber (reg:CC FLAGS_REG))])]
13602   "")
13603
13604 (define_insn_and_split "*ffs_no_cmove"
13605   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13606         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13607    (clobber (match_scratch:SI 2 "=&q"))
13608    (clobber (reg:CC FLAGS_REG))]
13609   ""
13610   "#"
13611   "reload_completed"
13612   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13613               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13614    (set (strict_low_part (match_dup 3))
13615         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13616    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13617               (clobber (reg:CC FLAGS_REG))])
13618    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13619               (clobber (reg:CC FLAGS_REG))])
13620    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13621               (clobber (reg:CC FLAGS_REG))])]
13622 {
13623   operands[3] = gen_lowpart (QImode, operands[2]);
13624   ix86_expand_clear (operands[2]);
13625 })
13626
13627 (define_insn "*ffssi_1"
13628   [(set (reg:CCZ FLAGS_REG)
13629         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13630                      (const_int 0)))
13631    (set (match_operand:SI 0 "register_operand" "=r")
13632         (ctz:SI (match_dup 1)))]
13633   ""
13634   "bsf{l}\t{%1, %0|%0, %1}"
13635   [(set_attr "prefix_0f" "1")])
13636
13637 (define_expand "ffsdi2"
13638   [(parallel
13639      [(set (match_operand:DI 0 "register_operand" "") 
13640            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13641       (clobber (match_scratch:DI 2 ""))
13642       (clobber (reg:CC FLAGS_REG))])]
13643   "TARGET_64BIT && TARGET_CMOVE"
13644   "")
13645
13646 (define_insn_and_split "*ffs_rex64"
13647   [(set (match_operand:DI 0 "register_operand" "=r") 
13648         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13649    (clobber (match_scratch:DI 2 "=&r"))
13650    (clobber (reg:CC FLAGS_REG))]
13651   "TARGET_64BIT && TARGET_CMOVE"
13652   "#"
13653   "&& reload_completed"
13654   [(set (match_dup 2) (const_int -1))
13655    (parallel [(set (reg:CCZ FLAGS_REG)
13656                    (compare:CCZ (match_dup 1) (const_int 0)))
13657               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13658    (set (match_dup 0) (if_then_else:DI
13659                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13660                         (match_dup 2)
13661                         (match_dup 0)))
13662    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13663               (clobber (reg:CC FLAGS_REG))])]
13664   "")
13665
13666 (define_insn "*ffsdi_1"
13667   [(set (reg:CCZ FLAGS_REG)
13668         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13669                      (const_int 0)))
13670    (set (match_operand:DI 0 "register_operand" "=r")
13671         (ctz:DI (match_dup 1)))]
13672   "TARGET_64BIT"
13673   "bsf{q}\t{%1, %0|%0, %1}"
13674   [(set_attr "prefix_0f" "1")])
13675
13676 (define_insn "ctzsi2"
13677   [(set (match_operand:SI 0 "register_operand" "=r")
13678         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13679    (clobber (reg:CC FLAGS_REG))]
13680   ""
13681   "bsf{l}\t{%1, %0|%0, %1}"
13682   [(set_attr "prefix_0f" "1")])
13683
13684 (define_insn "ctzdi2"
13685   [(set (match_operand:DI 0 "register_operand" "=r")
13686         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "TARGET_64BIT"
13689   "bsf{q}\t{%1, %0|%0, %1}"
13690   [(set_attr "prefix_0f" "1")])
13691
13692 (define_expand "clzsi2"
13693   [(parallel
13694      [(set (match_operand:SI 0 "register_operand" "")
13695            (minus:SI (const_int 31)
13696                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13697       (clobber (reg:CC FLAGS_REG))])
13698    (parallel
13699      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13700       (clobber (reg:CC FLAGS_REG))])]
13701   ""
13702   "")
13703
13704 (define_insn "*bsr"
13705   [(set (match_operand:SI 0 "register_operand" "=r")
13706         (minus:SI (const_int 31)
13707                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13708    (clobber (reg:CC FLAGS_REG))]
13709   ""
13710   "bsr{l}\t{%1, %0|%0, %1}"
13711   [(set_attr "prefix_0f" "1")])
13712
13713 (define_expand "clzdi2"
13714   [(parallel
13715      [(set (match_operand:DI 0 "register_operand" "")
13716            (minus:DI (const_int 63)
13717                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13718       (clobber (reg:CC FLAGS_REG))])
13719    (parallel
13720      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13721       (clobber (reg:CC FLAGS_REG))])]
13722   "TARGET_64BIT"
13723   "")
13724
13725 (define_insn "*bsr_rex64"
13726   [(set (match_operand:DI 0 "register_operand" "=r")
13727         (minus:DI (const_int 63)
13728                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13729    (clobber (reg:CC FLAGS_REG))]
13730   "TARGET_64BIT"
13731   "bsr{q}\t{%1, %0|%0, %1}"
13732   [(set_attr "prefix_0f" "1")])
13733 \f
13734 ;; Thread-local storage patterns for ELF.
13735 ;;
13736 ;; Note that these code sequences must appear exactly as shown
13737 ;; in order to allow linker relaxation.
13738
13739 (define_insn "*tls_global_dynamic_32_gnu"
13740   [(set (match_operand:SI 0 "register_operand" "=a")
13741         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13742                     (match_operand:SI 2 "tls_symbolic_operand" "")
13743                     (match_operand:SI 3 "call_insn_operand" "")]
13744                     UNSPEC_TLS_GD))
13745    (clobber (match_scratch:SI 4 "=d"))
13746    (clobber (match_scratch:SI 5 "=c"))
13747    (clobber (reg:CC FLAGS_REG))]
13748   "!TARGET_64BIT && TARGET_GNU_TLS"
13749   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13750   [(set_attr "type" "multi")
13751    (set_attr "length" "12")])
13752
13753 (define_insn "*tls_global_dynamic_32_sun"
13754   [(set (match_operand:SI 0 "register_operand" "=a")
13755         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13756                     (match_operand:SI 2 "tls_symbolic_operand" "")
13757                     (match_operand:SI 3 "call_insn_operand" "")]
13758                     UNSPEC_TLS_GD))
13759    (clobber (match_scratch:SI 4 "=d"))
13760    (clobber (match_scratch:SI 5 "=c"))
13761    (clobber (reg:CC FLAGS_REG))]
13762   "!TARGET_64BIT && TARGET_SUN_TLS"
13763   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13764         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13765   [(set_attr "type" "multi")
13766    (set_attr "length" "14")])
13767
13768 (define_expand "tls_global_dynamic_32"
13769   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13770                    (unspec:SI
13771                     [(match_dup 2)
13772                      (match_operand:SI 1 "tls_symbolic_operand" "")
13773                      (match_dup 3)]
13774                     UNSPEC_TLS_GD))
13775               (clobber (match_scratch:SI 4 ""))
13776               (clobber (match_scratch:SI 5 ""))
13777               (clobber (reg:CC FLAGS_REG))])]
13778   ""
13779 {
13780   if (flag_pic)
13781     operands[2] = pic_offset_table_rtx;
13782   else
13783     {
13784       operands[2] = gen_reg_rtx (Pmode);
13785       emit_insn (gen_set_got (operands[2]));
13786     }
13787   operands[3] = ix86_tls_get_addr ();
13788 })
13789
13790 (define_insn "*tls_global_dynamic_64"
13791   [(set (match_operand:DI 0 "register_operand" "=a")
13792         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13793                       (match_operand:DI 3 "" "")))
13794    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13795               UNSPEC_TLS_GD)]
13796   "TARGET_64BIT"
13797   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13798   [(set_attr "type" "multi")
13799    (set_attr "length" "16")])
13800
13801 (define_expand "tls_global_dynamic_64"
13802   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13803                    (call (mem:QI (match_dup 2)) (const_int 0)))
13804               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13805                          UNSPEC_TLS_GD)])]
13806   ""
13807 {
13808   operands[2] = ix86_tls_get_addr ();
13809 })
13810
13811 (define_insn "*tls_local_dynamic_base_32_gnu"
13812   [(set (match_operand:SI 0 "register_operand" "=a")
13813         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13814                     (match_operand:SI 2 "call_insn_operand" "")]
13815                    UNSPEC_TLS_LD_BASE))
13816    (clobber (match_scratch:SI 3 "=d"))
13817    (clobber (match_scratch:SI 4 "=c"))
13818    (clobber (reg:CC FLAGS_REG))]
13819   "!TARGET_64BIT && TARGET_GNU_TLS"
13820   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13821   [(set_attr "type" "multi")
13822    (set_attr "length" "11")])
13823
13824 (define_insn "*tls_local_dynamic_base_32_sun"
13825   [(set (match_operand:SI 0 "register_operand" "=a")
13826         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13827                     (match_operand:SI 2 "call_insn_operand" "")]
13828                    UNSPEC_TLS_LD_BASE))
13829    (clobber (match_scratch:SI 3 "=d"))
13830    (clobber (match_scratch:SI 4 "=c"))
13831    (clobber (reg:CC FLAGS_REG))]
13832   "!TARGET_64BIT && TARGET_SUN_TLS"
13833   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13834         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13835   [(set_attr "type" "multi")
13836    (set_attr "length" "13")])
13837
13838 (define_expand "tls_local_dynamic_base_32"
13839   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13840                    (unspec:SI [(match_dup 1) (match_dup 2)]
13841                               UNSPEC_TLS_LD_BASE))
13842               (clobber (match_scratch:SI 3 ""))
13843               (clobber (match_scratch:SI 4 ""))
13844               (clobber (reg:CC FLAGS_REG))])]
13845   ""
13846 {
13847   if (flag_pic)
13848     operands[1] = pic_offset_table_rtx;
13849   else
13850     {
13851       operands[1] = gen_reg_rtx (Pmode);
13852       emit_insn (gen_set_got (operands[1]));
13853     }
13854   operands[2] = ix86_tls_get_addr ();
13855 })
13856
13857 (define_insn "*tls_local_dynamic_base_64"
13858   [(set (match_operand:DI 0 "register_operand" "=a")
13859         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13860                       (match_operand:DI 2 "" "")))
13861    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13862   "TARGET_64BIT"
13863   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13864   [(set_attr "type" "multi")
13865    (set_attr "length" "12")])
13866
13867 (define_expand "tls_local_dynamic_base_64"
13868   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13869                    (call (mem:QI (match_dup 1)) (const_int 0)))
13870               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13871   ""
13872 {
13873   operands[1] = ix86_tls_get_addr ();
13874 })
13875
13876 ;; Local dynamic of a single variable is a lose.  Show combine how
13877 ;; to convert that back to global dynamic.
13878
13879 (define_insn_and_split "*tls_local_dynamic_32_once"
13880   [(set (match_operand:SI 0 "register_operand" "=a")
13881         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13882                              (match_operand:SI 2 "call_insn_operand" "")]
13883                             UNSPEC_TLS_LD_BASE)
13884                  (const:SI (unspec:SI
13885                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13886                             UNSPEC_DTPOFF))))
13887    (clobber (match_scratch:SI 4 "=d"))
13888    (clobber (match_scratch:SI 5 "=c"))
13889    (clobber (reg:CC FLAGS_REG))]
13890   ""
13891   "#"
13892   ""
13893   [(parallel [(set (match_dup 0)
13894                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13895                               UNSPEC_TLS_GD))
13896               (clobber (match_dup 4))
13897               (clobber (match_dup 5))
13898               (clobber (reg:CC FLAGS_REG))])]
13899   "")
13900
13901 ;; Load and add the thread base pointer from %gs:0.
13902
13903 (define_insn "*load_tp_si"
13904   [(set (match_operand:SI 0 "register_operand" "=r")
13905         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13906   "!TARGET_64BIT"
13907   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13908   [(set_attr "type" "imov")
13909    (set_attr "modrm" "0")
13910    (set_attr "length" "7")
13911    (set_attr "memory" "load")
13912    (set_attr "imm_disp" "false")])
13913
13914 (define_insn "*add_tp_si"
13915   [(set (match_operand:SI 0 "register_operand" "=r")
13916         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13917                  (match_operand:SI 1 "register_operand" "0")))
13918    (clobber (reg:CC FLAGS_REG))]
13919   "!TARGET_64BIT"
13920   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13921   [(set_attr "type" "alu")
13922    (set_attr "modrm" "0")
13923    (set_attr "length" "7")
13924    (set_attr "memory" "load")
13925    (set_attr "imm_disp" "false")])
13926
13927 (define_insn "*load_tp_di"
13928   [(set (match_operand:DI 0 "register_operand" "=r")
13929         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13930   "TARGET_64BIT"
13931   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13932   [(set_attr "type" "imov")
13933    (set_attr "modrm" "0")
13934    (set_attr "length" "7")
13935    (set_attr "memory" "load")
13936    (set_attr "imm_disp" "false")])
13937
13938 (define_insn "*add_tp_di"
13939   [(set (match_operand:DI 0 "register_operand" "=r")
13940         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13941                  (match_operand:DI 1 "register_operand" "0")))
13942    (clobber (reg:CC FLAGS_REG))]
13943   "TARGET_64BIT"
13944   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13945   [(set_attr "type" "alu")
13946    (set_attr "modrm" "0")
13947    (set_attr "length" "7")
13948    (set_attr "memory" "load")
13949    (set_attr "imm_disp" "false")])
13950 \f
13951 ;; These patterns match the binary 387 instructions for addM3, subM3,
13952 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13953 ;; SFmode.  The first is the normal insn, the second the same insn but
13954 ;; with one operand a conversion, and the third the same insn but with
13955 ;; the other operand a conversion.  The conversion may be SFmode or
13956 ;; SImode if the target mode DFmode, but only SImode if the target mode
13957 ;; is SFmode.
13958
13959 ;; Gcc is slightly more smart about handling normal two address instructions
13960 ;; so use special patterns for add and mull.
13961
13962 (define_insn "*fop_sf_comm_mixed"
13963   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13964         (match_operator:SF 3 "binary_fp_operator"
13965                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13966                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13967   "TARGET_MIX_SSE_I387
13968    && COMMUTATIVE_ARITH_P (operands[3])
13969    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13970   "* return output_387_binary_op (insn, operands);"
13971   [(set (attr "type") 
13972         (if_then_else (eq_attr "alternative" "1")
13973            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13974               (const_string "ssemul")
13975               (const_string "sseadd"))
13976            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13977               (const_string "fmul")
13978               (const_string "fop"))))
13979    (set_attr "mode" "SF")])
13980
13981 (define_insn "*fop_sf_comm_sse"
13982   [(set (match_operand:SF 0 "register_operand" "=x")
13983         (match_operator:SF 3 "binary_fp_operator"
13984                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13985                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13986   "TARGET_SSE_MATH
13987    && COMMUTATIVE_ARITH_P (operands[3])
13988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13989   "* return output_387_binary_op (insn, operands);"
13990   [(set (attr "type") 
13991         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13992            (const_string "ssemul")
13993            (const_string "sseadd")))
13994    (set_attr "mode" "SF")])
13995
13996 (define_insn "*fop_sf_comm_i387"
13997   [(set (match_operand:SF 0 "register_operand" "=f")
13998         (match_operator:SF 3 "binary_fp_operator"
13999                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14000                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14001   "TARGET_80387
14002    && COMMUTATIVE_ARITH_P (operands[3])
14003    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14004   "* return output_387_binary_op (insn, operands);"
14005   [(set (attr "type") 
14006         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14007            (const_string "fmul")
14008            (const_string "fop")))
14009    (set_attr "mode" "SF")])
14010
14011 (define_insn "*fop_sf_1_mixed"
14012   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14013         (match_operator:SF 3 "binary_fp_operator"
14014                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14015                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14016   "TARGET_MIX_SSE_I387
14017    && !COMMUTATIVE_ARITH_P (operands[3])
14018    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14019   "* return output_387_binary_op (insn, operands);"
14020   [(set (attr "type") 
14021         (cond [(and (eq_attr "alternative" "2")
14022                     (match_operand:SF 3 "mult_operator" ""))
14023                  (const_string "ssemul")
14024                (and (eq_attr "alternative" "2")
14025                     (match_operand:SF 3 "div_operator" ""))
14026                  (const_string "ssediv")
14027                (eq_attr "alternative" "2")
14028                  (const_string "sseadd")
14029                (match_operand:SF 3 "mult_operator" "") 
14030                  (const_string "fmul")
14031                (match_operand:SF 3 "div_operator" "") 
14032                  (const_string "fdiv")
14033               ]
14034               (const_string "fop")))
14035    (set_attr "mode" "SF")])
14036
14037 (define_insn "*fop_sf_1_sse"
14038   [(set (match_operand:SF 0 "register_operand" "=x")
14039         (match_operator:SF 3 "binary_fp_operator"
14040                         [(match_operand:SF 1 "register_operand" "0")
14041                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14042   "TARGET_SSE_MATH
14043    && !COMMUTATIVE_ARITH_P (operands[3])"
14044   "* return output_387_binary_op (insn, operands);"
14045   [(set (attr "type") 
14046         (cond [(match_operand:SF 3 "mult_operator" "")
14047                  (const_string "ssemul")
14048                (match_operand:SF 3 "div_operator" "")
14049                  (const_string "ssediv")
14050               ]
14051               (const_string "sseadd")))
14052    (set_attr "mode" "SF")])
14053
14054 ;; This pattern is not fully shadowed by the pattern above.
14055 (define_insn "*fop_sf_1_i387"
14056   [(set (match_operand:SF 0 "register_operand" "=f,f")
14057         (match_operator:SF 3 "binary_fp_operator"
14058                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14059                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14060   "TARGET_80387 && !TARGET_SSE_MATH
14061    && !COMMUTATIVE_ARITH_P (operands[3])
14062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14063   "* return output_387_binary_op (insn, operands);"
14064   [(set (attr "type") 
14065         (cond [(match_operand:SF 3 "mult_operator" "") 
14066                  (const_string "fmul")
14067                (match_operand:SF 3 "div_operator" "") 
14068                  (const_string "fdiv")
14069               ]
14070               (const_string "fop")))
14071    (set_attr "mode" "SF")])
14072
14073
14074 ;; ??? Add SSE splitters for these!
14075 (define_insn "*fop_sf_2_i387"
14076   [(set (match_operand:SF 0 "register_operand" "=f,f")
14077         (match_operator:SF 3 "binary_fp_operator"
14078           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14079            (match_operand:SF 2 "register_operand" "0,0")]))]
14080   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14081   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14082   [(set (attr "type") 
14083         (cond [(match_operand:SF 3 "mult_operator" "") 
14084                  (const_string "fmul")
14085                (match_operand:SF 3 "div_operator" "") 
14086                  (const_string "fdiv")
14087               ]
14088               (const_string "fop")))
14089    (set_attr "fp_int_src" "true")
14090    (set_attr "mode" "SI")])
14091
14092 (define_insn "*fop_sf_3_i387"
14093   [(set (match_operand:SF 0 "register_operand" "=f,f")
14094         (match_operator:SF 3 "binary_fp_operator"
14095           [(match_operand:SF 1 "register_operand" "0,0")
14096            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14097   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14098   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14099   [(set (attr "type") 
14100         (cond [(match_operand:SF 3 "mult_operator" "") 
14101                  (const_string "fmul")
14102                (match_operand:SF 3 "div_operator" "") 
14103                  (const_string "fdiv")
14104               ]
14105               (const_string "fop")))
14106    (set_attr "fp_int_src" "true")
14107    (set_attr "mode" "SI")])
14108
14109 (define_insn "*fop_df_comm_mixed"
14110   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14111         (match_operator:DF 3 "binary_fp_operator"
14112                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14113                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14114   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14115    && COMMUTATIVE_ARITH_P (operands[3])
14116    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14117   "* return output_387_binary_op (insn, operands);"
14118   [(set (attr "type") 
14119         (if_then_else (eq_attr "alternative" "1")
14120            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14121               (const_string "ssemul")
14122               (const_string "sseadd"))
14123            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14124               (const_string "fmul")
14125               (const_string "fop"))))
14126    (set_attr "mode" "DF")])
14127
14128 (define_insn "*fop_df_comm_sse"
14129   [(set (match_operand:DF 0 "register_operand" "=Y")
14130         (match_operator:DF 3 "binary_fp_operator"
14131                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14132                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14133   "TARGET_SSE2 && TARGET_SSE_MATH
14134    && COMMUTATIVE_ARITH_P (operands[3])
14135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14136   "* return output_387_binary_op (insn, operands);"
14137   [(set (attr "type") 
14138         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14139            (const_string "ssemul")
14140            (const_string "sseadd")))
14141    (set_attr "mode" "DF")])
14142
14143 (define_insn "*fop_df_comm_i387"
14144   [(set (match_operand:DF 0 "register_operand" "=f")
14145         (match_operator:DF 3 "binary_fp_operator"
14146                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14147                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14148   "TARGET_80387
14149    && COMMUTATIVE_ARITH_P (operands[3])
14150    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14151   "* return output_387_binary_op (insn, operands);"
14152   [(set (attr "type") 
14153         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14154            (const_string "fmul")
14155            (const_string "fop")))
14156    (set_attr "mode" "DF")])
14157
14158 (define_insn "*fop_df_1_mixed"
14159   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14160         (match_operator:DF 3 "binary_fp_operator"
14161                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14162                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14163   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14164    && !COMMUTATIVE_ARITH_P (operands[3])
14165    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14166   "* return output_387_binary_op (insn, operands);"
14167   [(set (attr "type") 
14168         (cond [(and (eq_attr "alternative" "2")
14169                     (match_operand:SF 3 "mult_operator" ""))
14170                  (const_string "ssemul")
14171                (and (eq_attr "alternative" "2")
14172                     (match_operand:SF 3 "div_operator" ""))
14173                  (const_string "ssediv")
14174                (eq_attr "alternative" "2")
14175                  (const_string "sseadd")
14176                (match_operand:DF 3 "mult_operator" "") 
14177                  (const_string "fmul")
14178                (match_operand:DF 3 "div_operator" "") 
14179                  (const_string "fdiv")
14180               ]
14181               (const_string "fop")))
14182    (set_attr "mode" "DF")])
14183
14184 (define_insn "*fop_df_1_sse"
14185   [(set (match_operand:DF 0 "register_operand" "=Y")
14186         (match_operator:DF 3 "binary_fp_operator"
14187                         [(match_operand:DF 1 "register_operand" "0")
14188                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14189   "TARGET_SSE2 && TARGET_SSE_MATH
14190    && !COMMUTATIVE_ARITH_P (operands[3])"
14191   "* return output_387_binary_op (insn, operands);"
14192   [(set_attr "mode" "DF")
14193    (set (attr "type") 
14194         (cond [(match_operand:SF 3 "mult_operator" "")
14195                  (const_string "ssemul")
14196                (match_operand:SF 3 "div_operator" "")
14197                  (const_string "ssediv")
14198               ]
14199               (const_string "sseadd")))])
14200
14201 ;; This pattern is not fully shadowed by the pattern above.
14202 (define_insn "*fop_df_1_i387"
14203   [(set (match_operand:DF 0 "register_operand" "=f,f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14206                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14207   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14208    && !COMMUTATIVE_ARITH_P (operands[3])
14209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14210   "* return output_387_binary_op (insn, operands);"
14211   [(set (attr "type") 
14212         (cond [(match_operand:DF 3 "mult_operator" "") 
14213                  (const_string "fmul")
14214                (match_operand:DF 3 "div_operator" "")
14215                  (const_string "fdiv")
14216               ]
14217               (const_string "fop")))
14218    (set_attr "mode" "DF")])
14219
14220 ;; ??? Add SSE splitters for these!
14221 (define_insn "*fop_df_2_i387"
14222   [(set (match_operand:DF 0 "register_operand" "=f,f")
14223         (match_operator:DF 3 "binary_fp_operator"
14224            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14225             (match_operand:DF 2 "register_operand" "0,0")]))]
14226   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14227   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14228   [(set (attr "type") 
14229         (cond [(match_operand:DF 3 "mult_operator" "") 
14230                  (const_string "fmul")
14231                (match_operand:DF 3 "div_operator" "") 
14232                  (const_string "fdiv")
14233               ]
14234               (const_string "fop")))
14235    (set_attr "fp_int_src" "true")
14236    (set_attr "mode" "SI")])
14237
14238 (define_insn "*fop_df_3_i387"
14239   [(set (match_operand:DF 0 "register_operand" "=f,f")
14240         (match_operator:DF 3 "binary_fp_operator"
14241            [(match_operand:DF 1 "register_operand" "0,0")
14242             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14243   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14244   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14245   [(set (attr "type") 
14246         (cond [(match_operand:DF 3 "mult_operator" "") 
14247                  (const_string "fmul")
14248                (match_operand:DF 3 "div_operator" "") 
14249                  (const_string "fdiv")
14250               ]
14251               (const_string "fop")))
14252    (set_attr "fp_int_src" "true")
14253    (set_attr "mode" "SI")])
14254
14255 (define_insn "*fop_df_4_i387"
14256   [(set (match_operand:DF 0 "register_operand" "=f,f")
14257         (match_operator:DF 3 "binary_fp_operator"
14258            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14259             (match_operand:DF 2 "register_operand" "0,f")]))]
14260   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14262   "* return output_387_binary_op (insn, operands);"
14263   [(set (attr "type") 
14264         (cond [(match_operand:DF 3 "mult_operator" "") 
14265                  (const_string "fmul")
14266                (match_operand:DF 3 "div_operator" "") 
14267                  (const_string "fdiv")
14268               ]
14269               (const_string "fop")))
14270    (set_attr "mode" "SF")])
14271
14272 (define_insn "*fop_df_5_i387"
14273   [(set (match_operand:DF 0 "register_operand" "=f,f")
14274         (match_operator:DF 3 "binary_fp_operator"
14275           [(match_operand:DF 1 "register_operand" "0,f")
14276            (float_extend:DF
14277             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14278   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14279   "* return output_387_binary_op (insn, operands);"
14280   [(set (attr "type") 
14281         (cond [(match_operand:DF 3 "mult_operator" "") 
14282                  (const_string "fmul")
14283                (match_operand:DF 3 "div_operator" "") 
14284                  (const_string "fdiv")
14285               ]
14286               (const_string "fop")))
14287    (set_attr "mode" "SF")])
14288
14289 (define_insn "*fop_df_6_i387"
14290   [(set (match_operand:DF 0 "register_operand" "=f,f")
14291         (match_operator:DF 3 "binary_fp_operator"
14292           [(float_extend:DF
14293             (match_operand:SF 1 "register_operand" "0,f"))
14294            (float_extend:DF
14295             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14296   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14297   "* return output_387_binary_op (insn, operands);"
14298   [(set (attr "type") 
14299         (cond [(match_operand:DF 3 "mult_operator" "") 
14300                  (const_string "fmul")
14301                (match_operand:DF 3 "div_operator" "") 
14302                  (const_string "fdiv")
14303               ]
14304               (const_string "fop")))
14305    (set_attr "mode" "SF")])
14306
14307 (define_insn "*fop_xf_comm_i387"
14308   [(set (match_operand:XF 0 "register_operand" "=f")
14309         (match_operator:XF 3 "binary_fp_operator"
14310                         [(match_operand:XF 1 "register_operand" "%0")
14311                          (match_operand:XF 2 "register_operand" "f")]))]
14312   "TARGET_80387
14313    && COMMUTATIVE_ARITH_P (operands[3])"
14314   "* return output_387_binary_op (insn, operands);"
14315   [(set (attr "type") 
14316         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14317            (const_string "fmul")
14318            (const_string "fop")))
14319    (set_attr "mode" "XF")])
14320
14321 (define_insn "*fop_xf_1_i387"
14322   [(set (match_operand:XF 0 "register_operand" "=f,f")
14323         (match_operator:XF 3 "binary_fp_operator"
14324                         [(match_operand:XF 1 "register_operand" "0,f")
14325                          (match_operand:XF 2 "register_operand" "f,0")]))]
14326   "TARGET_80387
14327    && !COMMUTATIVE_ARITH_P (operands[3])"
14328   "* return output_387_binary_op (insn, operands);"
14329   [(set (attr "type") 
14330         (cond [(match_operand:XF 3 "mult_operator" "") 
14331                  (const_string "fmul")
14332                (match_operand:XF 3 "div_operator" "") 
14333                  (const_string "fdiv")
14334               ]
14335               (const_string "fop")))
14336    (set_attr "mode" "XF")])
14337
14338 (define_insn "*fop_xf_2_i387"
14339   [(set (match_operand:XF 0 "register_operand" "=f,f")
14340         (match_operator:XF 3 "binary_fp_operator"
14341            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14342             (match_operand:XF 2 "register_operand" "0,0")]))]
14343   "TARGET_80387 && TARGET_USE_FIOP"
14344   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14345   [(set (attr "type") 
14346         (cond [(match_operand:XF 3 "mult_operator" "") 
14347                  (const_string "fmul")
14348                (match_operand:XF 3 "div_operator" "") 
14349                  (const_string "fdiv")
14350               ]
14351               (const_string "fop")))
14352    (set_attr "fp_int_src" "true")
14353    (set_attr "mode" "SI")])
14354
14355 (define_insn "*fop_xf_3_i387"
14356   [(set (match_operand:XF 0 "register_operand" "=f,f")
14357         (match_operator:XF 3 "binary_fp_operator"
14358           [(match_operand:XF 1 "register_operand" "0,0")
14359            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14360   "TARGET_80387 && TARGET_USE_FIOP"
14361   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14362   [(set (attr "type") 
14363         (cond [(match_operand:XF 3 "mult_operator" "") 
14364                  (const_string "fmul")
14365                (match_operand:XF 3 "div_operator" "") 
14366                  (const_string "fdiv")
14367               ]
14368               (const_string "fop")))
14369    (set_attr "fp_int_src" "true")
14370    (set_attr "mode" "SI")])
14371
14372 (define_insn "*fop_xf_4_i387"
14373   [(set (match_operand:XF 0 "register_operand" "=f,f")
14374         (match_operator:XF 3 "binary_fp_operator"
14375            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14376             (match_operand:XF 2 "register_operand" "0,f")]))]
14377   "TARGET_80387"
14378   "* return output_387_binary_op (insn, operands);"
14379   [(set (attr "type") 
14380         (cond [(match_operand:XF 3 "mult_operator" "") 
14381                  (const_string "fmul")
14382                (match_operand:XF 3 "div_operator" "") 
14383                  (const_string "fdiv")
14384               ]
14385               (const_string "fop")))
14386    (set_attr "mode" "SF")])
14387
14388 (define_insn "*fop_xf_5_i387"
14389   [(set (match_operand:XF 0 "register_operand" "=f,f")
14390         (match_operator:XF 3 "binary_fp_operator"
14391           [(match_operand:XF 1 "register_operand" "0,f")
14392            (float_extend:XF
14393             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14394   "TARGET_80387"
14395   "* return output_387_binary_op (insn, operands);"
14396   [(set (attr "type") 
14397         (cond [(match_operand:XF 3 "mult_operator" "") 
14398                  (const_string "fmul")
14399                (match_operand:XF 3 "div_operator" "") 
14400                  (const_string "fdiv")
14401               ]
14402               (const_string "fop")))
14403    (set_attr "mode" "SF")])
14404
14405 (define_insn "*fop_xf_6_i387"
14406   [(set (match_operand:XF 0 "register_operand" "=f,f")
14407         (match_operator:XF 3 "binary_fp_operator"
14408           [(float_extend:XF
14409             (match_operand 1 "register_operand" "0,f"))
14410            (float_extend:XF
14411             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14412   "TARGET_80387"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type") 
14415         (cond [(match_operand:XF 3 "mult_operator" "") 
14416                  (const_string "fmul")
14417                (match_operand:XF 3 "div_operator" "") 
14418                  (const_string "fdiv")
14419               ]
14420               (const_string "fop")))
14421    (set_attr "mode" "SF")])
14422
14423 (define_split
14424   [(set (match_operand 0 "register_operand" "")
14425         (match_operator 3 "binary_fp_operator"
14426            [(float (match_operand:SI 1 "register_operand" ""))
14427             (match_operand 2 "register_operand" "")]))]
14428   "TARGET_80387 && reload_completed
14429    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14430   [(const_int 0)]
14431
14432   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14433   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14434   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14435                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14436                                           GET_MODE (operands[3]),
14437                                           operands[4],
14438                                           operands[2])));
14439   ix86_free_from_memory (GET_MODE (operands[1]));
14440   DONE;
14441 })
14442
14443 (define_split
14444   [(set (match_operand 0 "register_operand" "")
14445         (match_operator 3 "binary_fp_operator"
14446            [(match_operand 1 "register_operand" "")
14447             (float (match_operand:SI 2 "register_operand" ""))]))]
14448   "TARGET_80387 && reload_completed
14449    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14450   [(const_int 0)]
14451 {
14452   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14453   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14454   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14455                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14456                                           GET_MODE (operands[3]),
14457                                           operands[1],
14458                                           operands[4])));
14459   ix86_free_from_memory (GET_MODE (operands[2]));
14460   DONE;
14461 })
14462 \f
14463 ;; FPU special functions.
14464
14465 (define_expand "sqrtsf2"
14466   [(set (match_operand:SF 0 "register_operand" "")
14467         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14468   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14469 {
14470   if (!TARGET_SSE_MATH)
14471     operands[1] = force_reg (SFmode, operands[1]);
14472 })
14473
14474 (define_insn "*sqrtsf2_mixed"
14475   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14476         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14477   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14478   "@
14479    fsqrt
14480    sqrtss\t{%1, %0|%0, %1}"
14481   [(set_attr "type" "fpspc,sse")
14482    (set_attr "mode" "SF,SF")
14483    (set_attr "athlon_decode" "direct,*")])
14484
14485 (define_insn "*sqrtsf2_sse"
14486   [(set (match_operand:SF 0 "register_operand" "=x")
14487         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14488   "TARGET_SSE_MATH"
14489   "sqrtss\t{%1, %0|%0, %1}"
14490   [(set_attr "type" "sse")
14491    (set_attr "mode" "SF")
14492    (set_attr "athlon_decode" "*")])
14493
14494 (define_insn "*sqrtsf2_i387"
14495   [(set (match_operand:SF 0 "register_operand" "=f")
14496         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14497   "TARGET_USE_FANCY_MATH_387"
14498   "fsqrt"
14499   [(set_attr "type" "fpspc")
14500    (set_attr "mode" "SF")
14501    (set_attr "athlon_decode" "direct")])
14502
14503 (define_expand "sqrtdf2"
14504   [(set (match_operand:DF 0 "register_operand" "")
14505         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14506   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14507 {
14508   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14509     operands[1] = force_reg (DFmode, operands[1]);
14510 })
14511
14512 (define_insn "*sqrtdf2_mixed"
14513   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14514         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14515   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14516   "@
14517    fsqrt
14518    sqrtsd\t{%1, %0|%0, %1}"
14519   [(set_attr "type" "fpspc,sse")
14520    (set_attr "mode" "DF,DF")
14521    (set_attr "athlon_decode" "direct,*")])
14522
14523 (define_insn "*sqrtdf2_sse"
14524   [(set (match_operand:DF 0 "register_operand" "=Y")
14525         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14526   "TARGET_SSE2 && TARGET_SSE_MATH"
14527   "sqrtsd\t{%1, %0|%0, %1}"
14528   [(set_attr "type" "sse")
14529    (set_attr "mode" "DF")
14530    (set_attr "athlon_decode" "*")])
14531
14532 (define_insn "*sqrtdf2_i387"
14533   [(set (match_operand:DF 0 "register_operand" "=f")
14534         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14535   "TARGET_USE_FANCY_MATH_387"
14536   "fsqrt"
14537   [(set_attr "type" "fpspc")
14538    (set_attr "mode" "DF")
14539    (set_attr "athlon_decode" "direct")])
14540
14541 (define_insn "*sqrtextendsfdf2_i387"
14542   [(set (match_operand:DF 0 "register_operand" "=f")
14543         (sqrt:DF (float_extend:DF
14544                   (match_operand:SF 1 "register_operand" "0"))))]
14545   "TARGET_USE_FANCY_MATH_387
14546    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14547   "fsqrt"
14548   [(set_attr "type" "fpspc")
14549    (set_attr "mode" "DF")
14550    (set_attr "athlon_decode" "direct")])
14551
14552 (define_insn "sqrtxf2"
14553   [(set (match_operand:XF 0 "register_operand" "=f")
14554         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14555   "TARGET_USE_FANCY_MATH_387 
14556    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14557   "fsqrt"
14558   [(set_attr "type" "fpspc")
14559    (set_attr "mode" "XF")
14560    (set_attr "athlon_decode" "direct")])
14561
14562 (define_insn "*sqrtextendsfxf2_i387"
14563   [(set (match_operand:XF 0 "register_operand" "=f")
14564         (sqrt:XF (float_extend:XF
14565                   (match_operand:SF 1 "register_operand" "0"))))]
14566   "TARGET_USE_FANCY_MATH_387"
14567   "fsqrt"
14568   [(set_attr "type" "fpspc")
14569    (set_attr "mode" "XF")
14570    (set_attr "athlon_decode" "direct")])
14571
14572 (define_insn "*sqrtextenddfxf2_i387"
14573   [(set (match_operand:XF 0 "register_operand" "=f")
14574         (sqrt:XF (float_extend:XF
14575                   (match_operand:DF 1 "register_operand" "0"))))]
14576   "TARGET_USE_FANCY_MATH_387"
14577   "fsqrt"
14578   [(set_attr "type" "fpspc")
14579    (set_attr "mode" "XF")
14580    (set_attr "athlon_decode" "direct")])
14581
14582 (define_insn "fpremxf4"
14583   [(set (match_operand:XF 0 "register_operand" "=f")
14584         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14585                     (match_operand:XF 3 "register_operand" "1")]
14586                    UNSPEC_FPREM_F))
14587    (set (match_operand:XF 1 "register_operand" "=u")
14588         (unspec:XF [(match_dup 2) (match_dup 3)]
14589                    UNSPEC_FPREM_U))
14590    (set (reg:CCFP FPSR_REG)
14591         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14592   "TARGET_USE_FANCY_MATH_387
14593    && flag_unsafe_math_optimizations"
14594   "fprem"
14595   [(set_attr "type" "fpspc")
14596    (set_attr "mode" "XF")])
14597
14598 (define_expand "fmodsf3"
14599   [(use (match_operand:SF 0 "register_operand" ""))
14600    (use (match_operand:SF 1 "register_operand" ""))
14601    (use (match_operand:SF 2 "register_operand" ""))]
14602   "TARGET_USE_FANCY_MATH_387
14603    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14604    && flag_unsafe_math_optimizations"
14605 {
14606   rtx label = gen_label_rtx ();
14607
14608   rtx op1 = gen_reg_rtx (XFmode);
14609   rtx op2 = gen_reg_rtx (XFmode);
14610
14611   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14612   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14613
14614   emit_label (label);
14615
14616   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14617   ix86_emit_fp_unordered_jump (label);
14618
14619   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14620   DONE;
14621 })
14622
14623 (define_expand "fmoddf3"
14624   [(use (match_operand:DF 0 "register_operand" ""))
14625    (use (match_operand:DF 1 "register_operand" ""))
14626    (use (match_operand:DF 2 "register_operand" ""))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14629    && flag_unsafe_math_optimizations"
14630 {
14631   rtx label = gen_label_rtx ();
14632
14633   rtx op1 = gen_reg_rtx (XFmode);
14634   rtx op2 = gen_reg_rtx (XFmode);
14635
14636   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14637   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14638
14639   emit_label (label);
14640
14641   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14642   ix86_emit_fp_unordered_jump (label);
14643
14644   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14645   DONE;
14646 })
14647
14648 (define_expand "fmodxf3"
14649   [(use (match_operand:XF 0 "register_operand" ""))
14650    (use (match_operand:XF 1 "register_operand" ""))
14651    (use (match_operand:XF 2 "register_operand" ""))]
14652   "TARGET_USE_FANCY_MATH_387
14653    && flag_unsafe_math_optimizations"
14654 {
14655   rtx label = gen_label_rtx ();
14656
14657   emit_label (label);
14658
14659   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14660                            operands[1], operands[2]));
14661   ix86_emit_fp_unordered_jump (label);
14662
14663   emit_move_insn (operands[0], operands[1]);
14664   DONE;
14665 })
14666
14667 (define_insn "fprem1xf4"
14668   [(set (match_operand:XF 0 "register_operand" "=f")
14669         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14670                     (match_operand:XF 3 "register_operand" "1")]
14671                    UNSPEC_FPREM1_F))
14672    (set (match_operand:XF 1 "register_operand" "=u")
14673         (unspec:XF [(match_dup 2) (match_dup 3)]
14674                    UNSPEC_FPREM1_U))
14675    (set (reg:CCFP FPSR_REG)
14676         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14677   "TARGET_USE_FANCY_MATH_387
14678    && flag_unsafe_math_optimizations"
14679   "fprem1"
14680   [(set_attr "type" "fpspc")
14681    (set_attr "mode" "XF")])
14682
14683 (define_expand "dremsf3"
14684   [(use (match_operand:SF 0 "register_operand" ""))
14685    (use (match_operand:SF 1 "register_operand" ""))
14686    (use (match_operand:SF 2 "register_operand" ""))]
14687   "TARGET_USE_FANCY_MATH_387
14688    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14689    && flag_unsafe_math_optimizations"
14690 {
14691   rtx label = gen_label_rtx ();
14692
14693   rtx op1 = gen_reg_rtx (XFmode);
14694   rtx op2 = gen_reg_rtx (XFmode);
14695
14696   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14697   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14698
14699   emit_label (label);
14700
14701   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14702   ix86_emit_fp_unordered_jump (label);
14703
14704   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14705   DONE;
14706 })
14707
14708 (define_expand "dremdf3"
14709   [(use (match_operand:DF 0 "register_operand" ""))
14710    (use (match_operand:DF 1 "register_operand" ""))
14711    (use (match_operand:DF 2 "register_operand" ""))]
14712   "TARGET_USE_FANCY_MATH_387
14713    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14714    && flag_unsafe_math_optimizations"
14715 {
14716   rtx label = gen_label_rtx ();
14717
14718   rtx op1 = gen_reg_rtx (XFmode);
14719   rtx op2 = gen_reg_rtx (XFmode);
14720
14721   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14722   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14723
14724   emit_label (label);
14725
14726   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14727   ix86_emit_fp_unordered_jump (label);
14728
14729   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14730   DONE;
14731 })
14732
14733 (define_expand "dremxf3"
14734   [(use (match_operand:XF 0 "register_operand" ""))
14735    (use (match_operand:XF 1 "register_operand" ""))
14736    (use (match_operand:XF 2 "register_operand" ""))]
14737   "TARGET_USE_FANCY_MATH_387
14738    && flag_unsafe_math_optimizations"
14739 {
14740   rtx label = gen_label_rtx ();
14741
14742   emit_label (label);
14743
14744   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14745                             operands[1], operands[2]));
14746   ix86_emit_fp_unordered_jump (label);
14747
14748   emit_move_insn (operands[0], operands[1]);
14749   DONE;
14750 })
14751
14752 (define_insn "*sindf2"
14753   [(set (match_operand:DF 0 "register_operand" "=f")
14754         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14755   "TARGET_USE_FANCY_MATH_387
14756    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14757    && flag_unsafe_math_optimizations"
14758   "fsin"
14759   [(set_attr "type" "fpspc")
14760    (set_attr "mode" "DF")])
14761
14762 (define_insn "*sinsf2"
14763   [(set (match_operand:SF 0 "register_operand" "=f")
14764         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14767    && flag_unsafe_math_optimizations"
14768   "fsin"
14769   [(set_attr "type" "fpspc")
14770    (set_attr "mode" "SF")])
14771
14772 (define_insn "*sinextendsfdf2"
14773   [(set (match_operand:DF 0 "register_operand" "=f")
14774         (unspec:DF [(float_extend:DF
14775                      (match_operand:SF 1 "register_operand" "0"))]
14776                    UNSPEC_SIN))]
14777   "TARGET_USE_FANCY_MATH_387
14778    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14779    && flag_unsafe_math_optimizations"
14780   "fsin"
14781   [(set_attr "type" "fpspc")
14782    (set_attr "mode" "DF")])
14783
14784 (define_insn "*sinxf2"
14785   [(set (match_operand:XF 0 "register_operand" "=f")
14786         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14787   "TARGET_USE_FANCY_MATH_387
14788    && flag_unsafe_math_optimizations"
14789   "fsin"
14790   [(set_attr "type" "fpspc")
14791    (set_attr "mode" "XF")])
14792
14793 (define_insn "*cosdf2"
14794   [(set (match_operand:DF 0 "register_operand" "=f")
14795         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14796   "TARGET_USE_FANCY_MATH_387
14797    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14798    && flag_unsafe_math_optimizations"
14799   "fcos"
14800   [(set_attr "type" "fpspc")
14801    (set_attr "mode" "DF")])
14802
14803 (define_insn "*cossf2"
14804   [(set (match_operand:SF 0 "register_operand" "=f")
14805         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14806   "TARGET_USE_FANCY_MATH_387
14807    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14808    && flag_unsafe_math_optimizations"
14809   "fcos"
14810   [(set_attr "type" "fpspc")
14811    (set_attr "mode" "SF")])
14812
14813 (define_insn "*cosextendsfdf2"
14814   [(set (match_operand:DF 0 "register_operand" "=f")
14815         (unspec:DF [(float_extend:DF
14816                      (match_operand:SF 1 "register_operand" "0"))]
14817                    UNSPEC_COS))]
14818   "TARGET_USE_FANCY_MATH_387
14819    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14820    && flag_unsafe_math_optimizations"
14821   "fcos"
14822   [(set_attr "type" "fpspc")
14823    (set_attr "mode" "DF")])
14824
14825 (define_insn "*cosxf2"
14826   [(set (match_operand:XF 0 "register_operand" "=f")
14827         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && flag_unsafe_math_optimizations"
14830   "fcos"
14831   [(set_attr "type" "fpspc")
14832    (set_attr "mode" "XF")])
14833
14834 ;; With sincos pattern defined, sin and cos builtin function will be
14835 ;; expanded to sincos pattern with one of its outputs left unused. 
14836 ;; Cse pass  will detected, if two sincos patterns can be combined,
14837 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14838 ;; depending on the unused output.
14839
14840 (define_insn "sincosdf3"
14841   [(set (match_operand:DF 0 "register_operand" "=f")
14842         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14843                    UNSPEC_SINCOS_COS))
14844    (set (match_operand:DF 1 "register_operand" "=u")
14845         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14846   "TARGET_USE_FANCY_MATH_387
14847    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14848    && flag_unsafe_math_optimizations"
14849   "fsincos"
14850   [(set_attr "type" "fpspc")
14851    (set_attr "mode" "DF")])
14852
14853 (define_split
14854   [(set (match_operand:DF 0 "register_operand" "")
14855         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14856                    UNSPEC_SINCOS_COS))
14857    (set (match_operand:DF 1 "register_operand" "")
14858         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14859   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14860    && !reload_completed && !reload_in_progress"
14861   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14862   "")
14863
14864 (define_split
14865   [(set (match_operand:DF 0 "register_operand" "")
14866         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14867                    UNSPEC_SINCOS_COS))
14868    (set (match_operand:DF 1 "register_operand" "")
14869         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14870   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14871    && !reload_completed && !reload_in_progress"
14872   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14873   "")
14874
14875 (define_insn "sincossf3"
14876   [(set (match_operand:SF 0 "register_operand" "=f")
14877         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14878                    UNSPEC_SINCOS_COS))
14879    (set (match_operand:SF 1 "register_operand" "=u")
14880         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14881   "TARGET_USE_FANCY_MATH_387
14882    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14883    && flag_unsafe_math_optimizations"
14884   "fsincos"
14885   [(set_attr "type" "fpspc")
14886    (set_attr "mode" "SF")])
14887
14888 (define_split
14889   [(set (match_operand:SF 0 "register_operand" "")
14890         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14891                    UNSPEC_SINCOS_COS))
14892    (set (match_operand:SF 1 "register_operand" "")
14893         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14894   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14895    && !reload_completed && !reload_in_progress"
14896   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14897   "")
14898
14899 (define_split
14900   [(set (match_operand:SF 0 "register_operand" "")
14901         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14902                    UNSPEC_SINCOS_COS))
14903    (set (match_operand:SF 1 "register_operand" "")
14904         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14905   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14906    && !reload_completed && !reload_in_progress"
14907   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14908   "")
14909
14910 (define_insn "*sincosextendsfdf3"
14911   [(set (match_operand:DF 0 "register_operand" "=f")
14912         (unspec:DF [(float_extend:DF
14913                      (match_operand:SF 2 "register_operand" "0"))]
14914                    UNSPEC_SINCOS_COS))
14915    (set (match_operand:DF 1 "register_operand" "=u")
14916         (unspec:DF [(float_extend:DF
14917                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14918   "TARGET_USE_FANCY_MATH_387
14919    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14920    && flag_unsafe_math_optimizations"
14921   "fsincos"
14922   [(set_attr "type" "fpspc")
14923    (set_attr "mode" "DF")])
14924
14925 (define_split
14926   [(set (match_operand:DF 0 "register_operand" "")
14927         (unspec:DF [(float_extend:DF
14928                      (match_operand:SF 2 "register_operand" ""))]
14929                    UNSPEC_SINCOS_COS))
14930    (set (match_operand:DF 1 "register_operand" "")
14931         (unspec:DF [(float_extend:DF
14932                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14933   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14934    && !reload_completed && !reload_in_progress"
14935   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14936                                    (match_dup 2))] UNSPEC_SIN))]
14937   "")
14938
14939 (define_split
14940   [(set (match_operand:DF 0 "register_operand" "")
14941         (unspec:DF [(float_extend:DF
14942                      (match_operand:SF 2 "register_operand" ""))]
14943                    UNSPEC_SINCOS_COS))
14944    (set (match_operand:DF 1 "register_operand" "")
14945         (unspec:DF [(float_extend:DF
14946                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14948    && !reload_completed && !reload_in_progress"
14949   [(set (match_dup 0) (unspec:DF [(float_extend:DF
14950                                    (match_dup 2))] UNSPEC_COS))]
14951   "")
14952
14953 (define_insn "sincosxf3"
14954   [(set (match_operand:XF 0 "register_operand" "=f")
14955         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14956                    UNSPEC_SINCOS_COS))
14957    (set (match_operand:XF 1 "register_operand" "=u")
14958         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14959   "TARGET_USE_FANCY_MATH_387
14960    && flag_unsafe_math_optimizations"
14961   "fsincos"
14962   [(set_attr "type" "fpspc")
14963    (set_attr "mode" "XF")])
14964
14965 (define_split
14966   [(set (match_operand:XF 0 "register_operand" "")
14967         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14968                    UNSPEC_SINCOS_COS))
14969    (set (match_operand:XF 1 "register_operand" "")
14970         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14971   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14972    && !reload_completed && !reload_in_progress"
14973   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14974   "")
14975
14976 (define_split
14977   [(set (match_operand:XF 0 "register_operand" "")
14978         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14979                    UNSPEC_SINCOS_COS))
14980    (set (match_operand:XF 1 "register_operand" "")
14981         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14982   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14983    && !reload_completed && !reload_in_progress"
14984   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14985   "")
14986
14987 (define_insn "*tandf3_1"
14988   [(set (match_operand:DF 0 "register_operand" "=f")
14989         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14990                    UNSPEC_TAN_ONE))
14991    (set (match_operand:DF 1 "register_operand" "=u")
14992         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14993   "TARGET_USE_FANCY_MATH_387
14994    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14995    && flag_unsafe_math_optimizations"
14996   "fptan"
14997   [(set_attr "type" "fpspc")
14998    (set_attr "mode" "DF")])
14999
15000 ;; optimize sequence: fptan
15001 ;;                    fstp    %st(0)
15002 ;;                    fld1
15003 ;; into fptan insn.
15004
15005 (define_peephole2
15006   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15007                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15008                              UNSPEC_TAN_ONE))
15009              (set (match_operand:DF 1 "register_operand" "")
15010                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15011    (set (match_dup 0)
15012         (match_operand:DF 3 "immediate_operand" ""))]
15013   "standard_80387_constant_p (operands[3]) == 2"
15014   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15015              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15016   "")
15017
15018 (define_expand "tandf2"
15019   [(parallel [(set (match_dup 2)
15020                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15021                               UNSPEC_TAN_ONE))
15022               (set (match_operand:DF 0 "register_operand" "")
15023                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15024   "TARGET_USE_FANCY_MATH_387
15025    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15026    && flag_unsafe_math_optimizations"
15027 {
15028   operands[2] = gen_reg_rtx (DFmode);
15029 })
15030
15031 (define_insn "*tansf3_1"
15032   [(set (match_operand:SF 0 "register_operand" "=f")
15033         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15034                    UNSPEC_TAN_ONE))
15035    (set (match_operand:SF 1 "register_operand" "=u")
15036         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15039    && flag_unsafe_math_optimizations"
15040   "fptan"
15041   [(set_attr "type" "fpspc")
15042    (set_attr "mode" "SF")])
15043
15044 ;; optimize sequence: fptan
15045 ;;                    fstp    %st(0)
15046 ;;                    fld1
15047 ;; into fptan insn.
15048
15049 (define_peephole2
15050   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15051                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15052                              UNSPEC_TAN_ONE))
15053              (set (match_operand:SF 1 "register_operand" "")
15054                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15055    (set (match_dup 0)
15056         (match_operand:SF 3 "immediate_operand" ""))]
15057   "standard_80387_constant_p (operands[3]) == 2"
15058   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15059              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15060   "")
15061
15062 (define_expand "tansf2"
15063   [(parallel [(set (match_dup 2)
15064                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15065                               UNSPEC_TAN_ONE))
15066               (set (match_operand:SF 0 "register_operand" "")
15067                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15068   "TARGET_USE_FANCY_MATH_387
15069    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15070    && flag_unsafe_math_optimizations"
15071 {
15072   operands[2] = gen_reg_rtx (SFmode);
15073 })
15074
15075 (define_insn "*tanxf3_1"
15076   [(set (match_operand:XF 0 "register_operand" "=f")
15077         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15078                    UNSPEC_TAN_ONE))
15079    (set (match_operand:XF 1 "register_operand" "=u")
15080         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15081   "TARGET_USE_FANCY_MATH_387
15082    && flag_unsafe_math_optimizations"
15083   "fptan"
15084   [(set_attr "type" "fpspc")
15085    (set_attr "mode" "XF")])
15086
15087 ;; optimize sequence: fptan
15088 ;;                    fstp    %st(0)
15089 ;;                    fld1
15090 ;; into fptan insn.
15091
15092 (define_peephole2
15093   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15094                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15095                              UNSPEC_TAN_ONE))
15096              (set (match_operand:XF 1 "register_operand" "")
15097                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15098    (set (match_dup 0)
15099         (match_operand:XF 3 "immediate_operand" ""))]
15100   "standard_80387_constant_p (operands[3]) == 2"
15101   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15102              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15103   "")
15104
15105 (define_expand "tanxf2"
15106   [(parallel [(set (match_dup 2)
15107                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15108                               UNSPEC_TAN_ONE))
15109               (set (match_operand:XF 0 "register_operand" "")
15110                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15111   "TARGET_USE_FANCY_MATH_387
15112    && flag_unsafe_math_optimizations"
15113 {
15114   operands[2] = gen_reg_rtx (XFmode);
15115 })
15116
15117 (define_insn "atan2df3_1"
15118   [(set (match_operand:DF 0 "register_operand" "=f")
15119         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15120                     (match_operand:DF 1 "register_operand" "u")]
15121                    UNSPEC_FPATAN))
15122    (clobber (match_scratch:DF 3 "=1"))]
15123   "TARGET_USE_FANCY_MATH_387
15124    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15125    && flag_unsafe_math_optimizations"
15126   "fpatan"
15127   [(set_attr "type" "fpspc")
15128    (set_attr "mode" "DF")])
15129
15130 (define_expand "atan2df3"
15131   [(use (match_operand:DF 0 "register_operand" ""))
15132    (use (match_operand:DF 2 "register_operand" ""))
15133    (use (match_operand:DF 1 "register_operand" ""))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15136    && flag_unsafe_math_optimizations"
15137 {
15138   rtx copy = gen_reg_rtx (DFmode);
15139   emit_move_insn (copy, operands[1]);
15140   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15141   DONE;
15142 })
15143
15144 (define_expand "atandf2"
15145   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15146                    (unspec:DF [(match_dup 2)
15147                                (match_operand:DF 1 "register_operand" "")]
15148                     UNSPEC_FPATAN))
15149               (clobber (match_scratch:DF 3 ""))])]
15150   "TARGET_USE_FANCY_MATH_387
15151    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15152    && flag_unsafe_math_optimizations"
15153 {
15154   operands[2] = gen_reg_rtx (DFmode);
15155   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15156 })
15157
15158 (define_insn "atan2sf3_1"
15159   [(set (match_operand:SF 0 "register_operand" "=f")
15160         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15161                     (match_operand:SF 1 "register_operand" "u")]
15162                    UNSPEC_FPATAN))
15163    (clobber (match_scratch:SF 3 "=1"))]
15164   "TARGET_USE_FANCY_MATH_387
15165    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15166    && flag_unsafe_math_optimizations"
15167   "fpatan"
15168   [(set_attr "type" "fpspc")
15169    (set_attr "mode" "SF")])
15170
15171 (define_expand "atan2sf3"
15172   [(use (match_operand:SF 0 "register_operand" ""))
15173    (use (match_operand:SF 2 "register_operand" ""))
15174    (use (match_operand:SF 1 "register_operand" ""))]
15175   "TARGET_USE_FANCY_MATH_387
15176    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15177    && flag_unsafe_math_optimizations"
15178 {
15179   rtx copy = gen_reg_rtx (SFmode);
15180   emit_move_insn (copy, operands[1]);
15181   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15182   DONE;
15183 })
15184
15185 (define_expand "atansf2"
15186   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15187                    (unspec:SF [(match_dup 2)
15188                                (match_operand:SF 1 "register_operand" "")]
15189                     UNSPEC_FPATAN))
15190               (clobber (match_scratch:SF 3 ""))])]
15191   "TARGET_USE_FANCY_MATH_387
15192    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15193    && flag_unsafe_math_optimizations"
15194 {
15195   operands[2] = gen_reg_rtx (SFmode);
15196   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15197 })
15198
15199 (define_insn "atan2xf3_1"
15200   [(set (match_operand:XF 0 "register_operand" "=f")
15201         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15202                     (match_operand:XF 1 "register_operand" "u")]
15203                    UNSPEC_FPATAN))
15204    (clobber (match_scratch:XF 3 "=1"))]
15205   "TARGET_USE_FANCY_MATH_387
15206    && flag_unsafe_math_optimizations"
15207   "fpatan"
15208   [(set_attr "type" "fpspc")
15209    (set_attr "mode" "XF")])
15210
15211 (define_expand "atan2xf3"
15212   [(use (match_operand:XF 0 "register_operand" ""))
15213    (use (match_operand:XF 2 "register_operand" ""))
15214    (use (match_operand:XF 1 "register_operand" ""))]
15215   "TARGET_USE_FANCY_MATH_387
15216    && flag_unsafe_math_optimizations"
15217 {
15218   rtx copy = gen_reg_rtx (XFmode);
15219   emit_move_insn (copy, operands[1]);
15220   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15221   DONE;
15222 })
15223
15224 (define_expand "atanxf2"
15225   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15226                    (unspec:XF [(match_dup 2)
15227                                (match_operand:XF 1 "register_operand" "")]
15228                     UNSPEC_FPATAN))
15229               (clobber (match_scratch:XF 3 ""))])]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations"
15232 {
15233   operands[2] = gen_reg_rtx (XFmode);
15234   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15235 })
15236
15237 (define_expand "asindf2"
15238   [(set (match_dup 2)
15239         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15240    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15241    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15242    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15243    (parallel [(set (match_dup 7)
15244                    (unspec:XF [(match_dup 6) (match_dup 2)]
15245                               UNSPEC_FPATAN))
15246               (clobber (match_scratch:XF 8 ""))])
15247    (set (match_operand:DF 0 "register_operand" "")
15248         (float_truncate:DF (match_dup 7)))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15251    && flag_unsafe_math_optimizations"
15252 {
15253   int i;
15254
15255   for (i=2; i<8; i++)
15256     operands[i] = gen_reg_rtx (XFmode);
15257
15258   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15259 })
15260
15261 (define_expand "asinsf2"
15262   [(set (match_dup 2)
15263         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15264    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15265    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15266    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15267    (parallel [(set (match_dup 7)
15268                    (unspec:XF [(match_dup 6) (match_dup 2)]
15269                               UNSPEC_FPATAN))
15270               (clobber (match_scratch:XF 8 ""))])
15271    (set (match_operand:SF 0 "register_operand" "")
15272         (float_truncate:SF (match_dup 7)))]
15273   "TARGET_USE_FANCY_MATH_387
15274    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15275    && flag_unsafe_math_optimizations"
15276 {
15277   int i;
15278
15279   for (i=2; i<8; i++)
15280     operands[i] = gen_reg_rtx (XFmode);
15281
15282   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15283 })
15284
15285 (define_expand "asinxf2"
15286   [(set (match_dup 2)
15287         (mult:XF (match_operand:XF 1 "register_operand" "")
15288                  (match_dup 1)))
15289    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15290    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15291    (parallel [(set (match_operand:XF 0 "register_operand" "")
15292                    (unspec:XF [(match_dup 5) (match_dup 1)]
15293                               UNSPEC_FPATAN))
15294               (clobber (match_scratch:XF 6 ""))])]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations"
15297 {
15298   int i;
15299
15300   for (i=2; i<6; i++)
15301     operands[i] = gen_reg_rtx (XFmode);
15302
15303   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15304 })
15305
15306 (define_expand "acosdf2"
15307   [(set (match_dup 2)
15308         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15309    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15310    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15311    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15312    (parallel [(set (match_dup 7)
15313                    (unspec:XF [(match_dup 2) (match_dup 6)]
15314                               UNSPEC_FPATAN))
15315               (clobber (match_scratch:XF 8 ""))])
15316    (set (match_operand:DF 0 "register_operand" "")
15317         (float_truncate:DF (match_dup 7)))]
15318   "TARGET_USE_FANCY_MATH_387
15319    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15320    && flag_unsafe_math_optimizations"
15321 {
15322   int i;
15323
15324   for (i=2; i<8; i++)
15325     operands[i] = gen_reg_rtx (XFmode);
15326
15327   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15328 })
15329
15330 (define_expand "acossf2"
15331   [(set (match_dup 2)
15332         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15333    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15334    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15335    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15336    (parallel [(set (match_dup 7)
15337                    (unspec:XF [(match_dup 2) (match_dup 6)]
15338                               UNSPEC_FPATAN))
15339               (clobber (match_scratch:XF 8 ""))])
15340    (set (match_operand:SF 0 "register_operand" "")
15341         (float_truncate:SF (match_dup 7)))]
15342   "TARGET_USE_FANCY_MATH_387
15343    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15344    && flag_unsafe_math_optimizations"
15345 {
15346   int i;
15347
15348   for (i=2; i<8; i++)
15349     operands[i] = gen_reg_rtx (XFmode);
15350
15351   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15352 })
15353
15354 (define_expand "acosxf2"
15355   [(set (match_dup 2)
15356         (mult:XF (match_operand:XF 1 "register_operand" "")
15357                  (match_dup 1)))
15358    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15359    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15360    (parallel [(set (match_operand:XF 0 "register_operand" "")
15361                    (unspec:XF [(match_dup 1) (match_dup 5)]
15362                               UNSPEC_FPATAN))
15363               (clobber (match_scratch:XF 6 ""))])]
15364   "TARGET_USE_FANCY_MATH_387
15365    && flag_unsafe_math_optimizations"
15366 {
15367   int i;
15368
15369   for (i=2; i<6; i++)
15370     operands[i] = gen_reg_rtx (XFmode);
15371
15372   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15373 })
15374
15375 (define_insn "fyl2x_xf3"
15376   [(set (match_operand:XF 0 "register_operand" "=f")
15377         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15378                     (match_operand:XF 1 "register_operand" "u")]
15379                    UNSPEC_FYL2X))
15380    (clobber (match_scratch:XF 3 "=1"))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && flag_unsafe_math_optimizations"
15383   "fyl2x"
15384   [(set_attr "type" "fpspc")
15385    (set_attr "mode" "XF")])
15386
15387 (define_expand "logsf2"
15388   [(set (match_dup 2)
15389         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15390    (parallel [(set (match_dup 4)
15391                    (unspec:XF [(match_dup 2)
15392                                (match_dup 3)] UNSPEC_FYL2X))
15393               (clobber (match_scratch:XF 5 ""))])
15394    (set (match_operand:SF 0 "register_operand" "")
15395         (float_truncate:SF (match_dup 4)))]
15396   "TARGET_USE_FANCY_MATH_387
15397    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15398    && flag_unsafe_math_optimizations"
15399 {
15400   rtx temp;
15401
15402   operands[2] = gen_reg_rtx (XFmode);
15403   operands[3] = gen_reg_rtx (XFmode);
15404   operands[4] = gen_reg_rtx (XFmode);
15405
15406   temp = standard_80387_constant_rtx (4); /* fldln2 */
15407   emit_move_insn (operands[3], temp);
15408 })
15409
15410 (define_expand "logdf2"
15411   [(set (match_dup 2)
15412         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15413    (parallel [(set (match_dup 4)
15414                    (unspec:XF [(match_dup 2)
15415                                (match_dup 3)] UNSPEC_FYL2X))
15416               (clobber (match_scratch:XF 5 ""))])
15417    (set (match_operand:DF 0 "register_operand" "")
15418         (float_truncate:DF (match_dup 4)))]
15419   "TARGET_USE_FANCY_MATH_387
15420    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15421    && flag_unsafe_math_optimizations"
15422 {
15423   rtx temp;
15424
15425   operands[2] = gen_reg_rtx (XFmode);
15426   operands[3] = gen_reg_rtx (XFmode);
15427   operands[4] = gen_reg_rtx (XFmode);
15428
15429   temp = standard_80387_constant_rtx (4); /* fldln2 */
15430   emit_move_insn (operands[3], temp);
15431 })
15432
15433 (define_expand "logxf2"
15434   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15435                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15436                                (match_dup 2)] UNSPEC_FYL2X))
15437               (clobber (match_scratch:XF 3 ""))])]
15438   "TARGET_USE_FANCY_MATH_387
15439    && flag_unsafe_math_optimizations"
15440 {
15441   rtx temp;
15442
15443   operands[2] = gen_reg_rtx (XFmode);
15444   temp = standard_80387_constant_rtx (4); /* fldln2 */
15445   emit_move_insn (operands[2], temp);
15446 })
15447
15448 (define_expand "log10sf2"
15449   [(set (match_dup 2)
15450         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15451    (parallel [(set (match_dup 4)
15452                    (unspec:XF [(match_dup 2)
15453                                (match_dup 3)] UNSPEC_FYL2X))
15454               (clobber (match_scratch:XF 5 ""))])
15455    (set (match_operand:SF 0 "register_operand" "")
15456         (float_truncate:SF (match_dup 4)))]
15457   "TARGET_USE_FANCY_MATH_387
15458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459    && flag_unsafe_math_optimizations"
15460 {
15461   rtx temp;
15462
15463   operands[2] = gen_reg_rtx (XFmode);
15464   operands[3] = gen_reg_rtx (XFmode);
15465   operands[4] = gen_reg_rtx (XFmode);
15466
15467   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15468   emit_move_insn (operands[3], temp);
15469 })
15470
15471 (define_expand "log10df2"
15472   [(set (match_dup 2)
15473         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15474    (parallel [(set (match_dup 4)
15475                    (unspec:XF [(match_dup 2)
15476                                (match_dup 3)] UNSPEC_FYL2X))
15477               (clobber (match_scratch:XF 5 ""))])
15478    (set (match_operand:DF 0 "register_operand" "")
15479         (float_truncate:DF (match_dup 4)))]
15480   "TARGET_USE_FANCY_MATH_387
15481    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15482    && flag_unsafe_math_optimizations"
15483 {
15484   rtx temp;
15485
15486   operands[2] = gen_reg_rtx (XFmode);
15487   operands[3] = gen_reg_rtx (XFmode);
15488   operands[4] = gen_reg_rtx (XFmode);
15489
15490   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15491   emit_move_insn (operands[3], temp);
15492 })
15493
15494 (define_expand "log10xf2"
15495   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15496                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15497                                (match_dup 2)] UNSPEC_FYL2X))
15498               (clobber (match_scratch:XF 3 ""))])]
15499   "TARGET_USE_FANCY_MATH_387
15500    && flag_unsafe_math_optimizations"
15501 {
15502   rtx temp;
15503
15504   operands[2] = gen_reg_rtx (XFmode);
15505   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15506   emit_move_insn (operands[2], temp);
15507 })
15508
15509 (define_expand "log2sf2"
15510   [(set (match_dup 2)
15511         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15512    (parallel [(set (match_dup 4)
15513                    (unspec:XF [(match_dup 2)
15514                                (match_dup 3)] UNSPEC_FYL2X))
15515               (clobber (match_scratch:XF 5 ""))])
15516    (set (match_operand:SF 0 "register_operand" "")
15517         (float_truncate:SF (match_dup 4)))]
15518   "TARGET_USE_FANCY_MATH_387
15519    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15520    && flag_unsafe_math_optimizations"
15521 {
15522   operands[2] = gen_reg_rtx (XFmode);
15523   operands[3] = gen_reg_rtx (XFmode);
15524   operands[4] = gen_reg_rtx (XFmode);
15525
15526   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15527 })
15528
15529 (define_expand "log2df2"
15530   [(set (match_dup 2)
15531         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15532    (parallel [(set (match_dup 4)
15533                    (unspec:XF [(match_dup 2)
15534                                (match_dup 3)] UNSPEC_FYL2X))
15535               (clobber (match_scratch:XF 5 ""))])
15536    (set (match_operand:DF 0 "register_operand" "")
15537         (float_truncate:DF (match_dup 4)))]
15538   "TARGET_USE_FANCY_MATH_387
15539    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15540    && flag_unsafe_math_optimizations"
15541 {
15542   operands[2] = gen_reg_rtx (XFmode);
15543   operands[3] = gen_reg_rtx (XFmode);
15544   operands[4] = gen_reg_rtx (XFmode);
15545
15546   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15547 })
15548
15549 (define_expand "log2xf2"
15550   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15551                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15552                                (match_dup 2)] UNSPEC_FYL2X))
15553               (clobber (match_scratch:XF 3 ""))])]
15554   "TARGET_USE_FANCY_MATH_387
15555    && flag_unsafe_math_optimizations"
15556 {
15557   operands[2] = gen_reg_rtx (XFmode);
15558   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15559 })
15560
15561 (define_insn "fyl2xp1_xf3"
15562   [(set (match_operand:XF 0 "register_operand" "=f")
15563         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15564                     (match_operand:XF 1 "register_operand" "u")]
15565                    UNSPEC_FYL2XP1))
15566    (clobber (match_scratch:XF 3 "=1"))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && flag_unsafe_math_optimizations"
15569   "fyl2xp1"
15570   [(set_attr "type" "fpspc")
15571    (set_attr "mode" "XF")])
15572
15573 (define_expand "log1psf2"
15574   [(use (match_operand:SF 0 "register_operand" ""))
15575    (use (match_operand:SF 1 "register_operand" ""))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15578    && flag_unsafe_math_optimizations"
15579 {
15580   rtx op0 = gen_reg_rtx (XFmode);
15581   rtx op1 = gen_reg_rtx (XFmode);
15582
15583   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15584   ix86_emit_i387_log1p (op0, op1);
15585   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15586   DONE;
15587 })
15588
15589 (define_expand "log1pdf2"
15590   [(use (match_operand:DF 0 "register_operand" ""))
15591    (use (match_operand:DF 1 "register_operand" ""))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15594    && flag_unsafe_math_optimizations"
15595 {
15596   rtx op0 = gen_reg_rtx (XFmode);
15597   rtx op1 = gen_reg_rtx (XFmode);
15598
15599   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15600   ix86_emit_i387_log1p (op0, op1);
15601   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15602   DONE;
15603 })
15604
15605 (define_expand "log1pxf2"
15606   [(use (match_operand:XF 0 "register_operand" ""))
15607    (use (match_operand:XF 1 "register_operand" ""))]
15608   "TARGET_USE_FANCY_MATH_387
15609    && flag_unsafe_math_optimizations"
15610 {
15611   ix86_emit_i387_log1p (operands[0], operands[1]);
15612   DONE;
15613 })
15614
15615 (define_insn "*fxtractxf3"
15616   [(set (match_operand:XF 0 "register_operand" "=f")
15617         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15618                    UNSPEC_XTRACT_FRACT))
15619    (set (match_operand:XF 1 "register_operand" "=u")
15620         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15621   "TARGET_USE_FANCY_MATH_387
15622    && flag_unsafe_math_optimizations"
15623   "fxtract"
15624   [(set_attr "type" "fpspc")
15625    (set_attr "mode" "XF")])
15626
15627 (define_expand "logbsf2"
15628   [(set (match_dup 2)
15629         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15630    (parallel [(set (match_dup 3)
15631                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15632               (set (match_dup 4)
15633                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15634    (set (match_operand:SF 0 "register_operand" "")
15635         (float_truncate:SF (match_dup 4)))]
15636   "TARGET_USE_FANCY_MATH_387
15637    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15638    && flag_unsafe_math_optimizations"
15639 {
15640   operands[2] = gen_reg_rtx (XFmode);
15641   operands[3] = gen_reg_rtx (XFmode);
15642   operands[4] = gen_reg_rtx (XFmode);
15643 })
15644
15645 (define_expand "logbdf2"
15646   [(set (match_dup 2)
15647         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15648    (parallel [(set (match_dup 3)
15649                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15650               (set (match_dup 4)
15651                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15652    (set (match_operand:DF 0 "register_operand" "")
15653         (float_truncate:DF (match_dup 4)))]
15654   "TARGET_USE_FANCY_MATH_387
15655    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15656    && flag_unsafe_math_optimizations"
15657 {
15658   operands[2] = gen_reg_rtx (XFmode);
15659   operands[3] = gen_reg_rtx (XFmode);
15660   operands[4] = gen_reg_rtx (XFmode);
15661 })
15662
15663 (define_expand "logbxf2"
15664   [(parallel [(set (match_dup 2)
15665                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15666                               UNSPEC_XTRACT_FRACT))
15667               (set (match_operand:XF 0 "register_operand" "")
15668                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15671 {
15672   operands[2] = gen_reg_rtx (XFmode);
15673 })
15674
15675 (define_expand "ilogbsi2"
15676   [(parallel [(set (match_dup 2)
15677                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15678                               UNSPEC_XTRACT_FRACT))
15679               (set (match_operand:XF 3 "register_operand" "")
15680                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15681    (parallel [(set (match_operand:SI 0 "register_operand" "")
15682                    (fix:SI (match_dup 3)))
15683               (clobber (reg:CC FLAGS_REG))])]
15684   "TARGET_USE_FANCY_MATH_387
15685    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15686    && flag_unsafe_math_optimizations"
15687 {
15688   operands[2] = gen_reg_rtx (XFmode);
15689   operands[3] = gen_reg_rtx (XFmode);
15690 })
15691
15692 (define_insn "*f2xm1xf2"
15693   [(set (match_operand:XF 0 "register_operand" "=f")
15694         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15695          UNSPEC_F2XM1))]
15696   "TARGET_USE_FANCY_MATH_387
15697    && flag_unsafe_math_optimizations"
15698   "f2xm1"
15699   [(set_attr "type" "fpspc")
15700    (set_attr "mode" "XF")])
15701
15702 (define_insn "*fscalexf4"
15703   [(set (match_operand:XF 0 "register_operand" "=f")
15704         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15705                     (match_operand:XF 3 "register_operand" "1")]
15706                    UNSPEC_FSCALE_FRACT))
15707    (set (match_operand:XF 1 "register_operand" "=u")
15708         (unspec:XF [(match_dup 2) (match_dup 3)]
15709                    UNSPEC_FSCALE_EXP))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && flag_unsafe_math_optimizations"
15712   "fscale"
15713   [(set_attr "type" "fpspc")
15714    (set_attr "mode" "XF")])
15715
15716 (define_expand "expsf2"
15717   [(set (match_dup 2)
15718         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15719    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15720    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15721    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15722    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15723    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15724    (parallel [(set (match_dup 10)
15725                    (unspec:XF [(match_dup 9) (match_dup 5)]
15726                               UNSPEC_FSCALE_FRACT))
15727               (set (match_dup 11)
15728                    (unspec:XF [(match_dup 9) (match_dup 5)]
15729                               UNSPEC_FSCALE_EXP))])
15730    (set (match_operand:SF 0 "register_operand" "")
15731         (float_truncate:SF (match_dup 10)))]
15732   "TARGET_USE_FANCY_MATH_387
15733    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15734    && flag_unsafe_math_optimizations"
15735 {
15736   rtx temp;
15737   int i;
15738
15739   for (i=2; i<12; i++)
15740     operands[i] = gen_reg_rtx (XFmode);
15741   temp = standard_80387_constant_rtx (5); /* fldl2e */
15742   emit_move_insn (operands[3], temp);
15743   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15744 })
15745
15746 (define_expand "expdf2"
15747   [(set (match_dup 2)
15748         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15749    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15750    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15751    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15752    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15753    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15754    (parallel [(set (match_dup 10)
15755                    (unspec:XF [(match_dup 9) (match_dup 5)]
15756                               UNSPEC_FSCALE_FRACT))
15757               (set (match_dup 11)
15758                    (unspec:XF [(match_dup 9) (match_dup 5)]
15759                               UNSPEC_FSCALE_EXP))])
15760    (set (match_operand:DF 0 "register_operand" "")
15761         (float_truncate:DF (match_dup 10)))]
15762   "TARGET_USE_FANCY_MATH_387
15763    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15764    && flag_unsafe_math_optimizations"
15765 {
15766   rtx temp;
15767   int i;
15768
15769   for (i=2; i<12; i++)
15770     operands[i] = gen_reg_rtx (XFmode);
15771   temp = standard_80387_constant_rtx (5); /* fldl2e */
15772   emit_move_insn (operands[3], temp);
15773   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15774 })
15775
15776 (define_expand "expxf2"
15777   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15778                                (match_dup 2)))
15779    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15780    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15781    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15782    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15783    (parallel [(set (match_operand:XF 0 "register_operand" "")
15784                    (unspec:XF [(match_dup 8) (match_dup 4)]
15785                               UNSPEC_FSCALE_FRACT))
15786               (set (match_dup 9)
15787                    (unspec:XF [(match_dup 8) (match_dup 4)]
15788                               UNSPEC_FSCALE_EXP))])]
15789   "TARGET_USE_FANCY_MATH_387
15790    && flag_unsafe_math_optimizations"
15791 {
15792   rtx temp;
15793   int i;
15794
15795   for (i=2; i<10; i++)
15796     operands[i] = gen_reg_rtx (XFmode);
15797   temp = standard_80387_constant_rtx (5); /* fldl2e */
15798   emit_move_insn (operands[2], temp);
15799   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15800 })
15801
15802 (define_expand "exp10sf2"
15803   [(set (match_dup 2)
15804         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15805    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15806    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15807    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15808    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15809    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15810    (parallel [(set (match_dup 10)
15811                    (unspec:XF [(match_dup 9) (match_dup 5)]
15812                               UNSPEC_FSCALE_FRACT))
15813               (set (match_dup 11)
15814                    (unspec:XF [(match_dup 9) (match_dup 5)]
15815                               UNSPEC_FSCALE_EXP))])
15816    (set (match_operand:SF 0 "register_operand" "")
15817         (float_truncate:SF (match_dup 10)))]
15818   "TARGET_USE_FANCY_MATH_387
15819    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15820    && flag_unsafe_math_optimizations"
15821 {
15822   rtx temp;
15823   int i;
15824
15825   for (i=2; i<12; i++)
15826     operands[i] = gen_reg_rtx (XFmode);
15827   temp = standard_80387_constant_rtx (6); /* fldl2t */
15828   emit_move_insn (operands[3], temp);
15829   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15830 })
15831
15832 (define_expand "exp10df2"
15833   [(set (match_dup 2)
15834         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15835    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15836    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15837    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15838    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15839    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15840    (parallel [(set (match_dup 10)
15841                    (unspec:XF [(match_dup 9) (match_dup 5)]
15842                               UNSPEC_FSCALE_FRACT))
15843               (set (match_dup 11)
15844                    (unspec:XF [(match_dup 9) (match_dup 5)]
15845                               UNSPEC_FSCALE_EXP))])
15846    (set (match_operand:DF 0 "register_operand" "")
15847         (float_truncate:DF (match_dup 10)))]
15848   "TARGET_USE_FANCY_MATH_387
15849    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15850    && flag_unsafe_math_optimizations"
15851 {
15852   rtx temp;
15853   int i;
15854
15855   for (i=2; i<12; i++)
15856     operands[i] = gen_reg_rtx (XFmode);
15857   temp = standard_80387_constant_rtx (6); /* fldl2t */
15858   emit_move_insn (operands[3], temp);
15859   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15860 })
15861
15862 (define_expand "exp10xf2"
15863   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15864                                (match_dup 2)))
15865    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15866    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15867    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15868    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15869    (parallel [(set (match_operand:XF 0 "register_operand" "")
15870                    (unspec:XF [(match_dup 8) (match_dup 4)]
15871                               UNSPEC_FSCALE_FRACT))
15872               (set (match_dup 9)
15873                    (unspec:XF [(match_dup 8) (match_dup 4)]
15874                               UNSPEC_FSCALE_EXP))])]
15875   "TARGET_USE_FANCY_MATH_387
15876    && flag_unsafe_math_optimizations"
15877 {
15878   rtx temp;
15879   int i;
15880
15881   for (i=2; i<10; i++)
15882     operands[i] = gen_reg_rtx (XFmode);
15883   temp = standard_80387_constant_rtx (6); /* fldl2t */
15884   emit_move_insn (operands[2], temp);
15885   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15886 })
15887
15888 (define_expand "exp2sf2"
15889   [(set (match_dup 2)
15890         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15891    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15892    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15893    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15894    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15895    (parallel [(set (match_dup 8)
15896                    (unspec:XF [(match_dup 7) (match_dup 3)]
15897                               UNSPEC_FSCALE_FRACT))
15898               (set (match_dup 9)
15899                    (unspec:XF [(match_dup 7) (match_dup 3)]
15900                               UNSPEC_FSCALE_EXP))])
15901    (set (match_operand:SF 0 "register_operand" "")
15902         (float_truncate:SF (match_dup 8)))]
15903   "TARGET_USE_FANCY_MATH_387
15904    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15905    && flag_unsafe_math_optimizations"
15906 {
15907   int i;
15908
15909   for (i=2; i<10; i++)
15910     operands[i] = gen_reg_rtx (XFmode);
15911   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15912 })
15913
15914 (define_expand "exp2df2"
15915   [(set (match_dup 2)
15916         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15917    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15918    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15919    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15920    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15921    (parallel [(set (match_dup 8)
15922                    (unspec:XF [(match_dup 7) (match_dup 3)]
15923                               UNSPEC_FSCALE_FRACT))
15924               (set (match_dup 9)
15925                    (unspec:XF [(match_dup 7) (match_dup 3)]
15926                               UNSPEC_FSCALE_EXP))])
15927    (set (match_operand:DF 0 "register_operand" "")
15928         (float_truncate:DF (match_dup 8)))]
15929   "TARGET_USE_FANCY_MATH_387
15930    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15931    && flag_unsafe_math_optimizations"
15932 {
15933   int i;
15934
15935   for (i=2; i<10; i++)
15936     operands[i] = gen_reg_rtx (XFmode);
15937   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15938 })
15939
15940 (define_expand "exp2xf2"
15941   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15942    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15943    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15944    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15945    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15946    (parallel [(set (match_operand:XF 0 "register_operand" "")
15947                    (unspec:XF [(match_dup 7) (match_dup 3)]
15948                               UNSPEC_FSCALE_FRACT))
15949               (set (match_dup 8)
15950                    (unspec:XF [(match_dup 7) (match_dup 3)]
15951                               UNSPEC_FSCALE_EXP))])]
15952   "TARGET_USE_FANCY_MATH_387
15953    && flag_unsafe_math_optimizations"
15954 {
15955   int i;
15956
15957   for (i=2; i<9; i++)
15958     operands[i] = gen_reg_rtx (XFmode);
15959   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15960 })
15961
15962 (define_expand "expm1df2"
15963   [(set (match_dup 2)
15964         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15965    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15966    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15967    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15968    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15969    (parallel [(set (match_dup 8)
15970                    (unspec:XF [(match_dup 7) (match_dup 5)]
15971                               UNSPEC_FSCALE_FRACT))
15972                    (set (match_dup 9)
15973                    (unspec:XF [(match_dup 7) (match_dup 5)]
15974                               UNSPEC_FSCALE_EXP))])
15975    (parallel [(set (match_dup 11)
15976                    (unspec:XF [(match_dup 10) (match_dup 9)]
15977                               UNSPEC_FSCALE_FRACT))
15978               (set (match_dup 12)
15979                    (unspec:XF [(match_dup 10) (match_dup 9)]
15980                               UNSPEC_FSCALE_EXP))])
15981    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15982    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15983    (set (match_operand:DF 0 "register_operand" "")
15984         (float_truncate:DF (match_dup 14)))]
15985   "TARGET_USE_FANCY_MATH_387
15986    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987    && flag_unsafe_math_optimizations"
15988 {
15989   rtx temp;
15990   int i;
15991
15992   for (i=2; i<15; i++)
15993     operands[i] = gen_reg_rtx (XFmode);
15994   temp = standard_80387_constant_rtx (5); /* fldl2e */
15995   emit_move_insn (operands[3], temp);
15996   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15997 })
15998
15999 (define_expand "expm1sf2"
16000   [(set (match_dup 2)
16001         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16002    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16003    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16004    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16005    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16006    (parallel [(set (match_dup 8)
16007                    (unspec:XF [(match_dup 7) (match_dup 5)]
16008                               UNSPEC_FSCALE_FRACT))
16009                    (set (match_dup 9)
16010                    (unspec:XF [(match_dup 7) (match_dup 5)]
16011                               UNSPEC_FSCALE_EXP))])
16012    (parallel [(set (match_dup 11)
16013                    (unspec:XF [(match_dup 10) (match_dup 9)]
16014                               UNSPEC_FSCALE_FRACT))
16015               (set (match_dup 12)
16016                    (unspec:XF [(match_dup 10) (match_dup 9)]
16017                               UNSPEC_FSCALE_EXP))])
16018    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16019    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16020    (set (match_operand:SF 0 "register_operand" "")
16021         (float_truncate:SF (match_dup 14)))]
16022   "TARGET_USE_FANCY_MATH_387
16023    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16024    && flag_unsafe_math_optimizations"
16025 {
16026   rtx temp;
16027   int i;
16028
16029   for (i=2; i<15; i++)
16030     operands[i] = gen_reg_rtx (XFmode);
16031   temp = standard_80387_constant_rtx (5); /* fldl2e */
16032   emit_move_insn (operands[3], temp);
16033   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16034 })
16035
16036 (define_expand "expm1xf2"
16037   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16038                                (match_dup 2)))
16039    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16040    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16041    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16042    (parallel [(set (match_dup 7)
16043                    (unspec:XF [(match_dup 6) (match_dup 4)]
16044                               UNSPEC_FSCALE_FRACT))
16045                    (set (match_dup 8)
16046                    (unspec:XF [(match_dup 6) (match_dup 4)]
16047                               UNSPEC_FSCALE_EXP))])
16048    (parallel [(set (match_dup 10)
16049                    (unspec:XF [(match_dup 9) (match_dup 8)]
16050                               UNSPEC_FSCALE_FRACT))
16051               (set (match_dup 11)
16052                    (unspec:XF [(match_dup 9) (match_dup 8)]
16053                               UNSPEC_FSCALE_EXP))])
16054    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16055    (set (match_operand:XF 0 "register_operand" "")
16056         (plus:XF (match_dup 12) (match_dup 7)))]
16057   "TARGET_USE_FANCY_MATH_387
16058    && flag_unsafe_math_optimizations"
16059 {
16060   rtx temp;
16061   int i;
16062
16063   for (i=2; i<13; i++)
16064     operands[i] = gen_reg_rtx (XFmode);
16065   temp = standard_80387_constant_rtx (5); /* fldl2e */
16066   emit_move_insn (operands[2], temp);
16067   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16068 })
16069 \f
16070
16071 (define_insn "frndintxf2"
16072   [(set (match_operand:XF 0 "register_operand" "=f")
16073         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16074          UNSPEC_FRNDINT))]
16075   "TARGET_USE_FANCY_MATH_387
16076    && flag_unsafe_math_optimizations"
16077   "frndint"
16078   [(set_attr "type" "fpspc")
16079    (set_attr "mode" "XF")])
16080
16081 (define_expand "rintdf2"
16082   [(use (match_operand:DF 0 "register_operand" ""))
16083    (use (match_operand:DF 1 "register_operand" ""))]
16084   "TARGET_USE_FANCY_MATH_387
16085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16086    && flag_unsafe_math_optimizations"
16087 {
16088   rtx op0 = gen_reg_rtx (XFmode);
16089   rtx op1 = gen_reg_rtx (XFmode);
16090
16091   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16092   emit_insn (gen_frndintxf2 (op0, op1));
16093
16094   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16095   DONE;
16096 })
16097
16098 (define_expand "rintsf2"
16099   [(use (match_operand:SF 0 "register_operand" ""))
16100    (use (match_operand:SF 1 "register_operand" ""))]
16101   "TARGET_USE_FANCY_MATH_387
16102    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16103    && flag_unsafe_math_optimizations"
16104 {
16105   rtx op0 = gen_reg_rtx (XFmode);
16106   rtx op1 = gen_reg_rtx (XFmode);
16107
16108   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16109   emit_insn (gen_frndintxf2 (op0, op1));
16110
16111   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16112   DONE;
16113 })
16114
16115 (define_expand "rintxf2"
16116   [(use (match_operand:XF 0 "register_operand" ""))
16117    (use (match_operand:XF 1 "register_operand" ""))]
16118   "TARGET_USE_FANCY_MATH_387
16119    && flag_unsafe_math_optimizations"
16120 {
16121   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16122   DONE;
16123 })
16124
16125 (define_insn "frndintxf2_floor"
16126   [(set (match_operand:XF 0 "register_operand" "=f")
16127         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16128          UNSPEC_FRNDINT_FLOOR))
16129    (use (match_operand:HI 2 "memory_operand" "m"))
16130    (use (match_operand:HI 3 "memory_operand" "m"))]
16131   "TARGET_USE_FANCY_MATH_387
16132    && flag_unsafe_math_optimizations"
16133   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16134   [(set_attr "type" "frndint")
16135    (set_attr "i387_cw" "floor")
16136    (set_attr "mode" "XF")])
16137
16138 (define_expand "floordf2"
16139   [(use (match_operand:DF 0 "register_operand" ""))
16140    (use (match_operand:DF 1 "register_operand" ""))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16143    && flag_unsafe_math_optimizations"
16144 {
16145   rtx op0 = gen_reg_rtx (XFmode);
16146   rtx op1 = gen_reg_rtx (XFmode);
16147   rtx op2 = assign_386_stack_local (HImode, 1);
16148   rtx op3 = assign_386_stack_local (HImode, 2);
16149         
16150   ix86_optimize_mode_switching = 1;
16151
16152   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16153   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16154
16155   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16156   DONE;
16157 })
16158
16159 (define_expand "floorsf2"
16160   [(use (match_operand:SF 0 "register_operand" ""))
16161    (use (match_operand:SF 1 "register_operand" ""))]
16162   "TARGET_USE_FANCY_MATH_387
16163    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16164    && flag_unsafe_math_optimizations"
16165 {
16166   rtx op0 = gen_reg_rtx (XFmode);
16167   rtx op1 = gen_reg_rtx (XFmode);
16168   rtx op2 = assign_386_stack_local (HImode, 1);
16169   rtx op3 = assign_386_stack_local (HImode, 2);
16170         
16171   ix86_optimize_mode_switching = 1;
16172
16173   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16174   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16175
16176   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16177   DONE;
16178 })
16179
16180 (define_expand "floorxf2"
16181   [(use (match_operand:XF 0 "register_operand" ""))
16182    (use (match_operand:XF 1 "register_operand" ""))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16185 {
16186   rtx op2 = assign_386_stack_local (HImode, 1);
16187   rtx op3 = assign_386_stack_local (HImode, 2);
16188         
16189   ix86_optimize_mode_switching = 1;
16190
16191   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16192   DONE;
16193 })
16194
16195 (define_insn "frndintxf2_ceil"
16196   [(set (match_operand:XF 0 "register_operand" "=f")
16197         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16198          UNSPEC_FRNDINT_CEIL))
16199    (use (match_operand:HI 2 "memory_operand" "m"))
16200    (use (match_operand:HI 3 "memory_operand" "m"))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && flag_unsafe_math_optimizations"
16203   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16204   [(set_attr "type" "frndint")
16205    (set_attr "i387_cw" "ceil")
16206    (set_attr "mode" "XF")])
16207
16208 (define_expand "ceildf2"
16209   [(use (match_operand:DF 0 "register_operand" ""))
16210    (use (match_operand:DF 1 "register_operand" ""))]
16211   "TARGET_USE_FANCY_MATH_387
16212    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16213    && flag_unsafe_math_optimizations"
16214 {
16215   rtx op0 = gen_reg_rtx (XFmode);
16216   rtx op1 = gen_reg_rtx (XFmode);
16217   rtx op2 = assign_386_stack_local (HImode, 1);
16218   rtx op3 = assign_386_stack_local (HImode, 2);
16219         
16220   ix86_optimize_mode_switching = 1;
16221
16222   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16223   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16224
16225   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16226   DONE;
16227 })
16228
16229 (define_expand "ceilsf2"
16230   [(use (match_operand:SF 0 "register_operand" ""))
16231    (use (match_operand:SF 1 "register_operand" ""))]
16232   "TARGET_USE_FANCY_MATH_387
16233    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16234    && flag_unsafe_math_optimizations"
16235 {
16236   rtx op0 = gen_reg_rtx (XFmode);
16237   rtx op1 = gen_reg_rtx (XFmode);
16238   rtx op2 = assign_386_stack_local (HImode, 1);
16239   rtx op3 = assign_386_stack_local (HImode, 2);
16240         
16241   ix86_optimize_mode_switching = 1;
16242
16243   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16244   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16245
16246   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16247   DONE;
16248 })
16249
16250 (define_expand "ceilxf2"
16251   [(use (match_operand:XF 0 "register_operand" ""))
16252    (use (match_operand:XF 1 "register_operand" ""))]
16253   "TARGET_USE_FANCY_MATH_387
16254    && flag_unsafe_math_optimizations"
16255 {
16256   rtx op2 = assign_386_stack_local (HImode, 1);
16257   rtx op3 = assign_386_stack_local (HImode, 2);
16258         
16259   ix86_optimize_mode_switching = 1;
16260
16261   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16262   DONE;
16263 })
16264
16265 (define_insn "frndintxf2_trunc"
16266   [(set (match_operand:XF 0 "register_operand" "=f")
16267         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16268          UNSPEC_FRNDINT_TRUNC))
16269    (use (match_operand:HI 2 "memory_operand" "m"))
16270    (use (match_operand:HI 3 "memory_operand" "m"))]
16271   "TARGET_USE_FANCY_MATH_387
16272    && flag_unsafe_math_optimizations"
16273   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16274   [(set_attr "type" "frndint")
16275    (set_attr "i387_cw" "trunc")
16276    (set_attr "mode" "XF")])
16277
16278 (define_expand "btruncdf2"
16279   [(use (match_operand:DF 0 "register_operand" ""))
16280    (use (match_operand:DF 1 "register_operand" ""))]
16281   "TARGET_USE_FANCY_MATH_387
16282    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16283    && flag_unsafe_math_optimizations"
16284 {
16285   rtx op0 = gen_reg_rtx (XFmode);
16286   rtx op1 = gen_reg_rtx (XFmode);
16287   rtx op2 = assign_386_stack_local (HImode, 1);
16288   rtx op3 = assign_386_stack_local (HImode, 2);
16289         
16290   ix86_optimize_mode_switching = 1;
16291
16292   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16293   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16294
16295   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16296   DONE;
16297 })
16298
16299 (define_expand "btruncsf2"
16300   [(use (match_operand:SF 0 "register_operand" ""))
16301    (use (match_operand:SF 1 "register_operand" ""))]
16302   "TARGET_USE_FANCY_MATH_387
16303    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16304    && flag_unsafe_math_optimizations"
16305 {
16306   rtx op0 = gen_reg_rtx (XFmode);
16307   rtx op1 = gen_reg_rtx (XFmode);
16308   rtx op2 = assign_386_stack_local (HImode, 1);
16309   rtx op3 = assign_386_stack_local (HImode, 2);
16310         
16311   ix86_optimize_mode_switching = 1;
16312
16313   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16314   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16315
16316   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16317   DONE;
16318 })
16319
16320 (define_expand "btruncxf2"
16321   [(use (match_operand:XF 0 "register_operand" ""))
16322    (use (match_operand:XF 1 "register_operand" ""))]
16323   "TARGET_USE_FANCY_MATH_387
16324    && flag_unsafe_math_optimizations"
16325 {
16326   rtx op2 = assign_386_stack_local (HImode, 1);
16327   rtx op3 = assign_386_stack_local (HImode, 2);
16328         
16329   ix86_optimize_mode_switching = 1;
16330
16331   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16332   DONE;
16333 })
16334
16335 (define_insn "frndintxf2_mask_pm"
16336   [(set (match_operand:XF 0 "register_operand" "=f")
16337         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16338          UNSPEC_FRNDINT_MASK_PM))
16339    (use (match_operand:HI 2 "memory_operand" "m"))
16340    (use (match_operand:HI 3 "memory_operand" "m"))]
16341   "TARGET_USE_FANCY_MATH_387
16342    && flag_unsafe_math_optimizations"
16343   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16344   [(set_attr "type" "frndint")
16345    (set_attr "i387_cw" "mask_pm")
16346    (set_attr "mode" "XF")])
16347
16348 (define_expand "nearbyintdf2"
16349   [(use (match_operand:DF 0 "register_operand" ""))
16350    (use (match_operand:DF 1 "register_operand" ""))]
16351   "TARGET_USE_FANCY_MATH_387
16352    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16353    && flag_unsafe_math_optimizations"
16354 {
16355   rtx op0 = gen_reg_rtx (XFmode);
16356   rtx op1 = gen_reg_rtx (XFmode);
16357   rtx op2 = assign_386_stack_local (HImode, 1);
16358   rtx op3 = assign_386_stack_local (HImode, 2);
16359         
16360   ix86_optimize_mode_switching = 1;
16361
16362   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16363   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16364
16365   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16366   DONE;
16367 })
16368
16369 (define_expand "nearbyintsf2"
16370   [(use (match_operand:SF 0 "register_operand" ""))
16371    (use (match_operand:SF 1 "register_operand" ""))]
16372   "TARGET_USE_FANCY_MATH_387
16373    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16374    && flag_unsafe_math_optimizations"
16375 {
16376   rtx op0 = gen_reg_rtx (XFmode);
16377   rtx op1 = gen_reg_rtx (XFmode);
16378   rtx op2 = assign_386_stack_local (HImode, 1);
16379   rtx op3 = assign_386_stack_local (HImode, 2);
16380         
16381   ix86_optimize_mode_switching = 1;
16382
16383   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16384   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16385
16386   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16387   DONE;
16388 })
16389
16390 (define_expand "nearbyintxf2"
16391   [(use (match_operand:XF 0 "register_operand" ""))
16392    (use (match_operand:XF 1 "register_operand" ""))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && flag_unsafe_math_optimizations"
16395 {
16396   rtx op2 = assign_386_stack_local (HImode, 1);
16397   rtx op3 = assign_386_stack_local (HImode, 2);
16398         
16399   ix86_optimize_mode_switching = 1;
16400
16401   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16402                                      op2, op3));
16403   DONE;
16404 })
16405
16406 \f
16407 ;; Block operation instructions
16408
16409 (define_insn "cld"
16410  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16411  ""
16412  "cld"
16413   [(set_attr "type" "cld")])
16414
16415 (define_expand "movmemsi"
16416   [(use (match_operand:BLK 0 "memory_operand" ""))
16417    (use (match_operand:BLK 1 "memory_operand" ""))
16418    (use (match_operand:SI 2 "nonmemory_operand" ""))
16419    (use (match_operand:SI 3 "const_int_operand" ""))]
16420   "! optimize_size"
16421 {
16422  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16423    DONE;
16424  else
16425    FAIL;
16426 })
16427
16428 (define_expand "movmemdi"
16429   [(use (match_operand:BLK 0 "memory_operand" ""))
16430    (use (match_operand:BLK 1 "memory_operand" ""))
16431    (use (match_operand:DI 2 "nonmemory_operand" ""))
16432    (use (match_operand:DI 3 "const_int_operand" ""))]
16433   "TARGET_64BIT"
16434 {
16435  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16436    DONE;
16437  else
16438    FAIL;
16439 })
16440
16441 ;; Most CPUs don't like single string operations
16442 ;; Handle this case here to simplify previous expander.
16443
16444 (define_expand "strmov"
16445   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16446    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16447    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16448               (clobber (reg:CC FLAGS_REG))])
16449    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16450               (clobber (reg:CC FLAGS_REG))])]
16451   ""
16452 {
16453   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16454
16455   /* If .md ever supports :P for Pmode, these can be directly
16456      in the pattern above.  */
16457   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16458   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16459
16460   if (TARGET_SINGLE_STRINGOP || optimize_size)
16461     {
16462       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16463                                       operands[2], operands[3],
16464                                       operands[5], operands[6]));
16465       DONE;
16466     }
16467
16468   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16469 })
16470
16471 (define_expand "strmov_singleop"
16472   [(parallel [(set (match_operand 1 "memory_operand" "")
16473                    (match_operand 3 "memory_operand" ""))
16474               (set (match_operand 0 "register_operand" "")
16475                    (match_operand 4 "" ""))
16476               (set (match_operand 2 "register_operand" "")
16477                    (match_operand 5 "" ""))
16478               (use (reg:SI DIRFLAG_REG))])]
16479   "TARGET_SINGLE_STRINGOP || optimize_size"
16480   "")
16481
16482 (define_insn "*strmovdi_rex_1"
16483   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16484         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16485    (set (match_operand:DI 0 "register_operand" "=D")
16486         (plus:DI (match_dup 2)
16487                  (const_int 8)))
16488    (set (match_operand:DI 1 "register_operand" "=S")
16489         (plus:DI (match_dup 3)
16490                  (const_int 8)))
16491    (use (reg:SI DIRFLAG_REG))]
16492   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16493   "movsq"
16494   [(set_attr "type" "str")
16495    (set_attr "mode" "DI")
16496    (set_attr "memory" "both")])
16497
16498 (define_insn "*strmovsi_1"
16499   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16500         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16501    (set (match_operand:SI 0 "register_operand" "=D")
16502         (plus:SI (match_dup 2)
16503                  (const_int 4)))
16504    (set (match_operand:SI 1 "register_operand" "=S")
16505         (plus:SI (match_dup 3)
16506                  (const_int 4)))
16507    (use (reg:SI DIRFLAG_REG))]
16508   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16509   "{movsl|movsd}"
16510   [(set_attr "type" "str")
16511    (set_attr "mode" "SI")
16512    (set_attr "memory" "both")])
16513
16514 (define_insn "*strmovsi_rex_1"
16515   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16516         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16517    (set (match_operand:DI 0 "register_operand" "=D")
16518         (plus:DI (match_dup 2)
16519                  (const_int 4)))
16520    (set (match_operand:DI 1 "register_operand" "=S")
16521         (plus:DI (match_dup 3)
16522                  (const_int 4)))
16523    (use (reg:SI DIRFLAG_REG))]
16524   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16525   "{movsl|movsd}"
16526   [(set_attr "type" "str")
16527    (set_attr "mode" "SI")
16528    (set_attr "memory" "both")])
16529
16530 (define_insn "*strmovhi_1"
16531   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16532         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16533    (set (match_operand:SI 0 "register_operand" "=D")
16534         (plus:SI (match_dup 2)
16535                  (const_int 2)))
16536    (set (match_operand:SI 1 "register_operand" "=S")
16537         (plus:SI (match_dup 3)
16538                  (const_int 2)))
16539    (use (reg:SI DIRFLAG_REG))]
16540   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16541   "movsw"
16542   [(set_attr "type" "str")
16543    (set_attr "memory" "both")
16544    (set_attr "mode" "HI")])
16545
16546 (define_insn "*strmovhi_rex_1"
16547   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16548         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16549    (set (match_operand:DI 0 "register_operand" "=D")
16550         (plus:DI (match_dup 2)
16551                  (const_int 2)))
16552    (set (match_operand:DI 1 "register_operand" "=S")
16553         (plus:DI (match_dup 3)
16554                  (const_int 2)))
16555    (use (reg:SI DIRFLAG_REG))]
16556   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16557   "movsw"
16558   [(set_attr "type" "str")
16559    (set_attr "memory" "both")
16560    (set_attr "mode" "HI")])
16561
16562 (define_insn "*strmovqi_1"
16563   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16564         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16565    (set (match_operand:SI 0 "register_operand" "=D")
16566         (plus:SI (match_dup 2)
16567                  (const_int 1)))
16568    (set (match_operand:SI 1 "register_operand" "=S")
16569         (plus:SI (match_dup 3)
16570                  (const_int 1)))
16571    (use (reg:SI DIRFLAG_REG))]
16572   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16573   "movsb"
16574   [(set_attr "type" "str")
16575    (set_attr "memory" "both")
16576    (set_attr "mode" "QI")])
16577
16578 (define_insn "*strmovqi_rex_1"
16579   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16580         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16581    (set (match_operand:DI 0 "register_operand" "=D")
16582         (plus:DI (match_dup 2)
16583                  (const_int 1)))
16584    (set (match_operand:DI 1 "register_operand" "=S")
16585         (plus:DI (match_dup 3)
16586                  (const_int 1)))
16587    (use (reg:SI DIRFLAG_REG))]
16588   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16589   "movsb"
16590   [(set_attr "type" "str")
16591    (set_attr "memory" "both")
16592    (set_attr "mode" "QI")])
16593
16594 (define_expand "rep_mov"
16595   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16596               (set (match_operand 0 "register_operand" "")
16597                    (match_operand 5 "" ""))
16598               (set (match_operand 2 "register_operand" "")
16599                    (match_operand 6 "" ""))
16600               (set (match_operand 1 "memory_operand" "")
16601                    (match_operand 3 "memory_operand" ""))
16602               (use (match_dup 4))
16603               (use (reg:SI DIRFLAG_REG))])]
16604   ""
16605   "")
16606
16607 (define_insn "*rep_movdi_rex64"
16608   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16609    (set (match_operand:DI 0 "register_operand" "=D") 
16610         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16611                             (const_int 3))
16612                  (match_operand:DI 3 "register_operand" "0")))
16613    (set (match_operand:DI 1 "register_operand" "=S") 
16614         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16615                  (match_operand:DI 4 "register_operand" "1")))
16616    (set (mem:BLK (match_dup 3))
16617         (mem:BLK (match_dup 4)))
16618    (use (match_dup 5))
16619    (use (reg:SI DIRFLAG_REG))]
16620   "TARGET_64BIT"
16621   "{rep\;movsq|rep movsq}"
16622   [(set_attr "type" "str")
16623    (set_attr "prefix_rep" "1")
16624    (set_attr "memory" "both")
16625    (set_attr "mode" "DI")])
16626
16627 (define_insn "*rep_movsi"
16628   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16629    (set (match_operand:SI 0 "register_operand" "=D") 
16630         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16631                             (const_int 2))
16632                  (match_operand:SI 3 "register_operand" "0")))
16633    (set (match_operand:SI 1 "register_operand" "=S") 
16634         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16635                  (match_operand:SI 4 "register_operand" "1")))
16636    (set (mem:BLK (match_dup 3))
16637         (mem:BLK (match_dup 4)))
16638    (use (match_dup 5))
16639    (use (reg:SI DIRFLAG_REG))]
16640   "!TARGET_64BIT"
16641   "{rep\;movsl|rep movsd}"
16642   [(set_attr "type" "str")
16643    (set_attr "prefix_rep" "1")
16644    (set_attr "memory" "both")
16645    (set_attr "mode" "SI")])
16646
16647 (define_insn "*rep_movsi_rex64"
16648   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16649    (set (match_operand:DI 0 "register_operand" "=D") 
16650         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16651                             (const_int 2))
16652                  (match_operand:DI 3 "register_operand" "0")))
16653    (set (match_operand:DI 1 "register_operand" "=S") 
16654         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16655                  (match_operand:DI 4 "register_operand" "1")))
16656    (set (mem:BLK (match_dup 3))
16657         (mem:BLK (match_dup 4)))
16658    (use (match_dup 5))
16659    (use (reg:SI DIRFLAG_REG))]
16660   "TARGET_64BIT"
16661   "{rep\;movsl|rep movsd}"
16662   [(set_attr "type" "str")
16663    (set_attr "prefix_rep" "1")
16664    (set_attr "memory" "both")
16665    (set_attr "mode" "SI")])
16666
16667 (define_insn "*rep_movqi"
16668   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16669    (set (match_operand:SI 0 "register_operand" "=D") 
16670         (plus:SI (match_operand:SI 3 "register_operand" "0")
16671                  (match_operand:SI 5 "register_operand" "2")))
16672    (set (match_operand:SI 1 "register_operand" "=S") 
16673         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16674    (set (mem:BLK (match_dup 3))
16675         (mem:BLK (match_dup 4)))
16676    (use (match_dup 5))
16677    (use (reg:SI DIRFLAG_REG))]
16678   "!TARGET_64BIT"
16679   "{rep\;movsb|rep movsb}"
16680   [(set_attr "type" "str")
16681    (set_attr "prefix_rep" "1")
16682    (set_attr "memory" "both")
16683    (set_attr "mode" "SI")])
16684
16685 (define_insn "*rep_movqi_rex64"
16686   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16687    (set (match_operand:DI 0 "register_operand" "=D") 
16688         (plus:DI (match_operand:DI 3 "register_operand" "0")
16689                  (match_operand:DI 5 "register_operand" "2")))
16690    (set (match_operand:DI 1 "register_operand" "=S") 
16691         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16692    (set (mem:BLK (match_dup 3))
16693         (mem:BLK (match_dup 4)))
16694    (use (match_dup 5))
16695    (use (reg:SI DIRFLAG_REG))]
16696   "TARGET_64BIT"
16697   "{rep\;movsb|rep movsb}"
16698   [(set_attr "type" "str")
16699    (set_attr "prefix_rep" "1")
16700    (set_attr "memory" "both")
16701    (set_attr "mode" "SI")])
16702
16703 (define_expand "clrmemsi"
16704    [(use (match_operand:BLK 0 "memory_operand" ""))
16705     (use (match_operand:SI 1 "nonmemory_operand" ""))
16706     (use (match_operand 2 "const_int_operand" ""))]
16707   ""
16708 {
16709  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16710    DONE;
16711  else
16712    FAIL;
16713 })
16714
16715 (define_expand "clrmemdi"
16716    [(use (match_operand:BLK 0 "memory_operand" ""))
16717     (use (match_operand:DI 1 "nonmemory_operand" ""))
16718     (use (match_operand 2 "const_int_operand" ""))]
16719   "TARGET_64BIT"
16720 {
16721  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16722    DONE;
16723  else
16724    FAIL;
16725 })
16726
16727 ;; Most CPUs don't like single string operations
16728 ;; Handle this case here to simplify previous expander.
16729
16730 (define_expand "strset"
16731   [(set (match_operand 1 "memory_operand" "")
16732         (match_operand 2 "register_operand" ""))
16733    (parallel [(set (match_operand 0 "register_operand" "")
16734                    (match_dup 3))
16735               (clobber (reg:CC FLAGS_REG))])]
16736   ""
16737 {
16738   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16739     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16740
16741   /* If .md ever supports :P for Pmode, this can be directly
16742      in the pattern above.  */
16743   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16744                               GEN_INT (GET_MODE_SIZE (GET_MODE
16745                                                       (operands[2]))));
16746   if (TARGET_SINGLE_STRINGOP || optimize_size)
16747     {
16748       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16749                                       operands[3]));
16750       DONE;
16751     }
16752 })
16753
16754 (define_expand "strset_singleop"
16755   [(parallel [(set (match_operand 1 "memory_operand" "")
16756                    (match_operand 2 "register_operand" ""))
16757               (set (match_operand 0 "register_operand" "")
16758                    (match_operand 3 "" ""))
16759               (use (reg:SI DIRFLAG_REG))])]
16760   "TARGET_SINGLE_STRINGOP || optimize_size"
16761   "")
16762
16763 (define_insn "*strsetdi_rex_1"
16764   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16765         (match_operand:DI 2 "register_operand" "a"))
16766    (set (match_operand:DI 0 "register_operand" "=D")
16767         (plus:DI (match_dup 1)
16768                  (const_int 8)))
16769    (use (reg:SI DIRFLAG_REG))]
16770   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16771   "stosq"
16772   [(set_attr "type" "str")
16773    (set_attr "memory" "store")
16774    (set_attr "mode" "DI")])
16775
16776 (define_insn "*strsetsi_1"
16777   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16778         (match_operand:SI 2 "register_operand" "a"))
16779    (set (match_operand:SI 0 "register_operand" "=D")
16780         (plus:SI (match_dup 1)
16781                  (const_int 4)))
16782    (use (reg:SI DIRFLAG_REG))]
16783   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16784   "{stosl|stosd}"
16785   [(set_attr "type" "str")
16786    (set_attr "memory" "store")
16787    (set_attr "mode" "SI")])
16788
16789 (define_insn "*strsetsi_rex_1"
16790   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16791         (match_operand:SI 2 "register_operand" "a"))
16792    (set (match_operand:DI 0 "register_operand" "=D")
16793         (plus:DI (match_dup 1)
16794                  (const_int 4)))
16795    (use (reg:SI DIRFLAG_REG))]
16796   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16797   "{stosl|stosd}"
16798   [(set_attr "type" "str")
16799    (set_attr "memory" "store")
16800    (set_attr "mode" "SI")])
16801
16802 (define_insn "*strsethi_1"
16803   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16804         (match_operand:HI 2 "register_operand" "a"))
16805    (set (match_operand:SI 0 "register_operand" "=D")
16806         (plus:SI (match_dup 1)
16807                  (const_int 2)))
16808    (use (reg:SI DIRFLAG_REG))]
16809   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16810   "stosw"
16811   [(set_attr "type" "str")
16812    (set_attr "memory" "store")
16813    (set_attr "mode" "HI")])
16814
16815 (define_insn "*strsethi_rex_1"
16816   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16817         (match_operand:HI 2 "register_operand" "a"))
16818    (set (match_operand:DI 0 "register_operand" "=D")
16819         (plus:DI (match_dup 1)
16820                  (const_int 2)))
16821    (use (reg:SI DIRFLAG_REG))]
16822   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16823   "stosw"
16824   [(set_attr "type" "str")
16825    (set_attr "memory" "store")
16826    (set_attr "mode" "HI")])
16827
16828 (define_insn "*strsetqi_1"
16829   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16830         (match_operand:QI 2 "register_operand" "a"))
16831    (set (match_operand:SI 0 "register_operand" "=D")
16832         (plus:SI (match_dup 1)
16833                  (const_int 1)))
16834    (use (reg:SI DIRFLAG_REG))]
16835   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16836   "stosb"
16837   [(set_attr "type" "str")
16838    (set_attr "memory" "store")
16839    (set_attr "mode" "QI")])
16840
16841 (define_insn "*strsetqi_rex_1"
16842   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16843         (match_operand:QI 2 "register_operand" "a"))
16844    (set (match_operand:DI 0 "register_operand" "=D")
16845         (plus:DI (match_dup 1)
16846                  (const_int 1)))
16847    (use (reg:SI DIRFLAG_REG))]
16848   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16849   "stosb"
16850   [(set_attr "type" "str")
16851    (set_attr "memory" "store")
16852    (set_attr "mode" "QI")])
16853
16854 (define_expand "rep_stos"
16855   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16856               (set (match_operand 0 "register_operand" "")
16857                    (match_operand 4 "" ""))
16858               (set (match_operand 2 "memory_operand" "") (const_int 0))
16859               (use (match_operand 3 "register_operand" ""))
16860               (use (match_dup 1))
16861               (use (reg:SI DIRFLAG_REG))])]
16862   ""
16863   "")
16864
16865 (define_insn "*rep_stosdi_rex64"
16866   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16867    (set (match_operand:DI 0 "register_operand" "=D") 
16868         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16869                             (const_int 3))
16870                  (match_operand:DI 3 "register_operand" "0")))
16871    (set (mem:BLK (match_dup 3))
16872         (const_int 0))
16873    (use (match_operand:DI 2 "register_operand" "a"))
16874    (use (match_dup 4))
16875    (use (reg:SI DIRFLAG_REG))]
16876   "TARGET_64BIT"
16877   "{rep\;stosq|rep stosq}"
16878   [(set_attr "type" "str")
16879    (set_attr "prefix_rep" "1")
16880    (set_attr "memory" "store")
16881    (set_attr "mode" "DI")])
16882
16883 (define_insn "*rep_stossi"
16884   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16885    (set (match_operand:SI 0 "register_operand" "=D") 
16886         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16887                             (const_int 2))
16888                  (match_operand:SI 3 "register_operand" "0")))
16889    (set (mem:BLK (match_dup 3))
16890         (const_int 0))
16891    (use (match_operand:SI 2 "register_operand" "a"))
16892    (use (match_dup 4))
16893    (use (reg:SI DIRFLAG_REG))]
16894   "!TARGET_64BIT"
16895   "{rep\;stosl|rep stosd}"
16896   [(set_attr "type" "str")
16897    (set_attr "prefix_rep" "1")
16898    (set_attr "memory" "store")
16899    (set_attr "mode" "SI")])
16900
16901 (define_insn "*rep_stossi_rex64"
16902   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16903    (set (match_operand:DI 0 "register_operand" "=D") 
16904         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16905                             (const_int 2))
16906                  (match_operand:DI 3 "register_operand" "0")))
16907    (set (mem:BLK (match_dup 3))
16908         (const_int 0))
16909    (use (match_operand:SI 2 "register_operand" "a"))
16910    (use (match_dup 4))
16911    (use (reg:SI DIRFLAG_REG))]
16912   "TARGET_64BIT"
16913   "{rep\;stosl|rep stosd}"
16914   [(set_attr "type" "str")
16915    (set_attr "prefix_rep" "1")
16916    (set_attr "memory" "store")
16917    (set_attr "mode" "SI")])
16918
16919 (define_insn "*rep_stosqi"
16920   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16921    (set (match_operand:SI 0 "register_operand" "=D") 
16922         (plus:SI (match_operand:SI 3 "register_operand" "0")
16923                  (match_operand:SI 4 "register_operand" "1")))
16924    (set (mem:BLK (match_dup 3))
16925         (const_int 0))
16926    (use (match_operand:QI 2 "register_operand" "a"))
16927    (use (match_dup 4))
16928    (use (reg:SI DIRFLAG_REG))]
16929   "!TARGET_64BIT"
16930   "{rep\;stosb|rep stosb}"
16931   [(set_attr "type" "str")
16932    (set_attr "prefix_rep" "1")
16933    (set_attr "memory" "store")
16934    (set_attr "mode" "QI")])
16935
16936 (define_insn "*rep_stosqi_rex64"
16937   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16938    (set (match_operand:DI 0 "register_operand" "=D") 
16939         (plus:DI (match_operand:DI 3 "register_operand" "0")
16940                  (match_operand:DI 4 "register_operand" "1")))
16941    (set (mem:BLK (match_dup 3))
16942         (const_int 0))
16943    (use (match_operand:QI 2 "register_operand" "a"))
16944    (use (match_dup 4))
16945    (use (reg:SI DIRFLAG_REG))]
16946   "TARGET_64BIT"
16947   "{rep\;stosb|rep stosb}"
16948   [(set_attr "type" "str")
16949    (set_attr "prefix_rep" "1")
16950    (set_attr "memory" "store")
16951    (set_attr "mode" "QI")])
16952
16953 (define_expand "cmpstrsi"
16954   [(set (match_operand:SI 0 "register_operand" "")
16955         (compare:SI (match_operand:BLK 1 "general_operand" "")
16956                     (match_operand:BLK 2 "general_operand" "")))
16957    (use (match_operand 3 "general_operand" ""))
16958    (use (match_operand 4 "immediate_operand" ""))]
16959   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16960 {
16961   rtx addr1, addr2, out, outlow, count, countreg, align;
16962
16963   /* Can't use this if the user has appropriated esi or edi.  */
16964   if (global_regs[4] || global_regs[5])
16965     FAIL;
16966
16967   out = operands[0];
16968   if (GET_CODE (out) != REG)
16969     out = gen_reg_rtx (SImode);
16970
16971   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16972   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16973   if (addr1 != XEXP (operands[1], 0))
16974     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16975   if (addr2 != XEXP (operands[2], 0))
16976     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16977
16978   count = operands[3];
16979   countreg = ix86_zero_extend_to_Pmode (count);
16980
16981   /* %%% Iff we are testing strict equality, we can use known alignment
16982      to good advantage.  This may be possible with combine, particularly
16983      once cc0 is dead.  */
16984   align = operands[4];
16985
16986   emit_insn (gen_cld ());
16987   if (GET_CODE (count) == CONST_INT)
16988     {
16989       if (INTVAL (count) == 0)
16990         {
16991           emit_move_insn (operands[0], const0_rtx);
16992           DONE;
16993         }
16994       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16995                                     operands[1], operands[2]));
16996     }
16997   else
16998     {
16999       if (TARGET_64BIT)
17000         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17001       else
17002         emit_insn (gen_cmpsi_1 (countreg, countreg));
17003       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17004                                  operands[1], operands[2]));
17005     }
17006
17007   outlow = gen_lowpart (QImode, out);
17008   emit_insn (gen_cmpintqi (outlow));
17009   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17010
17011   if (operands[0] != out)
17012     emit_move_insn (operands[0], out);
17013
17014   DONE;
17015 })
17016
17017 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17018
17019 (define_expand "cmpintqi"
17020   [(set (match_dup 1)
17021         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17022    (set (match_dup 2)
17023         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17024    (parallel [(set (match_operand:QI 0 "register_operand" "")
17025                    (minus:QI (match_dup 1)
17026                              (match_dup 2)))
17027               (clobber (reg:CC FLAGS_REG))])]
17028   ""
17029   "operands[1] = gen_reg_rtx (QImode);
17030    operands[2] = gen_reg_rtx (QImode);")
17031
17032 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17033 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17034
17035 (define_expand "cmpstrqi_nz_1"
17036   [(parallel [(set (reg:CC FLAGS_REG)
17037                    (compare:CC (match_operand 4 "memory_operand" "")
17038                                (match_operand 5 "memory_operand" "")))
17039               (use (match_operand 2 "register_operand" ""))
17040               (use (match_operand:SI 3 "immediate_operand" ""))
17041               (use (reg:SI DIRFLAG_REG))
17042               (clobber (match_operand 0 "register_operand" ""))
17043               (clobber (match_operand 1 "register_operand" ""))
17044               (clobber (match_dup 2))])]
17045   ""
17046   "")
17047
17048 (define_insn "*cmpstrqi_nz_1"
17049   [(set (reg:CC FLAGS_REG)
17050         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17051                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17052    (use (match_operand:SI 6 "register_operand" "2"))
17053    (use (match_operand:SI 3 "immediate_operand" "i"))
17054    (use (reg:SI DIRFLAG_REG))
17055    (clobber (match_operand:SI 0 "register_operand" "=S"))
17056    (clobber (match_operand:SI 1 "register_operand" "=D"))
17057    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17058   "!TARGET_64BIT"
17059   "repz{\;| }cmpsb"
17060   [(set_attr "type" "str")
17061    (set_attr "mode" "QI")
17062    (set_attr "prefix_rep" "1")])
17063
17064 (define_insn "*cmpstrqi_nz_rex_1"
17065   [(set (reg:CC FLAGS_REG)
17066         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17067                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17068    (use (match_operand:DI 6 "register_operand" "2"))
17069    (use (match_operand:SI 3 "immediate_operand" "i"))
17070    (use (reg:SI DIRFLAG_REG))
17071    (clobber (match_operand:DI 0 "register_operand" "=S"))
17072    (clobber (match_operand:DI 1 "register_operand" "=D"))
17073    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17074   "TARGET_64BIT"
17075   "repz{\;| }cmpsb"
17076   [(set_attr "type" "str")
17077    (set_attr "mode" "QI")
17078    (set_attr "prefix_rep" "1")])
17079
17080 ;; The same, but the count is not known to not be zero.
17081
17082 (define_expand "cmpstrqi_1"
17083   [(parallel [(set (reg:CC FLAGS_REG)
17084                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17085                                      (const_int 0))
17086                   (compare:CC (match_operand 4 "memory_operand" "")
17087                               (match_operand 5 "memory_operand" ""))
17088                   (const_int 0)))
17089               (use (match_operand:SI 3 "immediate_operand" ""))
17090               (use (reg:CC FLAGS_REG))
17091               (use (reg:SI DIRFLAG_REG))
17092               (clobber (match_operand 0 "register_operand" ""))
17093               (clobber (match_operand 1 "register_operand" ""))
17094               (clobber (match_dup 2))])]
17095   ""
17096   "")
17097
17098 (define_insn "*cmpstrqi_1"
17099   [(set (reg:CC FLAGS_REG)
17100         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17101                              (const_int 0))
17102           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17103                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17104           (const_int 0)))
17105    (use (match_operand:SI 3 "immediate_operand" "i"))
17106    (use (reg:CC FLAGS_REG))
17107    (use (reg:SI DIRFLAG_REG))
17108    (clobber (match_operand:SI 0 "register_operand" "=S"))
17109    (clobber (match_operand:SI 1 "register_operand" "=D"))
17110    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17111   "!TARGET_64BIT"
17112   "repz{\;| }cmpsb"
17113   [(set_attr "type" "str")
17114    (set_attr "mode" "QI")
17115    (set_attr "prefix_rep" "1")])
17116
17117 (define_insn "*cmpstrqi_rex_1"
17118   [(set (reg:CC FLAGS_REG)
17119         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17120                              (const_int 0))
17121           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17122                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17123           (const_int 0)))
17124    (use (match_operand:SI 3 "immediate_operand" "i"))
17125    (use (reg:CC FLAGS_REG))
17126    (use (reg:SI DIRFLAG_REG))
17127    (clobber (match_operand:DI 0 "register_operand" "=S"))
17128    (clobber (match_operand:DI 1 "register_operand" "=D"))
17129    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17130   "TARGET_64BIT"
17131   "repz{\;| }cmpsb"
17132   [(set_attr "type" "str")
17133    (set_attr "mode" "QI")
17134    (set_attr "prefix_rep" "1")])
17135
17136 (define_expand "strlensi"
17137   [(set (match_operand:SI 0 "register_operand" "")
17138         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17139                     (match_operand:QI 2 "immediate_operand" "")
17140                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17141   ""
17142 {
17143  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17144    DONE;
17145  else
17146    FAIL;
17147 })
17148
17149 (define_expand "strlendi"
17150   [(set (match_operand:DI 0 "register_operand" "")
17151         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17152                     (match_operand:QI 2 "immediate_operand" "")
17153                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17154   ""
17155 {
17156  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17157    DONE;
17158  else
17159    FAIL;
17160 })
17161
17162 (define_expand "strlenqi_1"
17163   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17164               (use (reg:SI DIRFLAG_REG))
17165               (clobber (match_operand 1 "register_operand" ""))
17166               (clobber (reg:CC FLAGS_REG))])]
17167   ""
17168   "")
17169
17170 (define_insn "*strlenqi_1"
17171   [(set (match_operand:SI 0 "register_operand" "=&c")
17172         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17173                     (match_operand:QI 2 "register_operand" "a")
17174                     (match_operand:SI 3 "immediate_operand" "i")
17175                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17176    (use (reg:SI DIRFLAG_REG))
17177    (clobber (match_operand:SI 1 "register_operand" "=D"))
17178    (clobber (reg:CC FLAGS_REG))]
17179   "!TARGET_64BIT"
17180   "repnz{\;| }scasb"
17181   [(set_attr "type" "str")
17182    (set_attr "mode" "QI")
17183    (set_attr "prefix_rep" "1")])
17184
17185 (define_insn "*strlenqi_rex_1"
17186   [(set (match_operand:DI 0 "register_operand" "=&c")
17187         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17188                     (match_operand:QI 2 "register_operand" "a")
17189                     (match_operand:DI 3 "immediate_operand" "i")
17190                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17191    (use (reg:SI DIRFLAG_REG))
17192    (clobber (match_operand:DI 1 "register_operand" "=D"))
17193    (clobber (reg:CC FLAGS_REG))]
17194   "TARGET_64BIT"
17195   "repnz{\;| }scasb"
17196   [(set_attr "type" "str")
17197    (set_attr "mode" "QI")
17198    (set_attr "prefix_rep" "1")])
17199
17200 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17201 ;; handled in combine, but it is not currently up to the task.
17202 ;; When used for their truth value, the cmpstr* expanders generate
17203 ;; code like this:
17204 ;;
17205 ;;   repz cmpsb
17206 ;;   seta       %al
17207 ;;   setb       %dl
17208 ;;   cmpb       %al, %dl
17209 ;;   jcc        label
17210 ;;
17211 ;; The intermediate three instructions are unnecessary.
17212
17213 ;; This one handles cmpstr*_nz_1...
17214 (define_peephole2
17215   [(parallel[
17216      (set (reg:CC FLAGS_REG)
17217           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17218                       (mem:BLK (match_operand 5 "register_operand" ""))))
17219      (use (match_operand 6 "register_operand" ""))
17220      (use (match_operand:SI 3 "immediate_operand" ""))
17221      (use (reg:SI DIRFLAG_REG))
17222      (clobber (match_operand 0 "register_operand" ""))
17223      (clobber (match_operand 1 "register_operand" ""))
17224      (clobber (match_operand 2 "register_operand" ""))])
17225    (set (match_operand:QI 7 "register_operand" "")
17226         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17227    (set (match_operand:QI 8 "register_operand" "")
17228         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17229    (set (reg FLAGS_REG)
17230         (compare (match_dup 7) (match_dup 8)))
17231   ]
17232   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17233   [(parallel[
17234      (set (reg:CC FLAGS_REG)
17235           (compare:CC (mem:BLK (match_dup 4))
17236                       (mem:BLK (match_dup 5))))
17237      (use (match_dup 6))
17238      (use (match_dup 3))
17239      (use (reg:SI DIRFLAG_REG))
17240      (clobber (match_dup 0))
17241      (clobber (match_dup 1))
17242      (clobber (match_dup 2))])]
17243   "")
17244
17245 ;; ...and this one handles cmpstr*_1.
17246 (define_peephole2
17247   [(parallel[
17248      (set (reg:CC FLAGS_REG)
17249           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17250                                (const_int 0))
17251             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17252                         (mem:BLK (match_operand 5 "register_operand" "")))
17253             (const_int 0)))
17254      (use (match_operand:SI 3 "immediate_operand" ""))
17255      (use (reg:CC FLAGS_REG))
17256      (use (reg:SI DIRFLAG_REG))
17257      (clobber (match_operand 0 "register_operand" ""))
17258      (clobber (match_operand 1 "register_operand" ""))
17259      (clobber (match_operand 2 "register_operand" ""))])
17260    (set (match_operand:QI 7 "register_operand" "")
17261         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17262    (set (match_operand:QI 8 "register_operand" "")
17263         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17264    (set (reg FLAGS_REG)
17265         (compare (match_dup 7) (match_dup 8)))
17266   ]
17267   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17268   [(parallel[
17269      (set (reg:CC FLAGS_REG)
17270           (if_then_else:CC (ne (match_dup 6)
17271                                (const_int 0))
17272             (compare:CC (mem:BLK (match_dup 4))
17273                         (mem:BLK (match_dup 5)))
17274             (const_int 0)))
17275      (use (match_dup 3))
17276      (use (reg:CC FLAGS_REG))
17277      (use (reg:SI DIRFLAG_REG))
17278      (clobber (match_dup 0))
17279      (clobber (match_dup 1))
17280      (clobber (match_dup 2))])]
17281   "")
17282
17283
17284 \f
17285 ;; Conditional move instructions.
17286
17287 (define_expand "movdicc"
17288   [(set (match_operand:DI 0 "register_operand" "")
17289         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17290                          (match_operand:DI 2 "general_operand" "")
17291                          (match_operand:DI 3 "general_operand" "")))]
17292   "TARGET_64BIT"
17293   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17294
17295 (define_insn "x86_movdicc_0_m1_rex64"
17296   [(set (match_operand:DI 0 "register_operand" "=r")
17297         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17298           (const_int -1)
17299           (const_int 0)))
17300    (clobber (reg:CC FLAGS_REG))]
17301   "TARGET_64BIT"
17302   "sbb{q}\t%0, %0"
17303   ; Since we don't have the proper number of operands for an alu insn,
17304   ; fill in all the blanks.
17305   [(set_attr "type" "alu")
17306    (set_attr "pent_pair" "pu")
17307    (set_attr "memory" "none")
17308    (set_attr "imm_disp" "false")
17309    (set_attr "mode" "DI")
17310    (set_attr "length_immediate" "0")])
17311
17312 (define_insn "*movdicc_c_rex64"
17313   [(set (match_operand:DI 0 "register_operand" "=r,r")
17314         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17315                                 [(reg FLAGS_REG) (const_int 0)])
17316                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17317                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17318   "TARGET_64BIT && TARGET_CMOVE
17319    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17320   "@
17321    cmov%O2%C1\t{%2, %0|%0, %2}
17322    cmov%O2%c1\t{%3, %0|%0, %3}"
17323   [(set_attr "type" "icmov")
17324    (set_attr "mode" "DI")])
17325
17326 (define_expand "movsicc"
17327   [(set (match_operand:SI 0 "register_operand" "")
17328         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17329                          (match_operand:SI 2 "general_operand" "")
17330                          (match_operand:SI 3 "general_operand" "")))]
17331   ""
17332   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17333
17334 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17335 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17336 ;; So just document what we're doing explicitly.
17337
17338 (define_insn "x86_movsicc_0_m1"
17339   [(set (match_operand:SI 0 "register_operand" "=r")
17340         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17341           (const_int -1)
17342           (const_int 0)))
17343    (clobber (reg:CC FLAGS_REG))]
17344   ""
17345   "sbb{l}\t%0, %0"
17346   ; Since we don't have the proper number of operands for an alu insn,
17347   ; fill in all the blanks.
17348   [(set_attr "type" "alu")
17349    (set_attr "pent_pair" "pu")
17350    (set_attr "memory" "none")
17351    (set_attr "imm_disp" "false")
17352    (set_attr "mode" "SI")
17353    (set_attr "length_immediate" "0")])
17354
17355 (define_insn "*movsicc_noc"
17356   [(set (match_operand:SI 0 "register_operand" "=r,r")
17357         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17358                                 [(reg FLAGS_REG) (const_int 0)])
17359                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17360                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17361   "TARGET_CMOVE
17362    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17363   "@
17364    cmov%O2%C1\t{%2, %0|%0, %2}
17365    cmov%O2%c1\t{%3, %0|%0, %3}"
17366   [(set_attr "type" "icmov")
17367    (set_attr "mode" "SI")])
17368
17369 (define_expand "movhicc"
17370   [(set (match_operand:HI 0 "register_operand" "")
17371         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17372                          (match_operand:HI 2 "general_operand" "")
17373                          (match_operand:HI 3 "general_operand" "")))]
17374   "TARGET_HIMODE_MATH"
17375   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17376
17377 (define_insn "*movhicc_noc"
17378   [(set (match_operand:HI 0 "register_operand" "=r,r")
17379         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17380                                 [(reg FLAGS_REG) (const_int 0)])
17381                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17382                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17383   "TARGET_CMOVE
17384    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17385   "@
17386    cmov%O2%C1\t{%2, %0|%0, %2}
17387    cmov%O2%c1\t{%3, %0|%0, %3}"
17388   [(set_attr "type" "icmov")
17389    (set_attr "mode" "HI")])
17390
17391 (define_expand "movqicc"
17392   [(set (match_operand:QI 0 "register_operand" "")
17393         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17394                          (match_operand:QI 2 "general_operand" "")
17395                          (match_operand:QI 3 "general_operand" "")))]
17396   "TARGET_QIMODE_MATH"
17397   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17398
17399 (define_insn_and_split "*movqicc_noc"
17400   [(set (match_operand:QI 0 "register_operand" "=r,r")
17401         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17402                                 [(match_operand 4 "flags_reg_operand" "")
17403                                  (const_int 0)])
17404                       (match_operand:QI 2 "register_operand" "r,0")
17405                       (match_operand:QI 3 "register_operand" "0,r")))]
17406   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17407   "#"
17408   "&& reload_completed"
17409   [(set (match_dup 0)
17410         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17411                       (match_dup 2)
17412                       (match_dup 3)))]
17413   "operands[0] = gen_lowpart (SImode, operands[0]);
17414    operands[2] = gen_lowpart (SImode, operands[2]);
17415    operands[3] = gen_lowpart (SImode, operands[3]);"
17416   [(set_attr "type" "icmov")
17417    (set_attr "mode" "SI")])
17418
17419 (define_expand "movsfcc"
17420   [(set (match_operand:SF 0 "register_operand" "")
17421         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17422                          (match_operand:SF 2 "register_operand" "")
17423                          (match_operand:SF 3 "register_operand" "")))]
17424   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17425   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17426
17427 ;; These versions of min/max are aware of the instruction's behavior
17428 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17429 ;; should have used the smin/smax expanders in the first place.
17430 (define_insn "*movsfcc_1_sse_min"
17431   [(set (match_operand:SF 0 "register_operand" "=x")
17432         (if_then_else:SF
17433           (lt:SF (match_operand:SF 1 "register_operand" "0")
17434                  (match_operand:SF 2 "nonimmediate_operand" "xm"))
17435           (match_dup 1)
17436           (match_dup 2)))]
17437   "TARGET_SSE_MATH"
17438   "minss\t{%2, %0|%0, %2}"
17439   [(set_attr "type" "sseadd")
17440    (set_attr "mode" "SF")])
17441
17442 (define_insn "*movsfcc_1_sse_max"
17443   [(set (match_operand:SF 0 "register_operand" "=x")
17444         (if_then_else:SF
17445           (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
17446                  (match_operand:SF 1 "nonimmediate_operand" "0"))
17447           (match_dup 1)
17448           (match_dup 2)))]
17449   "TARGET_SSE_MATH"
17450   "maxss\t{%2, %0|%0, %2}"
17451   [(set_attr "type" "sseadd")
17452    (set_attr "mode" "SF")])
17453
17454 (define_insn_and_split "*movsfcc_1_sse"
17455   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
17456         (if_then_else:SF
17457           (match_operator:SF 4 "sse_comparison_operator"
17458             [(match_operand:SF 5 "register_operand" "0,0,0")
17459              (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
17460           (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
17461           (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
17462    (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
17463   "TARGET_SSE_MATH"
17464   "#"
17465   "&& reload_completed"
17466   [(const_int 0)]
17467 {
17468   ix86_split_sse_movcc (operands);
17469   DONE;
17470 })
17471
17472 (define_insn "*movsfcc_1_387"
17473   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17474         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17475                                 [(reg FLAGS_REG) (const_int 0)])
17476                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17477                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17478   "TARGET_80387 && TARGET_CMOVE
17479    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17480   "@
17481    fcmov%F1\t{%2, %0|%0, %2}
17482    fcmov%f1\t{%3, %0|%0, %3}
17483    cmov%O2%C1\t{%2, %0|%0, %2}
17484    cmov%O2%c1\t{%3, %0|%0, %3}"
17485   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17486    (set_attr "mode" "SF,SF,SI,SI")])
17487
17488 (define_expand "movdfcc"
17489   [(set (match_operand:DF 0 "register_operand" "")
17490         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17491                          (match_operand:DF 2 "register_operand" "")
17492                          (match_operand:DF 3 "register_operand" "")))]
17493   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17494   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17495
17496 ;; These versions of min/max are aware of the instruction's behavior
17497 ;; wrt -0.0 and NaN inputs.  If we don't care about either, then we
17498 ;; should have used the smin/smax expanders in the first place.
17499 (define_insn "*movdfcc_1_sse_min"
17500   [(set (match_operand:DF 0 "register_operand" "=x")
17501         (if_then_else:DF
17502           (lt:DF (match_operand:DF 1 "register_operand" "0")
17503                  (match_operand:DF 2 "nonimmediate_operand" "xm"))
17504           (match_dup 1)
17505           (match_dup 2)))]
17506   "TARGET_SSE2 && TARGET_SSE_MATH"
17507   "minsd\t{%2, %0|%0, %2}"
17508   [(set_attr "type" "sseadd")
17509    (set_attr "mode" "DF")])
17510
17511 (define_insn "*movdfcc_1_sse_max"
17512   [(set (match_operand:DF 0 "register_operand" "=x")
17513         (if_then_else:DF
17514           (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
17515                  (match_operand:DF 1 "nonimmediate_operand" "0"))
17516           (match_dup 1)
17517           (match_dup 2)))]
17518   "TARGET_SSE2 && TARGET_SSE_MATH"
17519   "maxsd\t{%2, %0|%0, %2}"
17520   [(set_attr "type" "sseadd")
17521    (set_attr "mode" "DF")])
17522
17523 (define_insn_and_split "*movdfcc_1_sse"
17524   [(set (match_operand:DF 0 "register_operand" "=x,x,x")
17525         (if_then_else:DF
17526           (match_operator:DF 4 "sse_comparison_operator"
17527             [(match_operand:DF 5 "register_operand" "0,0,0")
17528              (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
17529           (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
17530           (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
17531    (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
17532   "TARGET_SSE2 && TARGET_SSE_MATH"
17533   "#"
17534   "&& reload_completed"
17535   [(const_int 0)]
17536 {
17537   ix86_split_sse_movcc (operands);
17538   DONE;
17539 })
17540
17541 (define_insn "*movdfcc_1"
17542   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17543         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17544                                 [(reg FLAGS_REG) (const_int 0)])
17545                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17546                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17547   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17548    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17549   "@
17550    fcmov%F1\t{%2, %0|%0, %2}
17551    fcmov%f1\t{%3, %0|%0, %3}
17552    #
17553    #"
17554   [(set_attr "type" "fcmov,fcmov,multi,multi")
17555    (set_attr "mode" "DF")])
17556
17557 (define_insn "*movdfcc_1_rex64"
17558   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17559         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17560                                 [(reg FLAGS_REG) (const_int 0)])
17561                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17562                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17563   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17564    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17565   "@
17566    fcmov%F1\t{%2, %0|%0, %2}
17567    fcmov%f1\t{%3, %0|%0, %3}
17568    cmov%O2%C1\t{%2, %0|%0, %2}
17569    cmov%O2%c1\t{%3, %0|%0, %3}"
17570   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17571    (set_attr "mode" "DF")])
17572
17573 (define_split
17574   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17575         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17576                                 [(match_operand 4 "flags_reg_operand" "")
17577                                  (const_int 0)])
17578                       (match_operand:DF 2 "nonimmediate_operand" "")
17579                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17580   "!TARGET_64BIT && reload_completed"
17581   [(set (match_dup 2)
17582         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17583                       (match_dup 5)
17584                       (match_dup 7)))
17585    (set (match_dup 3)
17586         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17587                       (match_dup 6)
17588                       (match_dup 8)))]
17589   "split_di (operands+2, 1, operands+5, operands+6);
17590    split_di (operands+3, 1, operands+7, operands+8);
17591    split_di (operands, 1, operands+2, operands+3);")
17592
17593 (define_expand "movxfcc"
17594   [(set (match_operand:XF 0 "register_operand" "")
17595         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17596                          (match_operand:XF 2 "register_operand" "")
17597                          (match_operand:XF 3 "register_operand" "")))]
17598   "TARGET_80387 && TARGET_CMOVE"
17599   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17600
17601 (define_insn "*movxfcc_1"
17602   [(set (match_operand:XF 0 "register_operand" "=f,f")
17603         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17604                                 [(reg FLAGS_REG) (const_int 0)])
17605                       (match_operand:XF 2 "register_operand" "f,0")
17606                       (match_operand:XF 3 "register_operand" "0,f")))]
17607   "TARGET_80387 && TARGET_CMOVE"
17608   "@
17609    fcmov%F1\t{%2, %0|%0, %2}
17610    fcmov%f1\t{%3, %0|%0, %3}"
17611   [(set_attr "type" "fcmov")
17612    (set_attr "mode" "XF")])
17613
17614 ;; These versions of the min/max patterns are intentionally ignorant of
17615 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17616 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17617 ;; are undefined in this condition, we're certain this is correct.
17618
17619 (define_insn "sminsf3"
17620   [(set (match_operand:SF 0 "register_operand" "=x")
17621         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17622                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17623   "TARGET_SSE_MATH"
17624   "minss\t{%2, %0|%0, %2}"
17625   [(set_attr "type" "sseadd")
17626    (set_attr "mode" "SF")])
17627
17628 (define_insn "smaxsf3"
17629   [(set (match_operand:SF 0 "register_operand" "=x")
17630         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
17631                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
17632   "TARGET_SSE_MATH"
17633   "maxss\t{%2, %0|%0, %2}"
17634   [(set_attr "type" "sseadd")
17635    (set_attr "mode" "SF")])
17636
17637 (define_insn "smindf3"
17638   [(set (match_operand:DF 0 "register_operand" "=x")
17639         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17640                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17641   "TARGET_SSE2 && TARGET_SSE_MATH"
17642   "minsd\t{%2, %0|%0, %2}"
17643   [(set_attr "type" "sseadd")
17644    (set_attr "mode" "DF")])
17645
17646 (define_insn "smaxdf3"
17647   [(set (match_operand:DF 0 "register_operand" "=x")
17648         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
17649                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
17650   "TARGET_SSE2 && TARGET_SSE_MATH"
17651   "maxsd\t{%2, %0|%0, %2}"
17652   [(set_attr "type" "sseadd")
17653    (set_attr "mode" "DF")])
17654
17655 ;; Conditional addition patterns
17656 (define_expand "addqicc"
17657   [(match_operand:QI 0 "register_operand" "")
17658    (match_operand 1 "comparison_operator" "")
17659    (match_operand:QI 2 "register_operand" "")
17660    (match_operand:QI 3 "const_int_operand" "")]
17661   ""
17662   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17663
17664 (define_expand "addhicc"
17665   [(match_operand:HI 0 "register_operand" "")
17666    (match_operand 1 "comparison_operator" "")
17667    (match_operand:HI 2 "register_operand" "")
17668    (match_operand:HI 3 "const_int_operand" "")]
17669   ""
17670   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17671
17672 (define_expand "addsicc"
17673   [(match_operand:SI 0 "register_operand" "")
17674    (match_operand 1 "comparison_operator" "")
17675    (match_operand:SI 2 "register_operand" "")
17676    (match_operand:SI 3 "const_int_operand" "")]
17677   ""
17678   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17679
17680 (define_expand "adddicc"
17681   [(match_operand:DI 0 "register_operand" "")
17682    (match_operand 1 "comparison_operator" "")
17683    (match_operand:DI 2 "register_operand" "")
17684    (match_operand:DI 3 "const_int_operand" "")]
17685   "TARGET_64BIT"
17686   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17687
17688 \f
17689 ;; Misc patterns (?)
17690
17691 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17692 ;; Otherwise there will be nothing to keep
17693 ;; 
17694 ;; [(set (reg ebp) (reg esp))]
17695 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17696 ;;  (clobber (eflags)]
17697 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17698 ;;
17699 ;; in proper program order.
17700 (define_insn "pro_epilogue_adjust_stack_1"
17701   [(set (match_operand:SI 0 "register_operand" "=r,r")
17702         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17703                  (match_operand:SI 2 "immediate_operand" "i,i")))
17704    (clobber (reg:CC FLAGS_REG))
17705    (clobber (mem:BLK (scratch)))]
17706   "!TARGET_64BIT"
17707 {
17708   switch (get_attr_type (insn))
17709     {
17710     case TYPE_IMOV:
17711       return "mov{l}\t{%1, %0|%0, %1}";
17712
17713     case TYPE_ALU:
17714       if (GET_CODE (operands[2]) == CONST_INT
17715           && (INTVAL (operands[2]) == 128
17716               || (INTVAL (operands[2]) < 0
17717                   && INTVAL (operands[2]) != -128)))
17718         {
17719           operands[2] = GEN_INT (-INTVAL (operands[2]));
17720           return "sub{l}\t{%2, %0|%0, %2}";
17721         }
17722       return "add{l}\t{%2, %0|%0, %2}";
17723
17724     case TYPE_LEA:
17725       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17726       return "lea{l}\t{%a2, %0|%0, %a2}";
17727
17728     default:
17729       abort ();
17730     }
17731 }
17732   [(set (attr "type")
17733         (cond [(eq_attr "alternative" "0")
17734                  (const_string "alu")
17735                (match_operand:SI 2 "const0_operand" "")
17736                  (const_string "imov")
17737               ]
17738               (const_string "lea")))
17739    (set_attr "mode" "SI")])
17740
17741 (define_insn "pro_epilogue_adjust_stack_rex64"
17742   [(set (match_operand:DI 0 "register_operand" "=r,r")
17743         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17744                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17745    (clobber (reg:CC FLAGS_REG))
17746    (clobber (mem:BLK (scratch)))]
17747   "TARGET_64BIT"
17748 {
17749   switch (get_attr_type (insn))
17750     {
17751     case TYPE_IMOV:
17752       return "mov{q}\t{%1, %0|%0, %1}";
17753
17754     case TYPE_ALU:
17755       if (GET_CODE (operands[2]) == CONST_INT
17756           /* Avoid overflows.  */
17757           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17758           && (INTVAL (operands[2]) == 128
17759               || (INTVAL (operands[2]) < 0
17760                   && INTVAL (operands[2]) != -128)))
17761         {
17762           operands[2] = GEN_INT (-INTVAL (operands[2]));
17763           return "sub{q}\t{%2, %0|%0, %2}";
17764         }
17765       return "add{q}\t{%2, %0|%0, %2}";
17766
17767     case TYPE_LEA:
17768       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17769       return "lea{q}\t{%a2, %0|%0, %a2}";
17770
17771     default:
17772       abort ();
17773     }
17774 }
17775   [(set (attr "type")
17776         (cond [(eq_attr "alternative" "0")
17777                  (const_string "alu")
17778                (match_operand:DI 2 "const0_operand" "")
17779                  (const_string "imov")
17780               ]
17781               (const_string "lea")))
17782    (set_attr "mode" "DI")])
17783
17784 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17785   [(set (match_operand:DI 0 "register_operand" "=r,r")
17786         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17787                  (match_operand:DI 3 "immediate_operand" "i,i")))
17788    (use (match_operand:DI 2 "register_operand" "r,r"))
17789    (clobber (reg:CC FLAGS_REG))
17790    (clobber (mem:BLK (scratch)))]
17791   "TARGET_64BIT"
17792 {
17793   switch (get_attr_type (insn))
17794     {
17795     case TYPE_ALU:
17796       return "add{q}\t{%2, %0|%0, %2}";
17797
17798     case TYPE_LEA:
17799       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17800       return "lea{q}\t{%a2, %0|%0, %a2}";
17801
17802     default:
17803       abort ();
17804     }
17805 }
17806   [(set_attr "type" "alu,lea")
17807    (set_attr "mode" "DI")])
17808
17809 (define_expand "allocate_stack_worker"
17810   [(match_operand:SI 0 "register_operand" "")]
17811   "TARGET_STACK_PROBE"
17812 {
17813   if (reload_completed)
17814     {
17815       if (TARGET_64BIT)
17816         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17817       else
17818         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17819     }
17820   else
17821     {
17822       if (TARGET_64BIT)
17823         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17824       else
17825         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17826     }
17827   DONE;
17828 })
17829
17830 (define_insn "allocate_stack_worker_1"
17831   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17832     UNSPECV_STACK_PROBE)
17833    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17834    (clobber (match_scratch:SI 1 "=0"))
17835    (clobber (reg:CC FLAGS_REG))]
17836   "!TARGET_64BIT && TARGET_STACK_PROBE"
17837   "call\t__alloca"
17838   [(set_attr "type" "multi")
17839    (set_attr "length" "5")])
17840
17841 (define_expand "allocate_stack_worker_postreload"
17842   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17843                                     UNSPECV_STACK_PROBE)
17844               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
17845               (clobber (match_dup 0))
17846               (clobber (reg:CC FLAGS_REG))])]
17847   ""
17848   "")
17849
17850 (define_insn "allocate_stack_worker_rex64"
17851   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17852     UNSPECV_STACK_PROBE)
17853    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17854    (clobber (match_scratch:DI 1 "=0"))
17855    (clobber (reg:CC FLAGS_REG))]
17856   "TARGET_64BIT && TARGET_STACK_PROBE"
17857   "call\t__alloca"
17858   [(set_attr "type" "multi")
17859    (set_attr "length" "5")])
17860
17861 (define_expand "allocate_stack_worker_rex64_postreload"
17862   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17863                                     UNSPECV_STACK_PROBE)
17864               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
17865               (clobber (match_dup 0))
17866               (clobber (reg:CC FLAGS_REG))])]
17867   ""
17868   "")
17869
17870 (define_expand "allocate_stack"
17871   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17872                    (minus:SI (reg:SI SP_REG)
17873                              (match_operand:SI 1 "general_operand" "")))
17874               (clobber (reg:CC FLAGS_REG))])
17875    (parallel [(set (reg:SI SP_REG)
17876                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
17877               (clobber (reg:CC FLAGS_REG))])]
17878   "TARGET_STACK_PROBE"
17879 {
17880 #ifdef CHECK_STACK_LIMIT
17881   if (GET_CODE (operands[1]) == CONST_INT
17882       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17883     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17884                            operands[1]));
17885   else 
17886 #endif
17887     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17888                                                             operands[1])));
17889
17890   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17891   DONE;
17892 })
17893
17894 (define_expand "builtin_setjmp_receiver"
17895   [(label_ref (match_operand 0 "" ""))]
17896   "!TARGET_64BIT && flag_pic"
17897 {
17898   emit_insn (gen_set_got (pic_offset_table_rtx));
17899   DONE;
17900 })
17901 \f
17902 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17903
17904 (define_split
17905   [(set (match_operand 0 "register_operand" "")
17906         (match_operator 3 "promotable_binary_operator"
17907            [(match_operand 1 "register_operand" "")
17908             (match_operand 2 "aligned_operand" "")]))
17909    (clobber (reg:CC FLAGS_REG))]
17910   "! TARGET_PARTIAL_REG_STALL && reload_completed
17911    && ((GET_MODE (operands[0]) == HImode 
17912         && ((!optimize_size && !TARGET_FAST_PREFIX)
17913             || GET_CODE (operands[2]) != CONST_INT
17914             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17915        || (GET_MODE (operands[0]) == QImode 
17916            && (TARGET_PROMOTE_QImode || optimize_size)))"
17917   [(parallel [(set (match_dup 0)
17918                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17919               (clobber (reg:CC FLAGS_REG))])]
17920   "operands[0] = gen_lowpart (SImode, operands[0]);
17921    operands[1] = gen_lowpart (SImode, operands[1]);
17922    if (GET_CODE (operands[3]) != ASHIFT)
17923      operands[2] = gen_lowpart (SImode, operands[2]);
17924    PUT_MODE (operands[3], SImode);")
17925
17926 ; Promote the QImode tests, as i386 has encoding of the AND
17927 ; instruction with 32-bit sign-extended immediate and thus the
17928 ; instruction size is unchanged, except in the %eax case for
17929 ; which it is increased by one byte, hence the ! optimize_size.
17930 (define_split
17931   [(set (match_operand 0 "flags_reg_operand" "")
17932         (match_operator 2 "compare_operator"
17933           [(and (match_operand 3 "aligned_operand" "")
17934                 (match_operand 4 "const_int_operand" ""))
17935            (const_int 0)]))
17936    (set (match_operand 1 "register_operand" "")
17937         (and (match_dup 3) (match_dup 4)))]
17938   "! TARGET_PARTIAL_REG_STALL && reload_completed
17939    /* Ensure that the operand will remain sign-extended immediate.  */
17940    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
17941    && ! optimize_size
17942    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17943        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
17944   [(parallel [(set (match_dup 0)
17945                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17946                                     (const_int 0)]))
17947               (set (match_dup 1)
17948                    (and:SI (match_dup 3) (match_dup 4)))])]
17949 {
17950   operands[4]
17951     = gen_int_mode (INTVAL (operands[4])
17952                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17953   operands[1] = gen_lowpart (SImode, operands[1]);
17954   operands[3] = gen_lowpart (SImode, operands[3]);
17955 })
17956
17957 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17958 ; the TEST instruction with 32-bit sign-extended immediate and thus
17959 ; the instruction size would at least double, which is not what we
17960 ; want even with ! optimize_size.
17961 (define_split
17962   [(set (match_operand 0 "flags_reg_operand" "")
17963         (match_operator 1 "compare_operator"
17964           [(and (match_operand:HI 2 "aligned_operand" "")
17965                 (match_operand:HI 3 "const_int_operand" ""))
17966            (const_int 0)]))]
17967   "! TARGET_PARTIAL_REG_STALL && reload_completed
17968    /* Ensure that the operand will remain sign-extended immediate.  */
17969    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
17970    && ! TARGET_FAST_PREFIX
17971    && ! optimize_size"
17972   [(set (match_dup 0)
17973         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17974                          (const_int 0)]))]
17975 {
17976   operands[3]
17977     = gen_int_mode (INTVAL (operands[3])
17978                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17979   operands[2] = gen_lowpart (SImode, operands[2]);
17980 })
17981
17982 (define_split
17983   [(set (match_operand 0 "register_operand" "")
17984         (neg (match_operand 1 "register_operand" "")))
17985    (clobber (reg:CC FLAGS_REG))]
17986   "! TARGET_PARTIAL_REG_STALL && reload_completed
17987    && (GET_MODE (operands[0]) == HImode
17988        || (GET_MODE (operands[0]) == QImode 
17989            && (TARGET_PROMOTE_QImode || optimize_size)))"
17990   [(parallel [(set (match_dup 0)
17991                    (neg:SI (match_dup 1)))
17992               (clobber (reg:CC FLAGS_REG))])]
17993   "operands[0] = gen_lowpart (SImode, operands[0]);
17994    operands[1] = gen_lowpart (SImode, operands[1]);")
17995
17996 (define_split
17997   [(set (match_operand 0 "register_operand" "")
17998         (not (match_operand 1 "register_operand" "")))]
17999   "! TARGET_PARTIAL_REG_STALL && reload_completed
18000    && (GET_MODE (operands[0]) == HImode
18001        || (GET_MODE (operands[0]) == QImode 
18002            && (TARGET_PROMOTE_QImode || optimize_size)))"
18003   [(set (match_dup 0)
18004         (not:SI (match_dup 1)))]
18005   "operands[0] = gen_lowpart (SImode, operands[0]);
18006    operands[1] = gen_lowpart (SImode, operands[1]);")
18007
18008 (define_split 
18009   [(set (match_operand 0 "register_operand" "")
18010         (if_then_else (match_operator 1 "comparison_operator" 
18011                                 [(reg FLAGS_REG) (const_int 0)])
18012                       (match_operand 2 "register_operand" "")
18013                       (match_operand 3 "register_operand" "")))]
18014   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18015    && (GET_MODE (operands[0]) == HImode
18016        || (GET_MODE (operands[0]) == QImode 
18017            && (TARGET_PROMOTE_QImode || optimize_size)))"
18018   [(set (match_dup 0)
18019         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18020   "operands[0] = gen_lowpart (SImode, operands[0]);
18021    operands[2] = gen_lowpart (SImode, operands[2]);
18022    operands[3] = gen_lowpart (SImode, operands[3]);")
18023                         
18024 \f
18025 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18026 ;; transform a complex memory operation into two memory to register operations.
18027
18028 ;; Don't push memory operands
18029 (define_peephole2
18030   [(set (match_operand:SI 0 "push_operand" "")
18031         (match_operand:SI 1 "memory_operand" ""))
18032    (match_scratch:SI 2 "r")]
18033   "! optimize_size && ! TARGET_PUSH_MEMORY"
18034   [(set (match_dup 2) (match_dup 1))
18035    (set (match_dup 0) (match_dup 2))]
18036   "")
18037
18038 (define_peephole2
18039   [(set (match_operand:DI 0 "push_operand" "")
18040         (match_operand:DI 1 "memory_operand" ""))
18041    (match_scratch:DI 2 "r")]
18042   "! optimize_size && ! TARGET_PUSH_MEMORY"
18043   [(set (match_dup 2) (match_dup 1))
18044    (set (match_dup 0) (match_dup 2))]
18045   "")
18046
18047 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18048 ;; SImode pushes.
18049 (define_peephole2
18050   [(set (match_operand:SF 0 "push_operand" "")
18051         (match_operand:SF 1 "memory_operand" ""))
18052    (match_scratch:SF 2 "r")]
18053   "! optimize_size && ! TARGET_PUSH_MEMORY"
18054   [(set (match_dup 2) (match_dup 1))
18055    (set (match_dup 0) (match_dup 2))]
18056   "")
18057
18058 (define_peephole2
18059   [(set (match_operand:HI 0 "push_operand" "")
18060         (match_operand:HI 1 "memory_operand" ""))
18061    (match_scratch:HI 2 "r")]
18062   "! optimize_size && ! TARGET_PUSH_MEMORY"
18063   [(set (match_dup 2) (match_dup 1))
18064    (set (match_dup 0) (match_dup 2))]
18065   "")
18066
18067 (define_peephole2
18068   [(set (match_operand:QI 0 "push_operand" "")
18069         (match_operand:QI 1 "memory_operand" ""))
18070    (match_scratch:QI 2 "q")]
18071   "! optimize_size && ! TARGET_PUSH_MEMORY"
18072   [(set (match_dup 2) (match_dup 1))
18073    (set (match_dup 0) (match_dup 2))]
18074   "")
18075
18076 ;; Don't move an immediate directly to memory when the instruction
18077 ;; gets too big.
18078 (define_peephole2
18079   [(match_scratch:SI 1 "r")
18080    (set (match_operand:SI 0 "memory_operand" "")
18081         (const_int 0))]
18082   "! optimize_size
18083    && ! TARGET_USE_MOV0
18084    && TARGET_SPLIT_LONG_MOVES
18085    && get_attr_length (insn) >= ix86_cost->large_insn
18086    && peep2_regno_dead_p (0, FLAGS_REG)"
18087   [(parallel [(set (match_dup 1) (const_int 0))
18088               (clobber (reg:CC FLAGS_REG))])
18089    (set (match_dup 0) (match_dup 1))]
18090   "")
18091
18092 (define_peephole2
18093   [(match_scratch:HI 1 "r")
18094    (set (match_operand:HI 0 "memory_operand" "")
18095         (const_int 0))]
18096   "! optimize_size
18097    && ! TARGET_USE_MOV0
18098    && TARGET_SPLIT_LONG_MOVES
18099    && get_attr_length (insn) >= ix86_cost->large_insn
18100    && peep2_regno_dead_p (0, FLAGS_REG)"
18101   [(parallel [(set (match_dup 2) (const_int 0))
18102               (clobber (reg:CC FLAGS_REG))])
18103    (set (match_dup 0) (match_dup 1))]
18104   "operands[2] = gen_lowpart (SImode, operands[1]);")
18105
18106 (define_peephole2
18107   [(match_scratch:QI 1 "q")
18108    (set (match_operand:QI 0 "memory_operand" "")
18109         (const_int 0))]
18110   "! optimize_size
18111    && ! TARGET_USE_MOV0
18112    && TARGET_SPLIT_LONG_MOVES
18113    && get_attr_length (insn) >= ix86_cost->large_insn
18114    && peep2_regno_dead_p (0, FLAGS_REG)"
18115   [(parallel [(set (match_dup 2) (const_int 0))
18116               (clobber (reg:CC FLAGS_REG))])
18117    (set (match_dup 0) (match_dup 1))]
18118   "operands[2] = gen_lowpart (SImode, operands[1]);")
18119
18120 (define_peephole2
18121   [(match_scratch:SI 2 "r")
18122    (set (match_operand:SI 0 "memory_operand" "")
18123         (match_operand:SI 1 "immediate_operand" ""))]
18124   "! optimize_size
18125    && get_attr_length (insn) >= ix86_cost->large_insn
18126    && TARGET_SPLIT_LONG_MOVES"
18127   [(set (match_dup 2) (match_dup 1))
18128    (set (match_dup 0) (match_dup 2))]
18129   "")
18130
18131 (define_peephole2
18132   [(match_scratch:HI 2 "r")
18133    (set (match_operand:HI 0 "memory_operand" "")
18134         (match_operand:HI 1 "immediate_operand" ""))]
18135   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18136   && TARGET_SPLIT_LONG_MOVES"
18137   [(set (match_dup 2) (match_dup 1))
18138    (set (match_dup 0) (match_dup 2))]
18139   "")
18140
18141 (define_peephole2
18142   [(match_scratch:QI 2 "q")
18143    (set (match_operand:QI 0 "memory_operand" "")
18144         (match_operand:QI 1 "immediate_operand" ""))]
18145   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18146   && TARGET_SPLIT_LONG_MOVES"
18147   [(set (match_dup 2) (match_dup 1))
18148    (set (match_dup 0) (match_dup 2))]
18149   "")
18150
18151 ;; Don't compare memory with zero, load and use a test instead.
18152 (define_peephole2
18153   [(set (match_operand 0 "flags_reg_operand" "")
18154         (match_operator 1 "compare_operator"
18155           [(match_operand:SI 2 "memory_operand" "")
18156            (const_int 0)]))
18157    (match_scratch:SI 3 "r")]
18158   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18159   [(set (match_dup 3) (match_dup 2))
18160    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18161   "")
18162
18163 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18164 ;; Don't split NOTs with a displacement operand, because resulting XOR
18165 ;; will not be pairable anyway.
18166 ;;
18167 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18168 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18169 ;; so this split helps here as well.
18170 ;;
18171 ;; Note: Can't do this as a regular split because we can't get proper
18172 ;; lifetime information then.
18173
18174 (define_peephole2
18175   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18176         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18177   "!optimize_size
18178    && peep2_regno_dead_p (0, FLAGS_REG)
18179    && ((TARGET_PENTIUM 
18180         && (GET_CODE (operands[0]) != MEM
18181             || !memory_displacement_operand (operands[0], SImode)))
18182        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18183   [(parallel [(set (match_dup 0)
18184                    (xor:SI (match_dup 1) (const_int -1)))
18185               (clobber (reg:CC FLAGS_REG))])]
18186   "")
18187
18188 (define_peephole2
18189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18190         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18191   "!optimize_size
18192    && peep2_regno_dead_p (0, FLAGS_REG)
18193    && ((TARGET_PENTIUM 
18194         && (GET_CODE (operands[0]) != MEM
18195             || !memory_displacement_operand (operands[0], HImode)))
18196        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18197   [(parallel [(set (match_dup 0)
18198                    (xor:HI (match_dup 1) (const_int -1)))
18199               (clobber (reg:CC FLAGS_REG))])]
18200   "")
18201
18202 (define_peephole2
18203   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18204         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18205   "!optimize_size
18206    && peep2_regno_dead_p (0, FLAGS_REG)
18207    && ((TARGET_PENTIUM 
18208         && (GET_CODE (operands[0]) != MEM
18209             || !memory_displacement_operand (operands[0], QImode)))
18210        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18211   [(parallel [(set (match_dup 0)
18212                    (xor:QI (match_dup 1) (const_int -1)))
18213               (clobber (reg:CC FLAGS_REG))])]
18214   "")
18215
18216 ;; Non pairable "test imm, reg" instructions can be translated to
18217 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18218 ;; byte opcode instead of two, have a short form for byte operands),
18219 ;; so do it for other CPUs as well.  Given that the value was dead,
18220 ;; this should not create any new dependencies.  Pass on the sub-word
18221 ;; versions if we're concerned about partial register stalls.
18222
18223 (define_peephole2
18224   [(set (match_operand 0 "flags_reg_operand" "")
18225         (match_operator 1 "compare_operator"
18226           [(and:SI (match_operand:SI 2 "register_operand" "")
18227                    (match_operand:SI 3 "immediate_operand" ""))
18228            (const_int 0)]))]
18229   "ix86_match_ccmode (insn, CCNOmode)
18230    && (true_regnum (operands[2]) != 0
18231        || (GET_CODE (operands[3]) == CONST_INT
18232            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18233    && peep2_reg_dead_p (1, operands[2])"
18234   [(parallel
18235      [(set (match_dup 0)
18236            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18237                             (const_int 0)]))
18238       (set (match_dup 2)
18239            (and:SI (match_dup 2) (match_dup 3)))])]
18240   "")
18241
18242 ;; We don't need to handle HImode case, because it will be promoted to SImode
18243 ;; on ! TARGET_PARTIAL_REG_STALL
18244
18245 (define_peephole2
18246   [(set (match_operand 0 "flags_reg_operand" "")
18247         (match_operator 1 "compare_operator"
18248           [(and:QI (match_operand:QI 2 "register_operand" "")
18249                    (match_operand:QI 3 "immediate_operand" ""))
18250            (const_int 0)]))]
18251   "! TARGET_PARTIAL_REG_STALL
18252    && ix86_match_ccmode (insn, CCNOmode)
18253    && true_regnum (operands[2]) != 0
18254    && peep2_reg_dead_p (1, operands[2])"
18255   [(parallel
18256      [(set (match_dup 0)
18257            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18258                             (const_int 0)]))
18259       (set (match_dup 2)
18260            (and:QI (match_dup 2) (match_dup 3)))])]
18261   "")
18262
18263 (define_peephole2
18264   [(set (match_operand 0 "flags_reg_operand" "")
18265         (match_operator 1 "compare_operator"
18266           [(and:SI
18267              (zero_extract:SI
18268                (match_operand 2 "ext_register_operand" "")
18269                (const_int 8)
18270                (const_int 8))
18271              (match_operand 3 "const_int_operand" ""))
18272            (const_int 0)]))]
18273   "! TARGET_PARTIAL_REG_STALL
18274    && ix86_match_ccmode (insn, CCNOmode)
18275    && true_regnum (operands[2]) != 0
18276    && peep2_reg_dead_p (1, operands[2])"
18277   [(parallel [(set (match_dup 0)
18278                    (match_op_dup 1
18279                      [(and:SI
18280                         (zero_extract:SI
18281                           (match_dup 2)
18282                           (const_int 8)
18283                           (const_int 8))
18284                         (match_dup 3))
18285                       (const_int 0)]))
18286               (set (zero_extract:SI (match_dup 2)
18287                                     (const_int 8)
18288                                     (const_int 8))
18289                    (and:SI 
18290                      (zero_extract:SI
18291                        (match_dup 2)
18292                        (const_int 8)
18293                        (const_int 8))
18294                      (match_dup 3)))])]
18295   "")
18296
18297 ;; Don't do logical operations with memory inputs.
18298 (define_peephole2
18299   [(match_scratch:SI 2 "r")
18300    (parallel [(set (match_operand:SI 0 "register_operand" "")
18301                    (match_operator:SI 3 "arith_or_logical_operator"
18302                      [(match_dup 0)
18303                       (match_operand:SI 1 "memory_operand" "")]))
18304               (clobber (reg:CC FLAGS_REG))])]
18305   "! optimize_size && ! TARGET_READ_MODIFY"
18306   [(set (match_dup 2) (match_dup 1))
18307    (parallel [(set (match_dup 0)
18308                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18309               (clobber (reg:CC FLAGS_REG))])]
18310   "")
18311
18312 (define_peephole2
18313   [(match_scratch:SI 2 "r")
18314    (parallel [(set (match_operand:SI 0 "register_operand" "")
18315                    (match_operator:SI 3 "arith_or_logical_operator"
18316                      [(match_operand:SI 1 "memory_operand" "")
18317                       (match_dup 0)]))
18318               (clobber (reg:CC FLAGS_REG))])]
18319   "! optimize_size && ! TARGET_READ_MODIFY"
18320   [(set (match_dup 2) (match_dup 1))
18321    (parallel [(set (match_dup 0)
18322                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18323               (clobber (reg:CC FLAGS_REG))])]
18324   "")
18325
18326 ; Don't do logical operations with memory outputs
18327 ;
18328 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18329 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18330 ; the same decoder scheduling characteristics as the original.
18331
18332 (define_peephole2
18333   [(match_scratch:SI 2 "r")
18334    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18335                    (match_operator:SI 3 "arith_or_logical_operator"
18336                      [(match_dup 0)
18337                       (match_operand:SI 1 "nonmemory_operand" "")]))
18338               (clobber (reg:CC FLAGS_REG))])]
18339   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18340   [(set (match_dup 2) (match_dup 0))
18341    (parallel [(set (match_dup 2)
18342                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18343               (clobber (reg:CC FLAGS_REG))])
18344    (set (match_dup 0) (match_dup 2))]
18345   "")
18346
18347 (define_peephole2
18348   [(match_scratch:SI 2 "r")
18349    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18350                    (match_operator:SI 3 "arith_or_logical_operator"
18351                      [(match_operand:SI 1 "nonmemory_operand" "")
18352                       (match_dup 0)]))
18353               (clobber (reg:CC FLAGS_REG))])]
18354   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18355   [(set (match_dup 2) (match_dup 0))
18356    (parallel [(set (match_dup 2)
18357                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18358               (clobber (reg:CC FLAGS_REG))])
18359    (set (match_dup 0) (match_dup 2))]
18360   "")
18361
18362 ;; Attempt to always use XOR for zeroing registers.
18363 (define_peephole2
18364   [(set (match_operand 0 "register_operand" "")
18365         (const_int 0))]
18366   "(GET_MODE (operands[0]) == QImode
18367     || GET_MODE (operands[0]) == HImode
18368     || GET_MODE (operands[0]) == SImode
18369     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18370    && (! TARGET_USE_MOV0 || optimize_size)
18371    && GENERAL_REG_P (operands[0])
18372    && peep2_regno_dead_p (0, FLAGS_REG)"
18373   [(parallel [(set (match_dup 0) (const_int 0))
18374               (clobber (reg:CC FLAGS_REG))])]
18375   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18376                               operands[0]);")
18377
18378 (define_peephole2
18379   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18380         (const_int 0))]
18381   "(GET_MODE (operands[0]) == QImode
18382     || GET_MODE (operands[0]) == HImode)
18383    && (! TARGET_USE_MOV0 || optimize_size)
18384    && peep2_regno_dead_p (0, FLAGS_REG)"
18385   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18386               (clobber (reg:CC FLAGS_REG))])])
18387
18388 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18389 (define_peephole2
18390   [(set (match_operand 0 "register_operand" "")
18391         (const_int -1))]
18392   "(GET_MODE (operands[0]) == HImode
18393     || GET_MODE (operands[0]) == SImode 
18394     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18395    && (optimize_size || TARGET_PENTIUM)
18396    && peep2_regno_dead_p (0, FLAGS_REG)"
18397   [(parallel [(set (match_dup 0) (const_int -1))
18398               (clobber (reg:CC FLAGS_REG))])]
18399   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18400                               operands[0]);")
18401
18402 ;; Attempt to convert simple leas to adds. These can be created by
18403 ;; move expanders.
18404 (define_peephole2
18405   [(set (match_operand:SI 0 "register_operand" "")
18406         (plus:SI (match_dup 0)
18407                  (match_operand:SI 1 "nonmemory_operand" "")))]
18408   "peep2_regno_dead_p (0, FLAGS_REG)"
18409   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18410               (clobber (reg:CC FLAGS_REG))])]
18411   "")
18412
18413 (define_peephole2
18414   [(set (match_operand:SI 0 "register_operand" "")
18415         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18416                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18417   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18418   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18419               (clobber (reg:CC FLAGS_REG))])]
18420   "operands[2] = gen_lowpart (SImode, operands[2]);")
18421
18422 (define_peephole2
18423   [(set (match_operand:DI 0 "register_operand" "")
18424         (plus:DI (match_dup 0)
18425                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18426   "peep2_regno_dead_p (0, FLAGS_REG)"
18427   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18428               (clobber (reg:CC FLAGS_REG))])]
18429   "")
18430
18431 (define_peephole2
18432   [(set (match_operand:SI 0 "register_operand" "")
18433         (mult:SI (match_dup 0)
18434                  (match_operand:SI 1 "const_int_operand" "")))]
18435   "exact_log2 (INTVAL (operands[1])) >= 0
18436    && peep2_regno_dead_p (0, FLAGS_REG)"
18437   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18438               (clobber (reg:CC FLAGS_REG))])]
18439   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18440
18441 (define_peephole2
18442   [(set (match_operand:DI 0 "register_operand" "")
18443         (mult:DI (match_dup 0)
18444                  (match_operand:DI 1 "const_int_operand" "")))]
18445   "exact_log2 (INTVAL (operands[1])) >= 0
18446    && peep2_regno_dead_p (0, FLAGS_REG)"
18447   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18448               (clobber (reg:CC FLAGS_REG))])]
18449   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18450
18451 (define_peephole2
18452   [(set (match_operand:SI 0 "register_operand" "")
18453         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18454                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18455   "exact_log2 (INTVAL (operands[2])) >= 0
18456    && REGNO (operands[0]) == REGNO (operands[1])
18457    && peep2_regno_dead_p (0, FLAGS_REG)"
18458   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18459               (clobber (reg:CC FLAGS_REG))])]
18460   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18461
18462 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18463 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18464 ;; many CPUs it is also faster, since special hardware to avoid esp
18465 ;; dependencies is present.
18466
18467 ;; While some of these conversions may be done using splitters, we use peepholes
18468 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18469
18470 ;; Convert prologue esp subtractions to push.
18471 ;; We need register to push.  In order to keep verify_flow_info happy we have
18472 ;; two choices
18473 ;; - use scratch and clobber it in order to avoid dependencies
18474 ;; - use already live register
18475 ;; We can't use the second way right now, since there is no reliable way how to
18476 ;; verify that given register is live.  First choice will also most likely in
18477 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18478 ;; call clobbered registers are dead.  We may want to use base pointer as an
18479 ;; alternative when no register is available later.
18480
18481 (define_peephole2
18482   [(match_scratch:SI 0 "r")
18483    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18484               (clobber (reg:CC FLAGS_REG))
18485               (clobber (mem:BLK (scratch)))])]
18486   "optimize_size || !TARGET_SUB_ESP_4"
18487   [(clobber (match_dup 0))
18488    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18489               (clobber (mem:BLK (scratch)))])])
18490
18491 (define_peephole2
18492   [(match_scratch:SI 0 "r")
18493    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18494               (clobber (reg:CC FLAGS_REG))
18495               (clobber (mem:BLK (scratch)))])]
18496   "optimize_size || !TARGET_SUB_ESP_8"
18497   [(clobber (match_dup 0))
18498    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18499    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18500               (clobber (mem:BLK (scratch)))])])
18501
18502 ;; Convert esp subtractions to push.
18503 (define_peephole2
18504   [(match_scratch:SI 0 "r")
18505    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18506               (clobber (reg:CC FLAGS_REG))])]
18507   "optimize_size || !TARGET_SUB_ESP_4"
18508   [(clobber (match_dup 0))
18509    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18510
18511 (define_peephole2
18512   [(match_scratch:SI 0 "r")
18513    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18514               (clobber (reg:CC FLAGS_REG))])]
18515   "optimize_size || !TARGET_SUB_ESP_8"
18516   [(clobber (match_dup 0))
18517    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18518    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18519
18520 ;; Convert epilogue deallocator to pop.
18521 (define_peephole2
18522   [(match_scratch:SI 0 "r")
18523    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18524               (clobber (reg:CC FLAGS_REG))
18525               (clobber (mem:BLK (scratch)))])]
18526   "optimize_size || !TARGET_ADD_ESP_4"
18527   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18528               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18529               (clobber (mem:BLK (scratch)))])]
18530   "")
18531
18532 ;; Two pops case is tricky, since pop causes dependency on destination register.
18533 ;; We use two registers if available.
18534 (define_peephole2
18535   [(match_scratch:SI 0 "r")
18536    (match_scratch:SI 1 "r")
18537    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18538               (clobber (reg:CC FLAGS_REG))
18539               (clobber (mem:BLK (scratch)))])]
18540   "optimize_size || !TARGET_ADD_ESP_8"
18541   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18542               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18543               (clobber (mem:BLK (scratch)))])
18544    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18545               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18546   "")
18547
18548 (define_peephole2
18549   [(match_scratch:SI 0 "r")
18550    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18551               (clobber (reg:CC FLAGS_REG))
18552               (clobber (mem:BLK (scratch)))])]
18553   "optimize_size"
18554   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18555               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18556               (clobber (mem:BLK (scratch)))])
18557    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18558               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18559   "")
18560
18561 ;; Convert esp additions to pop.
18562 (define_peephole2
18563   [(match_scratch:SI 0 "r")
18564    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18565               (clobber (reg:CC FLAGS_REG))])]
18566   ""
18567   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18568               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18569   "")
18570
18571 ;; Two pops case is tricky, since pop causes dependency on destination register.
18572 ;; We use two registers if available.
18573 (define_peephole2
18574   [(match_scratch:SI 0 "r")
18575    (match_scratch:SI 1 "r")
18576    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18577               (clobber (reg:CC FLAGS_REG))])]
18578   ""
18579   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18580               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18581    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18582               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18583   "")
18584
18585 (define_peephole2
18586   [(match_scratch:SI 0 "r")
18587    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18588               (clobber (reg:CC FLAGS_REG))])]
18589   "optimize_size"
18590   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18591               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18592    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18593               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18594   "")
18595 \f
18596 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18597 ;; required and register dies.  Similarly for 128 to plus -128.
18598 (define_peephole2
18599   [(set (match_operand 0 "flags_reg_operand" "")
18600         (match_operator 1 "compare_operator"
18601           [(match_operand 2 "register_operand" "")
18602            (match_operand 3 "const_int_operand" "")]))]
18603   "(INTVAL (operands[3]) == -1
18604     || INTVAL (operands[3]) == 1
18605     || INTVAL (operands[3]) == 128)
18606    && ix86_match_ccmode (insn, CCGCmode)
18607    && peep2_reg_dead_p (1, operands[2])"
18608   [(parallel [(set (match_dup 0)
18609                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18610               (clobber (match_dup 2))])]
18611   "")
18612 \f
18613 (define_peephole2
18614   [(match_scratch:DI 0 "r")
18615    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18616               (clobber (reg:CC FLAGS_REG))
18617               (clobber (mem:BLK (scratch)))])]
18618   "optimize_size || !TARGET_SUB_ESP_4"
18619   [(clobber (match_dup 0))
18620    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18621               (clobber (mem:BLK (scratch)))])])
18622
18623 (define_peephole2
18624   [(match_scratch:DI 0 "r")
18625    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18626               (clobber (reg:CC FLAGS_REG))
18627               (clobber (mem:BLK (scratch)))])]
18628   "optimize_size || !TARGET_SUB_ESP_8"
18629   [(clobber (match_dup 0))
18630    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18631    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18632               (clobber (mem:BLK (scratch)))])])
18633
18634 ;; Convert esp subtractions to push.
18635 (define_peephole2
18636   [(match_scratch:DI 0 "r")
18637    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18638               (clobber (reg:CC FLAGS_REG))])]
18639   "optimize_size || !TARGET_SUB_ESP_4"
18640   [(clobber (match_dup 0))
18641    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18642
18643 (define_peephole2
18644   [(match_scratch:DI 0 "r")
18645    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18646               (clobber (reg:CC FLAGS_REG))])]
18647   "optimize_size || !TARGET_SUB_ESP_8"
18648   [(clobber (match_dup 0))
18649    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18650    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18651
18652 ;; Convert epilogue deallocator to pop.
18653 (define_peephole2
18654   [(match_scratch:DI 0 "r")
18655    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18656               (clobber (reg:CC FLAGS_REG))
18657               (clobber (mem:BLK (scratch)))])]
18658   "optimize_size || !TARGET_ADD_ESP_4"
18659   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18660               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18661               (clobber (mem:BLK (scratch)))])]
18662   "")
18663
18664 ;; Two pops case is tricky, since pop causes dependency on destination register.
18665 ;; We use two registers if available.
18666 (define_peephole2
18667   [(match_scratch:DI 0 "r")
18668    (match_scratch:DI 1 "r")
18669    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18670               (clobber (reg:CC FLAGS_REG))
18671               (clobber (mem:BLK (scratch)))])]
18672   "optimize_size || !TARGET_ADD_ESP_8"
18673   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18674               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18675               (clobber (mem:BLK (scratch)))])
18676    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18677               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18678   "")
18679
18680 (define_peephole2
18681   [(match_scratch:DI 0 "r")
18682    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18683               (clobber (reg:CC FLAGS_REG))
18684               (clobber (mem:BLK (scratch)))])]
18685   "optimize_size"
18686   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18687               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18688               (clobber (mem:BLK (scratch)))])
18689    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18690               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18691   "")
18692
18693 ;; Convert esp additions to pop.
18694 (define_peephole2
18695   [(match_scratch:DI 0 "r")
18696    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18697               (clobber (reg:CC FLAGS_REG))])]
18698   ""
18699   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18700               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18701   "")
18702
18703 ;; Two pops case is tricky, since pop causes dependency on destination register.
18704 ;; We use two registers if available.
18705 (define_peephole2
18706   [(match_scratch:DI 0 "r")
18707    (match_scratch:DI 1 "r")
18708    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18709               (clobber (reg:CC FLAGS_REG))])]
18710   ""
18711   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18712               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18713    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18714               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18715   "")
18716
18717 (define_peephole2
18718   [(match_scratch:DI 0 "r")
18719    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18720               (clobber (reg:CC FLAGS_REG))])]
18721   "optimize_size"
18722   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18723               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18724    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18725               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18726   "")
18727 \f
18728 ;; Convert imul by three, five and nine into lea
18729 (define_peephole2
18730   [(parallel
18731     [(set (match_operand:SI 0 "register_operand" "")
18732           (mult:SI (match_operand:SI 1 "register_operand" "")
18733                    (match_operand:SI 2 "const_int_operand" "")))
18734      (clobber (reg:CC FLAGS_REG))])]
18735   "INTVAL (operands[2]) == 3
18736    || INTVAL (operands[2]) == 5
18737    || INTVAL (operands[2]) == 9"
18738   [(set (match_dup 0)
18739         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18740                  (match_dup 1)))]
18741   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18742
18743 (define_peephole2
18744   [(parallel
18745     [(set (match_operand:SI 0 "register_operand" "")
18746           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18747                    (match_operand:SI 2 "const_int_operand" "")))
18748      (clobber (reg:CC FLAGS_REG))])]
18749   "!optimize_size 
18750    && (INTVAL (operands[2]) == 3
18751        || INTVAL (operands[2]) == 5
18752        || INTVAL (operands[2]) == 9)"
18753   [(set (match_dup 0) (match_dup 1))
18754    (set (match_dup 0)
18755         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18756                  (match_dup 0)))]
18757   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18758
18759 (define_peephole2
18760   [(parallel
18761     [(set (match_operand:DI 0 "register_operand" "")
18762           (mult:DI (match_operand:DI 1 "register_operand" "")
18763                    (match_operand:DI 2 "const_int_operand" "")))
18764      (clobber (reg:CC FLAGS_REG))])]
18765   "TARGET_64BIT
18766    && (INTVAL (operands[2]) == 3
18767        || INTVAL (operands[2]) == 5
18768        || INTVAL (operands[2]) == 9)"
18769   [(set (match_dup 0)
18770         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18771                  (match_dup 1)))]
18772   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18773
18774 (define_peephole2
18775   [(parallel
18776     [(set (match_operand:DI 0 "register_operand" "")
18777           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18778                    (match_operand:DI 2 "const_int_operand" "")))
18779      (clobber (reg:CC FLAGS_REG))])]
18780   "TARGET_64BIT
18781    && !optimize_size 
18782    && (INTVAL (operands[2]) == 3
18783        || INTVAL (operands[2]) == 5
18784        || INTVAL (operands[2]) == 9)"
18785   [(set (match_dup 0) (match_dup 1))
18786    (set (match_dup 0)
18787         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18788                  (match_dup 0)))]
18789   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18790
18791 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18792 ;; imul $32bit_imm, reg, reg is direct decoded.
18793 (define_peephole2
18794   [(match_scratch:DI 3 "r")
18795    (parallel [(set (match_operand:DI 0 "register_operand" "")
18796                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18797                             (match_operand:DI 2 "immediate_operand" "")))
18798               (clobber (reg:CC FLAGS_REG))])]
18799   "TARGET_K8 && !optimize_size
18800    && (GET_CODE (operands[2]) != CONST_INT
18801        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18802   [(set (match_dup 3) (match_dup 1))
18803    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18804               (clobber (reg:CC FLAGS_REG))])]
18805 "")
18806
18807 (define_peephole2
18808   [(match_scratch:SI 3 "r")
18809    (parallel [(set (match_operand:SI 0 "register_operand" "")
18810                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18811                             (match_operand:SI 2 "immediate_operand" "")))
18812               (clobber (reg:CC FLAGS_REG))])]
18813   "TARGET_K8 && !optimize_size
18814    && (GET_CODE (operands[2]) != CONST_INT
18815        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18816   [(set (match_dup 3) (match_dup 1))
18817    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18818               (clobber (reg:CC FLAGS_REG))])]
18819 "")
18820
18821 (define_peephole2
18822   [(match_scratch:SI 3 "r")
18823    (parallel [(set (match_operand:DI 0 "register_operand" "")
18824                    (zero_extend:DI
18825                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18826                               (match_operand:SI 2 "immediate_operand" ""))))
18827               (clobber (reg:CC FLAGS_REG))])]
18828   "TARGET_K8 && !optimize_size
18829    && (GET_CODE (operands[2]) != CONST_INT
18830        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18831   [(set (match_dup 3) (match_dup 1))
18832    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18833               (clobber (reg:CC FLAGS_REG))])]
18834 "")
18835
18836 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18837 ;; Convert it into imul reg, reg
18838 ;; It would be better to force assembler to encode instruction using long
18839 ;; immediate, but there is apparently no way to do so.
18840 (define_peephole2
18841   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18842                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18843                             (match_operand:DI 2 "const_int_operand" "")))
18844               (clobber (reg:CC FLAGS_REG))])
18845    (match_scratch:DI 3 "r")]
18846   "TARGET_K8 && !optimize_size
18847    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18848   [(set (match_dup 3) (match_dup 2))
18849    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18850               (clobber (reg:CC FLAGS_REG))])]
18851 {
18852   if (!rtx_equal_p (operands[0], operands[1]))
18853     emit_move_insn (operands[0], operands[1]);
18854 })
18855
18856 (define_peephole2
18857   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18858                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18859                             (match_operand:SI 2 "const_int_operand" "")))
18860               (clobber (reg:CC FLAGS_REG))])
18861    (match_scratch:SI 3 "r")]
18862   "TARGET_K8 && !optimize_size
18863    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18864   [(set (match_dup 3) (match_dup 2))
18865    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18866               (clobber (reg:CC FLAGS_REG))])]
18867 {
18868   if (!rtx_equal_p (operands[0], operands[1]))
18869     emit_move_insn (operands[0], operands[1]);
18870 })
18871
18872 (define_peephole2
18873   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18874                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18875                             (match_operand:HI 2 "immediate_operand" "")))
18876               (clobber (reg:CC FLAGS_REG))])
18877    (match_scratch:HI 3 "r")]
18878   "TARGET_K8 && !optimize_size"
18879   [(set (match_dup 3) (match_dup 2))
18880    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18881               (clobber (reg:CC FLAGS_REG))])]
18882 {
18883   if (!rtx_equal_p (operands[0], operands[1]))
18884     emit_move_insn (operands[0], operands[1]);
18885 })
18886 \f
18887 ;; Call-value patterns last so that the wildcard operand does not
18888 ;; disrupt insn-recog's switch tables.
18889
18890 (define_insn "*call_value_pop_0"
18891   [(set (match_operand 0 "" "")
18892         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18893               (match_operand:SI 2 "" "")))
18894    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
18895                             (match_operand:SI 3 "immediate_operand" "")))]
18896   "!TARGET_64BIT"
18897 {
18898   if (SIBLING_CALL_P (insn))
18899     return "jmp\t%P1";
18900   else
18901     return "call\t%P1";
18902 }
18903   [(set_attr "type" "callv")])
18904
18905 (define_insn "*call_value_pop_1"
18906   [(set (match_operand 0 "" "")
18907         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18908               (match_operand:SI 2 "" "")))
18909    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
18910                             (match_operand:SI 3 "immediate_operand" "i")))]
18911   "!TARGET_64BIT"
18912 {
18913   if (constant_call_address_operand (operands[1], Pmode))
18914     {
18915       if (SIBLING_CALL_P (insn))
18916         return "jmp\t%P1";
18917       else
18918         return "call\t%P1";
18919     }
18920   if (SIBLING_CALL_P (insn))
18921     return "jmp\t%A1";
18922   else
18923     return "call\t%A1";
18924 }
18925   [(set_attr "type" "callv")])
18926
18927 (define_insn "*call_value_0"
18928   [(set (match_operand 0 "" "")
18929         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18930               (match_operand:SI 2 "" "")))]
18931   "!TARGET_64BIT"
18932 {
18933   if (SIBLING_CALL_P (insn))
18934     return "jmp\t%P1";
18935   else
18936     return "call\t%P1";
18937 }
18938   [(set_attr "type" "callv")])
18939
18940 (define_insn "*call_value_0_rex64"
18941   [(set (match_operand 0 "" "")
18942         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18943               (match_operand:DI 2 "const_int_operand" "")))]
18944   "TARGET_64BIT"
18945 {
18946   if (SIBLING_CALL_P (insn))
18947     return "jmp\t%P1";
18948   else
18949     return "call\t%P1";
18950 }
18951   [(set_attr "type" "callv")])
18952
18953 (define_insn "*call_value_1"
18954   [(set (match_operand 0 "" "")
18955         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18956               (match_operand:SI 2 "" "")))]
18957   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18958 {
18959   if (constant_call_address_operand (operands[1], Pmode))
18960     return "call\t%P1";
18961   return "call\t%A1";
18962 }
18963   [(set_attr "type" "callv")])
18964
18965 (define_insn "*sibcall_value_1"
18966   [(set (match_operand 0 "" "")
18967         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18968               (match_operand:SI 2 "" "")))]
18969   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18970 {
18971   if (constant_call_address_operand (operands[1], Pmode))
18972     return "jmp\t%P1";
18973   return "jmp\t%A1";
18974 }
18975   [(set_attr "type" "callv")])
18976
18977 (define_insn "*call_value_1_rex64"
18978   [(set (match_operand 0 "" "")
18979         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18980               (match_operand:DI 2 "" "")))]
18981   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18982 {
18983   if (constant_call_address_operand (operands[1], Pmode))
18984     return "call\t%P1";
18985   return "call\t%A1";
18986 }
18987   [(set_attr "type" "callv")])
18988
18989 (define_insn "*sibcall_value_1_rex64"
18990   [(set (match_operand 0 "" "")
18991         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18992               (match_operand:DI 2 "" "")))]
18993   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18994   "jmp\t%P1"
18995   [(set_attr "type" "callv")])
18996
18997 (define_insn "*sibcall_value_1_rex64_v"
18998   [(set (match_operand 0 "" "")
18999         (call (mem:QI (reg:DI 40))
19000               (match_operand:DI 1 "" "")))]
19001   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19002   "jmp\t*%%r11"
19003   [(set_attr "type" "callv")])
19004 \f
19005 (define_insn "trap"
19006   [(trap_if (const_int 1) (const_int 5))]
19007   ""
19008   "int\t$5")
19009
19010 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19011 ;;; for the sake of bounds checking.  By emitting bounds checks as
19012 ;;; conditional traps rather than as conditional jumps around
19013 ;;; unconditional traps we avoid introducing spurious basic-block
19014 ;;; boundaries and facilitate elimination of redundant checks.  In
19015 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19016 ;;; interrupt 5.
19017 ;;; 
19018 ;;; FIXME: Static branch prediction rules for ix86 are such that
19019 ;;; forward conditional branches predict as untaken.  As implemented
19020 ;;; below, pseudo conditional traps violate that rule.  We should use
19021 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19022 ;;; section loaded at the end of the text segment and branch forward
19023 ;;; there on bounds-failure, and then jump back immediately (in case
19024 ;;; the system chooses to ignore bounds violations, or to report
19025 ;;; violations and continue execution).
19026
19027 (define_expand "conditional_trap"
19028   [(trap_if (match_operator 0 "comparison_operator"
19029              [(match_dup 2) (const_int 0)])
19030             (match_operand 1 "const_int_operand" ""))]
19031   ""
19032 {
19033   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19034                               ix86_expand_compare (GET_CODE (operands[0]),
19035                                                    NULL, NULL),
19036                               operands[1]));
19037   DONE;
19038 })
19039
19040 (define_insn "*conditional_trap_1"
19041   [(trap_if (match_operator 0 "comparison_operator"
19042              [(reg FLAGS_REG) (const_int 0)])
19043             (match_operand 1 "const_int_operand" ""))]
19044   ""
19045 {
19046   operands[2] = gen_label_rtx ();
19047   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19048   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19049                              CODE_LABEL_NUMBER (operands[2]));
19050   RET;
19051 })
19052
19053 (define_expand "sse_prologue_save"
19054   [(parallel [(set (match_operand:BLK 0 "" "")
19055                    (unspec:BLK [(reg:DI 21)
19056                                 (reg:DI 22)
19057                                 (reg:DI 23)
19058                                 (reg:DI 24)
19059                                 (reg:DI 25)
19060                                 (reg:DI 26)
19061                                 (reg:DI 27)
19062                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19063               (use (match_operand:DI 1 "register_operand" ""))
19064               (use (match_operand:DI 2 "immediate_operand" ""))
19065               (use (label_ref:DI (match_operand 3 "" "")))])]
19066   "TARGET_64BIT"
19067   "")
19068
19069 (define_insn "*sse_prologue_save_insn"
19070   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19071                           (match_operand:DI 4 "const_int_operand" "n")))
19072         (unspec:BLK [(reg:DI 21)
19073                      (reg:DI 22)
19074                      (reg:DI 23)
19075                      (reg:DI 24)
19076                      (reg:DI 25)
19077                      (reg:DI 26)
19078                      (reg:DI 27)
19079                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19080    (use (match_operand:DI 1 "register_operand" "r"))
19081    (use (match_operand:DI 2 "const_int_operand" "i"))
19082    (use (label_ref:DI (match_operand 3 "" "X")))]
19083   "TARGET_64BIT
19084    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19085    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19086   "*
19087 {
19088   int i;
19089   operands[0] = gen_rtx_MEM (Pmode,
19090                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19091   output_asm_insn (\"jmp\\t%A1\", operands);
19092   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19093     {
19094       operands[4] = adjust_address (operands[0], DImode, i*16);
19095       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19096       PUT_MODE (operands[4], TImode);
19097       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19098         output_asm_insn (\"rex\", operands);
19099       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19100     }
19101   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19102                              CODE_LABEL_NUMBER (operands[3]));
19103   RET;
19104 }
19105   "
19106   [(set_attr "type" "other")
19107    (set_attr "length_immediate" "0")
19108    (set_attr "length_address" "0")
19109    (set_attr "length" "135")
19110    (set_attr "memory" "store")
19111    (set_attr "modrm" "0")
19112    (set_attr "mode" "DI")])
19113
19114 (define_expand "prefetch"
19115   [(prefetch (match_operand 0 "address_operand" "")
19116              (match_operand:SI 1 "const_int_operand" "")
19117              (match_operand:SI 2 "const_int_operand" ""))]
19118   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19119 {
19120   int rw = INTVAL (operands[1]);
19121   int locality = INTVAL (operands[2]);
19122
19123   if (rw != 0 && rw != 1)
19124     abort ();
19125   if (locality < 0 || locality > 3)
19126     abort ();
19127   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19128     abort ();
19129
19130   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19131      suported by SSE counterpart or the SSE prefetch is not available
19132      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19133      of locality.  */
19134   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19135     operands[2] = GEN_INT (3);
19136   else
19137     operands[1] = const0_rtx;
19138 })
19139
19140 (define_insn "*prefetch_sse"
19141   [(prefetch (match_operand:SI 0 "address_operand" "p")
19142              (const_int 0)
19143              (match_operand:SI 1 "const_int_operand" ""))]
19144   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19145 {
19146   static const char * const patterns[4] = {
19147    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19148   };
19149
19150   int locality = INTVAL (operands[1]);
19151   if (locality < 0 || locality > 3)
19152     abort ();
19153
19154   return patterns[locality];  
19155 }
19156   [(set_attr "type" "sse")
19157    (set_attr "memory" "none")])
19158
19159 (define_insn "*prefetch_sse_rex"
19160   [(prefetch (match_operand:DI 0 "address_operand" "p")
19161              (const_int 0)
19162              (match_operand:SI 1 "const_int_operand" ""))]
19163   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19164 {
19165   static const char * const patterns[4] = {
19166    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19167   };
19168
19169   int locality = INTVAL (operands[1]);
19170   if (locality < 0 || locality > 3)
19171     abort ();
19172
19173   return patterns[locality];  
19174 }
19175   [(set_attr "type" "sse")
19176    (set_attr "memory" "none")])
19177
19178 (define_insn "*prefetch_3dnow"
19179   [(prefetch (match_operand:SI 0 "address_operand" "p")
19180              (match_operand:SI 1 "const_int_operand" "n")
19181              (const_int 3))]
19182   "TARGET_3DNOW && !TARGET_64BIT"
19183 {
19184   if (INTVAL (operands[1]) == 0)
19185     return "prefetch\t%a0";
19186   else
19187     return "prefetchw\t%a0";
19188 }
19189   [(set_attr "type" "mmx")
19190    (set_attr "memory" "none")])
19191
19192 (define_insn "*prefetch_3dnow_rex"
19193   [(prefetch (match_operand:DI 0 "address_operand" "p")
19194              (match_operand:SI 1 "const_int_operand" "n")
19195              (const_int 3))]
19196   "TARGET_3DNOW && TARGET_64BIT"
19197 {
19198   if (INTVAL (operands[1]) == 0)
19199     return "prefetch\t%a0";
19200   else
19201     return "prefetchw\t%a0";
19202 }
19203   [(set_attr "type" "mmx")
19204    (set_attr "memory" "none")])
19205
19206 (include "sse.md")
19207 (include "mmx.md")