OSDN Git Service

* config/i386/i386.md (addhi_4): Correct reference in comment.
[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"
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"
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"
939   [(set (reg:CCFP FLAGS_REG)
940         (compare:CCFP (match_operand 0 "register_operand" "f")
941                       (match_operand 1 "register_operand" "f")))]
942   "TARGET_80387 && TARGET_CMOVE
943    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
944    && FLOAT_MODE_P (GET_MODE (operands[0]))
945    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
946   "* return output_fp_compare (insn, operands, 1, 0);"
947   [(set_attr "type" "fcmp")
948    (set (attr "mode")
949      (cond [(match_operand:SF 1 "" "")
950               (const_string "SF")
951             (match_operand:DF 1 "" "")
952               (const_string "DF")
953            ]
954            (const_string "XF")))
955    (set_attr "athlon_decode" "vector")])
956
957 (define_insn "*cmpfp_i_sse"
958   [(set (reg:CCFP FLAGS_REG)
959         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
960                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
961   "TARGET_80387
962    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
963    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
964   "* return output_fp_compare (insn, operands, 1, 0);"
965   [(set_attr "type" "fcmp,ssecomi")
966    (set (attr "mode")
967      (if_then_else (match_operand:SF 1 "" "")
968         (const_string "SF")
969         (const_string "DF")))
970    (set_attr "athlon_decode" "vector")])
971
972 (define_insn "*cmpfp_i_sse_only"
973   [(set (reg:CCFP FLAGS_REG)
974         (compare:CCFP (match_operand 0 "register_operand" "x")
975                       (match_operand 1 "nonimmediate_operand" "xm")))]
976   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
977    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
978   "* return output_fp_compare (insn, operands, 1, 0);"
979   [(set_attr "type" "ssecomi")
980    (set (attr "mode")
981      (if_then_else (match_operand:SF 1 "" "")
982         (const_string "SF")
983         (const_string "DF")))
984    (set_attr "athlon_decode" "vector")])
985
986 (define_insn "*cmpfp_iu"
987   [(set (reg:CCFPU FLAGS_REG)
988         (compare:CCFPU (match_operand 0 "register_operand" "f")
989                        (match_operand 1 "register_operand" "f")))]
990   "TARGET_80387 && TARGET_CMOVE
991    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
992    && 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")
996    (set (attr "mode")
997      (cond [(match_operand:SF 1 "" "")
998               (const_string "SF")
999             (match_operand:DF 1 "" "")
1000               (const_string "DF")
1001            ]
1002            (const_string "XF")))
1003    (set_attr "athlon_decode" "vector")])
1004
1005 (define_insn "*cmpfp_iu_sse"
1006   [(set (reg:CCFPU FLAGS_REG)
1007         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1008                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1009   "TARGET_80387
1010    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1011    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012   "* return output_fp_compare (insn, operands, 1, 1);"
1013   [(set_attr "type" "fcmp,ssecomi")
1014    (set (attr "mode")
1015      (if_then_else (match_operand:SF 1 "" "")
1016         (const_string "SF")
1017         (const_string "DF")))
1018    (set_attr "athlon_decode" "vector")])
1019
1020 (define_insn "*cmpfp_iu_sse_only"
1021   [(set (reg:CCFPU FLAGS_REG)
1022         (compare:CCFPU (match_operand 0 "register_operand" "x")
1023                        (match_operand 1 "nonimmediate_operand" "xm")))]
1024   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1025    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1026   "* return output_fp_compare (insn, operands, 1, 1);"
1027   [(set_attr "type" "ssecomi")
1028    (set (attr "mode")
1029      (if_then_else (match_operand:SF 1 "" "")
1030         (const_string "SF")
1031         (const_string "DF")))
1032    (set_attr "athlon_decode" "vector")])
1033 \f
1034 ;; Move instructions.
1035
1036 ;; General case of fullword move.
1037
1038 (define_expand "movsi"
1039   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1040         (match_operand:SI 1 "general_operand" ""))]
1041   ""
1042   "ix86_expand_move (SImode, operands); DONE;")
1043
1044 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1045 ;; general_operand.
1046 ;;
1047 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1048 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1049 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1050 ;; targets without our curiosities, and it is just as easy to represent
1051 ;; this differently.
1052
1053 (define_insn "*pushsi2"
1054   [(set (match_operand:SI 0 "push_operand" "=<")
1055         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1056   "!TARGET_64BIT"
1057   "push{l}\t%1"
1058   [(set_attr "type" "push")
1059    (set_attr "mode" "SI")])
1060
1061 ;; For 64BIT abi we always round up to 8 bytes.
1062 (define_insn "*pushsi2_rex64"
1063   [(set (match_operand:SI 0 "push_operand" "=X")
1064         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1065   "TARGET_64BIT"
1066   "push{q}\t%q1"
1067   [(set_attr "type" "push")
1068    (set_attr "mode" "SI")])
1069
1070 (define_insn "*pushsi2_prologue"
1071   [(set (match_operand:SI 0 "push_operand" "=<")
1072         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1073    (clobber (mem:BLK (scratch)))]
1074   "!TARGET_64BIT"
1075   "push{l}\t%1"
1076   [(set_attr "type" "push")
1077    (set_attr "mode" "SI")])
1078
1079 (define_insn "*popsi1_epilogue"
1080   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1081         (mem:SI (reg:SI SP_REG)))
1082    (set (reg:SI SP_REG)
1083         (plus:SI (reg:SI SP_REG) (const_int 4)))
1084    (clobber (mem:BLK (scratch)))]
1085   "!TARGET_64BIT"
1086   "pop{l}\t%0"
1087   [(set_attr "type" "pop")
1088    (set_attr "mode" "SI")])
1089
1090 (define_insn "popsi1"
1091   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1092         (mem:SI (reg:SI SP_REG)))
1093    (set (reg:SI SP_REG)
1094         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1095   "!TARGET_64BIT"
1096   "pop{l}\t%0"
1097   [(set_attr "type" "pop")
1098    (set_attr "mode" "SI")])
1099
1100 (define_insn "*movsi_xor"
1101   [(set (match_operand:SI 0 "register_operand" "=r")
1102         (match_operand:SI 1 "const0_operand" "i"))
1103    (clobber (reg:CC FLAGS_REG))]
1104   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1105   "xor{l}\t{%0, %0|%0, %0}"
1106   [(set_attr "type" "alu1")
1107    (set_attr "mode" "SI")
1108    (set_attr "length_immediate" "0")])
1109  
1110 (define_insn "*movsi_or"
1111   [(set (match_operand:SI 0 "register_operand" "=r")
1112         (match_operand:SI 1 "immediate_operand" "i"))
1113    (clobber (reg:CC FLAGS_REG))]
1114   "reload_completed
1115    && operands[1] == constm1_rtx
1116    && (TARGET_PENTIUM || optimize_size)"
1117 {
1118   operands[1] = constm1_rtx;
1119   return "or{l}\t{%1, %0|%0, %1}";
1120 }
1121   [(set_attr "type" "alu1")
1122    (set_attr "mode" "SI")
1123    (set_attr "length_immediate" "1")])
1124
1125 (define_insn "*movsi_1"
1126   [(set (match_operand:SI 0 "nonimmediate_operand"
1127                         "=r  ,m  ,!*y,!rm,!*y,!*x,!rm,!*x")
1128         (match_operand:SI 1 "general_operand"
1129                         "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
1130   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1132 {
1133   switch (get_attr_type (insn))
1134     {
1135     case TYPE_SSEMOV:
1136       if (get_attr_mode (insn) == MODE_TI)
1137         return "movdqa\t{%1, %0|%0, %1}";
1138       return "movd\t{%1, %0|%0, %1}";
1139
1140     case TYPE_MMXMOV:
1141       if (get_attr_mode (insn) == MODE_DI)
1142         return "movq\t{%1, %0|%0, %1}";
1143       return "movd\t{%1, %0|%0, %1}";
1144
1145     case TYPE_LEA:
1146       return "lea{l}\t{%1, %0|%0, %1}";
1147
1148     default:
1149       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1150         abort();
1151       return "mov{l}\t{%1, %0|%0, %1}";
1152     }
1153 }
1154   [(set (attr "type")
1155      (cond [(eq_attr "alternative" "2,3,4")
1156               (const_string "mmxmov")
1157             (eq_attr "alternative" "5,6,7")
1158               (const_string "ssemov")
1159             (and (ne (symbol_ref "flag_pic") (const_int 0))
1160                  (match_operand:SI 1 "symbolic_operand" ""))
1161               (const_string "lea")
1162            ]
1163            (const_string "imov")))
1164    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1165
1166 (define_insn "*movsi_1_nointernunit"
1167   [(set (match_operand:SI 0 "nonimmediate_operand"
1168                         "=r  ,m  ,!*y,!m,!*y,!*x,!m,!*x")
1169         (match_operand:SI 1 "general_operand"
1170                         "rinm,rin,*y ,*y,m  ,*x ,*x,m"))]
1171   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1172    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1173 {
1174   switch (get_attr_type (insn))
1175     {
1176     case TYPE_SSEMOV:
1177       if (get_attr_mode (insn) == MODE_TI)
1178         return "movdqa\t{%1, %0|%0, %1}";
1179       return "movd\t{%1, %0|%0, %1}";
1180
1181     case TYPE_MMXMOV:
1182       if (get_attr_mode (insn) == MODE_DI)
1183         return "movq\t{%1, %0|%0, %1}";
1184       return "movd\t{%1, %0|%0, %1}";
1185
1186     case TYPE_LEA:
1187       return "lea{l}\t{%1, %0|%0, %1}";
1188
1189     default:
1190       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1191         abort();
1192       return "mov{l}\t{%1, %0|%0, %1}";
1193     }
1194 }
1195   [(set (attr "type")
1196      (cond [(eq_attr "alternative" "2,3,4")
1197               (const_string "mmxmov")
1198             (eq_attr "alternative" "5,6,7")
1199               (const_string "ssemov")
1200             (and (ne (symbol_ref "flag_pic") (const_int 0))
1201                  (match_operand:SI 1 "symbolic_operand" ""))
1202               (const_string "lea")
1203            ]
1204            (const_string "imov")))
1205    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1206
1207 ;; Stores and loads of ax to arbitrary constant address.
1208 ;; We fake an second form of instruction to force reload to load address
1209 ;; into register when rax is not available
1210 (define_insn "*movabssi_1_rex64"
1211   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1212         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1213   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1214   "@
1215    movabs{l}\t{%1, %P0|%P0, %1}
1216    mov{l}\t{%1, %a0|%a0, %1}"
1217   [(set_attr "type" "imov")
1218    (set_attr "modrm" "0,*")
1219    (set_attr "length_address" "8,0")
1220    (set_attr "length_immediate" "0,*")
1221    (set_attr "memory" "store")
1222    (set_attr "mode" "SI")])
1223
1224 (define_insn "*movabssi_2_rex64"
1225   [(set (match_operand:SI 0 "register_operand" "=a,r")
1226         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1227   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1228   "@
1229    movabs{l}\t{%P1, %0|%0, %P1}
1230    mov{l}\t{%a1, %0|%0, %a1}"
1231   [(set_attr "type" "imov")
1232    (set_attr "modrm" "0,*")
1233    (set_attr "length_address" "8,0")
1234    (set_attr "length_immediate" "0")
1235    (set_attr "memory" "load")
1236    (set_attr "mode" "SI")])
1237
1238 (define_insn "*swapsi"
1239   [(set (match_operand:SI 0 "register_operand" "+r")
1240         (match_operand:SI 1 "register_operand" "+r"))
1241    (set (match_dup 1)
1242         (match_dup 0))]
1243   ""
1244   "xchg{l}\t%1, %0"
1245   [(set_attr "type" "imov")
1246    (set_attr "mode" "SI")
1247    (set_attr "pent_pair" "np")
1248    (set_attr "athlon_decode" "vector")])
1249
1250 (define_expand "movhi"
1251   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1252         (match_operand:HI 1 "general_operand" ""))]
1253   ""
1254   "ix86_expand_move (HImode, operands); DONE;")
1255
1256 (define_insn "*pushhi2"
1257   [(set (match_operand:HI 0 "push_operand" "=<,<")
1258         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1259   "!TARGET_64BIT"
1260   "@
1261    push{w}\t{|WORD PTR }%1
1262    push{w}\t%1"
1263   [(set_attr "type" "push")
1264    (set_attr "mode" "HI")])
1265
1266 ;; For 64BIT abi we always round up to 8 bytes.
1267 (define_insn "*pushhi2_rex64"
1268   [(set (match_operand:HI 0 "push_operand" "=X")
1269         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1270   "TARGET_64BIT"
1271   "push{q}\t%q1"
1272   [(set_attr "type" "push")
1273    (set_attr "mode" "QI")])
1274
1275 (define_insn "*movhi_1"
1276   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1277         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1278   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1279 {
1280   switch (get_attr_type (insn))
1281     {
1282     case TYPE_IMOVX:
1283       /* movzwl is faster than movw on p2 due to partial word stalls,
1284          though not as fast as an aligned movl.  */
1285       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1286     default:
1287       if (get_attr_mode (insn) == MODE_SI)
1288         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1289       else
1290         return "mov{w}\t{%1, %0|%0, %1}";
1291     }
1292 }
1293   [(set (attr "type")
1294      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1295               (const_string "imov")
1296             (and (eq_attr "alternative" "0")
1297                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1298                           (const_int 0))
1299                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1300                           (const_int 0))))
1301               (const_string "imov")
1302             (and (eq_attr "alternative" "1,2")
1303                  (match_operand:HI 1 "aligned_operand" ""))
1304               (const_string "imov")
1305             (and (ne (symbol_ref "TARGET_MOVX")
1306                      (const_int 0))
1307                  (eq_attr "alternative" "0,2"))
1308               (const_string "imovx")
1309            ]
1310            (const_string "imov")))
1311     (set (attr "mode")
1312       (cond [(eq_attr "type" "imovx")
1313                (const_string "SI")
1314              (and (eq_attr "alternative" "1,2")
1315                   (match_operand:HI 1 "aligned_operand" ""))
1316                (const_string "SI")
1317              (and (eq_attr "alternative" "0")
1318                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319                            (const_int 0))
1320                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1321                            (const_int 0))))
1322                (const_string "SI")
1323             ]
1324             (const_string "HI")))])
1325
1326 ;; Stores and loads of ax to arbitrary constant address.
1327 ;; We fake an second form of instruction to force reload to load address
1328 ;; into register when rax is not available
1329 (define_insn "*movabshi_1_rex64"
1330   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1331         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1332   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1333   "@
1334    movabs{w}\t{%1, %P0|%P0, %1}
1335    mov{w}\t{%1, %a0|%a0, %1}"
1336   [(set_attr "type" "imov")
1337    (set_attr "modrm" "0,*")
1338    (set_attr "length_address" "8,0")
1339    (set_attr "length_immediate" "0,*")
1340    (set_attr "memory" "store")
1341    (set_attr "mode" "HI")])
1342
1343 (define_insn "*movabshi_2_rex64"
1344   [(set (match_operand:HI 0 "register_operand" "=a,r")
1345         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1346   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1347   "@
1348    movabs{w}\t{%P1, %0|%0, %P1}
1349    mov{w}\t{%a1, %0|%0, %a1}"
1350   [(set_attr "type" "imov")
1351    (set_attr "modrm" "0,*")
1352    (set_attr "length_address" "8,0")
1353    (set_attr "length_immediate" "0")
1354    (set_attr "memory" "load")
1355    (set_attr "mode" "HI")])
1356
1357 (define_insn "*swaphi_1"
1358   [(set (match_operand:HI 0 "register_operand" "+r")
1359         (match_operand:HI 1 "register_operand" "+r"))
1360    (set (match_dup 1)
1361         (match_dup 0))]
1362   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1363   "xchg{l}\t%k1, %k0"
1364   [(set_attr "type" "imov")
1365    (set_attr "mode" "SI")
1366    (set_attr "pent_pair" "np")
1367    (set_attr "athlon_decode" "vector")])
1368
1369 (define_insn "*swaphi_2"
1370   [(set (match_operand:HI 0 "register_operand" "+r")
1371         (match_operand:HI 1 "register_operand" "+r"))
1372    (set (match_dup 1)
1373         (match_dup 0))]
1374   "TARGET_PARTIAL_REG_STALL"
1375   "xchg{w}\t%1, %0"
1376   [(set_attr "type" "imov")
1377    (set_attr "mode" "HI")
1378    (set_attr "pent_pair" "np")
1379    (set_attr "athlon_decode" "vector")])
1380
1381 (define_expand "movstricthi"
1382   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1383         (match_operand:HI 1 "general_operand" ""))]
1384   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1385 {
1386   /* Don't generate memory->memory moves, go through a register */
1387   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1388     operands[1] = force_reg (HImode, operands[1]);
1389 })
1390
1391 (define_insn "*movstricthi_1"
1392   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1393         (match_operand:HI 1 "general_operand" "rn,m"))]
1394   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1395    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1396   "mov{w}\t{%1, %0|%0, %1}"
1397   [(set_attr "type" "imov")
1398    (set_attr "mode" "HI")])
1399
1400 (define_insn "*movstricthi_xor"
1401   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1402         (match_operand:HI 1 "const0_operand" "i"))
1403    (clobber (reg:CC FLAGS_REG))]
1404   "reload_completed
1405    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1406   "xor{w}\t{%0, %0|%0, %0}"
1407   [(set_attr "type" "alu1")
1408    (set_attr "mode" "HI")
1409    (set_attr "length_immediate" "0")])
1410
1411 (define_expand "movqi"
1412   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1413         (match_operand:QI 1 "general_operand" ""))]
1414   ""
1415   "ix86_expand_move (QImode, operands); DONE;")
1416
1417 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1418 ;; "push a byte".  But actually we use pushw, which has the effect
1419 ;; of rounding the amount pushed up to a halfword.
1420
1421 (define_insn "*pushqi2"
1422   [(set (match_operand:QI 0 "push_operand" "=X,X")
1423         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1424   "!TARGET_64BIT"
1425   "@
1426    push{w}\t{|word ptr }%1
1427    push{w}\t%w1"
1428   [(set_attr "type" "push")
1429    (set_attr "mode" "HI")])
1430
1431 ;; For 64BIT abi we always round up to 8 bytes.
1432 (define_insn "*pushqi2_rex64"
1433   [(set (match_operand:QI 0 "push_operand" "=X")
1434         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1435   "TARGET_64BIT"
1436   "push{q}\t%q1"
1437   [(set_attr "type" "push")
1438    (set_attr "mode" "QI")])
1439
1440 ;; Situation is quite tricky about when to choose full sized (SImode) move
1441 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1442 ;; partial register dependency machines (such as AMD Athlon), where QImode
1443 ;; moves issue extra dependency and for partial register stalls machines
1444 ;; that don't use QImode patterns (and QImode move cause stall on the next
1445 ;; instruction).
1446 ;;
1447 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1448 ;; register stall machines with, where we use QImode instructions, since
1449 ;; partial register stall can be caused there.  Then we use movzx.
1450 (define_insn "*movqi_1"
1451   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1452         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1453   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1454 {
1455   switch (get_attr_type (insn))
1456     {
1457     case TYPE_IMOVX:
1458       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1459         abort ();
1460       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1461     default:
1462       if (get_attr_mode (insn) == MODE_SI)
1463         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1464       else
1465         return "mov{b}\t{%1, %0|%0, %1}";
1466     }
1467 }
1468   [(set (attr "type")
1469      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1470               (const_string "imov")
1471             (and (eq_attr "alternative" "3")
1472                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1473                           (const_int 0))
1474                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1475                           (const_int 0))))
1476               (const_string "imov")
1477             (eq_attr "alternative" "3,5")
1478               (const_string "imovx")
1479             (and (ne (symbol_ref "TARGET_MOVX")
1480                      (const_int 0))
1481                  (eq_attr "alternative" "2"))
1482               (const_string "imovx")
1483            ]
1484            (const_string "imov")))
1485    (set (attr "mode")
1486       (cond [(eq_attr "alternative" "3,4,5")
1487                (const_string "SI")
1488              (eq_attr "alternative" "6")
1489                (const_string "QI")
1490              (eq_attr "type" "imovx")
1491                (const_string "SI")
1492              (and (eq_attr "type" "imov")
1493                   (and (eq_attr "alternative" "0,1")
1494                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1495                            (const_int 0))))
1496                (const_string "SI")
1497              ;; Avoid partial register stalls when not using QImode arithmetic
1498              (and (eq_attr "type" "imov")
1499                   (and (eq_attr "alternative" "0,1")
1500                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1501                                 (const_int 0))
1502                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1503                                 (const_int 0)))))
1504                (const_string "SI")
1505            ]
1506            (const_string "QI")))])
1507
1508 (define_expand "reload_outqi"
1509   [(parallel [(match_operand:QI 0 "" "=m")
1510               (match_operand:QI 1 "register_operand" "r")
1511               (match_operand:QI 2 "register_operand" "=&q")])]
1512   ""
1513 {
1514   rtx op0, op1, op2;
1515   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1516
1517   if (reg_overlap_mentioned_p (op2, op0))
1518     abort ();
1519   if (! q_regs_operand (op1, QImode))
1520     {
1521       emit_insn (gen_movqi (op2, op1));
1522       op1 = op2;
1523     }
1524   emit_insn (gen_movqi (op0, op1));
1525   DONE;
1526 })
1527
1528 (define_insn "*swapqi_1"
1529   [(set (match_operand:QI 0 "register_operand" "+r")
1530         (match_operand:QI 1 "register_operand" "+r"))
1531    (set (match_dup 1)
1532         (match_dup 0))]
1533   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1534   "xchg{l}\t%k1, %k0"
1535   [(set_attr "type" "imov")
1536    (set_attr "mode" "SI")
1537    (set_attr "pent_pair" "np")
1538    (set_attr "athlon_decode" "vector")])
1539
1540 (define_insn "*swapqi_2"
1541   [(set (match_operand:QI 0 "register_operand" "+q")
1542         (match_operand:QI 1 "register_operand" "+q"))
1543    (set (match_dup 1)
1544         (match_dup 0))]
1545   "TARGET_PARTIAL_REG_STALL"
1546   "xchg{b}\t%1, %0"
1547   [(set_attr "type" "imov")
1548    (set_attr "mode" "QI")
1549    (set_attr "pent_pair" "np")
1550    (set_attr "athlon_decode" "vector")])
1551
1552 (define_expand "movstrictqi"
1553   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1554         (match_operand:QI 1 "general_operand" ""))]
1555   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1556 {
1557   /* Don't generate memory->memory moves, go through a register.  */
1558   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1559     operands[1] = force_reg (QImode, operands[1]);
1560 })
1561
1562 (define_insn "*movstrictqi_1"
1563   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1564         (match_operand:QI 1 "general_operand" "*qn,m"))]
1565   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1566    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1567   "mov{b}\t{%1, %0|%0, %1}"
1568   [(set_attr "type" "imov")
1569    (set_attr "mode" "QI")])
1570
1571 (define_insn "*movstrictqi_xor"
1572   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1573         (match_operand:QI 1 "const0_operand" "i"))
1574    (clobber (reg:CC FLAGS_REG))]
1575   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1576   "xor{b}\t{%0, %0|%0, %0}"
1577   [(set_attr "type" "alu1")
1578    (set_attr "mode" "QI")
1579    (set_attr "length_immediate" "0")])
1580
1581 (define_insn "*movsi_extv_1"
1582   [(set (match_operand:SI 0 "register_operand" "=R")
1583         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1584                          (const_int 8)
1585                          (const_int 8)))]
1586   ""
1587   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1588   [(set_attr "type" "imovx")
1589    (set_attr "mode" "SI")])
1590
1591 (define_insn "*movhi_extv_1"
1592   [(set (match_operand:HI 0 "register_operand" "=R")
1593         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1594                          (const_int 8)
1595                          (const_int 8)))]
1596   ""
1597   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1598   [(set_attr "type" "imovx")
1599    (set_attr "mode" "SI")])
1600
1601 (define_insn "*movqi_extv_1"
1602   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1603         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1604                          (const_int 8)
1605                          (const_int 8)))]
1606   "!TARGET_64BIT"
1607 {
1608   switch (get_attr_type (insn))
1609     {
1610     case TYPE_IMOVX:
1611       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1612     default:
1613       return "mov{b}\t{%h1, %0|%0, %h1}";
1614     }
1615 }
1616   [(set (attr "type")
1617      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1618                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1619                              (ne (symbol_ref "TARGET_MOVX")
1620                                  (const_int 0))))
1621         (const_string "imovx")
1622         (const_string "imov")))
1623    (set (attr "mode")
1624      (if_then_else (eq_attr "type" "imovx")
1625         (const_string "SI")
1626         (const_string "QI")))])
1627
1628 (define_insn "*movqi_extv_1_rex64"
1629   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1630         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1631                          (const_int 8)
1632                          (const_int 8)))]
1633   "TARGET_64BIT"
1634 {
1635   switch (get_attr_type (insn))
1636     {
1637     case TYPE_IMOVX:
1638       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1639     default:
1640       return "mov{b}\t{%h1, %0|%0, %h1}";
1641     }
1642 }
1643   [(set (attr "type")
1644      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1645                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1646                              (ne (symbol_ref "TARGET_MOVX")
1647                                  (const_int 0))))
1648         (const_string "imovx")
1649         (const_string "imov")))
1650    (set (attr "mode")
1651      (if_then_else (eq_attr "type" "imovx")
1652         (const_string "SI")
1653         (const_string "QI")))])
1654
1655 ;; Stores and loads of ax to arbitrary constant address.
1656 ;; We fake an second form of instruction to force reload to load address
1657 ;; into register when rax is not available
1658 (define_insn "*movabsqi_1_rex64"
1659   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1660         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1661   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1662   "@
1663    movabs{b}\t{%1, %P0|%P0, %1}
1664    mov{b}\t{%1, %a0|%a0, %1}"
1665   [(set_attr "type" "imov")
1666    (set_attr "modrm" "0,*")
1667    (set_attr "length_address" "8,0")
1668    (set_attr "length_immediate" "0,*")
1669    (set_attr "memory" "store")
1670    (set_attr "mode" "QI")])
1671
1672 (define_insn "*movabsqi_2_rex64"
1673   [(set (match_operand:QI 0 "register_operand" "=a,r")
1674         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1675   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1676   "@
1677    movabs{b}\t{%P1, %0|%0, %P1}
1678    mov{b}\t{%a1, %0|%0, %a1}"
1679   [(set_attr "type" "imov")
1680    (set_attr "modrm" "0,*")
1681    (set_attr "length_address" "8,0")
1682    (set_attr "length_immediate" "0")
1683    (set_attr "memory" "load")
1684    (set_attr "mode" "QI")])
1685
1686 (define_insn "*movsi_extzv_1"
1687   [(set (match_operand:SI 0 "register_operand" "=R")
1688         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1689                          (const_int 8)
1690                          (const_int 8)))]
1691   ""
1692   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1693   [(set_attr "type" "imovx")
1694    (set_attr "mode" "SI")])
1695
1696 (define_insn "*movqi_extzv_2"
1697   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1698         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1699                                     (const_int 8)
1700                                     (const_int 8)) 0))]
1701   "!TARGET_64BIT"
1702 {
1703   switch (get_attr_type (insn))
1704     {
1705     case TYPE_IMOVX:
1706       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1707     default:
1708       return "mov{b}\t{%h1, %0|%0, %h1}";
1709     }
1710 }
1711   [(set (attr "type")
1712      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1713                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1714                              (ne (symbol_ref "TARGET_MOVX")
1715                                  (const_int 0))))
1716         (const_string "imovx")
1717         (const_string "imov")))
1718    (set (attr "mode")
1719      (if_then_else (eq_attr "type" "imovx")
1720         (const_string "SI")
1721         (const_string "QI")))])
1722
1723 (define_insn "*movqi_extzv_2_rex64"
1724   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1725         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1726                                     (const_int 8)
1727                                     (const_int 8)) 0))]
1728   "TARGET_64BIT"
1729 {
1730   switch (get_attr_type (insn))
1731     {
1732     case TYPE_IMOVX:
1733       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1734     default:
1735       return "mov{b}\t{%h1, %0|%0, %h1}";
1736     }
1737 }
1738   [(set (attr "type")
1739      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1740                         (ne (symbol_ref "TARGET_MOVX")
1741                             (const_int 0)))
1742         (const_string "imovx")
1743         (const_string "imov")))
1744    (set (attr "mode")
1745      (if_then_else (eq_attr "type" "imovx")
1746         (const_string "SI")
1747         (const_string "QI")))])
1748
1749 (define_insn "movsi_insv_1"
1750   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1751                          (const_int 8)
1752                          (const_int 8))
1753         (match_operand:SI 1 "general_operand" "Qmn"))]
1754   "!TARGET_64BIT"
1755   "mov{b}\t{%b1, %h0|%h0, %b1}"
1756   [(set_attr "type" "imov")
1757    (set_attr "mode" "QI")])
1758
1759 (define_insn "movdi_insv_1_rex64"
1760   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1761                          (const_int 8)
1762                          (const_int 8))
1763         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1764   "TARGET_64BIT"
1765   "mov{b}\t{%b1, %h0|%h0, %b1}"
1766   [(set_attr "type" "imov")
1767    (set_attr "mode" "QI")])
1768
1769 (define_insn "*movqi_insv_2"
1770   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1771                          (const_int 8)
1772                          (const_int 8))
1773         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1774                      (const_int 8)))]
1775   ""
1776   "mov{b}\t{%h1, %h0|%h0, %h1}"
1777   [(set_attr "type" "imov")
1778    (set_attr "mode" "QI")])
1779
1780 (define_expand "movdi"
1781   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1782         (match_operand:DI 1 "general_operand" ""))]
1783   ""
1784   "ix86_expand_move (DImode, operands); DONE;")
1785
1786 (define_insn "*pushdi"
1787   [(set (match_operand:DI 0 "push_operand" "=<")
1788         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1789   "!TARGET_64BIT"
1790   "#")
1791
1792 (define_insn "*pushdi2_rex64"
1793   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1794         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1795   "TARGET_64BIT"
1796   "@
1797    push{q}\t%1
1798    #"
1799   [(set_attr "type" "push,multi")
1800    (set_attr "mode" "DI")])
1801
1802 ;; Convert impossible pushes of immediate to existing instructions.
1803 ;; First try to get scratch register and go through it.  In case this
1804 ;; fails, push sign extended lower part first and then overwrite
1805 ;; upper part by 32bit move.
1806 (define_peephole2
1807   [(match_scratch:DI 2 "r")
1808    (set (match_operand:DI 0 "push_operand" "")
1809         (match_operand:DI 1 "immediate_operand" ""))]
1810   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1811    && !x86_64_immediate_operand (operands[1], DImode)"
1812   [(set (match_dup 2) (match_dup 1))
1813    (set (match_dup 0) (match_dup 2))]
1814   "")
1815
1816 ;; We need to define this as both peepholer and splitter for case
1817 ;; peephole2 pass is not run.
1818 ;; "&& 1" is needed to keep it from matching the previous pattern.
1819 (define_peephole2
1820   [(set (match_operand:DI 0 "push_operand" "")
1821         (match_operand:DI 1 "immediate_operand" ""))]
1822   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1823    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1824   [(set (match_dup 0) (match_dup 1))
1825    (set (match_dup 2) (match_dup 3))]
1826   "split_di (operands + 1, 1, operands + 2, operands + 3);
1827    operands[1] = gen_lowpart (DImode, operands[2]);
1828    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1829                                                     GEN_INT (4)));
1830   ")
1831
1832 (define_split
1833   [(set (match_operand:DI 0 "push_operand" "")
1834         (match_operand:DI 1 "immediate_operand" ""))]
1835   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1836    && !symbolic_operand (operands[1], DImode)
1837    && !x86_64_immediate_operand (operands[1], DImode)"
1838   [(set (match_dup 0) (match_dup 1))
1839    (set (match_dup 2) (match_dup 3))]
1840   "split_di (operands + 1, 1, operands + 2, operands + 3);
1841    operands[1] = gen_lowpart (DImode, operands[2]);
1842    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1843                                                     GEN_INT (4)));
1844   ")
1845
1846 (define_insn "*pushdi2_prologue_rex64"
1847   [(set (match_operand:DI 0 "push_operand" "=<")
1848         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1849    (clobber (mem:BLK (scratch)))]
1850   "TARGET_64BIT"
1851   "push{q}\t%1"
1852   [(set_attr "type" "push")
1853    (set_attr "mode" "DI")])
1854
1855 (define_insn "*popdi1_epilogue_rex64"
1856   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1857         (mem:DI (reg:DI SP_REG)))
1858    (set (reg:DI SP_REG)
1859         (plus:DI (reg:DI SP_REG) (const_int 8)))
1860    (clobber (mem:BLK (scratch)))]
1861   "TARGET_64BIT"
1862   "pop{q}\t%0"
1863   [(set_attr "type" "pop")
1864    (set_attr "mode" "DI")])
1865
1866 (define_insn "popdi1"
1867   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1868         (mem:DI (reg:DI SP_REG)))
1869    (set (reg:DI SP_REG)
1870         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1871   "TARGET_64BIT"
1872   "pop{q}\t%0"
1873   [(set_attr "type" "pop")
1874    (set_attr "mode" "DI")])
1875
1876 (define_insn "*movdi_xor_rex64"
1877   [(set (match_operand:DI 0 "register_operand" "=r")
1878         (match_operand:DI 1 "const0_operand" "i"))
1879    (clobber (reg:CC FLAGS_REG))]
1880   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1881    && reload_completed"
1882   "xor{l}\t{%k0, %k0|%k0, %k0}"
1883   [(set_attr "type" "alu1")
1884    (set_attr "mode" "SI")
1885    (set_attr "length_immediate" "0")])
1886
1887 (define_insn "*movdi_or_rex64"
1888   [(set (match_operand:DI 0 "register_operand" "=r")
1889         (match_operand:DI 1 "const_int_operand" "i"))
1890    (clobber (reg:CC FLAGS_REG))]
1891   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1892    && reload_completed
1893    && operands[1] == constm1_rtx"
1894 {
1895   operands[1] = constm1_rtx;
1896   return "or{q}\t{%1, %0|%0, %1}";
1897 }
1898   [(set_attr "type" "alu1")
1899    (set_attr "mode" "DI")
1900    (set_attr "length_immediate" "1")])
1901
1902 (define_insn "*movdi_2"
1903   [(set (match_operand:DI 0 "nonimmediate_operand"
1904                                         "=r  ,o  ,m*y,*y,m ,*Y,*Y,m ,*x,*x")
1905         (match_operand:DI 1 "general_operand"
1906                                         "riFo,riF,*y ,m ,*Y,*Y,m ,*x,*x,m "))]
1907   "!TARGET_64BIT
1908    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1909   "@
1910    #
1911    #
1912    movq\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}
1914    movq\t{%1, %0|%0, %1}
1915    movdqa\t{%1, %0|%0, %1}
1916    movq\t{%1, %0|%0, %1}
1917    movlps\t{%1, %0|%0, %1}
1918    movaps\t{%1, %0|%0, %1}
1919    movlps\t{%1, %0|%0, %1}"
1920   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
1921    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,V2SF,V4SF,V2SF")])
1922
1923 (define_split
1924   [(set (match_operand:DI 0 "push_operand" "")
1925         (match_operand:DI 1 "general_operand" ""))]
1926   "!TARGET_64BIT && reload_completed
1927    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1928   [(const_int 0)]
1929   "ix86_split_long_move (operands); DONE;")
1930
1931 ;; %%% This multiword shite has got to go.
1932 (define_split
1933   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1934         (match_operand:DI 1 "general_operand" ""))]
1935   "!TARGET_64BIT && reload_completed
1936    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1937    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1938   [(const_int 0)]
1939   "ix86_split_long_move (operands); DONE;")
1940
1941 (define_insn "*movdi_1_rex64"
1942   [(set (match_operand:DI 0 "nonimmediate_operand"
1943                 "=r,r  ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
1944         (match_operand:DI 1 "general_operand"
1945                 "Z ,rem,i,re,n  ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
1946   "TARGET_64BIT
1947    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1948    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1949 {
1950   switch (get_attr_type (insn))
1951     {
1952     case TYPE_SSECVT:
1953       if (which_alternative == 11)
1954         return "movq2dq\t{%1, %0|%0, %1}";
1955       else
1956         return "movdq2q\t{%1, %0|%0, %1}";
1957     case TYPE_SSEMOV:
1958       if (get_attr_mode (insn) == MODE_TI)
1959           return "movdqa\t{%1, %0|%0, %1}";
1960       /* FALLTHRU */
1961     case TYPE_MMXMOV:
1962       /* Moves from and into integer register is done using movd opcode with
1963          REX prefix.  */
1964       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1965           return "movd\t{%1, %0|%0, %1}";
1966       return "movq\t{%1, %0|%0, %1}";
1967     case TYPE_MULTI:
1968       return "#";
1969     case TYPE_LEA:
1970       return "lea{q}\t{%a1, %0|%0, %a1}";
1971     default:
1972       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1973         abort ();
1974       if (get_attr_mode (insn) == MODE_SI)
1975         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1976       else if (which_alternative == 2)
1977         return "movabs{q}\t{%1, %0|%0, %1}";
1978       else
1979         return "mov{q}\t{%1, %0|%0, %1}";
1980     }
1981 }
1982   [(set (attr "type")
1983      (cond [(eq_attr "alternative" "5,6,7")
1984               (const_string "mmxmov")
1985             (eq_attr "alternative" "8,9,10")
1986               (const_string "ssemov")
1987             (eq_attr "alternative" "11,12")
1988               (const_string "ssecvt")
1989             (eq_attr "alternative" "4")
1990               (const_string "multi")
1991             (and (ne (symbol_ref "flag_pic") (const_int 0))
1992                  (match_operand:DI 1 "symbolic_operand" ""))
1993               (const_string "lea")
1994            ]
1995            (const_string "imov")))
1996    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1997    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1998    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1999
2000 (define_insn "*movdi_1_rex64_nointerunit"
2001   [(set (match_operand:DI 0 "nonimmediate_operand"
2002                 "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2003         (match_operand:DI 1 "general_operand"
2004                 "Z,rem,i,re,n  ,*y ,*y,m  ,*Y ,*Y,m"))]
2005   "TARGET_64BIT
2006    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2007    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2008 {
2009   switch (get_attr_type (insn))
2010     {
2011     case TYPE_SSEMOV:
2012       if (get_attr_mode (insn) == MODE_TI)
2013           return "movdqa\t{%1, %0|%0, %1}";
2014       /* FALLTHRU */
2015     case TYPE_MMXMOV:
2016       return "movq\t{%1, %0|%0, %1}";
2017     case TYPE_MULTI:
2018       return "#";
2019     case TYPE_LEA:
2020       return "lea{q}\t{%a1, %0|%0, %a1}";
2021     default:
2022       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2023         abort ();
2024       if (get_attr_mode (insn) == MODE_SI)
2025         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2026       else if (which_alternative == 2)
2027         return "movabs{q}\t{%1, %0|%0, %1}";
2028       else
2029         return "mov{q}\t{%1, %0|%0, %1}";
2030     }
2031 }
2032   [(set (attr "type")
2033      (cond [(eq_attr "alternative" "5,6,7")
2034               (const_string "mmxmov")
2035             (eq_attr "alternative" "8,9,10")
2036               (const_string "ssemov")
2037             (eq_attr "alternative" "4")
2038               (const_string "multi")
2039             (and (ne (symbol_ref "flag_pic") (const_int 0))
2040                  (match_operand:DI 1 "symbolic_operand" ""))
2041               (const_string "lea")
2042            ]
2043            (const_string "imov")))
2044    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2045    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2046    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2047
2048 ;; Stores and loads of ax to arbitrary constant address.
2049 ;; We fake an second form of instruction to force reload to load address
2050 ;; into register when rax is not available
2051 (define_insn "*movabsdi_1_rex64"
2052   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2053         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2054   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2055   "@
2056    movabs{q}\t{%1, %P0|%P0, %1}
2057    mov{q}\t{%1, %a0|%a0, %1}"
2058   [(set_attr "type" "imov")
2059    (set_attr "modrm" "0,*")
2060    (set_attr "length_address" "8,0")
2061    (set_attr "length_immediate" "0,*")
2062    (set_attr "memory" "store")
2063    (set_attr "mode" "DI")])
2064
2065 (define_insn "*movabsdi_2_rex64"
2066   [(set (match_operand:DI 0 "register_operand" "=a,r")
2067         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2068   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2069   "@
2070    movabs{q}\t{%P1, %0|%0, %P1}
2071    mov{q}\t{%a1, %0|%0, %a1}"
2072   [(set_attr "type" "imov")
2073    (set_attr "modrm" "0,*")
2074    (set_attr "length_address" "8,0")
2075    (set_attr "length_immediate" "0")
2076    (set_attr "memory" "load")
2077    (set_attr "mode" "DI")])
2078
2079 ;; Convert impossible stores of immediate to existing instructions.
2080 ;; First try to get scratch register and go through it.  In case this
2081 ;; fails, move by 32bit parts.
2082 (define_peephole2
2083   [(match_scratch:DI 2 "r")
2084    (set (match_operand:DI 0 "memory_operand" "")
2085         (match_operand:DI 1 "immediate_operand" ""))]
2086   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087    && !x86_64_immediate_operand (operands[1], DImode)"
2088   [(set (match_dup 2) (match_dup 1))
2089    (set (match_dup 0) (match_dup 2))]
2090   "")
2091
2092 ;; We need to define this as both peepholer and splitter for case
2093 ;; peephole2 pass is not run.
2094 ;; "&& 1" is needed to keep it from matching the previous pattern.
2095 (define_peephole2
2096   [(set (match_operand:DI 0 "memory_operand" "")
2097         (match_operand:DI 1 "immediate_operand" ""))]
2098   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2100   [(set (match_dup 2) (match_dup 3))
2101    (set (match_dup 4) (match_dup 5))]
2102   "split_di (operands, 2, operands + 2, operands + 4);")
2103
2104 (define_split
2105   [(set (match_operand:DI 0 "memory_operand" "")
2106         (match_operand:DI 1 "immediate_operand" ""))]
2107   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2108    && !symbolic_operand (operands[1], DImode)
2109    && !x86_64_immediate_operand (operands[1], DImode)"
2110   [(set (match_dup 2) (match_dup 3))
2111    (set (match_dup 4) (match_dup 5))]
2112   "split_di (operands, 2, operands + 2, operands + 4);")
2113
2114 (define_insn "*swapdi_rex64"
2115   [(set (match_operand:DI 0 "register_operand" "+r")
2116         (match_operand:DI 1 "register_operand" "+r"))
2117    (set (match_dup 1)
2118         (match_dup 0))]
2119   "TARGET_64BIT"
2120   "xchg{q}\t%1, %0"
2121   [(set_attr "type" "imov")
2122    (set_attr "mode" "DI")
2123    (set_attr "pent_pair" "np")
2124    (set_attr "athlon_decode" "vector")])
2125
2126 (define_expand "movti"
2127   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2128         (match_operand:TI 1 "nonimmediate_operand" ""))]
2129   "TARGET_SSE || TARGET_64BIT"
2130 {
2131   if (TARGET_64BIT)
2132     ix86_expand_move (TImode, operands);
2133   else
2134     ix86_expand_vector_move (TImode, operands);
2135   DONE;
2136 })
2137
2138 (define_insn "*movti_internal"
2139   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2140         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2141   "TARGET_SSE && !TARGET_64BIT
2142    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2143 {
2144   switch (which_alternative)
2145     {
2146     case 0:
2147       if (get_attr_mode (insn) == MODE_V4SF)
2148         return "xorps\t%0, %0";
2149       else
2150         return "pxor\t%0, %0";
2151     case 1:
2152     case 2:
2153       if (get_attr_mode (insn) == MODE_V4SF)
2154         return "movaps\t{%1, %0|%0, %1}";
2155       else
2156         return "movdqa\t{%1, %0|%0, %1}";
2157     default:
2158       abort ();
2159     }
2160 }
2161   [(set_attr "type" "ssemov,ssemov,ssemov")
2162    (set (attr "mode")
2163         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2164                  (const_string "V4SF")
2165
2166                (eq_attr "alternative" "0,1")
2167                  (if_then_else
2168                    (ne (symbol_ref "optimize_size")
2169                        (const_int 0))
2170                    (const_string "V4SF")
2171                    (const_string "TI"))
2172                (eq_attr "alternative" "2")
2173                  (if_then_else
2174                    (ne (symbol_ref "optimize_size")
2175                        (const_int 0))
2176                    (const_string "V4SF")
2177                    (const_string "TI"))]
2178                (const_string "TI")))])
2179
2180 (define_insn "*movti_rex64"
2181   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2182         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2183   "TARGET_64BIT
2184    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2185 {
2186   switch (which_alternative)
2187     {
2188     case 0:
2189     case 1:
2190       return "#";
2191     case 2:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 3:
2197     case 4:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       abort ();
2204     }
2205 }
2206   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(eq_attr "alternative" "2,3")
2209                  (if_then_else
2210                    (ne (symbol_ref "optimize_size")
2211                        (const_int 0))
2212                    (const_string "V4SF")
2213                    (const_string "TI"))
2214                (eq_attr "alternative" "4")
2215                  (if_then_else
2216                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2217                             (const_int 0))
2218                         (ne (symbol_ref "optimize_size")
2219                             (const_int 0)))
2220                    (const_string "V4SF")
2221                    (const_string "TI"))]
2222                (const_string "DI")))])
2223
2224 (define_split
2225   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2226         (match_operand:TI 1 "general_operand" ""))]
2227   "reload_completed && !SSE_REG_P (operands[0])
2228    && !SSE_REG_P (operands[1])"
2229   [(const_int 0)]
2230   "ix86_split_long_move (operands); DONE;")
2231
2232 (define_expand "movsf"
2233   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2234         (match_operand:SF 1 "general_operand" ""))]
2235   ""
2236   "ix86_expand_move (SFmode, operands); DONE;")
2237
2238 (define_insn "*pushsf"
2239   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2240         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2241   "!TARGET_64BIT"
2242 {
2243   switch (which_alternative)
2244     {
2245     case 1:
2246       return "push{l}\t%1";
2247
2248     default:
2249       /* This insn should be already split before reg-stack.  */
2250       abort ();
2251     }
2252 }
2253   [(set_attr "type" "multi,push,multi")
2254    (set_attr "mode" "SF,SI,SF")])
2255
2256 (define_insn "*pushsf_rex64"
2257   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2258         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2259   "TARGET_64BIT"
2260 {
2261   switch (which_alternative)
2262     {
2263     case 1:
2264       return "push{q}\t%q1";
2265
2266     default:
2267       /* This insn should be already split before reg-stack.  */
2268       abort ();
2269     }
2270 }
2271   [(set_attr "type" "multi,push,multi")
2272    (set_attr "mode" "SF,DI,SF")])
2273
2274 (define_split
2275   [(set (match_operand:SF 0 "push_operand" "")
2276         (match_operand:SF 1 "memory_operand" ""))]
2277   "reload_completed
2278    && GET_CODE (operands[1]) == MEM
2279    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2280    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2281   [(set (match_dup 0)
2282         (match_dup 1))]
2283   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2284
2285
2286 ;; %%% Kill this when call knows how to work this out.
2287 (define_split
2288   [(set (match_operand:SF 0 "push_operand" "")
2289         (match_operand:SF 1 "any_fp_register_operand" ""))]
2290   "!TARGET_64BIT"
2291   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2292    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2293
2294 (define_split
2295   [(set (match_operand:SF 0 "push_operand" "")
2296         (match_operand:SF 1 "any_fp_register_operand" ""))]
2297   "TARGET_64BIT"
2298   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2299    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2300
2301 (define_insn "*movsf_1"
2302   [(set (match_operand:SF 0 "nonimmediate_operand"
2303           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2304         (match_operand:SF 1 "general_operand"
2305           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2306   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2307    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2308    && (reload_in_progress || reload_completed
2309        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2310        || GET_CODE (operands[1]) != CONST_DOUBLE
2311        || memory_operand (operands[0], SFmode))" 
2312 {
2313   switch (which_alternative)
2314     {
2315     case 0:
2316       return output_387_reg_move (insn, operands);
2317
2318     case 1:
2319       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320         return "fstp%z0\t%y0";
2321       else
2322         return "fst%z0\t%y0";
2323
2324     case 2:
2325       return standard_80387_constant_opcode (operands[1]);
2326
2327     case 3:
2328     case 4:
2329       return "mov{l}\t{%1, %0|%0, %1}";
2330     case 5:
2331       if (get_attr_mode (insn) == MODE_TI)
2332         return "pxor\t%0, %0";
2333       else
2334         return "xorps\t%0, %0";
2335     case 6:
2336       if (get_attr_mode (insn) == MODE_V4SF)
2337         return "movaps\t{%1, %0|%0, %1}";
2338       else
2339         return "movss\t{%1, %0|%0, %1}";
2340     case 7:
2341     case 8:
2342       return "movss\t{%1, %0|%0, %1}";
2343
2344     case 9:
2345     case 10:
2346       return "movd\t{%1, %0|%0, %1}";
2347
2348     case 11:
2349       return "movq\t{%1, %0|%0, %1}";
2350
2351     default:
2352       abort();
2353     }
2354 }
2355   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356    (set (attr "mode")
2357         (cond [(eq_attr "alternative" "3,4,9,10")
2358                  (const_string "SI")
2359                (eq_attr "alternative" "5")
2360                  (if_then_else
2361                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362                                  (const_int 0))
2363                              (ne (symbol_ref "TARGET_SSE2")
2364                                  (const_int 0)))
2365                         (eq (symbol_ref "optimize_size")
2366                             (const_int 0)))
2367                    (const_string "TI")
2368                    (const_string "V4SF"))
2369                /* For architectures resolving dependencies on
2370                   whole SSE registers use APS move to break dependency
2371                   chains, otherwise use short move to avoid extra work. 
2372
2373                   Do the same for architectures resolving dependencies on
2374                   the parts.  While in DF mode it is better to always handle
2375                   just register parts, the SF mode is different due to lack
2376                   of instructions to load just part of the register.  It is
2377                   better to maintain the whole registers in single format
2378                   to avoid problems on using packed logical operations.  */
2379                (eq_attr "alternative" "6")
2380                  (if_then_else
2381                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382                             (const_int 0))
2383                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384                             (const_int 0)))
2385                    (const_string "V4SF")
2386                    (const_string "SF"))
2387                (eq_attr "alternative" "11")
2388                  (const_string "DI")]
2389                (const_string "SF")))])
2390
2391 (define_insn "*movsf_1_nointerunit"
2392   [(set (match_operand:SF 0 "nonimmediate_operand"
2393           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!m,!*y")
2394         (match_operand:SF 1 "general_operand"
2395           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,m  ,*y,*y"))]
2396   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2397    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2398    && (reload_in_progress || reload_completed
2399        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2400        || GET_CODE (operands[1]) != CONST_DOUBLE
2401        || memory_operand (operands[0], SFmode))" 
2402 {
2403   switch (which_alternative)
2404     {
2405     case 0:
2406       return output_387_reg_move (insn, operands);
2407
2408     case 1:
2409       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2410         return "fstp%z0\t%y0";
2411       else
2412         return "fst%z0\t%y0";
2413
2414     case 2:
2415       return standard_80387_constant_opcode (operands[1]);
2416
2417     case 3:
2418     case 4:
2419       return "mov{l}\t{%1, %0|%0, %1}";
2420     case 5:
2421       if (get_attr_mode (insn) == MODE_TI)
2422         return "pxor\t%0, %0";
2423       else
2424         return "xorps\t%0, %0";
2425     case 6:
2426       if (get_attr_mode (insn) == MODE_V4SF)
2427         return "movaps\t{%1, %0|%0, %1}";
2428       else
2429         return "movss\t{%1, %0|%0, %1}";
2430     case 7:
2431     case 8:
2432       return "movss\t{%1, %0|%0, %1}";
2433
2434     case 9:
2435     case 10:
2436       return "movd\t{%1, %0|%0, %1}";
2437
2438     case 11:
2439       return "movq\t{%1, %0|%0, %1}";
2440
2441     default:
2442       abort();
2443     }
2444 }
2445   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2446    (set (attr "mode")
2447         (cond [(eq_attr "alternative" "3,4,9,10")
2448                  (const_string "SI")
2449                (eq_attr "alternative" "5")
2450                  (if_then_else
2451                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2452                                  (const_int 0))
2453                              (ne (symbol_ref "TARGET_SSE2")
2454                                  (const_int 0)))
2455                         (eq (symbol_ref "optimize_size")
2456                             (const_int 0)))
2457                    (const_string "TI")
2458                    (const_string "V4SF"))
2459                /* For architectures resolving dependencies on
2460                   whole SSE registers use APS move to break dependency
2461                   chains, otherwise use short move to avoid extra work. 
2462
2463                   Do the same for architectures resolving dependencies on
2464                   the parts.  While in DF mode it is better to always handle
2465                   just register parts, the SF mode is different due to lack
2466                   of instructions to load just part of the register.  It is
2467                   better to maintain the whole registers in single format
2468                   to avoid problems on using packed logical operations.  */
2469                (eq_attr "alternative" "6")
2470                  (if_then_else
2471                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2472                             (const_int 0))
2473                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2474                             (const_int 0)))
2475                    (const_string "V4SF")
2476                    (const_string "SF"))
2477                (eq_attr "alternative" "11")
2478                  (const_string "DI")]
2479                (const_string "SF")))])
2480
2481 (define_insn "*swapsf"
2482   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2483         (match_operand:SF 1 "fp_register_operand" "+f"))
2484    (set (match_dup 1)
2485         (match_dup 0))]
2486   "reload_completed || TARGET_80387"
2487 {
2488   if (STACK_TOP_P (operands[0]))
2489     return "fxch\t%1";
2490   else
2491     return "fxch\t%0";
2492 }
2493   [(set_attr "type" "fxch")
2494    (set_attr "mode" "SF")])
2495
2496 (define_expand "movdf"
2497   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2498         (match_operand:DF 1 "general_operand" ""))]
2499   ""
2500   "ix86_expand_move (DFmode, operands); DONE;")
2501
2502 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2503 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2504 ;; On the average, pushdf using integers can be still shorter.  Allow this
2505 ;; pattern for optimize_size too.
2506
2507 (define_insn "*pushdf_nointeger"
2508   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2509         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2510   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2511 {
2512   /* This insn should be already split before reg-stack.  */
2513   abort ();
2514 }
2515   [(set_attr "type" "multi")
2516    (set_attr "mode" "DF,SI,SI,DF")])
2517
2518 (define_insn "*pushdf_integer"
2519   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2520         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2521   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2522 {
2523   /* This insn should be already split before reg-stack.  */
2524   abort ();
2525 }
2526   [(set_attr "type" "multi")
2527    (set_attr "mode" "DF,SI,DF")])
2528
2529 ;; %%% Kill this when call knows how to work this out.
2530 (define_split
2531   [(set (match_operand:DF 0 "push_operand" "")
2532         (match_operand:DF 1 "any_fp_register_operand" ""))]
2533   "!TARGET_64BIT && reload_completed"
2534   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2535    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2536   "")
2537
2538 (define_split
2539   [(set (match_operand:DF 0 "push_operand" "")
2540         (match_operand:DF 1 "any_fp_register_operand" ""))]
2541   "TARGET_64BIT && reload_completed"
2542   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2543    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2544   "")
2545
2546 (define_split
2547   [(set (match_operand:DF 0 "push_operand" "")
2548         (match_operand:DF 1 "general_operand" ""))]
2549   "reload_completed"
2550   [(const_int 0)]
2551   "ix86_split_long_move (operands); DONE;")
2552
2553 ;; Moving is usually shorter when only FP registers are used. This separate
2554 ;; movdf pattern avoids the use of integer registers for FP operations
2555 ;; when optimizing for size.
2556
2557 (define_insn "*movdf_nointeger"
2558   [(set (match_operand:DF 0 "nonimmediate_operand"
2559                         "=f#Y,m  ,f#Y,*r  ,o  ,Y#f*x,Y#f*x,Y#f*x  ,m    ")
2560         (match_operand:DF 1 "general_operand"
2561                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y#f*x,HmY#f*x,Y#f*x"))]
2562   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2563    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2564    && (reload_in_progress || reload_completed
2565        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2566        || GET_CODE (operands[1]) != CONST_DOUBLE
2567        || memory_operand (operands[0], DFmode))" 
2568 {
2569   switch (which_alternative)
2570     {
2571     case 0:
2572       return output_387_reg_move (insn, operands);
2573
2574     case 1:
2575       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2576         return "fstp%z0\t%y0";
2577       else
2578         return "fst%z0\t%y0";
2579
2580     case 2:
2581       return standard_80387_constant_opcode (operands[1]);
2582
2583     case 3:
2584     case 4:
2585       return "#";
2586     case 5:
2587       switch (get_attr_mode (insn))
2588         {
2589         case MODE_V4SF:
2590           return "xorps\t%0, %0";
2591         case MODE_V2DF:
2592           return "xorpd\t%0, %0";
2593         case MODE_TI:
2594           return "pxor\t%0, %0";
2595         default:
2596           abort ();
2597         }
2598     case 6:
2599     case 7:
2600     case 8:
2601       switch (get_attr_mode (insn))
2602         {
2603         case MODE_V4SF:
2604           return "movaps\t{%1, %0|%0, %1}";
2605         case MODE_V2DF:
2606           return "movapd\t{%1, %0|%0, %1}";
2607         case MODE_TI:
2608           return "movdqa\t{%1, %0|%0, %1}";
2609         case MODE_DI:
2610           return "movq\t{%1, %0|%0, %1}";
2611         case MODE_DF:
2612           return "movsd\t{%1, %0|%0, %1}";
2613         case MODE_V1DF:
2614           return "movlpd\t{%1, %0|%0, %1}";
2615         case MODE_V2SF:
2616           return "movlps\t{%1, %0|%0, %1}";
2617         default:
2618           abort ();
2619         }
2620
2621     default:
2622       abort();
2623     }
2624 }
2625   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2626    (set (attr "mode")
2627         (cond [(eq_attr "alternative" "0,1,2")
2628                  (const_string "DF")
2629                (eq_attr "alternative" "3,4")
2630                  (const_string "SI")
2631
2632                /* For SSE1, we have many fewer alternatives.  */
2633                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2634                  (cond [(eq_attr "alternative" "5,6")
2635                           (const_string "V4SF")
2636                        ]
2637                    (const_string "V2SF"))
2638
2639                /* xorps is one byte shorter.  */
2640                (eq_attr "alternative" "5")
2641                  (cond [(ne (symbol_ref "optimize_size")
2642                             (const_int 0))
2643                           (const_string "V4SF")
2644                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2645                             (const_int 0))
2646                           (const_string "TI")
2647                        ]
2648                        (const_string "V2DF"))
2649
2650                /* For architectures resolving dependencies on
2651                   whole SSE registers use APD move to break dependency
2652                   chains, otherwise use short move to avoid extra work.
2653
2654                   movaps encodes one byte shorter.  */
2655                (eq_attr "alternative" "6")
2656                  (cond
2657                    [(ne (symbol_ref "optimize_size")
2658                         (const_int 0))
2659                       (const_string "V4SF")
2660                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2661                         (const_int 0))
2662                       (const_string "V2DF")
2663                    ]
2664                    (const_string "DF"))
2665                /* For architectures resolving dependencies on register
2666                   parts we may avoid extra work to zero out upper part
2667                   of register.  */
2668                (eq_attr "alternative" "7")
2669                  (if_then_else
2670                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2671                        (const_int 0))
2672                    (const_string "V1DF")
2673                    (const_string "DF"))
2674               ]
2675               (const_string "DF")))])
2676
2677 (define_insn "*movdf_integer"
2678   [(set (match_operand:DF 0 "nonimmediate_operand"
2679                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y#rf*x,Y#rf*x,Y#rf*x,m")
2680         (match_operand:DF 1 "general_operand"
2681                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y#rf*x,m     ,Y#rf*x"))]
2682   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2683    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2684    && (reload_in_progress || reload_completed
2685        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2686        || GET_CODE (operands[1]) != CONST_DOUBLE
2687        || memory_operand (operands[0], DFmode))" 
2688 {
2689   switch (which_alternative)
2690     {
2691     case 0:
2692       return output_387_reg_move (insn, operands);
2693
2694     case 1:
2695       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2696         return "fstp%z0\t%y0";
2697       else
2698         return "fst%z0\t%y0";
2699
2700     case 2:
2701       return standard_80387_constant_opcode (operands[1]);
2702
2703     case 3:
2704     case 4:
2705       return "#";
2706
2707     case 5:
2708       switch (get_attr_mode (insn))
2709         {
2710         case MODE_V4SF:
2711           return "xorps\t%0, %0";
2712         case MODE_V2DF:
2713           return "xorpd\t%0, %0";
2714         case MODE_TI:
2715           return "pxor\t%0, %0";
2716         default:
2717           abort ();
2718         }
2719     case 6:
2720     case 7:
2721     case 8:
2722       switch (get_attr_mode (insn))
2723         {
2724         case MODE_V4SF:
2725           return "movaps\t{%1, %0|%0, %1}";
2726         case MODE_V2DF:
2727           return "movapd\t{%1, %0|%0, %1}";
2728         case MODE_TI:
2729           return "movdqa\t{%1, %0|%0, %1}";
2730         case MODE_DI:
2731           return "movq\t{%1, %0|%0, %1}";
2732         case MODE_DF:
2733           return "movsd\t{%1, %0|%0, %1}";
2734         case MODE_V1DF:
2735           return "movlpd\t{%1, %0|%0, %1}";
2736         case MODE_V2SF:
2737           return "movlps\t{%1, %0|%0, %1}";
2738         default:
2739           abort ();
2740         }
2741
2742     default:
2743       abort();
2744     }
2745 }
2746   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2747    (set (attr "mode")
2748         (cond [(eq_attr "alternative" "0,1,2")
2749                  (const_string "DF")
2750                (eq_attr "alternative" "3,4")
2751                  (const_string "SI")
2752
2753                /* For SSE1, we have many fewer alternatives.  */
2754                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2755                  (cond [(eq_attr "alternative" "5,6")
2756                           (const_string "V4SF")
2757                        ]
2758                    (const_string "V2SF"))
2759
2760                /* xorps is one byte shorter.  */
2761                (eq_attr "alternative" "5")
2762                  (cond [(ne (symbol_ref "optimize_size")
2763                             (const_int 0))
2764                           (const_string "V4SF")
2765                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2766                             (const_int 0))
2767                           (const_string "TI")
2768                        ]
2769                        (const_string "V2DF"))
2770
2771                /* For architectures resolving dependencies on
2772                   whole SSE registers use APD move to break dependency
2773                   chains, otherwise use short move to avoid extra work.
2774
2775                   movaps encodes one byte shorter.  */
2776                (eq_attr "alternative" "6")
2777                  (cond
2778                    [(ne (symbol_ref "optimize_size")
2779                         (const_int 0))
2780                       (const_string "V4SF")
2781                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2782                         (const_int 0))
2783                       (const_string "V2DF")
2784                    ]
2785                    (const_string "DF"))
2786                /* For architectures resolving dependencies on register
2787                   parts we may avoid extra work to zero out upper part
2788                   of register.  */
2789                (eq_attr "alternative" "7")
2790                  (if_then_else
2791                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2792                        (const_int 0))
2793                    (const_string "V1DF")
2794                    (const_string "DF"))
2795               ]
2796               (const_string "DF")))])
2797
2798 (define_split
2799   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2800         (match_operand:DF 1 "general_operand" ""))]
2801   "reload_completed
2802    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2803    && ! (ANY_FP_REG_P (operands[0]) || 
2804          (GET_CODE (operands[0]) == SUBREG
2805           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2806    && ! (ANY_FP_REG_P (operands[1]) || 
2807          (GET_CODE (operands[1]) == SUBREG
2808           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2809   [(const_int 0)]
2810   "ix86_split_long_move (operands); DONE;")
2811
2812 (define_insn "*swapdf"
2813   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2814         (match_operand:DF 1 "fp_register_operand" "+f"))
2815    (set (match_dup 1)
2816         (match_dup 0))]
2817   "reload_completed || TARGET_80387"
2818 {
2819   if (STACK_TOP_P (operands[0]))
2820     return "fxch\t%1";
2821   else
2822     return "fxch\t%0";
2823 }
2824   [(set_attr "type" "fxch")
2825    (set_attr "mode" "DF")])
2826
2827 (define_expand "movxf"
2828   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2829         (match_operand:XF 1 "general_operand" ""))]
2830   ""
2831   "ix86_expand_move (XFmode, operands); DONE;")
2832
2833 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2834 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2835 ;; Pushing using integer instructions is longer except for constants
2836 ;; and direct memory references.
2837 ;; (assuming that any given constant is pushed only once, but this ought to be
2838 ;;  handled elsewhere).
2839
2840 (define_insn "*pushxf_nointeger"
2841   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2842         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2843   "optimize_size"
2844 {
2845   /* This insn should be already split before reg-stack.  */
2846   abort ();
2847 }
2848   [(set_attr "type" "multi")
2849    (set_attr "mode" "XF,SI,SI")])
2850
2851 (define_insn "*pushxf_integer"
2852   [(set (match_operand:XF 0 "push_operand" "=<,<")
2853         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2854   "!optimize_size"
2855 {
2856   /* This insn should be already split before reg-stack.  */
2857   abort ();
2858 }
2859   [(set_attr "type" "multi")
2860    (set_attr "mode" "XF,SI")])
2861
2862 (define_split
2863   [(set (match_operand 0 "push_operand" "")
2864         (match_operand 1 "general_operand" ""))]
2865   "reload_completed
2866    && (GET_MODE (operands[0]) == XFmode
2867        || GET_MODE (operands[0]) == DFmode)
2868    && !ANY_FP_REG_P (operands[1])"
2869   [(const_int 0)]
2870   "ix86_split_long_move (operands); DONE;")
2871
2872 (define_split
2873   [(set (match_operand:XF 0 "push_operand" "")
2874         (match_operand:XF 1 "any_fp_register_operand" ""))]
2875   "!TARGET_64BIT"
2876   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2877    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2878   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2879
2880 (define_split
2881   [(set (match_operand:XF 0 "push_operand" "")
2882         (match_operand:XF 1 "any_fp_register_operand" ""))]
2883   "TARGET_64BIT"
2884   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2885    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2886   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2887
2888 ;; Do not use integer registers when optimizing for size
2889 (define_insn "*movxf_nointeger"
2890   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2891         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2892   "optimize_size
2893    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2894    && (reload_in_progress || reload_completed
2895        || GET_CODE (operands[1]) != CONST_DOUBLE
2896        || memory_operand (operands[0], XFmode))" 
2897 {
2898   switch (which_alternative)
2899     {
2900     case 0:
2901       return output_387_reg_move (insn, operands);
2902
2903     case 1:
2904       /* There is no non-popping store to memory for XFmode.  So if
2905          we need one, follow the store with a load.  */
2906       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2907         return "fstp%z0\t%y0\;fld%z0\t%y0";
2908       else
2909         return "fstp%z0\t%y0";
2910
2911     case 2:
2912       return standard_80387_constant_opcode (operands[1]);
2913
2914     case 3: case 4:
2915       return "#";
2916     }
2917   abort();
2918 }
2919   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2920    (set_attr "mode" "XF,XF,XF,SI,SI")])
2921
2922 (define_insn "*movxf_integer"
2923   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2924         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2925   "!optimize_size
2926    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2927    && (reload_in_progress || reload_completed
2928        || GET_CODE (operands[1]) != CONST_DOUBLE
2929        || memory_operand (operands[0], XFmode))" 
2930 {
2931   switch (which_alternative)
2932     {
2933     case 0:
2934       return output_387_reg_move (insn, operands);
2935
2936     case 1:
2937       /* There is no non-popping store to memory for XFmode.  So if
2938          we need one, follow the store with a load.  */
2939       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2940         return "fstp%z0\t%y0\;fld%z0\t%y0";
2941       else
2942         return "fstp%z0\t%y0";
2943
2944     case 2:
2945       return standard_80387_constant_opcode (operands[1]);
2946
2947     case 3: case 4:
2948       return "#";
2949     }
2950   abort();
2951 }
2952   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2953    (set_attr "mode" "XF,XF,XF,SI,SI")])
2954
2955 (define_split
2956   [(set (match_operand 0 "nonimmediate_operand" "")
2957         (match_operand 1 "general_operand" ""))]
2958   "reload_completed
2959    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2960    && GET_MODE (operands[0]) == XFmode
2961    && ! (ANY_FP_REG_P (operands[0]) || 
2962          (GET_CODE (operands[0]) == SUBREG
2963           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2964    && ! (ANY_FP_REG_P (operands[1]) || 
2965          (GET_CODE (operands[1]) == SUBREG
2966           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2967   [(const_int 0)]
2968   "ix86_split_long_move (operands); DONE;")
2969
2970 (define_split
2971   [(set (match_operand 0 "register_operand" "")
2972         (match_operand 1 "memory_operand" ""))]
2973   "reload_completed
2974    && GET_CODE (operands[1]) == MEM
2975    && (GET_MODE (operands[0]) == XFmode
2976        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2977    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2978    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2979   [(set (match_dup 0) (match_dup 1))]
2980 {
2981   rtx c = get_pool_constant (XEXP (operands[1], 0));
2982   rtx r = operands[0];
2983
2984   if (GET_CODE (r) == SUBREG)
2985     r = SUBREG_REG (r);
2986
2987   if (SSE_REG_P (r))
2988     {
2989       if (!standard_sse_constant_p (c))
2990         FAIL;
2991     }
2992   else if (FP_REG_P (r))
2993     {
2994       if (!standard_80387_constant_p (c))
2995         FAIL;
2996     }
2997   else if (MMX_REG_P (r))
2998     FAIL;
2999
3000   operands[1] = c;
3001 })
3002
3003 (define_insn "swapxf"
3004   [(set (match_operand:XF 0 "register_operand" "+f")
3005         (match_operand:XF 1 "register_operand" "+f"))
3006    (set (match_dup 1)
3007         (match_dup 0))]
3008   "TARGET_80387"
3009 {
3010   if (STACK_TOP_P (operands[0]))
3011     return "fxch\t%1";
3012   else
3013     return "fxch\t%0";
3014 }
3015   [(set_attr "type" "fxch")
3016    (set_attr "mode" "XF")])
3017
3018 (define_expand "movtf"
3019   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3020         (match_operand:TF 1 "nonimmediate_operand" ""))]
3021   "TARGET_64BIT"
3022 {
3023   ix86_expand_move (TFmode, operands);
3024   DONE;
3025 })
3026
3027 (define_insn "*movtf_internal"
3028   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3029         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3030   "TARGET_64BIT
3031    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3032 {
3033   switch (which_alternative)
3034     {
3035     case 0:
3036     case 1:
3037       return "#";
3038     case 2:
3039       if (get_attr_mode (insn) == MODE_V4SF)
3040         return "xorps\t%0, %0";
3041       else
3042         return "pxor\t%0, %0";
3043     case 3:
3044     case 4:
3045       if (get_attr_mode (insn) == MODE_V4SF)
3046         return "movaps\t{%1, %0|%0, %1}";
3047       else
3048         return "movdqa\t{%1, %0|%0, %1}";
3049     default:
3050       abort ();
3051     }
3052 }
3053   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
3054    (set (attr "mode")
3055         (cond [(eq_attr "alternative" "2,3")
3056                  (if_then_else
3057                    (ne (symbol_ref "optimize_size")
3058                        (const_int 0))
3059                    (const_string "V4SF")
3060                    (const_string "TI"))
3061                (eq_attr "alternative" "4")
3062                  (if_then_else
3063                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3064                             (const_int 0))
3065                         (ne (symbol_ref "optimize_size")
3066                             (const_int 0)))
3067                    (const_string "V4SF")
3068                    (const_string "TI"))]
3069                (const_string "DI")))])
3070
3071 (define_split
3072   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3073         (match_operand:TF 1 "general_operand" ""))]
3074   "reload_completed && !SSE_REG_P (operands[0])
3075    && !SSE_REG_P (operands[1])"
3076   [(const_int 0)]
3077   "ix86_split_long_move (operands); DONE;")
3078 \f
3079 ;; Zero extension instructions
3080
3081 (define_expand "zero_extendhisi2"
3082   [(set (match_operand:SI 0 "register_operand" "")
3083      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3084   ""
3085 {
3086   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3087     {
3088       operands[1] = force_reg (HImode, operands[1]);
3089       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3090       DONE;
3091     }
3092 })
3093
3094 (define_insn "zero_extendhisi2_and"
3095   [(set (match_operand:SI 0 "register_operand" "=r")
3096      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3097    (clobber (reg:CC FLAGS_REG))]
3098   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3099   "#"
3100   [(set_attr "type" "alu1")
3101    (set_attr "mode" "SI")])
3102
3103 (define_split
3104   [(set (match_operand:SI 0 "register_operand" "")
3105         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3109               (clobber (reg:CC FLAGS_REG))])]
3110   "")
3111
3112 (define_insn "*zero_extendhisi2_movzwl"
3113   [(set (match_operand:SI 0 "register_operand" "=r")
3114      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3115   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3116   "movz{wl|x}\t{%1, %0|%0, %1}"
3117   [(set_attr "type" "imovx")
3118    (set_attr "mode" "SI")])
3119
3120 (define_expand "zero_extendqihi2"
3121   [(parallel
3122     [(set (match_operand:HI 0 "register_operand" "")
3123        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3124      (clobber (reg:CC FLAGS_REG))])]
3125   ""
3126   "")
3127
3128 (define_insn "*zero_extendqihi2_and"
3129   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3130      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3131    (clobber (reg:CC FLAGS_REG))]
3132   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3133   "#"
3134   [(set_attr "type" "alu1")
3135    (set_attr "mode" "HI")])
3136
3137 (define_insn "*zero_extendqihi2_movzbw_and"
3138   [(set (match_operand:HI 0 "register_operand" "=r,r")
3139      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3140    (clobber (reg:CC FLAGS_REG))]
3141   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3142   "#"
3143   [(set_attr "type" "imovx,alu1")
3144    (set_attr "mode" "HI")])
3145
3146 (define_insn "*zero_extendqihi2_movzbw"
3147   [(set (match_operand:HI 0 "register_operand" "=r")
3148      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3149   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3150   "movz{bw|x}\t{%1, %0|%0, %1}"
3151   [(set_attr "type" "imovx")
3152    (set_attr "mode" "HI")])
3153
3154 ;; For the movzbw case strip only the clobber
3155 (define_split
3156   [(set (match_operand:HI 0 "register_operand" "")
3157         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3158    (clobber (reg:CC FLAGS_REG))]
3159   "reload_completed 
3160    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3161    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3162   [(set (match_operand:HI 0 "register_operand" "")
3163         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3164
3165 ;; When source and destination does not overlap, clear destination
3166 ;; first and then do the movb
3167 (define_split
3168   [(set (match_operand:HI 0 "register_operand" "")
3169         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3170    (clobber (reg:CC FLAGS_REG))]
3171   "reload_completed
3172    && ANY_QI_REG_P (operands[0])
3173    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3174    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3175   [(set (match_dup 0) (const_int 0))
3176    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3177   "operands[2] = gen_lowpart (QImode, operands[0]);")
3178
3179 ;; Rest is handled by single and.
3180 (define_split
3181   [(set (match_operand:HI 0 "register_operand" "")
3182         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3183    (clobber (reg:CC FLAGS_REG))]
3184   "reload_completed
3185    && true_regnum (operands[0]) == true_regnum (operands[1])"
3186   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3187               (clobber (reg:CC FLAGS_REG))])]
3188   "")
3189
3190 (define_expand "zero_extendqisi2"
3191   [(parallel
3192     [(set (match_operand:SI 0 "register_operand" "")
3193        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3194      (clobber (reg:CC FLAGS_REG))])]
3195   ""
3196   "")
3197
3198 (define_insn "*zero_extendqisi2_and"
3199   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3200      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3201    (clobber (reg:CC FLAGS_REG))]
3202   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3203   "#"
3204   [(set_attr "type" "alu1")
3205    (set_attr "mode" "SI")])
3206
3207 (define_insn "*zero_extendqisi2_movzbw_and"
3208   [(set (match_operand:SI 0 "register_operand" "=r,r")
3209      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3210    (clobber (reg:CC FLAGS_REG))]
3211   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3212   "#"
3213   [(set_attr "type" "imovx,alu1")
3214    (set_attr "mode" "SI")])
3215
3216 (define_insn "*zero_extendqisi2_movzbw"
3217   [(set (match_operand:SI 0 "register_operand" "=r")
3218      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3219   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3220   "movz{bl|x}\t{%1, %0|%0, %1}"
3221   [(set_attr "type" "imovx")
3222    (set_attr "mode" "SI")])
3223
3224 ;; For the movzbl case strip only the clobber
3225 (define_split
3226   [(set (match_operand:SI 0 "register_operand" "")
3227         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3228    (clobber (reg:CC FLAGS_REG))]
3229   "reload_completed 
3230    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3231    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3232   [(set (match_dup 0)
3233         (zero_extend:SI (match_dup 1)))])
3234
3235 ;; When source and destination does not overlap, clear destination
3236 ;; first and then do the movb
3237 (define_split
3238   [(set (match_operand:SI 0 "register_operand" "")
3239         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3240    (clobber (reg:CC FLAGS_REG))]
3241   "reload_completed
3242    && ANY_QI_REG_P (operands[0])
3243    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3244    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3245    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3246   [(set (match_dup 0) (const_int 0))
3247    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3248   "operands[2] = gen_lowpart (QImode, operands[0]);")
3249
3250 ;; Rest is handled by single and.
3251 (define_split
3252   [(set (match_operand:SI 0 "register_operand" "")
3253         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3254    (clobber (reg:CC FLAGS_REG))]
3255   "reload_completed
3256    && true_regnum (operands[0]) == true_regnum (operands[1])"
3257   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3258               (clobber (reg:CC FLAGS_REG))])]
3259   "")
3260
3261 ;; %%% Kill me once multi-word ops are sane.
3262 (define_expand "zero_extendsidi2"
3263   [(set (match_operand:DI 0 "register_operand" "=r")
3264      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3265   ""
3266   "if (!TARGET_64BIT)
3267      {
3268        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3269        DONE;
3270      }
3271   ")
3272
3273 (define_insn "zero_extendsidi2_32"
3274   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3275         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3276    (clobber (reg:CC FLAGS_REG))]
3277   "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3278   "@
3279    #
3280    #
3281    #
3282    movd\t{%1, %0|%0, %1}
3283    movd\t{%1, %0|%0, %1}"
3284   [(set_attr "mode" "SI,SI,SI,DI,TI")
3285    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3286
3287 (define_insn "*zero_extendsidi2_32_1"
3288   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3289         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3290    (clobber (reg:CC FLAGS_REG))]
3291   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3292   "@
3293    #
3294    #
3295    #
3296    movd\t{%1, %0|%0, %1}
3297    movd\t{%1, %0|%0, %1}"
3298   [(set_attr "mode" "SI,SI,SI,DI,TI")
3299    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3300
3301 (define_insn "zero_extendsidi2_rex64"
3302   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3303      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3304   "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3305   "@
3306    mov\t{%k1, %k0|%k0, %k1}
3307    #
3308    movd\t{%1, %0|%0, %1}
3309    movd\t{%1, %0|%0, %1}"
3310   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3311    (set_attr "mode" "SI,DI,DI,TI")])
3312
3313 (define_insn "*zero_extendsidi2_rex64_1"
3314   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3315      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3316   "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3317   "@
3318    mov\t{%k1, %k0|%k0, %k1}
3319    #
3320    movd\t{%1, %0|%0, %1}
3321    movd\t{%1, %0|%0, %1}"
3322   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3323    (set_attr "mode" "SI,DI,SI,SI")])
3324
3325 (define_split
3326   [(set (match_operand:DI 0 "memory_operand" "")
3327      (zero_extend:DI (match_dup 0)))]
3328   "TARGET_64BIT"
3329   [(set (match_dup 4) (const_int 0))]
3330   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3331
3332 (define_split 
3333   [(set (match_operand:DI 0 "register_operand" "")
3334         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3335    (clobber (reg:CC FLAGS_REG))]
3336   "!TARGET_64BIT && reload_completed
3337    && true_regnum (operands[0]) == true_regnum (operands[1])"
3338   [(set (match_dup 4) (const_int 0))]
3339   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3340
3341 (define_split 
3342   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3343         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3344    (clobber (reg:CC FLAGS_REG))]
3345   "!TARGET_64BIT && reload_completed
3346    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3347   [(set (match_dup 3) (match_dup 1))
3348    (set (match_dup 4) (const_int 0))]
3349   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3350
3351 (define_insn "zero_extendhidi2"
3352   [(set (match_operand:DI 0 "register_operand" "=r,r")
3353      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3354   "TARGET_64BIT"
3355   "@
3356    movz{wl|x}\t{%1, %k0|%k0, %1}
3357    movz{wq|x}\t{%1, %0|%0, %1}"
3358   [(set_attr "type" "imovx")
3359    (set_attr "mode" "SI,DI")])
3360
3361 (define_insn "zero_extendqidi2"
3362   [(set (match_operand:DI 0 "register_operand" "=r,r")
3363      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3364   "TARGET_64BIT"
3365   "@
3366    movz{bl|x}\t{%1, %k0|%k0, %1}
3367    movz{bq|x}\t{%1, %0|%0, %1}"
3368   [(set_attr "type" "imovx")
3369    (set_attr "mode" "SI,DI")])
3370 \f
3371 ;; Sign extension instructions
3372
3373 (define_expand "extendsidi2"
3374   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3375                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3376               (clobber (reg:CC FLAGS_REG))
3377               (clobber (match_scratch:SI 2 ""))])]
3378   ""
3379 {
3380   if (TARGET_64BIT)
3381     {
3382       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3383       DONE;
3384     }
3385 })
3386
3387 (define_insn "*extendsidi2_1"
3388   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3389         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3390    (clobber (reg:CC FLAGS_REG))
3391    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3392   "!TARGET_64BIT"
3393   "#")
3394
3395 (define_insn "extendsidi2_rex64"
3396   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3397         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3398   "TARGET_64BIT"
3399   "@
3400    {cltq|cdqe}
3401    movs{lq|x}\t{%1,%0|%0, %1}"
3402   [(set_attr "type" "imovx")
3403    (set_attr "mode" "DI")
3404    (set_attr "prefix_0f" "0")
3405    (set_attr "modrm" "0,1")])
3406
3407 (define_insn "extendhidi2"
3408   [(set (match_operand:DI 0 "register_operand" "=r")
3409         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3410   "TARGET_64BIT"
3411   "movs{wq|x}\t{%1,%0|%0, %1}"
3412   [(set_attr "type" "imovx")
3413    (set_attr "mode" "DI")])
3414
3415 (define_insn "extendqidi2"
3416   [(set (match_operand:DI 0 "register_operand" "=r")
3417         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3418   "TARGET_64BIT"
3419   "movs{bq|x}\t{%1,%0|%0, %1}"
3420    [(set_attr "type" "imovx")
3421     (set_attr "mode" "DI")])
3422
3423 ;; Extend to memory case when source register does die.
3424 (define_split 
3425   [(set (match_operand:DI 0 "memory_operand" "")
3426         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3427    (clobber (reg:CC FLAGS_REG))
3428    (clobber (match_operand:SI 2 "register_operand" ""))]
3429   "(reload_completed
3430     && dead_or_set_p (insn, operands[1])
3431     && !reg_mentioned_p (operands[1], operands[0]))"
3432   [(set (match_dup 3) (match_dup 1))
3433    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3434               (clobber (reg:CC FLAGS_REG))])
3435    (set (match_dup 4) (match_dup 1))]
3436   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3437
3438 ;; Extend to memory case when source register does not die.
3439 (define_split 
3440   [(set (match_operand:DI 0 "memory_operand" "")
3441         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3442    (clobber (reg:CC FLAGS_REG))
3443    (clobber (match_operand:SI 2 "register_operand" ""))]
3444   "reload_completed"
3445   [(const_int 0)]
3446 {
3447   split_di (&operands[0], 1, &operands[3], &operands[4]);
3448
3449   emit_move_insn (operands[3], operands[1]);
3450
3451   /* Generate a cltd if possible and doing so it profitable.  */
3452   if (true_regnum (operands[1]) == 0
3453       && true_regnum (operands[2]) == 1
3454       && (optimize_size || TARGET_USE_CLTD))
3455     {
3456       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3457     }
3458   else
3459     {
3460       emit_move_insn (operands[2], operands[1]);
3461       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3462     }
3463   emit_move_insn (operands[4], operands[2]);
3464   DONE;
3465 })
3466
3467 ;; Extend to register case.  Optimize case where source and destination
3468 ;; registers match and cases where we can use cltd.
3469 (define_split 
3470   [(set (match_operand:DI 0 "register_operand" "")
3471         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3472    (clobber (reg:CC FLAGS_REG))
3473    (clobber (match_scratch:SI 2 ""))]
3474   "reload_completed"
3475   [(const_int 0)]
3476 {
3477   split_di (&operands[0], 1, &operands[3], &operands[4]);
3478
3479   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3480     emit_move_insn (operands[3], operands[1]);
3481
3482   /* Generate a cltd if possible and doing so it profitable.  */
3483   if (true_regnum (operands[3]) == 0
3484       && (optimize_size || TARGET_USE_CLTD))
3485     {
3486       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3487       DONE;
3488     }
3489
3490   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3491     emit_move_insn (operands[4], operands[1]);
3492
3493   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3494   DONE;
3495 })
3496
3497 (define_insn "extendhisi2"
3498   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3499         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3500   ""
3501 {
3502   switch (get_attr_prefix_0f (insn))
3503     {
3504     case 0:
3505       return "{cwtl|cwde}";
3506     default:
3507       return "movs{wl|x}\t{%1,%0|%0, %1}";
3508     }
3509 }
3510   [(set_attr "type" "imovx")
3511    (set_attr "mode" "SI")
3512    (set (attr "prefix_0f")
3513      ;; movsx is short decodable while cwtl is vector decoded.
3514      (if_then_else (and (eq_attr "cpu" "!k6")
3515                         (eq_attr "alternative" "0"))
3516         (const_string "0")
3517         (const_string "1")))
3518    (set (attr "modrm")
3519      (if_then_else (eq_attr "prefix_0f" "0")
3520         (const_string "0")
3521         (const_string "1")))])
3522
3523 (define_insn "*extendhisi2_zext"
3524   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3525         (zero_extend:DI
3526           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3527   "TARGET_64BIT"
3528 {
3529   switch (get_attr_prefix_0f (insn))
3530     {
3531     case 0:
3532       return "{cwtl|cwde}";
3533     default:
3534       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3535     }
3536 }
3537   [(set_attr "type" "imovx")
3538    (set_attr "mode" "SI")
3539    (set (attr "prefix_0f")
3540      ;; movsx is short decodable while cwtl is vector decoded.
3541      (if_then_else (and (eq_attr "cpu" "!k6")
3542                         (eq_attr "alternative" "0"))
3543         (const_string "0")
3544         (const_string "1")))
3545    (set (attr "modrm")
3546      (if_then_else (eq_attr "prefix_0f" "0")
3547         (const_string "0")
3548         (const_string "1")))])
3549
3550 (define_insn "extendqihi2"
3551   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3552         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3553   ""
3554 {
3555   switch (get_attr_prefix_0f (insn))
3556     {
3557     case 0:
3558       return "{cbtw|cbw}";
3559     default:
3560       return "movs{bw|x}\t{%1,%0|%0, %1}";
3561     }
3562 }
3563   [(set_attr "type" "imovx")
3564    (set_attr "mode" "HI")
3565    (set (attr "prefix_0f")
3566      ;; movsx is short decodable while cwtl is vector decoded.
3567      (if_then_else (and (eq_attr "cpu" "!k6")
3568                         (eq_attr "alternative" "0"))
3569         (const_string "0")
3570         (const_string "1")))
3571    (set (attr "modrm")
3572      (if_then_else (eq_attr "prefix_0f" "0")
3573         (const_string "0")
3574         (const_string "1")))])
3575
3576 (define_insn "extendqisi2"
3577   [(set (match_operand:SI 0 "register_operand" "=r")
3578         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3579   ""
3580   "movs{bl|x}\t{%1,%0|%0, %1}"
3581    [(set_attr "type" "imovx")
3582     (set_attr "mode" "SI")])
3583
3584 (define_insn "*extendqisi2_zext"
3585   [(set (match_operand:DI 0 "register_operand" "=r")
3586         (zero_extend:DI
3587           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3588   "TARGET_64BIT"
3589   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3590    [(set_attr "type" "imovx")
3591     (set_attr "mode" "SI")])
3592 \f
3593 ;; Conversions between float and double.
3594
3595 ;; These are all no-ops in the model used for the 80387.  So just
3596 ;; emit moves.
3597
3598 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3599 (define_insn "*dummy_extendsfdf2"
3600   [(set (match_operand:DF 0 "push_operand" "=<")
3601         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3602   "0"
3603   "#")
3604
3605 (define_split
3606   [(set (match_operand:DF 0 "push_operand" "")
3607         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3608   "!TARGET_64BIT"
3609   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3610    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3611
3612 (define_split
3613   [(set (match_operand:DF 0 "push_operand" "")
3614         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3615   "TARGET_64BIT"
3616   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3617    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3618
3619 (define_insn "*dummy_extendsfxf2"
3620   [(set (match_operand:XF 0 "push_operand" "=<")
3621         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3622   "0"
3623   "#")
3624
3625 (define_split
3626   [(set (match_operand:XF 0 "push_operand" "")
3627         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3628   ""
3629   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3630    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3631   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3632
3633 (define_split
3634   [(set (match_operand:XF 0 "push_operand" "")
3635         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3636   "TARGET_64BIT"
3637   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3638    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3639   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3640
3641 (define_split
3642   [(set (match_operand:XF 0 "push_operand" "")
3643         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3644   ""
3645   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3646    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3647   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3648
3649 (define_split
3650   [(set (match_operand:XF 0 "push_operand" "")
3651         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3652   "TARGET_64BIT"
3653   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3654    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3655   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3656
3657 (define_expand "extendsfdf2"
3658   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3659         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3660   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3661 {
3662   /* ??? Needed for compress_float_constant since all fp constants
3663      are LEGITIMATE_CONSTANT_P.  */
3664   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3665     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3666   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667     operands[1] = force_reg (SFmode, operands[1]);
3668 })
3669
3670 (define_insn "*extendsfdf2_mixed"
3671   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3672         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3673   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3675 {
3676   switch (which_alternative)
3677     {
3678     case 0:
3679       return output_387_reg_move (insn, operands);
3680
3681     case 1:
3682       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3683         return "fstp%z0\t%y0";
3684       else
3685         return "fst%z0\t%y0";
3686
3687     case 2:
3688       return "cvtss2sd\t{%1, %0|%0, %1}";
3689
3690     default:
3691       abort ();
3692     }
3693 }
3694   [(set_attr "type" "fmov,fmov,ssecvt")
3695    (set_attr "mode" "SF,XF,DF")])
3696
3697 (define_insn "*extendsfdf2_sse"
3698   [(set (match_operand:DF 0 "register_operand" "=Y")
3699         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3700   "TARGET_SSE2 && TARGET_SSE_MATH
3701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3702   "cvtss2sd\t{%1, %0|%0, %1}"
3703   [(set_attr "type" "ssecvt")
3704    (set_attr "mode" "DF")])
3705
3706 (define_insn "*extendsfdf2_i387"
3707   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3708         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3709   "TARGET_80387
3710    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3711 {
3712   switch (which_alternative)
3713     {
3714     case 0:
3715       return output_387_reg_move (insn, operands);
3716
3717     case 1:
3718       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3719         return "fstp%z0\t%y0";
3720       else
3721         return "fst%z0\t%y0";
3722
3723     default:
3724       abort ();
3725     }
3726 }
3727   [(set_attr "type" "fmov")
3728    (set_attr "mode" "SF,XF")])
3729
3730 (define_expand "extendsfxf2"
3731   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3732         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3733   "TARGET_80387"
3734 {
3735   /* ??? Needed for compress_float_constant since all fp constants
3736      are LEGITIMATE_CONSTANT_P.  */
3737   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3738     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3739   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3740     operands[1] = force_reg (SFmode, operands[1]);
3741 })
3742
3743 (define_insn "*extendsfxf2_i387"
3744   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3745         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3746   "TARGET_80387
3747    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3748 {
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       return output_387_reg_move (insn, operands);
3753
3754     case 1:
3755       /* There is no non-popping store to memory for XFmode.  So if
3756          we need one, follow the store with a load.  */
3757       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758         return "fstp%z0\t%y0";
3759       else
3760         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3761
3762     default:
3763       abort ();
3764     }
3765 }
3766   [(set_attr "type" "fmov")
3767    (set_attr "mode" "SF,XF")])
3768
3769 (define_expand "extenddfxf2"
3770   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3771         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3772   "TARGET_80387"
3773 {
3774   /* ??? Needed for compress_float_constant since all fp constants
3775      are LEGITIMATE_CONSTANT_P.  */
3776   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3777     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3778   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3779     operands[1] = force_reg (DFmode, operands[1]);
3780 })
3781
3782 (define_insn "*extenddfxf2_i387"
3783   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3784         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3785   "TARGET_80387
3786    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3787 {
3788   switch (which_alternative)
3789     {
3790     case 0:
3791       return output_387_reg_move (insn, operands);
3792
3793     case 1:
3794       /* There is no non-popping store to memory for XFmode.  So if
3795          we need one, follow the store with a load.  */
3796       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3798       else
3799         return "fstp%z0\t%y0";
3800
3801     default:
3802       abort ();
3803     }
3804 }
3805   [(set_attr "type" "fmov")
3806    (set_attr "mode" "DF,XF")])
3807
3808 ;; %%% This seems bad bad news.
3809 ;; This cannot output into an f-reg because there is no way to be sure
3810 ;; of truncating in that case.  Otherwise this is just like a simple move
3811 ;; insn.  So we pretend we can output to a reg in order to get better
3812 ;; register preferencing, but we really use a stack slot.
3813
3814 ;; Conversion from DFmode to SFmode.
3815
3816 (define_expand "truncdfsf2"
3817   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3818         (float_truncate:SF
3819           (match_operand:DF 1 "nonimmediate_operand" "")))]
3820   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3821 {
3822   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3823     operands[1] = force_reg (DFmode, operands[1]);
3824
3825   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3826     ;
3827   else if (flag_unsafe_math_optimizations)
3828     ;
3829   else
3830     {
3831       rtx temp = assign_386_stack_local (SFmode, 0);
3832       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3833       DONE;
3834     }
3835 })
3836
3837 (define_expand "truncdfsf2_with_temp"
3838   [(parallel [(set (match_operand:SF 0 "" "")
3839                    (float_truncate:SF (match_operand:DF 1 "" "")))
3840               (clobber (match_operand:SF 2 "" ""))])]
3841   "")
3842
3843 (define_insn "*truncdfsf_fast_mixed"
3844   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3845         (float_truncate:SF
3846           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3847   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3848 {
3849   switch (which_alternative)
3850     {
3851     case 0:
3852       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3853         return "fstp%z0\t%y0";
3854       else
3855         return "fst%z0\t%y0";
3856     case 1:
3857       return output_387_reg_move (insn, operands);
3858     case 2:
3859       return "cvtsd2ss\t{%1, %0|%0, %1}";
3860     default:
3861       abort ();
3862     }
3863 }
3864   [(set_attr "type" "fmov,fmov,ssecvt")
3865    (set_attr "mode" "SF")])
3866
3867 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3868 ;; because nothing we do here is unsafe.
3869 (define_insn "*truncdfsf_fast_sse"
3870   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3871         (float_truncate:SF
3872           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3873   "TARGET_SSE2 && TARGET_SSE_MATH"
3874   "cvtsd2ss\t{%1, %0|%0, %1}"
3875   [(set_attr "type" "ssecvt")
3876    (set_attr "mode" "SF")])
3877
3878 (define_insn "*truncdfsf_fast_i387"
3879   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3880         (float_truncate:SF
3881           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3882   "TARGET_80387 && flag_unsafe_math_optimizations"
3883   "* return output_387_reg_move (insn, operands);"
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF")])
3886
3887 (define_insn "*truncdfsf_mixed"
3888   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3889         (float_truncate:SF
3890           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3891    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3892   "TARGET_MIX_SSE_I387"
3893 {
3894   switch (which_alternative)
3895     {
3896     case 0:
3897       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3898         return "fstp%z0\t%y0";
3899       else
3900         return "fst%z0\t%y0";
3901     case 1:
3902       return "#";
3903     case 2:
3904       return "cvtsd2ss\t{%1, %0|%0, %1}";
3905     default:
3906       abort ();
3907     }
3908 }
3909   [(set_attr "type" "fmov,multi,ssecvt")
3910    (set_attr "mode" "SF")])
3911
3912 (define_insn "*truncdfsf_i387"
3913   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3914         (float_truncate:SF
3915           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3916    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3917   "TARGET_80387"
3918 {
3919   switch (which_alternative)
3920     {
3921     case 0:
3922       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3923         return "fstp%z0\t%y0";
3924       else
3925         return "fst%z0\t%y0";
3926     case 1:
3927       return "#";
3928     default:
3929       abort ();
3930     }
3931 }
3932   [(set_attr "type" "fmov,multi")
3933    (set_attr "mode" "SF")])
3934
3935 (define_split
3936   [(set (match_operand:SF 0 "register_operand" "")
3937         (float_truncate:SF
3938          (match_operand:DF 1 "fp_register_operand" "")))
3939    (clobber (match_operand 2 "" ""))]
3940   "reload_completed"
3941   [(set (match_dup 2) (match_dup 1))
3942    (set (match_dup 0) (match_dup 2))]
3943 {
3944   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3945 })
3946
3947 ;; Conversion from XFmode to SFmode.
3948
3949 (define_expand "truncxfsf2"
3950   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3951                    (float_truncate:SF
3952                     (match_operand:XF 1 "register_operand" "")))
3953               (clobber (match_dup 2))])]
3954   "TARGET_80387"
3955 {
3956   if (flag_unsafe_math_optimizations)
3957     {
3958       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3959       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3960       if (reg != operands[0])
3961         emit_move_insn (operands[0], reg);
3962       DONE;
3963     }
3964   else
3965     operands[2] = assign_386_stack_local (SFmode, 0);
3966 })
3967
3968 (define_insn "*truncxfsf2_mixed"
3969   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3970         (float_truncate:SF
3971          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3972    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3973   "TARGET_MIX_SSE_I387"
3974 {
3975   switch (which_alternative)
3976     {
3977     case 0:
3978       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979         return "fstp%z0\t%y0";
3980       else
3981         return "fst%z0\t%y0";
3982     default:
3983       abort();
3984     }
3985 }
3986   [(set_attr "type" "fmov,multi,multi,multi")
3987    (set_attr "mode" "SF")])
3988
3989 (define_insn "truncxfsf2_i387_noop"
3990   [(set (match_operand:SF 0 "register_operand" "=f")
3991         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387 && flag_unsafe_math_optimizations"
3993 {
3994   return output_387_reg_move (insn, operands);
3995 }
3996   [(set_attr "type" "fmov")
3997    (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncxfsf2_i387"
4000   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4001         (float_truncate:SF
4002          (match_operand:XF 1 "register_operand" "f,f,f")))
4003    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
4004   "TARGET_80387"
4005 {
4006   switch (which_alternative)
4007     {
4008     case 0:
4009       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4010         return "fstp%z0\t%y0";
4011       else
4012         return "fst%z0\t%y0";
4013     default:
4014       abort ();
4015     }
4016 }
4017   [(set_attr "type" "fmov,multi,multi")
4018    (set_attr "mode" "SF")])
4019
4020 (define_insn "*truncxfsf2_i387_1"
4021   [(set (match_operand:SF 0 "memory_operand" "=m")
4022         (float_truncate:SF
4023          (match_operand:XF 1 "register_operand" "f")))]
4024   "TARGET_80387"
4025 {
4026   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4027     return "fstp%z0\t%y0";
4028   else
4029     return "fst%z0\t%y0";
4030 }
4031   [(set_attr "type" "fmov")
4032    (set_attr "mode" "SF")])
4033
4034 (define_split
4035   [(set (match_operand:SF 0 "register_operand" "")
4036         (float_truncate:SF
4037          (match_operand:XF 1 "register_operand" "")))
4038    (clobber (match_operand:SF 2 "memory_operand" ""))]
4039   "TARGET_80387 && reload_completed"
4040   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4041    (set (match_dup 0) (match_dup 2))]
4042   "")
4043
4044 (define_split
4045   [(set (match_operand:SF 0 "memory_operand" "")
4046         (float_truncate:SF
4047          (match_operand:XF 1 "register_operand" "")))
4048    (clobber (match_operand:SF 2 "memory_operand" ""))]
4049   "TARGET_80387"
4050   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4051   "")
4052
4053 ;; Conversion from XFmode to DFmode.
4054
4055 (define_expand "truncxfdf2"
4056   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4057                    (float_truncate:DF
4058                     (match_operand:XF 1 "register_operand" "")))
4059               (clobber (match_dup 2))])]
4060   "TARGET_80387"
4061 {
4062   if (flag_unsafe_math_optimizations)
4063     {
4064       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4065       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4066       if (reg != operands[0])
4067         emit_move_insn (operands[0], reg);
4068       DONE;
4069     }
4070   else
4071     operands[2] = assign_386_stack_local (DFmode, 0);
4072 })
4073
4074 (define_insn "*truncxfdf2_mixed"
4075   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4076         (float_truncate:DF
4077          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4078    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4079   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4080 {
4081   switch (which_alternative)
4082     {
4083     case 0:
4084       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4085         return "fstp%z0\t%y0";
4086       else
4087         return "fst%z0\t%y0";
4088     default:
4089       abort();
4090     }
4091   abort ();
4092 }
4093   [(set_attr "type" "fmov,multi,multi,multi")
4094    (set_attr "mode" "DF")])
4095
4096 (define_insn "truncxfdf2_i387_noop"
4097   [(set (match_operand:DF 0 "register_operand" "=f")
4098         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4099   "TARGET_80387 && flag_unsafe_math_optimizations"
4100 {
4101   return output_387_reg_move (insn, operands);
4102 }
4103   [(set_attr "type" "fmov")
4104    (set_attr "mode" "DF")])
4105
4106 (define_insn "*truncxfdf2_i387"
4107   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4108         (float_truncate:DF
4109          (match_operand:XF 1 "register_operand" "f,f,f")))
4110    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4111   "TARGET_80387"
4112 {
4113   switch (which_alternative)
4114     {
4115     case 0:
4116       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4117         return "fstp%z0\t%y0";
4118       else
4119         return "fst%z0\t%y0";
4120     default:
4121       abort ();
4122     }
4123 }
4124   [(set_attr "type" "fmov,multi,multi")
4125    (set_attr "mode" "DF")])
4126
4127 (define_insn "*truncxfdf2_i387_1"
4128   [(set (match_operand:DF 0 "memory_operand" "=m")
4129         (float_truncate:DF
4130           (match_operand:XF 1 "register_operand" "f")))]
4131   "TARGET_80387"
4132 {
4133   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4134     return "fstp%z0\t%y0";
4135   else
4136     return "fst%z0\t%y0";
4137 }
4138   [(set_attr "type" "fmov")
4139    (set_attr "mode" "DF")])
4140
4141 (define_split
4142   [(set (match_operand:DF 0 "register_operand" "")
4143         (float_truncate:DF
4144          (match_operand:XF 1 "register_operand" "")))
4145    (clobber (match_operand:DF 2 "memory_operand" ""))]
4146   "TARGET_80387 && reload_completed"
4147   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4148    (set (match_dup 0) (match_dup 2))]
4149   "")
4150
4151 (define_split
4152   [(set (match_operand:DF 0 "memory_operand" "")
4153         (float_truncate:DF
4154          (match_operand:XF 1 "register_operand" "")))
4155    (clobber (match_operand:DF 2 "memory_operand" ""))]
4156   "TARGET_80387"
4157   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4158   "")
4159 \f
4160 ;; %%% Break up all these bad boys.
4161
4162 ;; Signed conversion to DImode.
4163
4164 (define_expand "fix_truncxfdi2"
4165   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4166                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4167               (clobber (reg:CC FLAGS_REG))])]
4168   "TARGET_80387"
4169   "")
4170
4171 (define_expand "fix_truncdfdi2"
4172   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4173                    (fix:DI (match_operand:DF 1 "register_operand" "")))
4174               (clobber (reg:CC FLAGS_REG))])]
4175   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
4176 {
4177   if (TARGET_64BIT && TARGET_SSE2)
4178    {
4179      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4180      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4181      if (out != operands[0])
4182         emit_move_insn (operands[0], out);
4183      DONE;
4184    }
4185 })
4186
4187 (define_expand "fix_truncsfdi2"
4188   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4189                    (fix:DI (match_operand:SF 1 "register_operand" "")))
4190               (clobber (reg:CC FLAGS_REG))])] 
4191   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
4192 {
4193   if (TARGET_64BIT && TARGET_SSE)
4194    {
4195      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4196      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4197      if (out != operands[0])
4198         emit_move_insn (operands[0], out);
4199      DONE;
4200    }
4201 })
4202
4203 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4204 ;; of the machinery.
4205 (define_insn_and_split "*fix_truncdi_i387"
4206   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4207         (fix:DI (match_operand 1 "register_operand" "f,f")))
4208    (clobber (reg:CC FLAGS_REG))]
4209   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !reload_completed && !reload_in_progress
4211    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4212   "#"
4213   "&& 1"
4214   [(const_int 0)]
4215 {
4216   ix86_optimize_mode_switching = 1;
4217   operands[2] = assign_386_stack_local (HImode, 1);
4218   operands[3] = assign_386_stack_local (HImode, 2);
4219   if (memory_operand (operands[0], VOIDmode))
4220     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4221                                        operands[2], operands[3]));
4222   else
4223     {
4224       operands[4] = assign_386_stack_local (DImode, 0);
4225       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4226                                            operands[2], operands[3],
4227                                            operands[4]));
4228     }
4229   DONE;
4230 }
4231   [(set_attr "type" "fistp")
4232    (set_attr "i387_cw" "trunc")
4233    (set_attr "mode" "DI")])
4234
4235 (define_insn "fix_truncdi_nomemory"
4236   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4237         (fix:DI (match_operand 1 "register_operand" "f,f")))
4238    (use (match_operand:HI 2 "memory_operand" "m,m"))
4239    (use (match_operand:HI 3 "memory_operand" "m,m"))
4240    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4241    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4242   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4243    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4244   "#"
4245   [(set_attr "type" "fistp")
4246    (set_attr "i387_cw" "trunc")
4247    (set_attr "mode" "DI")])
4248
4249 (define_insn "fix_truncdi_memory"
4250   [(set (match_operand:DI 0 "memory_operand" "=m")
4251         (fix:DI (match_operand 1 "register_operand" "f")))
4252    (use (match_operand:HI 2 "memory_operand" "m"))
4253    (use (match_operand:HI 3 "memory_operand" "m"))
4254    (clobber (match_scratch:DF 4 "=&1f"))]
4255   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4256    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4257   "* return output_fix_trunc (insn, operands);"
4258   [(set_attr "type" "fistp")
4259    (set_attr "i387_cw" "trunc")
4260    (set_attr "mode" "DI")])
4261
4262 (define_split 
4263   [(set (match_operand:DI 0 "register_operand" "")
4264         (fix:DI (match_operand 1 "register_operand" "")))
4265    (use (match_operand:HI 2 "memory_operand" ""))
4266    (use (match_operand:HI 3 "memory_operand" ""))
4267    (clobber (match_operand:DI 4 "memory_operand" ""))
4268    (clobber (match_scratch 5 ""))]
4269   "reload_completed"
4270   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4271               (use (match_dup 2))
4272               (use (match_dup 3))
4273               (clobber (match_dup 5))])
4274    (set (match_dup 0) (match_dup 4))]
4275   "")
4276
4277 (define_split 
4278   [(set (match_operand:DI 0 "memory_operand" "")
4279         (fix:DI (match_operand 1 "register_operand" "")))
4280    (use (match_operand:HI 2 "memory_operand" ""))
4281    (use (match_operand:HI 3 "memory_operand" ""))
4282    (clobber (match_operand:DI 4 "memory_operand" ""))
4283    (clobber (match_scratch 5 ""))]
4284   "reload_completed"
4285   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4286               (use (match_dup 2))
4287               (use (match_dup 3))
4288               (clobber (match_dup 5))])]
4289   "")
4290
4291 ;; When SSE available, it is always faster to use it!
4292 (define_insn "fix_truncsfdi_sse"
4293   [(set (match_operand:DI 0 "register_operand" "=r,r")
4294         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4295   "TARGET_64BIT && TARGET_SSE"
4296   "cvttss2si{q}\t{%1, %0|%0, %1}"
4297   [(set_attr "type" "sseicvt")
4298    (set_attr "mode" "SF")
4299    (set_attr "athlon_decode" "double,vector")])
4300
4301 ;; Avoid vector decoded form of the instruction.
4302 (define_peephole2
4303   [(match_scratch:SF 2 "x")
4304    (set (match_operand:DI 0 "register_operand" "")
4305         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4306   "TARGET_K8 && !optimize_size"
4307   [(set (match_dup 2) (match_dup 1))
4308    (set (match_dup 0) (fix:DI (match_dup 2)))]
4309   "")
4310
4311 (define_insn "fix_truncdfdi_sse"
4312   [(set (match_operand:DI 0 "register_operand" "=r,r")
4313         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4314   "TARGET_64BIT && TARGET_SSE2"
4315   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4316   [(set_attr "type" "sseicvt,sseicvt")
4317    (set_attr "mode" "DF")
4318    (set_attr "athlon_decode" "double,vector")])
4319
4320 ;; Avoid vector decoded form of the instruction.
4321 (define_peephole2
4322   [(match_scratch:DF 2 "Y")
4323    (set (match_operand:DI 0 "register_operand" "")
4324         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4325   "TARGET_K8 && !optimize_size"
4326   [(set (match_dup 2) (match_dup 1))
4327    (set (match_dup 0) (fix:DI (match_dup 2)))]
4328   "")
4329
4330 ;; Signed conversion to SImode.
4331
4332 (define_expand "fix_truncxfsi2"
4333   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4334                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4335               (clobber (reg:CC FLAGS_REG))])]
4336   "TARGET_80387"
4337   "")
4338
4339 (define_expand "fix_truncdfsi2"
4340   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4341                    (fix:SI (match_operand:DF 1 "register_operand" "")))
4342               (clobber (reg:CC FLAGS_REG))])]
4343   "TARGET_80387 || TARGET_SSE2"
4344 {
4345   if (TARGET_SSE2)
4346    {
4347      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4348      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4349      if (out != operands[0])
4350         emit_move_insn (operands[0], out);
4351      DONE;
4352    }
4353 })
4354
4355 (define_expand "fix_truncsfsi2"
4356   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4357                    (fix:SI (match_operand:SF 1 "register_operand" "")))
4358               (clobber (reg:CC FLAGS_REG))])] 
4359   "TARGET_80387 || TARGET_SSE"
4360 {
4361   if (TARGET_SSE)
4362    {
4363      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4364      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4365      if (out != operands[0])
4366         emit_move_insn (operands[0], out);
4367      DONE;
4368    }
4369 })
4370
4371 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4372 ;; of the machinery.
4373 (define_insn_and_split "*fix_truncsi_i387"
4374   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4375         (fix:SI (match_operand 1 "register_operand" "f,f")))
4376    (clobber (reg:CC FLAGS_REG))]
4377   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4378    && !reload_completed && !reload_in_progress
4379    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380   "#"
4381   "&& 1"
4382   [(const_int 0)]
4383 {
4384   ix86_optimize_mode_switching = 1;
4385   operands[2] = assign_386_stack_local (HImode, 1);
4386   operands[3] = assign_386_stack_local (HImode, 2);
4387   if (memory_operand (operands[0], VOIDmode))
4388     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4389                                        operands[2], operands[3]));
4390   else
4391     {
4392       operands[4] = assign_386_stack_local (SImode, 0);
4393       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4394                                            operands[2], operands[3],
4395                                            operands[4]));
4396     }
4397   DONE;
4398 }
4399   [(set_attr "type" "fistp")
4400    (set_attr "i387_cw" "trunc")
4401    (set_attr "mode" "SI")])
4402
4403 (define_insn "fix_truncsi_nomemory"
4404   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4405         (fix:SI (match_operand 1 "register_operand" "f,f")))
4406    (use (match_operand:HI 2 "memory_operand" "m,m"))
4407    (use (match_operand:HI 3 "memory_operand" "m,m"))
4408    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4409   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4410    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4411   "#"
4412   [(set_attr "type" "fistp")
4413    (set_attr "i387_cw" "trunc")
4414    (set_attr "mode" "SI")])
4415
4416 (define_insn "fix_truncsi_memory"
4417   [(set (match_operand:SI 0 "memory_operand" "=m")
4418         (fix:SI (match_operand 1 "register_operand" "f")))
4419    (use (match_operand:HI 2 "memory_operand" "m"))
4420    (use (match_operand:HI 3 "memory_operand" "m"))]
4421   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4422    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4423   "* return output_fix_trunc (insn, operands);"
4424   [(set_attr "type" "fistp")
4425    (set_attr "i387_cw" "trunc")
4426    (set_attr "mode" "SI")])
4427
4428 ;; When SSE available, it is always faster to use it!
4429 (define_insn "fix_truncsfsi_sse"
4430   [(set (match_operand:SI 0 "register_operand" "=r,r")
4431         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4432   "TARGET_SSE"
4433   "cvttss2si\t{%1, %0|%0, %1}"
4434   [(set_attr "type" "sseicvt")
4435    (set_attr "mode" "DF")
4436    (set_attr "athlon_decode" "double,vector")])
4437
4438 ;; Avoid vector decoded form of the instruction.
4439 (define_peephole2
4440   [(match_scratch:SF 2 "x")
4441    (set (match_operand:SI 0 "register_operand" "")
4442         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4443   "TARGET_K8 && !optimize_size"
4444   [(set (match_dup 2) (match_dup 1))
4445    (set (match_dup 0) (fix:SI (match_dup 2)))]
4446   "")
4447
4448 (define_insn "fix_truncdfsi_sse"
4449   [(set (match_operand:SI 0 "register_operand" "=r,r")
4450         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4451   "TARGET_SSE2"
4452   "cvttsd2si\t{%1, %0|%0, %1}"
4453   [(set_attr "type" "sseicvt")
4454    (set_attr "mode" "DF")
4455    (set_attr "athlon_decode" "double,vector")])
4456
4457 ;; Avoid vector decoded form of the instruction.
4458 (define_peephole2
4459   [(match_scratch:DF 2 "Y")
4460    (set (match_operand:SI 0 "register_operand" "")
4461         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4462   "TARGET_K8 && !optimize_size"
4463   [(set (match_dup 2) (match_dup 1))
4464    (set (match_dup 0) (fix:SI (match_dup 2)))]
4465   "")
4466
4467 (define_split 
4468   [(set (match_operand:SI 0 "register_operand" "")
4469         (fix:SI (match_operand 1 "register_operand" "")))
4470    (use (match_operand:HI 2 "memory_operand" ""))
4471    (use (match_operand:HI 3 "memory_operand" ""))
4472    (clobber (match_operand:SI 4 "memory_operand" ""))]
4473   "reload_completed"
4474   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4475               (use (match_dup 2))
4476               (use (match_dup 3))])
4477    (set (match_dup 0) (match_dup 4))]
4478   "")
4479
4480 (define_split 
4481   [(set (match_operand:SI 0 "memory_operand" "")
4482         (fix:SI (match_operand 1 "register_operand" "")))
4483    (use (match_operand:HI 2 "memory_operand" ""))
4484    (use (match_operand:HI 3 "memory_operand" ""))
4485    (clobber (match_operand:SI 4 "memory_operand" ""))]
4486   "reload_completed"
4487   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4488               (use (match_dup 2))
4489               (use (match_dup 3))])]
4490   "")
4491
4492 ;; Signed conversion to HImode.
4493
4494 (define_expand "fix_truncxfhi2"
4495   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4496                    (fix:HI (match_operand:XF 1 "register_operand" "")))
4497               (clobber (reg:CC FLAGS_REG))])] 
4498   "TARGET_80387"
4499   "")
4500
4501 (define_expand "fix_truncdfhi2"
4502   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4503                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4504               (clobber (reg:CC FLAGS_REG))])]
4505   "TARGET_80387 && !TARGET_SSE2"
4506   "")
4507
4508 (define_expand "fix_truncsfhi2"
4509   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4510                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4511                (clobber (reg:CC FLAGS_REG))])]
4512   "TARGET_80387 && !TARGET_SSE"
4513   "")
4514
4515 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4516 ;; of the machinery.
4517 (define_insn_and_split "*fix_trunchi_i387"
4518   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4519         (fix:HI (match_operand 1 "register_operand" "f,f")))
4520    (clobber (reg:CC FLAGS_REG))]
4521   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4522    && !reload_completed && !reload_in_progress
4523    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4524   "#"
4525   "&& 1"
4526   [(const_int 0)]
4527 {
4528   ix86_optimize_mode_switching = 1;
4529   operands[2] = assign_386_stack_local (HImode, 1);
4530   operands[3] = assign_386_stack_local (HImode, 2);
4531   if (memory_operand (operands[0], VOIDmode))
4532     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4533                                        operands[2], operands[3]));
4534   else
4535     {
4536       operands[4] = assign_386_stack_local (HImode, 0);
4537       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4538                                            operands[2], operands[3],
4539                                            operands[4]));
4540     }
4541   DONE;
4542 }
4543   [(set_attr "type" "fistp")
4544    (set_attr "i387_cw" "trunc")
4545    (set_attr "mode" "HI")])
4546
4547 (define_insn "fix_trunchi_nomemory"
4548   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4549         (fix:HI (match_operand 1 "register_operand" "f,f")))
4550    (use (match_operand:HI 2 "memory_operand" "m,m"))
4551    (use (match_operand:HI 3 "memory_operand" "m,m"))
4552    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4553   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4554    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4555   "#"
4556   [(set_attr "type" "fistp")
4557    (set_attr "i387_cw" "trunc")
4558    (set_attr "mode" "HI")])
4559
4560 (define_insn "fix_trunchi_memory"
4561   [(set (match_operand:HI 0 "memory_operand" "=m")
4562         (fix:HI (match_operand 1 "register_operand" "f")))
4563    (use (match_operand:HI 2 "memory_operand" "m"))
4564    (use (match_operand:HI 3 "memory_operand" "m"))]
4565   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4566    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4567   "* return output_fix_trunc (insn, operands);"
4568   [(set_attr "type" "fistp")
4569    (set_attr "i387_cw" "trunc")
4570    (set_attr "mode" "HI")])
4571
4572 (define_split 
4573   [(set (match_operand:HI 0 "memory_operand" "")
4574         (fix:HI (match_operand 1 "register_operand" "")))
4575    (use (match_operand:HI 2 "memory_operand" ""))
4576    (use (match_operand:HI 3 "memory_operand" ""))
4577    (clobber (match_operand:HI 4 "memory_operand" ""))]
4578   "reload_completed"
4579   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4580               (use (match_dup 2))
4581               (use (match_dup 3))])]
4582   "")
4583
4584 (define_split 
4585   [(set (match_operand:HI 0 "register_operand" "")
4586         (fix:HI (match_operand 1 "register_operand" "")))
4587    (use (match_operand:HI 2 "memory_operand" ""))
4588    (use (match_operand:HI 3 "memory_operand" ""))
4589    (clobber (match_operand:HI 4 "memory_operand" ""))]
4590   "reload_completed"
4591   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4592               (use (match_dup 2))
4593               (use (match_dup 3))
4594               (clobber (match_dup 4))])
4595    (set (match_dup 0) (match_dup 4))]
4596   "")
4597
4598 (define_insn "x86_fnstcw_1"
4599   [(set (match_operand:HI 0 "memory_operand" "=m")
4600         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4601   "TARGET_80387"
4602   "fnstcw\t%0"
4603   [(set_attr "length" "2")
4604    (set_attr "mode" "HI")
4605    (set_attr "unit" "i387")])
4606
4607 (define_insn "x86_fldcw_1"
4608   [(set (reg:HI FPSR_REG)
4609         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4610   "TARGET_80387"
4611   "fldcw\t%0"
4612   [(set_attr "length" "2")
4613    (set_attr "mode" "HI")
4614    (set_attr "unit" "i387")
4615    (set_attr "athlon_decode" "vector")])
4616 \f
4617 ;; Conversion between fixed point and floating point.
4618
4619 ;; Even though we only accept memory inputs, the backend _really_
4620 ;; wants to be able to do this between registers.
4621
4622 (define_expand "floathisf2"
4623   [(set (match_operand:SF 0 "register_operand" "")
4624         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4625   "TARGET_80387 || TARGET_SSE_MATH"
4626 {
4627   if (TARGET_SSE_MATH)
4628     {
4629       emit_insn (gen_floatsisf2 (operands[0],
4630                                  convert_to_mode (SImode, operands[1], 0)));
4631       DONE;
4632     }
4633 })
4634
4635 (define_insn "*floathisf2_i387"
4636   [(set (match_operand:SF 0 "register_operand" "=f,f")
4637         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4639   "@
4640    fild%z1\t%1
4641    #"
4642   [(set_attr "type" "fmov,multi")
4643    (set_attr "mode" "SF")
4644    (set_attr "fp_int_src" "true")])
4645
4646 (define_expand "floatsisf2"
4647   [(set (match_operand:SF 0 "register_operand" "")
4648         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4649   "TARGET_80387 || TARGET_SSE_MATH"
4650   "")
4651
4652 (define_insn "*floatsisf2_mixed"
4653   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4654         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4655   "TARGET_MIX_SSE_I387"
4656   "@
4657    fild%z1\t%1
4658    #
4659    cvtsi2ss\t{%1, %0|%0, %1}
4660    cvtsi2ss\t{%1, %0|%0, %1}"
4661   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4662    (set_attr "mode" "SF")
4663    (set_attr "athlon_decode" "*,*,vector,double")
4664    (set_attr "fp_int_src" "true")])
4665
4666 (define_insn "*floatsisf2_sse"
4667   [(set (match_operand:SF 0 "register_operand" "=x,x")
4668         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4669   "TARGET_SSE_MATH"
4670   "cvtsi2ss\t{%1, %0|%0, %1}"
4671   [(set_attr "type" "sseicvt")
4672    (set_attr "mode" "SF")
4673    (set_attr "athlon_decode" "vector,double")
4674    (set_attr "fp_int_src" "true")])
4675
4676 (define_insn "*floatsisf2_i387"
4677   [(set (match_operand:SF 0 "register_operand" "=f,f")
4678         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4679   "TARGET_80387"
4680   "@
4681    fild%z1\t%1
4682    #"
4683   [(set_attr "type" "fmov,multi")
4684    (set_attr "mode" "SF")
4685    (set_attr "fp_int_src" "true")])
4686
4687 (define_expand "floatdisf2"
4688   [(set (match_operand:SF 0 "register_operand" "")
4689         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4690   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4691   "")
4692
4693 (define_insn "*floatdisf2_mixed"
4694   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4695         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4696   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4697   "@
4698    fild%z1\t%1
4699    #
4700    cvtsi2ss{q}\t{%1, %0|%0, %1}
4701    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4702   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4703    (set_attr "mode" "SF")
4704    (set_attr "athlon_decode" "*,*,vector,double")
4705    (set_attr "fp_int_src" "true")])
4706
4707 (define_insn "*floatdisf2_sse"
4708   [(set (match_operand:SF 0 "register_operand" "=x,x")
4709         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4710   "TARGET_64BIT && TARGET_SSE_MATH"
4711   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4712   [(set_attr "type" "sseicvt")
4713    (set_attr "mode" "SF")
4714    (set_attr "athlon_decode" "vector,double")
4715    (set_attr "fp_int_src" "true")])
4716
4717 (define_insn "*floatdisf2_i387"
4718   [(set (match_operand:SF 0 "register_operand" "=f,f")
4719         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4720   "TARGET_80387"
4721   "@
4722    fild%z1\t%1
4723    #"
4724   [(set_attr "type" "fmov,multi")
4725    (set_attr "mode" "SF")
4726    (set_attr "fp_int_src" "true")])
4727
4728 (define_expand "floathidf2"
4729   [(set (match_operand:DF 0 "register_operand" "")
4730         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4731   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4732 {
4733   if (TARGET_SSE2 && TARGET_SSE_MATH)
4734     {
4735       emit_insn (gen_floatsidf2 (operands[0],
4736                                  convert_to_mode (SImode, operands[1], 0)));
4737       DONE;
4738     }
4739 })
4740
4741 (define_insn "*floathidf2_i387"
4742   [(set (match_operand:DF 0 "register_operand" "=f,f")
4743         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4744   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4745   "@
4746    fild%z1\t%1
4747    #"
4748   [(set_attr "type" "fmov,multi")
4749    (set_attr "mode" "DF")
4750    (set_attr "fp_int_src" "true")])
4751
4752 (define_expand "floatsidf2"
4753   [(set (match_operand:DF 0 "register_operand" "")
4754         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4755   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4756   "")
4757
4758 (define_insn "*floatsidf2_mixed"
4759   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4760         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4761   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4762   "@
4763    fild%z1\t%1
4764    #
4765    cvtsi2sd\t{%1, %0|%0, %1}
4766    cvtsi2sd\t{%1, %0|%0, %1}"
4767   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4768    (set_attr "mode" "DF")
4769    (set_attr "athlon_decode" "*,*,double,direct")
4770    (set_attr "fp_int_src" "true")])
4771
4772 (define_insn "*floatsidf2_sse"
4773   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4774         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4775   "TARGET_SSE2 && TARGET_SSE_MATH"
4776   "cvtsi2sd\t{%1, %0|%0, %1}"
4777   [(set_attr "type" "sseicvt")
4778    (set_attr "mode" "DF")
4779    (set_attr "athlon_decode" "double,direct")
4780    (set_attr "fp_int_src" "true")])
4781
4782 (define_insn "*floatsidf2_i387"
4783   [(set (match_operand:DF 0 "register_operand" "=f,f")
4784         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4785   "TARGET_80387"
4786   "@
4787    fild%z1\t%1
4788    #"
4789   [(set_attr "type" "fmov,multi")
4790    (set_attr "mode" "DF")
4791    (set_attr "fp_int_src" "true")])
4792
4793 (define_expand "floatdidf2"
4794   [(set (match_operand:DF 0 "register_operand" "")
4795         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4796   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4797   "")
4798
4799 (define_insn "*floatdidf2_mixed"
4800   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4801         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4802   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4803   "@
4804    fild%z1\t%1
4805    #
4806    cvtsi2sd{q}\t{%1, %0|%0, %1}
4807    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4808   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4809    (set_attr "mode" "DF")
4810    (set_attr "athlon_decode" "*,*,double,direct")
4811    (set_attr "fp_int_src" "true")])
4812
4813 (define_insn "*floatdidf2_sse"
4814   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4815         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4816   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4817   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4818   [(set_attr "type" "sseicvt")
4819    (set_attr "mode" "DF")
4820    (set_attr "athlon_decode" "double,direct")
4821    (set_attr "fp_int_src" "true")])
4822
4823 (define_insn "*floatdidf2_i387"
4824   [(set (match_operand:DF 0 "register_operand" "=f,f")
4825         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4826   "TARGET_80387"
4827   "@
4828    fild%z1\t%1
4829    #"
4830   [(set_attr "type" "fmov,multi")
4831    (set_attr "mode" "DF")
4832    (set_attr "fp_int_src" "true")])
4833
4834 (define_insn "floathixf2"
4835   [(set (match_operand:XF 0 "register_operand" "=f,f")
4836         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4837   "TARGET_80387"
4838   "@
4839    fild%z1\t%1
4840    #"
4841   [(set_attr "type" "fmov,multi")
4842    (set_attr "mode" "XF")
4843    (set_attr "fp_int_src" "true")])
4844
4845 (define_insn "floatsixf2"
4846   [(set (match_operand:XF 0 "register_operand" "=f,f")
4847         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4848   "TARGET_80387"
4849   "@
4850    fild%z1\t%1
4851    #"
4852   [(set_attr "type" "fmov,multi")
4853    (set_attr "mode" "XF")
4854    (set_attr "fp_int_src" "true")])
4855
4856 (define_insn "floatdixf2"
4857   [(set (match_operand:XF 0 "register_operand" "=f,f")
4858         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4859   "TARGET_80387"
4860   "@
4861    fild%z1\t%1
4862    #"
4863   [(set_attr "type" "fmov,multi")
4864    (set_attr "mode" "XF")
4865    (set_attr "fp_int_src" "true")])
4866
4867 ;; %%% Kill these when reload knows how to do it.
4868 (define_split
4869   [(set (match_operand 0 "fp_register_operand" "")
4870         (float (match_operand 1 "register_operand" "")))]
4871   "reload_completed
4872    && TARGET_80387
4873    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4874   [(const_int 0)]
4875 {
4876   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4877   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4878   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4879   ix86_free_from_memory (GET_MODE (operands[1]));
4880   DONE;
4881 })
4882
4883 (define_expand "floatunssisf2"
4884   [(use (match_operand:SF 0 "register_operand" ""))
4885    (use (match_operand:SI 1 "register_operand" ""))]
4886   "!TARGET_64BIT && TARGET_SSE_MATH"
4887   "x86_emit_floatuns (operands); DONE;")
4888
4889 (define_expand "floatunsdisf2"
4890   [(use (match_operand:SF 0 "register_operand" ""))
4891    (use (match_operand:DI 1 "register_operand" ""))]
4892   "TARGET_64BIT && TARGET_SSE_MATH"
4893   "x86_emit_floatuns (operands); DONE;")
4894
4895 (define_expand "floatunsdidf2"
4896   [(use (match_operand:DF 0 "register_operand" ""))
4897    (use (match_operand:DI 1 "register_operand" ""))]
4898   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4899   "x86_emit_floatuns (operands); DONE;")
4900 \f
4901 ;; SSE extract/set expanders
4902
4903 \f
4904 ;; Add instructions
4905
4906 ;; %%% splits for addsidi3
4907 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4908 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4909 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4910
4911 (define_expand "adddi3"
4912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4913         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4914                  (match_operand:DI 2 "x86_64_general_operand" "")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   ""
4917   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4918
4919 (define_insn "*adddi3_1"
4920   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4921         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4922                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4923    (clobber (reg:CC FLAGS_REG))]
4924   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4925   "#")
4926
4927 (define_split
4928   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4929         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4930                  (match_operand:DI 2 "general_operand" "")))
4931    (clobber (reg:CC FLAGS_REG))]
4932   "!TARGET_64BIT && reload_completed"
4933   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4934                                           UNSPEC_ADD_CARRY))
4935               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4936    (parallel [(set (match_dup 3)
4937                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4938                                      (match_dup 4))
4939                             (match_dup 5)))
4940               (clobber (reg:CC FLAGS_REG))])]
4941   "split_di (operands+0, 1, operands+0, operands+3);
4942    split_di (operands+1, 1, operands+1, operands+4);
4943    split_di (operands+2, 1, operands+2, operands+5);")
4944
4945 (define_insn "adddi3_carry_rex64"
4946   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4947           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4948                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4949                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4950    (clobber (reg:CC FLAGS_REG))]
4951   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4952   "adc{q}\t{%2, %0|%0, %2}"
4953   [(set_attr "type" "alu")
4954    (set_attr "pent_pair" "pu")
4955    (set_attr "mode" "DI")])
4956
4957 (define_insn "*adddi3_cc_rex64"
4958   [(set (reg:CC FLAGS_REG)
4959         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4960                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4961                    UNSPEC_ADD_CARRY))
4962    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4963         (plus:DI (match_dup 1) (match_dup 2)))]
4964   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4965   "add{q}\t{%2, %0|%0, %2}"
4966   [(set_attr "type" "alu")
4967    (set_attr "mode" "DI")])
4968
4969 (define_insn "addqi3_carry"
4970   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4971           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4972                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4973                    (match_operand:QI 2 "general_operand" "qi,qm")))
4974    (clobber (reg:CC FLAGS_REG))]
4975   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4976   "adc{b}\t{%2, %0|%0, %2}"
4977   [(set_attr "type" "alu")
4978    (set_attr "pent_pair" "pu")
4979    (set_attr "mode" "QI")])
4980
4981 (define_insn "addhi3_carry"
4982   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4983           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4984                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4985                    (match_operand:HI 2 "general_operand" "ri,rm")))
4986    (clobber (reg:CC FLAGS_REG))]
4987   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4988   "adc{w}\t{%2, %0|%0, %2}"
4989   [(set_attr "type" "alu")
4990    (set_attr "pent_pair" "pu")
4991    (set_attr "mode" "HI")])
4992
4993 (define_insn "addsi3_carry"
4994   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4995           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4996                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4997                    (match_operand:SI 2 "general_operand" "ri,rm")))
4998    (clobber (reg:CC FLAGS_REG))]
4999   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5000   "adc{l}\t{%2, %0|%0, %2}"
5001   [(set_attr "type" "alu")
5002    (set_attr "pent_pair" "pu")
5003    (set_attr "mode" "SI")])
5004
5005 (define_insn "*addsi3_carry_zext"
5006   [(set (match_operand:DI 0 "register_operand" "=r")
5007           (zero_extend:DI 
5008             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5009                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5010                      (match_operand:SI 2 "general_operand" "rim"))))
5011    (clobber (reg:CC FLAGS_REG))]
5012   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5013   "adc{l}\t{%2, %k0|%k0, %2}"
5014   [(set_attr "type" "alu")
5015    (set_attr "pent_pair" "pu")
5016    (set_attr "mode" "SI")])
5017
5018 (define_insn "*addsi3_cc"
5019   [(set (reg:CC FLAGS_REG)
5020         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5021                     (match_operand:SI 2 "general_operand" "ri,rm")]
5022                    UNSPEC_ADD_CARRY))
5023    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5024         (plus:SI (match_dup 1) (match_dup 2)))]
5025   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5026   "add{l}\t{%2, %0|%0, %2}"
5027   [(set_attr "type" "alu")
5028    (set_attr "mode" "SI")])
5029
5030 (define_insn "addqi3_cc"
5031   [(set (reg:CC FLAGS_REG)
5032         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5033                     (match_operand:QI 2 "general_operand" "qi,qm")]
5034                    UNSPEC_ADD_CARRY))
5035    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5036         (plus:QI (match_dup 1) (match_dup 2)))]
5037   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5038   "add{b}\t{%2, %0|%0, %2}"
5039   [(set_attr "type" "alu")
5040    (set_attr "mode" "QI")])
5041
5042 (define_expand "addsi3"
5043   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5044                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5045                             (match_operand:SI 2 "general_operand" "")))
5046               (clobber (reg:CC FLAGS_REG))])]
5047   ""
5048   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5049
5050 (define_insn "*lea_1"
5051   [(set (match_operand:SI 0 "register_operand" "=r")
5052         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5053   "!TARGET_64BIT"
5054   "lea{l}\t{%a1, %0|%0, %a1}"
5055   [(set_attr "type" "lea")
5056    (set_attr "mode" "SI")])
5057
5058 (define_insn "*lea_1_rex64"
5059   [(set (match_operand:SI 0 "register_operand" "=r")
5060         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5061   "TARGET_64BIT"
5062   "lea{l}\t{%a1, %0|%0, %a1}"
5063   [(set_attr "type" "lea")
5064    (set_attr "mode" "SI")])
5065
5066 (define_insn "*lea_1_zext"
5067   [(set (match_operand:DI 0 "register_operand" "=r")
5068         (zero_extend:DI
5069          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5070   "TARGET_64BIT"
5071   "lea{l}\t{%a1, %k0|%k0, %a1}"
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "SI")])
5074
5075 (define_insn "*lea_2_rex64"
5076   [(set (match_operand:DI 0 "register_operand" "=r")
5077         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5078   "TARGET_64BIT"
5079   "lea{q}\t{%a1, %0|%0, %a1}"
5080   [(set_attr "type" "lea")
5081    (set_attr "mode" "DI")])
5082
5083 ;; The lea patterns for non-Pmodes needs to be matched by several
5084 ;; insns converted to real lea by splitters.
5085
5086 (define_insn_and_split "*lea_general_1"
5087   [(set (match_operand 0 "register_operand" "=r")
5088         (plus (plus (match_operand 1 "index_register_operand" "l")
5089                     (match_operand 2 "register_operand" "r"))
5090               (match_operand 3 "immediate_operand" "i")))]
5091   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5092     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5093    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5094    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5095    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5096    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5097        || GET_MODE (operands[3]) == VOIDmode)"
5098   "#"
5099   "&& reload_completed"
5100   [(const_int 0)]
5101 {
5102   rtx pat;
5103   operands[0] = gen_lowpart (SImode, operands[0]);
5104   operands[1] = gen_lowpart (Pmode, operands[1]);
5105   operands[2] = gen_lowpart (Pmode, operands[2]);
5106   operands[3] = gen_lowpart (Pmode, operands[3]);
5107   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5108                       operands[3]);
5109   if (Pmode != SImode)
5110     pat = gen_rtx_SUBREG (SImode, pat, 0);
5111   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5112   DONE;
5113 }
5114   [(set_attr "type" "lea")
5115    (set_attr "mode" "SI")])
5116
5117 (define_insn_and_split "*lea_general_1_zext"
5118   [(set (match_operand:DI 0 "register_operand" "=r")
5119         (zero_extend:DI
5120           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5121                             (match_operand:SI 2 "register_operand" "r"))
5122                    (match_operand:SI 3 "immediate_operand" "i"))))]
5123   "TARGET_64BIT"
5124   "#"
5125   "&& reload_completed"
5126   [(set (match_dup 0)
5127         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5128                                                      (match_dup 2))
5129                                             (match_dup 3)) 0)))]
5130 {
5131   operands[1] = gen_lowpart (Pmode, operands[1]);
5132   operands[2] = gen_lowpart (Pmode, operands[2]);
5133   operands[3] = gen_lowpart (Pmode, operands[3]);
5134 }
5135   [(set_attr "type" "lea")
5136    (set_attr "mode" "SI")])
5137
5138 (define_insn_and_split "*lea_general_2"
5139   [(set (match_operand 0 "register_operand" "=r")
5140         (plus (mult (match_operand 1 "index_register_operand" "l")
5141                     (match_operand 2 "const248_operand" "i"))
5142               (match_operand 3 "nonmemory_operand" "ri")))]
5143   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5144     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5145    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5146    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5147    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5148        || GET_MODE (operands[3]) == VOIDmode)"
5149   "#"
5150   "&& reload_completed"
5151   [(const_int 0)]
5152 {
5153   rtx pat;
5154   operands[0] = gen_lowpart (SImode, operands[0]);
5155   operands[1] = gen_lowpart (Pmode, operands[1]);
5156   operands[3] = gen_lowpart (Pmode, operands[3]);
5157   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5158                       operands[3]);
5159   if (Pmode != SImode)
5160     pat = gen_rtx_SUBREG (SImode, pat, 0);
5161   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5162   DONE;
5163 }
5164   [(set_attr "type" "lea")
5165    (set_attr "mode" "SI")])
5166
5167 (define_insn_and_split "*lea_general_2_zext"
5168   [(set (match_operand:DI 0 "register_operand" "=r")
5169         (zero_extend:DI
5170           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5171                             (match_operand:SI 2 "const248_operand" "n"))
5172                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5173   "TARGET_64BIT"
5174   "#"
5175   "&& reload_completed"
5176   [(set (match_dup 0)
5177         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5178                                                      (match_dup 2))
5179                                             (match_dup 3)) 0)))]
5180 {
5181   operands[1] = gen_lowpart (Pmode, operands[1]);
5182   operands[3] = gen_lowpart (Pmode, operands[3]);
5183 }
5184   [(set_attr "type" "lea")
5185    (set_attr "mode" "SI")])
5186
5187 (define_insn_and_split "*lea_general_3"
5188   [(set (match_operand 0 "register_operand" "=r")
5189         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5190                           (match_operand 2 "const248_operand" "i"))
5191                     (match_operand 3 "register_operand" "r"))
5192               (match_operand 4 "immediate_operand" "i")))]
5193   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5194     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5195    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5196    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5197    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5198   "#"
5199   "&& reload_completed"
5200   [(const_int 0)]
5201 {
5202   rtx pat;
5203   operands[0] = gen_lowpart (SImode, operands[0]);
5204   operands[1] = gen_lowpart (Pmode, operands[1]);
5205   operands[3] = gen_lowpart (Pmode, operands[3]);
5206   operands[4] = gen_lowpart (Pmode, operands[4]);
5207   pat = gen_rtx_PLUS (Pmode,
5208                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5209                                                          operands[2]),
5210                                     operands[3]),
5211                       operands[4]);
5212   if (Pmode != SImode)
5213     pat = gen_rtx_SUBREG (SImode, pat, 0);
5214   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5215   DONE;
5216 }
5217   [(set_attr "type" "lea")
5218    (set_attr "mode" "SI")])
5219
5220 (define_insn_and_split "*lea_general_3_zext"
5221   [(set (match_operand:DI 0 "register_operand" "=r")
5222         (zero_extend:DI
5223           (plus:SI (plus:SI (mult:SI
5224                               (match_operand:SI 1 "index_register_operand" "l")
5225                               (match_operand:SI 2 "const248_operand" "n"))
5226                             (match_operand:SI 3 "register_operand" "r"))
5227                    (match_operand:SI 4 "immediate_operand" "i"))))]
5228   "TARGET_64BIT"
5229   "#"
5230   "&& reload_completed"
5231   [(set (match_dup 0)
5232         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5233                                                               (match_dup 2))
5234                                                      (match_dup 3))
5235                                             (match_dup 4)) 0)))]
5236 {
5237   operands[1] = gen_lowpart (Pmode, operands[1]);
5238   operands[3] = gen_lowpart (Pmode, operands[3]);
5239   operands[4] = gen_lowpart (Pmode, operands[4]);
5240 }
5241   [(set_attr "type" "lea")
5242    (set_attr "mode" "SI")])
5243
5244 (define_insn "*adddi_1_rex64"
5245   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5246         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5247                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5248    (clobber (reg:CC FLAGS_REG))]
5249   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5250 {
5251   switch (get_attr_type (insn))
5252     {
5253     case TYPE_LEA:
5254       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5255       return "lea{q}\t{%a2, %0|%0, %a2}";
5256
5257     case TYPE_INCDEC:
5258       if (! rtx_equal_p (operands[0], operands[1]))
5259         abort ();
5260       if (operands[2] == const1_rtx)
5261         return "inc{q}\t%0";
5262       else if (operands[2] == constm1_rtx)
5263         return "dec{q}\t%0";
5264       else
5265         abort ();
5266
5267     default:
5268       if (! rtx_equal_p (operands[0], operands[1]))
5269         abort ();
5270
5271       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5272          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5273       if (GET_CODE (operands[2]) == CONST_INT
5274           /* Avoid overflows.  */
5275           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5276           && (INTVAL (operands[2]) == 128
5277               || (INTVAL (operands[2]) < 0
5278                   && INTVAL (operands[2]) != -128)))
5279         {
5280           operands[2] = GEN_INT (-INTVAL (operands[2]));
5281           return "sub{q}\t{%2, %0|%0, %2}";
5282         }
5283       return "add{q}\t{%2, %0|%0, %2}";
5284     }
5285 }
5286   [(set (attr "type")
5287      (cond [(eq_attr "alternative" "2")
5288               (const_string "lea")
5289             ; Current assemblers are broken and do not allow @GOTOFF in
5290             ; ought but a memory context.
5291             (match_operand:DI 2 "pic_symbolic_operand" "")
5292               (const_string "lea")
5293             (match_operand:DI 2 "incdec_operand" "")
5294               (const_string "incdec")
5295            ]
5296            (const_string "alu")))
5297    (set_attr "mode" "DI")])
5298
5299 ;; Convert lea to the lea pattern to avoid flags dependency.
5300 (define_split
5301   [(set (match_operand:DI 0 "register_operand" "")
5302         (plus:DI (match_operand:DI 1 "register_operand" "")
5303                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5304    (clobber (reg:CC FLAGS_REG))]
5305   "TARGET_64BIT && reload_completed
5306    && true_regnum (operands[0]) != true_regnum (operands[1])"
5307   [(set (match_dup 0)
5308         (plus:DI (match_dup 1)
5309                  (match_dup 2)))]
5310   "")
5311
5312 (define_insn "*adddi_2_rex64"
5313   [(set (reg FLAGS_REG)
5314         (compare
5315           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5316                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5317           (const_int 0)))                       
5318    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5319         (plus:DI (match_dup 1) (match_dup 2)))]
5320   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5321    && ix86_binary_operator_ok (PLUS, DImode, operands)
5322    /* Current assemblers are broken and do not allow @GOTOFF in
5323       ought but a memory context.  */
5324    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5325 {
5326   switch (get_attr_type (insn))
5327     {
5328     case TYPE_INCDEC:
5329       if (! rtx_equal_p (operands[0], operands[1]))
5330         abort ();
5331       if (operands[2] == const1_rtx)
5332         return "inc{q}\t%0";
5333       else if (operands[2] == constm1_rtx)
5334         return "dec{q}\t%0";
5335       else
5336         abort ();
5337
5338     default:
5339       if (! rtx_equal_p (operands[0], operands[1]))
5340         abort ();
5341       /* ???? We ought to handle there the 32bit case too
5342          - do we need new constraint?  */
5343       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5344          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5345       if (GET_CODE (operands[2]) == CONST_INT
5346           /* Avoid overflows.  */
5347           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5348           && (INTVAL (operands[2]) == 128
5349               || (INTVAL (operands[2]) < 0
5350                   && INTVAL (operands[2]) != -128)))
5351         {
5352           operands[2] = GEN_INT (-INTVAL (operands[2]));
5353           return "sub{q}\t{%2, %0|%0, %2}";
5354         }
5355       return "add{q}\t{%2, %0|%0, %2}";
5356     }
5357 }
5358   [(set (attr "type")
5359      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5360         (const_string "incdec")
5361         (const_string "alu")))
5362    (set_attr "mode" "DI")])
5363
5364 (define_insn "*adddi_3_rex64"
5365   [(set (reg FLAGS_REG)
5366         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5367                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5368    (clobber (match_scratch:DI 0 "=r"))]
5369   "TARGET_64BIT
5370    && ix86_match_ccmode (insn, CCZmode)
5371    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5372    /* Current assemblers are broken and do not allow @GOTOFF in
5373       ought but a memory context.  */
5374    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5375 {
5376   switch (get_attr_type (insn))
5377     {
5378     case TYPE_INCDEC:
5379       if (! rtx_equal_p (operands[0], operands[1]))
5380         abort ();
5381       if (operands[2] == const1_rtx)
5382         return "inc{q}\t%0";
5383       else if (operands[2] == constm1_rtx)
5384         return "dec{q}\t%0";
5385       else
5386         abort ();
5387
5388     default:
5389       if (! rtx_equal_p (operands[0], operands[1]))
5390         abort ();
5391       /* ???? We ought to handle there the 32bit case too
5392          - do we need new constraint?  */
5393       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5394          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5395       if (GET_CODE (operands[2]) == CONST_INT
5396           /* Avoid overflows.  */
5397           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5398           && (INTVAL (operands[2]) == 128
5399               || (INTVAL (operands[2]) < 0
5400                   && INTVAL (operands[2]) != -128)))
5401         {
5402           operands[2] = GEN_INT (-INTVAL (operands[2]));
5403           return "sub{q}\t{%2, %0|%0, %2}";
5404         }
5405       return "add{q}\t{%2, %0|%0, %2}";
5406     }
5407 }
5408   [(set (attr "type")
5409      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5410         (const_string "incdec")
5411         (const_string "alu")))
5412    (set_attr "mode" "DI")])
5413
5414 ; For comparisons against 1, -1 and 128, we may generate better code
5415 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5416 ; is matched then.  We can't accept general immediate, because for
5417 ; case of overflows,  the result is messed up.
5418 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5419 ; when negated.
5420 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5421 ; only for comparisons not depending on it.
5422 (define_insn "*adddi_4_rex64"
5423   [(set (reg FLAGS_REG)
5424         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5425                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5426    (clobber (match_scratch:DI 0 "=rm"))]
5427   "TARGET_64BIT
5428    &&  ix86_match_ccmode (insn, CCGCmode)"
5429 {
5430   switch (get_attr_type (insn))
5431     {
5432     case TYPE_INCDEC:
5433       if (operands[2] == constm1_rtx)
5434         return "inc{q}\t%0";
5435       else if (operands[2] == const1_rtx)
5436         return "dec{q}\t%0";
5437       else
5438         abort();
5439
5440     default:
5441       if (! rtx_equal_p (operands[0], operands[1]))
5442         abort ();
5443       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5445       if ((INTVAL (operands[2]) == -128
5446            || (INTVAL (operands[2]) > 0
5447                && INTVAL (operands[2]) != 128))
5448           /* Avoid overflows.  */
5449           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5450         return "sub{q}\t{%2, %0|%0, %2}";
5451       operands[2] = GEN_INT (-INTVAL (operands[2]));
5452       return "add{q}\t{%2, %0|%0, %2}";
5453     }
5454 }
5455   [(set (attr "type")
5456      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5457         (const_string "incdec")
5458         (const_string "alu")))
5459    (set_attr "mode" "DI")])
5460
5461 (define_insn "*adddi_5_rex64"
5462   [(set (reg FLAGS_REG)
5463         (compare
5464           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5465                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5466           (const_int 0)))                       
5467    (clobber (match_scratch:DI 0 "=r"))]
5468   "TARGET_64BIT
5469    && ix86_match_ccmode (insn, CCGOCmode)
5470    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5471    /* Current assemblers are broken and do not allow @GOTOFF in
5472       ought but a memory context.  */
5473    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5474 {
5475   switch (get_attr_type (insn))
5476     {
5477     case TYPE_INCDEC:
5478       if (! rtx_equal_p (operands[0], operands[1]))
5479         abort ();
5480       if (operands[2] == const1_rtx)
5481         return "inc{q}\t%0";
5482       else if (operands[2] == constm1_rtx)
5483         return "dec{q}\t%0";
5484       else
5485         abort();
5486
5487     default:
5488       if (! rtx_equal_p (operands[0], operands[1]))
5489         abort ();
5490       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5492       if (GET_CODE (operands[2]) == CONST_INT
5493           /* Avoid overflows.  */
5494           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5495           && (INTVAL (operands[2]) == 128
5496               || (INTVAL (operands[2]) < 0
5497                   && INTVAL (operands[2]) != -128)))
5498         {
5499           operands[2] = GEN_INT (-INTVAL (operands[2]));
5500           return "sub{q}\t{%2, %0|%0, %2}";
5501         }
5502       return "add{q}\t{%2, %0|%0, %2}";
5503     }
5504 }
5505   [(set (attr "type")
5506      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5507         (const_string "incdec")
5508         (const_string "alu")))
5509    (set_attr "mode" "DI")])
5510
5511
5512 (define_insn "*addsi_1"
5513   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5514         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5515                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5516    (clobber (reg:CC FLAGS_REG))]
5517   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5518 {
5519   switch (get_attr_type (insn))
5520     {
5521     case TYPE_LEA:
5522       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5523       return "lea{l}\t{%a2, %0|%0, %a2}";
5524
5525     case TYPE_INCDEC:
5526       if (! rtx_equal_p (operands[0], operands[1]))
5527         abort ();
5528       if (operands[2] == const1_rtx)
5529         return "inc{l}\t%0";
5530       else if (operands[2] == constm1_rtx)
5531         return "dec{l}\t%0";
5532       else
5533         abort();
5534
5535     default:
5536       if (! rtx_equal_p (operands[0], operands[1]))
5537         abort ();
5538
5539       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5541       if (GET_CODE (operands[2]) == CONST_INT
5542           && (INTVAL (operands[2]) == 128
5543               || (INTVAL (operands[2]) < 0
5544                   && INTVAL (operands[2]) != -128)))
5545         {
5546           operands[2] = GEN_INT (-INTVAL (operands[2]));
5547           return "sub{l}\t{%2, %0|%0, %2}";
5548         }
5549       return "add{l}\t{%2, %0|%0, %2}";
5550     }
5551 }
5552   [(set (attr "type")
5553      (cond [(eq_attr "alternative" "2")
5554               (const_string "lea")
5555             ; Current assemblers are broken and do not allow @GOTOFF in
5556             ; ought but a memory context.
5557             (match_operand:SI 2 "pic_symbolic_operand" "")
5558               (const_string "lea")
5559             (match_operand:SI 2 "incdec_operand" "")
5560               (const_string "incdec")
5561            ]
5562            (const_string "alu")))
5563    (set_attr "mode" "SI")])
5564
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567   [(set (match_operand 0 "register_operand" "")
5568         (plus (match_operand 1 "register_operand" "")
5569               (match_operand 2 "nonmemory_operand" "")))
5570    (clobber (reg:CC FLAGS_REG))]
5571   "reload_completed
5572    && true_regnum (operands[0]) != true_regnum (operands[1])"
5573   [(const_int 0)]
5574 {
5575   rtx pat;
5576   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5577      may confuse gen_lowpart.  */
5578   if (GET_MODE (operands[0]) != Pmode)
5579     {
5580       operands[1] = gen_lowpart (Pmode, operands[1]);
5581       operands[2] = gen_lowpart (Pmode, operands[2]);
5582     }
5583   operands[0] = gen_lowpart (SImode, operands[0]);
5584   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5585   if (Pmode != SImode)
5586     pat = gen_rtx_SUBREG (SImode, pat, 0);
5587   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5588   DONE;
5589 })
5590
5591 ;; It may seem that nonimmediate operand is proper one for operand 1.
5592 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5593 ;; we take care in ix86_binary_operator_ok to not allow two memory
5594 ;; operands so proper swapping will be done in reload.  This allow
5595 ;; patterns constructed from addsi_1 to match.
5596 (define_insn "addsi_1_zext"
5597   [(set (match_operand:DI 0 "register_operand" "=r,r")
5598         (zero_extend:DI
5599           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5600                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5601    (clobber (reg:CC FLAGS_REG))]
5602   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5603 {
5604   switch (get_attr_type (insn))
5605     {
5606     case TYPE_LEA:
5607       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5608       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5609
5610     case TYPE_INCDEC:
5611       if (operands[2] == const1_rtx)
5612         return "inc{l}\t%k0";
5613       else if (operands[2] == constm1_rtx)
5614         return "dec{l}\t%k0";
5615       else
5616         abort();
5617
5618     default:
5619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5621       if (GET_CODE (operands[2]) == CONST_INT
5622           && (INTVAL (operands[2]) == 128
5623               || (INTVAL (operands[2]) < 0
5624                   && INTVAL (operands[2]) != -128)))
5625         {
5626           operands[2] = GEN_INT (-INTVAL (operands[2]));
5627           return "sub{l}\t{%2, %k0|%k0, %2}";
5628         }
5629       return "add{l}\t{%2, %k0|%k0, %2}";
5630     }
5631 }
5632   [(set (attr "type")
5633      (cond [(eq_attr "alternative" "1")
5634               (const_string "lea")
5635             ; Current assemblers are broken and do not allow @GOTOFF in
5636             ; ought but a memory context.
5637             (match_operand:SI 2 "pic_symbolic_operand" "")
5638               (const_string "lea")
5639             (match_operand:SI 2 "incdec_operand" "")
5640               (const_string "incdec")
5641            ]
5642            (const_string "alu")))
5643    (set_attr "mode" "SI")])
5644
5645 ;; Convert lea to the lea pattern to avoid flags dependency.
5646 (define_split
5647   [(set (match_operand:DI 0 "register_operand" "")
5648         (zero_extend:DI
5649           (plus:SI (match_operand:SI 1 "register_operand" "")
5650                    (match_operand:SI 2 "nonmemory_operand" ""))))
5651    (clobber (reg:CC FLAGS_REG))]
5652   "TARGET_64BIT && reload_completed
5653    && true_regnum (operands[0]) != true_regnum (operands[1])"
5654   [(set (match_dup 0)
5655         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5656 {
5657   operands[1] = gen_lowpart (Pmode, operands[1]);
5658   operands[2] = gen_lowpart (Pmode, operands[2]);
5659 })
5660
5661 (define_insn "*addsi_2"
5662   [(set (reg FLAGS_REG)
5663         (compare
5664           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5665                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5666           (const_int 0)))                       
5667    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5668         (plus:SI (match_dup 1) (match_dup 2)))]
5669   "ix86_match_ccmode (insn, CCGOCmode)
5670    && ix86_binary_operator_ok (PLUS, SImode, operands)
5671    /* Current assemblers are broken and do not allow @GOTOFF in
5672       ought but a memory context.  */
5673    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5674 {
5675   switch (get_attr_type (insn))
5676     {
5677     case TYPE_INCDEC:
5678       if (! rtx_equal_p (operands[0], operands[1]))
5679         abort ();
5680       if (operands[2] == const1_rtx)
5681         return "inc{l}\t%0";
5682       else if (operands[2] == constm1_rtx)
5683         return "dec{l}\t%0";
5684       else
5685         abort();
5686
5687     default:
5688       if (! rtx_equal_p (operands[0], operands[1]))
5689         abort ();
5690       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5691          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5692       if (GET_CODE (operands[2]) == CONST_INT
5693           && (INTVAL (operands[2]) == 128
5694               || (INTVAL (operands[2]) < 0
5695                   && INTVAL (operands[2]) != -128)))
5696         {
5697           operands[2] = GEN_INT (-INTVAL (operands[2]));
5698           return "sub{l}\t{%2, %0|%0, %2}";
5699         }
5700       return "add{l}\t{%2, %0|%0, %2}";
5701     }
5702 }
5703   [(set (attr "type")
5704      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5705         (const_string "incdec")
5706         (const_string "alu")))
5707    (set_attr "mode" "SI")])
5708
5709 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5710 (define_insn "*addsi_2_zext"
5711   [(set (reg FLAGS_REG)
5712         (compare
5713           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5714                    (match_operand:SI 2 "general_operand" "rmni"))
5715           (const_int 0)))                       
5716    (set (match_operand:DI 0 "register_operand" "=r")
5717         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5718   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5719    && ix86_binary_operator_ok (PLUS, SImode, operands)
5720    /* Current assemblers are broken and do not allow @GOTOFF in
5721       ought but a memory context.  */
5722    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5723 {
5724   switch (get_attr_type (insn))
5725     {
5726     case TYPE_INCDEC:
5727       if (operands[2] == const1_rtx)
5728         return "inc{l}\t%k0";
5729       else if (operands[2] == constm1_rtx)
5730         return "dec{l}\t%k0";
5731       else
5732         abort();
5733
5734     default:
5735       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5736          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5737       if (GET_CODE (operands[2]) == CONST_INT
5738           && (INTVAL (operands[2]) == 128
5739               || (INTVAL (operands[2]) < 0
5740                   && INTVAL (operands[2]) != -128)))
5741         {
5742           operands[2] = GEN_INT (-INTVAL (operands[2]));
5743           return "sub{l}\t{%2, %k0|%k0, %2}";
5744         }
5745       return "add{l}\t{%2, %k0|%k0, %2}";
5746     }
5747 }
5748   [(set (attr "type")
5749      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5750         (const_string "incdec")
5751         (const_string "alu")))
5752    (set_attr "mode" "SI")])
5753
5754 (define_insn "*addsi_3"
5755   [(set (reg FLAGS_REG)
5756         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5757                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5758    (clobber (match_scratch:SI 0 "=r"))]
5759   "ix86_match_ccmode (insn, CCZmode)
5760    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761    /* Current assemblers are broken and do not allow @GOTOFF in
5762       ought but a memory context.  */
5763    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764 {
5765   switch (get_attr_type (insn))
5766     {
5767     case TYPE_INCDEC:
5768       if (! rtx_equal_p (operands[0], operands[1]))
5769         abort ();
5770       if (operands[2] == const1_rtx)
5771         return "inc{l}\t%0";
5772       else if (operands[2] == constm1_rtx)
5773         return "dec{l}\t%0";
5774       else
5775         abort();
5776
5777     default:
5778       if (! rtx_equal_p (operands[0], operands[1]))
5779         abort ();
5780       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5782       if (GET_CODE (operands[2]) == CONST_INT
5783           && (INTVAL (operands[2]) == 128
5784               || (INTVAL (operands[2]) < 0
5785                   && INTVAL (operands[2]) != -128)))
5786         {
5787           operands[2] = GEN_INT (-INTVAL (operands[2]));
5788           return "sub{l}\t{%2, %0|%0, %2}";
5789         }
5790       return "add{l}\t{%2, %0|%0, %2}";
5791     }
5792 }
5793   [(set (attr "type")
5794      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5795         (const_string "incdec")
5796         (const_string "alu")))
5797    (set_attr "mode" "SI")])
5798
5799 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5800 (define_insn "*addsi_3_zext"
5801   [(set (reg FLAGS_REG)
5802         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5803                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5804    (set (match_operand:DI 0 "register_operand" "=r")
5805         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5806   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5807    && ix86_binary_operator_ok (PLUS, SImode, operands)
5808    /* Current assemblers are broken and do not allow @GOTOFF in
5809       ought but a memory context.  */
5810    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5811 {
5812   switch (get_attr_type (insn))
5813     {
5814     case TYPE_INCDEC:
5815       if (operands[2] == const1_rtx)
5816         return "inc{l}\t%k0";
5817       else if (operands[2] == constm1_rtx)
5818         return "dec{l}\t%k0";
5819       else
5820         abort();
5821
5822     default:
5823       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5824          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5825       if (GET_CODE (operands[2]) == CONST_INT
5826           && (INTVAL (operands[2]) == 128
5827               || (INTVAL (operands[2]) < 0
5828                   && INTVAL (operands[2]) != -128)))
5829         {
5830           operands[2] = GEN_INT (-INTVAL (operands[2]));
5831           return "sub{l}\t{%2, %k0|%k0, %2}";
5832         }
5833       return "add{l}\t{%2, %k0|%k0, %2}";
5834     }
5835 }
5836   [(set (attr "type")
5837      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5838         (const_string "incdec")
5839         (const_string "alu")))
5840    (set_attr "mode" "SI")])
5841
5842 ; For comparisons against 1, -1 and 128, we may generate better code
5843 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5844 ; is matched then.  We can't accept general immediate, because for
5845 ; case of overflows,  the result is messed up.
5846 ; This pattern also don't hold of 0x80000000, since the value overflows
5847 ; when negated.
5848 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5849 ; only for comparisons not depending on it.
5850 (define_insn "*addsi_4"
5851   [(set (reg FLAGS_REG)
5852         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5853                  (match_operand:SI 2 "const_int_operand" "n")))
5854    (clobber (match_scratch:SI 0 "=rm"))]
5855   "ix86_match_ccmode (insn, CCGCmode)
5856    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5857 {
5858   switch (get_attr_type (insn))
5859     {
5860     case TYPE_INCDEC:
5861       if (operands[2] == constm1_rtx)
5862         return "inc{l}\t%0";
5863       else if (operands[2] == const1_rtx)
5864         return "dec{l}\t%0";
5865       else
5866         abort();
5867
5868     default:
5869       if (! rtx_equal_p (operands[0], operands[1]))
5870         abort ();
5871       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5872          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5873       if ((INTVAL (operands[2]) == -128
5874            || (INTVAL (operands[2]) > 0
5875                && INTVAL (operands[2]) != 128)))
5876         return "sub{l}\t{%2, %0|%0, %2}";
5877       operands[2] = GEN_INT (-INTVAL (operands[2]));
5878       return "add{l}\t{%2, %0|%0, %2}";
5879     }
5880 }
5881   [(set (attr "type")
5882      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883         (const_string "incdec")
5884         (const_string "alu")))
5885    (set_attr "mode" "SI")])
5886
5887 (define_insn "*addsi_5"
5888   [(set (reg FLAGS_REG)
5889         (compare
5890           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891                    (match_operand:SI 2 "general_operand" "rmni"))
5892           (const_int 0)))                       
5893    (clobber (match_scratch:SI 0 "=r"))]
5894   "ix86_match_ccmode (insn, CCGOCmode)
5895    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5896    /* Current assemblers are broken and do not allow @GOTOFF in
5897       ought but a memory context.  */
5898    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5899 {
5900   switch (get_attr_type (insn))
5901     {
5902     case TYPE_INCDEC:
5903       if (! rtx_equal_p (operands[0], operands[1]))
5904         abort ();
5905       if (operands[2] == const1_rtx)
5906         return "inc{l}\t%0";
5907       else if (operands[2] == constm1_rtx)
5908         return "dec{l}\t%0";
5909       else
5910         abort();
5911
5912     default:
5913       if (! rtx_equal_p (operands[0], operands[1]))
5914         abort ();
5915       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917       if (GET_CODE (operands[2]) == CONST_INT
5918           && (INTVAL (operands[2]) == 128
5919               || (INTVAL (operands[2]) < 0
5920                   && INTVAL (operands[2]) != -128)))
5921         {
5922           operands[2] = GEN_INT (-INTVAL (operands[2]));
5923           return "sub{l}\t{%2, %0|%0, %2}";
5924         }
5925       return "add{l}\t{%2, %0|%0, %2}";
5926     }
5927 }
5928   [(set (attr "type")
5929      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5930         (const_string "incdec")
5931         (const_string "alu")))
5932    (set_attr "mode" "SI")])
5933
5934 (define_expand "addhi3"
5935   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5936                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5937                             (match_operand:HI 2 "general_operand" "")))
5938               (clobber (reg:CC FLAGS_REG))])]
5939   "TARGET_HIMODE_MATH"
5940   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5941
5942 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5943 ;; type optimizations enabled by define-splits.  This is not important
5944 ;; for PII, and in fact harmful because of partial register stalls.
5945
5946 (define_insn "*addhi_1_lea"
5947   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5948         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5949                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5950    (clobber (reg:CC FLAGS_REG))]
5951   "!TARGET_PARTIAL_REG_STALL
5952    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5953 {
5954   switch (get_attr_type (insn))
5955     {
5956     case TYPE_LEA:
5957       return "#";
5958     case TYPE_INCDEC:
5959       if (operands[2] == const1_rtx)
5960         return "inc{w}\t%0";
5961       else if (operands[2] == constm1_rtx)
5962         return "dec{w}\t%0";
5963       abort();
5964
5965     default:
5966       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5968       if (GET_CODE (operands[2]) == CONST_INT
5969           && (INTVAL (operands[2]) == 128
5970               || (INTVAL (operands[2]) < 0
5971                   && INTVAL (operands[2]) != -128)))
5972         {
5973           operands[2] = GEN_INT (-INTVAL (operands[2]));
5974           return "sub{w}\t{%2, %0|%0, %2}";
5975         }
5976       return "add{w}\t{%2, %0|%0, %2}";
5977     }
5978 }
5979   [(set (attr "type")
5980      (if_then_else (eq_attr "alternative" "2")
5981         (const_string "lea")
5982         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983            (const_string "incdec")
5984            (const_string "alu"))))
5985    (set_attr "mode" "HI,HI,SI")])
5986
5987 (define_insn "*addhi_1"
5988   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5989         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5990                  (match_operand:HI 2 "general_operand" "ri,rm")))
5991    (clobber (reg:CC FLAGS_REG))]
5992   "TARGET_PARTIAL_REG_STALL
5993    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5994 {
5995   switch (get_attr_type (insn))
5996     {
5997     case TYPE_INCDEC:
5998       if (operands[2] == const1_rtx)
5999         return "inc{w}\t%0";
6000       else if (operands[2] == constm1_rtx)
6001         return "dec{w}\t%0";
6002       abort();
6003
6004     default:
6005       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6007       if (GET_CODE (operands[2]) == CONST_INT
6008           && (INTVAL (operands[2]) == 128
6009               || (INTVAL (operands[2]) < 0
6010                   && INTVAL (operands[2]) != -128)))
6011         {
6012           operands[2] = GEN_INT (-INTVAL (operands[2]));
6013           return "sub{w}\t{%2, %0|%0, %2}";
6014         }
6015       return "add{w}\t{%2, %0|%0, %2}";
6016     }
6017 }
6018   [(set (attr "type")
6019      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020         (const_string "incdec")
6021         (const_string "alu")))
6022    (set_attr "mode" "HI")])
6023
6024 (define_insn "*addhi_2"
6025   [(set (reg FLAGS_REG)
6026         (compare
6027           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6028                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6029           (const_int 0)))                       
6030    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6031         (plus:HI (match_dup 1) (match_dup 2)))]
6032   "ix86_match_ccmode (insn, CCGOCmode)
6033    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6034 {
6035   switch (get_attr_type (insn))
6036     {
6037     case TYPE_INCDEC:
6038       if (operands[2] == const1_rtx)
6039         return "inc{w}\t%0";
6040       else if (operands[2] == constm1_rtx)
6041         return "dec{w}\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           return "sub{w}\t{%2, %0|%0, %2}";
6054         }
6055       return "add{w}\t{%2, %0|%0, %2}";
6056     }
6057 }
6058   [(set (attr "type")
6059      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6060         (const_string "incdec")
6061         (const_string "alu")))
6062    (set_attr "mode" "HI")])
6063
6064 (define_insn "*addhi_3"
6065   [(set (reg FLAGS_REG)
6066         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6067                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6068    (clobber (match_scratch:HI 0 "=r"))]
6069   "ix86_match_ccmode (insn, CCZmode)
6070    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6071 {
6072   switch (get_attr_type (insn))
6073     {
6074     case TYPE_INCDEC:
6075       if (operands[2] == const1_rtx)
6076         return "inc{w}\t%0";
6077       else if (operands[2] == constm1_rtx)
6078         return "dec{w}\t%0";
6079       abort();
6080
6081     default:
6082       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6083          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6084       if (GET_CODE (operands[2]) == CONST_INT
6085           && (INTVAL (operands[2]) == 128
6086               || (INTVAL (operands[2]) < 0
6087                   && INTVAL (operands[2]) != -128)))
6088         {
6089           operands[2] = GEN_INT (-INTVAL (operands[2]));
6090           return "sub{w}\t{%2, %0|%0, %2}";
6091         }
6092       return "add{w}\t{%2, %0|%0, %2}";
6093     }
6094 }
6095   [(set (attr "type")
6096      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6097         (const_string "incdec")
6098         (const_string "alu")))
6099    (set_attr "mode" "HI")])
6100
6101 ; See comments above addsi_4 for details.
6102 (define_insn "*addhi_4"
6103   [(set (reg FLAGS_REG)
6104         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6105                  (match_operand:HI 2 "const_int_operand" "n")))
6106    (clobber (match_scratch:HI 0 "=rm"))]
6107   "ix86_match_ccmode (insn, CCGCmode)
6108    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6109 {
6110   switch (get_attr_type (insn))
6111     {
6112     case TYPE_INCDEC:
6113       if (operands[2] == constm1_rtx)
6114         return "inc{w}\t%0";
6115       else if (operands[2] == const1_rtx)
6116         return "dec{w}\t%0";
6117       else
6118         abort();
6119
6120     default:
6121       if (! rtx_equal_p (operands[0], operands[1]))
6122         abort ();
6123       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6124          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6125       if ((INTVAL (operands[2]) == -128
6126            || (INTVAL (operands[2]) > 0
6127                && INTVAL (operands[2]) != 128)))
6128         return "sub{w}\t{%2, %0|%0, %2}";
6129       operands[2] = GEN_INT (-INTVAL (operands[2]));
6130       return "add{w}\t{%2, %0|%0, %2}";
6131     }
6132 }
6133   [(set (attr "type")
6134      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135         (const_string "incdec")
6136         (const_string "alu")))
6137    (set_attr "mode" "SI")])
6138
6139
6140 (define_insn "*addhi_5"
6141   [(set (reg FLAGS_REG)
6142         (compare
6143           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6144                    (match_operand:HI 2 "general_operand" "rmni"))
6145           (const_int 0)))                       
6146    (clobber (match_scratch:HI 0 "=r"))]
6147   "ix86_match_ccmode (insn, CCGOCmode)
6148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6149 {
6150   switch (get_attr_type (insn))
6151     {
6152     case TYPE_INCDEC:
6153       if (operands[2] == const1_rtx)
6154         return "inc{w}\t%0";
6155       else if (operands[2] == constm1_rtx)
6156         return "dec{w}\t%0";
6157       abort();
6158
6159     default:
6160       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6161          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6162       if (GET_CODE (operands[2]) == CONST_INT
6163           && (INTVAL (operands[2]) == 128
6164               || (INTVAL (operands[2]) < 0
6165                   && INTVAL (operands[2]) != -128)))
6166         {
6167           operands[2] = GEN_INT (-INTVAL (operands[2]));
6168           return "sub{w}\t{%2, %0|%0, %2}";
6169         }
6170       return "add{w}\t{%2, %0|%0, %2}";
6171     }
6172 }
6173   [(set (attr "type")
6174      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6175         (const_string "incdec")
6176         (const_string "alu")))
6177    (set_attr "mode" "HI")])
6178
6179 (define_expand "addqi3"
6180   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6181                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6182                             (match_operand:QI 2 "general_operand" "")))
6183               (clobber (reg:CC FLAGS_REG))])]
6184   "TARGET_QIMODE_MATH"
6185   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6186
6187 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6188 (define_insn "*addqi_1_lea"
6189   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6190         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6191                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6192    (clobber (reg:CC FLAGS_REG))]
6193   "!TARGET_PARTIAL_REG_STALL
6194    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6195 {
6196   int widen = (which_alternative == 2);
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_LEA:
6200       return "#";
6201     case TYPE_INCDEC:
6202       if (operands[2] == const1_rtx)
6203         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6204       else if (operands[2] == constm1_rtx)
6205         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6206       abort();
6207
6208     default:
6209       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6210          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6211       if (GET_CODE (operands[2]) == CONST_INT
6212           && (INTVAL (operands[2]) == 128
6213               || (INTVAL (operands[2]) < 0
6214                   && INTVAL (operands[2]) != -128)))
6215         {
6216           operands[2] = GEN_INT (-INTVAL (operands[2]));
6217           if (widen)
6218             return "sub{l}\t{%2, %k0|%k0, %2}";
6219           else
6220             return "sub{b}\t{%2, %0|%0, %2}";
6221         }
6222       if (widen)
6223         return "add{l}\t{%k2, %k0|%k0, %k2}";
6224       else
6225         return "add{b}\t{%2, %0|%0, %2}";
6226     }
6227 }
6228   [(set (attr "type")
6229      (if_then_else (eq_attr "alternative" "3")
6230         (const_string "lea")
6231         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6232            (const_string "incdec")
6233            (const_string "alu"))))
6234    (set_attr "mode" "QI,QI,SI,SI")])
6235
6236 (define_insn "*addqi_1"
6237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6238         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6239                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6240    (clobber (reg:CC FLAGS_REG))]
6241   "TARGET_PARTIAL_REG_STALL
6242    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6243 {
6244   int widen = (which_alternative == 2);
6245   switch (get_attr_type (insn))
6246     {
6247     case TYPE_INCDEC:
6248       if (operands[2] == const1_rtx)
6249         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6250       else if (operands[2] == constm1_rtx)
6251         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6252       abort();
6253
6254     default:
6255       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6256          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6257       if (GET_CODE (operands[2]) == CONST_INT
6258           && (INTVAL (operands[2]) == 128
6259               || (INTVAL (operands[2]) < 0
6260                   && INTVAL (operands[2]) != -128)))
6261         {
6262           operands[2] = GEN_INT (-INTVAL (operands[2]));
6263           if (widen)
6264             return "sub{l}\t{%2, %k0|%k0, %2}";
6265           else
6266             return "sub{b}\t{%2, %0|%0, %2}";
6267         }
6268       if (widen)
6269         return "add{l}\t{%k2, %k0|%k0, %k2}";
6270       else
6271         return "add{b}\t{%2, %0|%0, %2}";
6272     }
6273 }
6274   [(set (attr "type")
6275      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6276         (const_string "incdec")
6277         (const_string "alu")))
6278    (set_attr "mode" "QI,QI,SI")])
6279
6280 (define_insn "*addqi_1_slp"
6281   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6282         (plus:QI (match_dup 0)
6283                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6284    (clobber (reg:CC FLAGS_REG))]
6285   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6286    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6287 {
6288   switch (get_attr_type (insn))
6289     {
6290     case TYPE_INCDEC:
6291       if (operands[1] == const1_rtx)
6292         return "inc{b}\t%0";
6293       else if (operands[1] == constm1_rtx)
6294         return "dec{b}\t%0";
6295       abort();
6296
6297     default:
6298       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6299       if (GET_CODE (operands[1]) == CONST_INT
6300           && INTVAL (operands[1]) < 0)
6301         {
6302           operands[1] = GEN_INT (-INTVAL (operands[1]));
6303           return "sub{b}\t{%1, %0|%0, %1}";
6304         }
6305       return "add{b}\t{%1, %0|%0, %1}";
6306     }
6307 }
6308   [(set (attr "type")
6309      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6310         (const_string "incdec")
6311         (const_string "alu1")))
6312    (set (attr "memory")
6313      (if_then_else (match_operand 1 "memory_operand" "")
6314         (const_string "load")
6315         (const_string "none")))
6316    (set_attr "mode" "QI")])
6317
6318 (define_insn "*addqi_2"
6319   [(set (reg FLAGS_REG)
6320         (compare
6321           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6322                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6323           (const_int 0)))
6324    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6325         (plus:QI (match_dup 1) (match_dup 2)))]
6326   "ix86_match_ccmode (insn, CCGOCmode)
6327    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6328 {
6329   switch (get_attr_type (insn))
6330     {
6331     case TYPE_INCDEC:
6332       if (operands[2] == const1_rtx)
6333         return "inc{b}\t%0";
6334       else if (operands[2] == constm1_rtx
6335                || (GET_CODE (operands[2]) == CONST_INT
6336                    && INTVAL (operands[2]) == 255))
6337         return "dec{b}\t%0";
6338       abort();
6339
6340     default:
6341       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6342       if (GET_CODE (operands[2]) == CONST_INT
6343           && INTVAL (operands[2]) < 0)
6344         {
6345           operands[2] = GEN_INT (-INTVAL (operands[2]));
6346           return "sub{b}\t{%2, %0|%0, %2}";
6347         }
6348       return "add{b}\t{%2, %0|%0, %2}";
6349     }
6350 }
6351   [(set (attr "type")
6352      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6353         (const_string "incdec")
6354         (const_string "alu")))
6355    (set_attr "mode" "QI")])
6356
6357 (define_insn "*addqi_3"
6358   [(set (reg FLAGS_REG)
6359         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6360                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6361    (clobber (match_scratch:QI 0 "=q"))]
6362   "ix86_match_ccmode (insn, CCZmode)
6363    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6364 {
6365   switch (get_attr_type (insn))
6366     {
6367     case TYPE_INCDEC:
6368       if (operands[2] == const1_rtx)
6369         return "inc{b}\t%0";
6370       else if (operands[2] == constm1_rtx
6371                || (GET_CODE (operands[2]) == CONST_INT
6372                    && INTVAL (operands[2]) == 255))
6373         return "dec{b}\t%0";
6374       abort();
6375
6376     default:
6377       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6378       if (GET_CODE (operands[2]) == CONST_INT
6379           && INTVAL (operands[2]) < 0)
6380         {
6381           operands[2] = GEN_INT (-INTVAL (operands[2]));
6382           return "sub{b}\t{%2, %0|%0, %2}";
6383         }
6384       return "add{b}\t{%2, %0|%0, %2}";
6385     }
6386 }
6387   [(set (attr "type")
6388      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389         (const_string "incdec")
6390         (const_string "alu")))
6391    (set_attr "mode" "QI")])
6392
6393 ; See comments above addsi_4 for details.
6394 (define_insn "*addqi_4"
6395   [(set (reg FLAGS_REG)
6396         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6397                  (match_operand:QI 2 "const_int_operand" "n")))
6398    (clobber (match_scratch:QI 0 "=qm"))]
6399   "ix86_match_ccmode (insn, CCGCmode)
6400    && (INTVAL (operands[2]) & 0xff) != 0x80"
6401 {
6402   switch (get_attr_type (insn))
6403     {
6404     case TYPE_INCDEC:
6405       if (operands[2] == constm1_rtx
6406           || (GET_CODE (operands[2]) == CONST_INT
6407               && INTVAL (operands[2]) == 255))
6408         return "inc{b}\t%0";
6409       else if (operands[2] == const1_rtx)
6410         return "dec{b}\t%0";
6411       else
6412         abort();
6413
6414     default:
6415       if (! rtx_equal_p (operands[0], operands[1]))
6416         abort ();
6417       if (INTVAL (operands[2]) < 0)
6418         {
6419           operands[2] = GEN_INT (-INTVAL (operands[2]));
6420           return "add{b}\t{%2, %0|%0, %2}";
6421         }
6422       return "sub{b}\t{%2, %0|%0, %2}";
6423     }
6424 }
6425   [(set (attr "type")
6426      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6427         (const_string "incdec")
6428         (const_string "alu")))
6429    (set_attr "mode" "QI")])
6430
6431
6432 (define_insn "*addqi_5"
6433   [(set (reg FLAGS_REG)
6434         (compare
6435           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6436                    (match_operand:QI 2 "general_operand" "qmni"))
6437           (const_int 0)))
6438    (clobber (match_scratch:QI 0 "=q"))]
6439   "ix86_match_ccmode (insn, CCGOCmode)
6440    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6441 {
6442   switch (get_attr_type (insn))
6443     {
6444     case TYPE_INCDEC:
6445       if (operands[2] == const1_rtx)
6446         return "inc{b}\t%0";
6447       else if (operands[2] == constm1_rtx
6448                || (GET_CODE (operands[2]) == CONST_INT
6449                    && INTVAL (operands[2]) == 255))
6450         return "dec{b}\t%0";
6451       abort();
6452
6453     default:
6454       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6455       if (GET_CODE (operands[2]) == CONST_INT
6456           && INTVAL (operands[2]) < 0)
6457         {
6458           operands[2] = GEN_INT (-INTVAL (operands[2]));
6459           return "sub{b}\t{%2, %0|%0, %2}";
6460         }
6461       return "add{b}\t{%2, %0|%0, %2}";
6462     }
6463 }
6464   [(set (attr "type")
6465      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6466         (const_string "incdec")
6467         (const_string "alu")))
6468    (set_attr "mode" "QI")])
6469
6470
6471 (define_insn "addqi_ext_1"
6472   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6473                          (const_int 8)
6474                          (const_int 8))
6475         (plus:SI
6476           (zero_extract:SI
6477             (match_operand 1 "ext_register_operand" "0")
6478             (const_int 8)
6479             (const_int 8))
6480           (match_operand:QI 2 "general_operand" "Qmn")))
6481    (clobber (reg:CC FLAGS_REG))]
6482   "!TARGET_64BIT"
6483 {
6484   switch (get_attr_type (insn))
6485     {
6486     case TYPE_INCDEC:
6487       if (operands[2] == const1_rtx)
6488         return "inc{b}\t%h0";
6489       else if (operands[2] == constm1_rtx
6490                || (GET_CODE (operands[2]) == CONST_INT
6491                    && INTVAL (operands[2]) == 255))
6492         return "dec{b}\t%h0";
6493       abort();
6494
6495     default:
6496       return "add{b}\t{%2, %h0|%h0, %2}";
6497     }
6498 }
6499   [(set (attr "type")
6500      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6501         (const_string "incdec")
6502         (const_string "alu")))
6503    (set_attr "mode" "QI")])
6504
6505 (define_insn "*addqi_ext_1_rex64"
6506   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6507                          (const_int 8)
6508                          (const_int 8))
6509         (plus:SI
6510           (zero_extract:SI
6511             (match_operand 1 "ext_register_operand" "0")
6512             (const_int 8)
6513             (const_int 8))
6514           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6515    (clobber (reg:CC FLAGS_REG))]
6516   "TARGET_64BIT"
6517 {
6518   switch (get_attr_type (insn))
6519     {
6520     case TYPE_INCDEC:
6521       if (operands[2] == const1_rtx)
6522         return "inc{b}\t%h0";
6523       else if (operands[2] == constm1_rtx
6524                || (GET_CODE (operands[2]) == CONST_INT
6525                    && INTVAL (operands[2]) == 255))
6526         return "dec{b}\t%h0";
6527       abort();
6528
6529     default:
6530       return "add{b}\t{%2, %h0|%h0, %2}";
6531     }
6532 }
6533   [(set (attr "type")
6534      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6535         (const_string "incdec")
6536         (const_string "alu")))
6537    (set_attr "mode" "QI")])
6538
6539 (define_insn "*addqi_ext_2"
6540   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6541                          (const_int 8)
6542                          (const_int 8))
6543         (plus:SI
6544           (zero_extract:SI
6545             (match_operand 1 "ext_register_operand" "%0")
6546             (const_int 8)
6547             (const_int 8))
6548           (zero_extract:SI
6549             (match_operand 2 "ext_register_operand" "Q")
6550             (const_int 8)
6551             (const_int 8))))
6552    (clobber (reg:CC FLAGS_REG))]
6553   ""
6554   "add{b}\t{%h2, %h0|%h0, %h2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "QI")])
6557
6558 ;; The patterns that match these are at the end of this file.
6559
6560 (define_expand "addxf3"
6561   [(set (match_operand:XF 0 "register_operand" "")
6562         (plus:XF (match_operand:XF 1 "register_operand" "")
6563                  (match_operand:XF 2 "register_operand" "")))]
6564   "TARGET_80387"
6565   "")
6566
6567 (define_expand "adddf3"
6568   [(set (match_operand:DF 0 "register_operand" "")
6569         (plus:DF (match_operand:DF 1 "register_operand" "")
6570                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6571   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6572   "")
6573
6574 (define_expand "addsf3"
6575   [(set (match_operand:SF 0 "register_operand" "")
6576         (plus:SF (match_operand:SF 1 "register_operand" "")
6577                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6578   "TARGET_80387 || TARGET_SSE_MATH"
6579   "")
6580 \f
6581 ;; Subtract instructions
6582
6583 ;; %%% splits for subsidi3
6584
6585 (define_expand "subdi3"
6586   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6587                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6588                              (match_operand:DI 2 "x86_64_general_operand" "")))
6589               (clobber (reg:CC FLAGS_REG))])]
6590   ""
6591   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6592
6593 (define_insn "*subdi3_1"
6594   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6595         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6596                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6597    (clobber (reg:CC FLAGS_REG))]
6598   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6599   "#")
6600
6601 (define_split
6602   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6603         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6604                   (match_operand:DI 2 "general_operand" "")))
6605    (clobber (reg:CC FLAGS_REG))]
6606   "!TARGET_64BIT && reload_completed"
6607   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6608               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6609    (parallel [(set (match_dup 3)
6610                    (minus:SI (match_dup 4)
6611                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6612                                       (match_dup 5))))
6613               (clobber (reg:CC FLAGS_REG))])]
6614   "split_di (operands+0, 1, operands+0, operands+3);
6615    split_di (operands+1, 1, operands+1, operands+4);
6616    split_di (operands+2, 1, operands+2, operands+5);")
6617
6618 (define_insn "subdi3_carry_rex64"
6619   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6620           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6621             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6622                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6623    (clobber (reg:CC FLAGS_REG))]
6624   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6625   "sbb{q}\t{%2, %0|%0, %2}"
6626   [(set_attr "type" "alu")
6627    (set_attr "pent_pair" "pu")
6628    (set_attr "mode" "DI")])
6629
6630 (define_insn "*subdi_1_rex64"
6631   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6632         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6633                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6634    (clobber (reg:CC FLAGS_REG))]
6635   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6636   "sub{q}\t{%2, %0|%0, %2}"
6637   [(set_attr "type" "alu")
6638    (set_attr "mode" "DI")])
6639
6640 (define_insn "*subdi_2_rex64"
6641   [(set (reg FLAGS_REG)
6642         (compare
6643           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6644                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6645           (const_int 0)))
6646    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:DI (match_dup 1) (match_dup 2)))]
6648   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6649    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6650   "sub{q}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "DI")])
6653
6654 (define_insn "*subdi_3_rex63"
6655   [(set (reg FLAGS_REG)
6656         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6657                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6658    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6659         (minus:DI (match_dup 1) (match_dup 2)))]
6660   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6661    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sub{q}\t{%2, %0|%0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "mode" "DI")])
6665
6666 (define_insn "subqi3_carry"
6667   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6668           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6669             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6670                (match_operand:QI 2 "general_operand" "qi,qm"))))
6671    (clobber (reg:CC FLAGS_REG))]
6672   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6673   "sbb{b}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "pent_pair" "pu")
6676    (set_attr "mode" "QI")])
6677
6678 (define_insn "subhi3_carry"
6679   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6680           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6681             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6682                (match_operand:HI 2 "general_operand" "ri,rm"))))
6683    (clobber (reg:CC FLAGS_REG))]
6684   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6685   "sbb{w}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "pent_pair" "pu")
6688    (set_attr "mode" "HI")])
6689
6690 (define_insn "subsi3_carry"
6691   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6692           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6693             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6694                (match_operand:SI 2 "general_operand" "ri,rm"))))
6695    (clobber (reg:CC FLAGS_REG))]
6696   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6697   "sbb{l}\t{%2, %0|%0, %2}"
6698   [(set_attr "type" "alu")
6699    (set_attr "pent_pair" "pu")
6700    (set_attr "mode" "SI")])
6701
6702 (define_insn "subsi3_carry_zext"
6703   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6704           (zero_extend:DI
6705             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6706               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6707                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6708    (clobber (reg:CC FLAGS_REG))]
6709   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710   "sbb{l}\t{%2, %k0|%k0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "pent_pair" "pu")
6713    (set_attr "mode" "SI")])
6714
6715 (define_expand "subsi3"
6716   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6717                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6718                              (match_operand:SI 2 "general_operand" "")))
6719               (clobber (reg:CC FLAGS_REG))])]
6720   ""
6721   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6722
6723 (define_insn "*subsi_1"
6724   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6725         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6726                   (match_operand:SI 2 "general_operand" "ri,rm")))
6727    (clobber (reg:CC FLAGS_REG))]
6728   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6729   "sub{l}\t{%2, %0|%0, %2}"
6730   [(set_attr "type" "alu")
6731    (set_attr "mode" "SI")])
6732
6733 (define_insn "*subsi_1_zext"
6734   [(set (match_operand:DI 0 "register_operand" "=r")
6735         (zero_extend:DI
6736           (minus:SI (match_operand:SI 1 "register_operand" "0")
6737                     (match_operand:SI 2 "general_operand" "rim"))))
6738    (clobber (reg:CC FLAGS_REG))]
6739   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6740   "sub{l}\t{%2, %k0|%k0, %2}"
6741   [(set_attr "type" "alu")
6742    (set_attr "mode" "SI")])
6743
6744 (define_insn "*subsi_2"
6745   [(set (reg FLAGS_REG)
6746         (compare
6747           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6748                     (match_operand:SI 2 "general_operand" "ri,rm"))
6749           (const_int 0)))
6750    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6751         (minus:SI (match_dup 1) (match_dup 2)))]
6752   "ix86_match_ccmode (insn, CCGOCmode)
6753    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6754   "sub{l}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "SI")])
6757
6758 (define_insn "*subsi_2_zext"
6759   [(set (reg FLAGS_REG)
6760         (compare
6761           (minus:SI (match_operand:SI 1 "register_operand" "0")
6762                     (match_operand:SI 2 "general_operand" "rim"))
6763           (const_int 0)))
6764    (set (match_operand:DI 0 "register_operand" "=r")
6765         (zero_extend:DI
6766           (minus:SI (match_dup 1)
6767                     (match_dup 2))))]
6768   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6769    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6770   "sub{l}\t{%2, %k0|%k0, %2}"
6771   [(set_attr "type" "alu")
6772    (set_attr "mode" "SI")])
6773
6774 (define_insn "*subsi_3"
6775   [(set (reg FLAGS_REG)
6776         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6777                  (match_operand:SI 2 "general_operand" "ri,rm")))
6778    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6779         (minus:SI (match_dup 1) (match_dup 2)))]
6780   "ix86_match_ccmode (insn, CCmode)
6781    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6782   "sub{l}\t{%2, %0|%0, %2}"
6783   [(set_attr "type" "alu")
6784    (set_attr "mode" "SI")])
6785
6786 (define_insn "*subsi_3_zext"
6787   [(set (reg FLAGS_REG)
6788         (compare (match_operand:SI 1 "register_operand" "0")
6789                  (match_operand:SI 2 "general_operand" "rim")))
6790    (set (match_operand:DI 0 "register_operand" "=r")
6791         (zero_extend:DI
6792           (minus:SI (match_dup 1)
6793                     (match_dup 2))))]
6794   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6795    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6796   "sub{q}\t{%2, %0|%0, %2}"
6797   [(set_attr "type" "alu")
6798    (set_attr "mode" "DI")])
6799
6800 (define_expand "subhi3"
6801   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6802                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6803                              (match_operand:HI 2 "general_operand" "")))
6804               (clobber (reg:CC FLAGS_REG))])]
6805   "TARGET_HIMODE_MATH"
6806   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6807
6808 (define_insn "*subhi_1"
6809   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6810         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6811                   (match_operand:HI 2 "general_operand" "ri,rm")))
6812    (clobber (reg:CC FLAGS_REG))]
6813   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6814   "sub{w}\t{%2, %0|%0, %2}"
6815   [(set_attr "type" "alu")
6816    (set_attr "mode" "HI")])
6817
6818 (define_insn "*subhi_2"
6819   [(set (reg FLAGS_REG)
6820         (compare
6821           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6822                     (match_operand:HI 2 "general_operand" "ri,rm"))
6823           (const_int 0)))
6824    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825         (minus:HI (match_dup 1) (match_dup 2)))]
6826   "ix86_match_ccmode (insn, CCGOCmode)
6827    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6828   "sub{w}\t{%2, %0|%0, %2}"
6829   [(set_attr "type" "alu")
6830    (set_attr "mode" "HI")])
6831
6832 (define_insn "*subhi_3"
6833   [(set (reg FLAGS_REG)
6834         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6835                  (match_operand:HI 2 "general_operand" "ri,rm")))
6836    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6837         (minus:HI (match_dup 1) (match_dup 2)))]
6838   "ix86_match_ccmode (insn, CCmode)
6839    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6840   "sub{w}\t{%2, %0|%0, %2}"
6841   [(set_attr "type" "alu")
6842    (set_attr "mode" "HI")])
6843
6844 (define_expand "subqi3"
6845   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6846                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6847                              (match_operand:QI 2 "general_operand" "")))
6848               (clobber (reg:CC FLAGS_REG))])]
6849   "TARGET_QIMODE_MATH"
6850   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6851
6852 (define_insn "*subqi_1"
6853   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6854         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6856    (clobber (reg:CC FLAGS_REG))]
6857   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6858   "sub{b}\t{%2, %0|%0, %2}"
6859   [(set_attr "type" "alu")
6860    (set_attr "mode" "QI")])
6861
6862 (define_insn "*subqi_1_slp"
6863   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6864         (minus:QI (match_dup 0)
6865                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6866    (clobber (reg:CC FLAGS_REG))]
6867   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6868    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6869   "sub{b}\t{%1, %0|%0, %1}"
6870   [(set_attr "type" "alu1")
6871    (set_attr "mode" "QI")])
6872
6873 (define_insn "*subqi_2"
6874   [(set (reg FLAGS_REG)
6875         (compare
6876           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6877                     (match_operand:QI 2 "general_operand" "qi,qm"))
6878           (const_int 0)))
6879    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6880         (minus:HI (match_dup 1) (match_dup 2)))]
6881   "ix86_match_ccmode (insn, CCGOCmode)
6882    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6883   "sub{b}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "QI")])
6886
6887 (define_insn "*subqi_3"
6888   [(set (reg FLAGS_REG)
6889         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6890                  (match_operand:QI 2 "general_operand" "qi,qm")))
6891    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6892         (minus:HI (match_dup 1) (match_dup 2)))]
6893   "ix86_match_ccmode (insn, CCmode)
6894    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6895   "sub{b}\t{%2, %0|%0, %2}"
6896   [(set_attr "type" "alu")
6897    (set_attr "mode" "QI")])
6898
6899 ;; The patterns that match these are at the end of this file.
6900
6901 (define_expand "subxf3"
6902   [(set (match_operand:XF 0 "register_operand" "")
6903         (minus:XF (match_operand:XF 1 "register_operand" "")
6904                   (match_operand:XF 2 "register_operand" "")))]
6905   "TARGET_80387"
6906   "")
6907
6908 (define_expand "subdf3"
6909   [(set (match_operand:DF 0 "register_operand" "")
6910         (minus:DF (match_operand:DF 1 "register_operand" "")
6911                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6912   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6913   "")
6914
6915 (define_expand "subsf3"
6916   [(set (match_operand:SF 0 "register_operand" "")
6917         (minus:SF (match_operand:SF 1 "register_operand" "")
6918                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6919   "TARGET_80387 || TARGET_SSE_MATH"
6920   "")
6921 \f
6922 ;; Multiply instructions
6923
6924 (define_expand "muldi3"
6925   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6926                    (mult:DI (match_operand:DI 1 "register_operand" "")
6927                             (match_operand:DI 2 "x86_64_general_operand" "")))
6928               (clobber (reg:CC FLAGS_REG))])]
6929   "TARGET_64BIT"
6930   "")
6931
6932 (define_insn "*muldi3_1_rex64"
6933   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6934         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6935                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6936    (clobber (reg:CC FLAGS_REG))]
6937   "TARGET_64BIT
6938    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6939   "@
6940    imul{q}\t{%2, %1, %0|%0, %1, %2}
6941    imul{q}\t{%2, %1, %0|%0, %1, %2}
6942    imul{q}\t{%2, %0|%0, %2}"
6943   [(set_attr "type" "imul")
6944    (set_attr "prefix_0f" "0,0,1")
6945    (set (attr "athlon_decode")
6946         (cond [(eq_attr "cpu" "athlon")
6947                   (const_string "vector")
6948                (eq_attr "alternative" "1")
6949                   (const_string "vector")
6950                (and (eq_attr "alternative" "2")
6951                     (match_operand 1 "memory_operand" ""))
6952                   (const_string "vector")]
6953               (const_string "direct")))
6954    (set_attr "mode" "DI")])
6955
6956 (define_expand "mulsi3"
6957   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6958                    (mult:SI (match_operand:SI 1 "register_operand" "")
6959                             (match_operand:SI 2 "general_operand" "")))
6960               (clobber (reg:CC FLAGS_REG))])]
6961   ""
6962   "")
6963
6964 (define_insn "*mulsi3_1"
6965   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6966         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6967                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6970   "@
6971    imul{l}\t{%2, %1, %0|%0, %1, %2}
6972    imul{l}\t{%2, %1, %0|%0, %1, %2}
6973    imul{l}\t{%2, %0|%0, %2}"
6974   [(set_attr "type" "imul")
6975    (set_attr "prefix_0f" "0,0,1")
6976    (set (attr "athlon_decode")
6977         (cond [(eq_attr "cpu" "athlon")
6978                   (const_string "vector")
6979                (eq_attr "alternative" "1")
6980                   (const_string "vector")
6981                (and (eq_attr "alternative" "2")
6982                     (match_operand 1 "memory_operand" ""))
6983                   (const_string "vector")]
6984               (const_string "direct")))
6985    (set_attr "mode" "SI")])
6986
6987 (define_insn "*mulsi3_1_zext"
6988   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6989         (zero_extend:DI
6990           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6991                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6992    (clobber (reg:CC FLAGS_REG))]
6993   "TARGET_64BIT
6994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6995   "@
6996    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6997    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6998    imul{l}\t{%2, %k0|%k0, %2}"
6999   [(set_attr "type" "imul")
7000    (set_attr "prefix_0f" "0,0,1")
7001    (set (attr "athlon_decode")
7002         (cond [(eq_attr "cpu" "athlon")
7003                   (const_string "vector")
7004                (eq_attr "alternative" "1")
7005                   (const_string "vector")
7006                (and (eq_attr "alternative" "2")
7007                     (match_operand 1 "memory_operand" ""))
7008                   (const_string "vector")]
7009               (const_string "direct")))
7010    (set_attr "mode" "SI")])
7011
7012 (define_expand "mulhi3"
7013   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7014                    (mult:HI (match_operand:HI 1 "register_operand" "")
7015                             (match_operand:HI 2 "general_operand" "")))
7016               (clobber (reg:CC FLAGS_REG))])]
7017   "TARGET_HIMODE_MATH"
7018   "")
7019
7020 (define_insn "*mulhi3_1"
7021   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7022         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7023                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7024    (clobber (reg:CC FLAGS_REG))]
7025   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7026   "@
7027    imul{w}\t{%2, %1, %0|%0, %1, %2}
7028    imul{w}\t{%2, %1, %0|%0, %1, %2}
7029    imul{w}\t{%2, %0|%0, %2}"
7030   [(set_attr "type" "imul")
7031    (set_attr "prefix_0f" "0,0,1")
7032    (set (attr "athlon_decode")
7033         (cond [(eq_attr "cpu" "athlon")
7034                   (const_string "vector")
7035                (eq_attr "alternative" "1,2")
7036                   (const_string "vector")]
7037               (const_string "direct")))
7038    (set_attr "mode" "HI")])
7039
7040 (define_expand "mulqi3"
7041   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7042                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7043                             (match_operand:QI 2 "register_operand" "")))
7044               (clobber (reg:CC FLAGS_REG))])]
7045   "TARGET_QIMODE_MATH"
7046   "")
7047
7048 (define_insn "*mulqi3_1"
7049   [(set (match_operand:QI 0 "register_operand" "=a")
7050         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7051                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7052    (clobber (reg:CC FLAGS_REG))]
7053   "TARGET_QIMODE_MATH
7054    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7055   "mul{b}\t%2"
7056   [(set_attr "type" "imul")
7057    (set_attr "length_immediate" "0")
7058    (set (attr "athlon_decode")
7059      (if_then_else (eq_attr "cpu" "athlon")
7060         (const_string "vector")
7061         (const_string "direct")))
7062    (set_attr "mode" "QI")])
7063
7064 (define_expand "umulqihi3"
7065   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7066                    (mult:HI (zero_extend:HI
7067                               (match_operand:QI 1 "nonimmediate_operand" ""))
7068                             (zero_extend:HI
7069                               (match_operand:QI 2 "register_operand" ""))))
7070               (clobber (reg:CC FLAGS_REG))])]
7071   "TARGET_QIMODE_MATH"
7072   "")
7073
7074 (define_insn "*umulqihi3_1"
7075   [(set (match_operand:HI 0 "register_operand" "=a")
7076         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7077                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7078    (clobber (reg:CC FLAGS_REG))]
7079   "TARGET_QIMODE_MATH
7080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7081   "mul{b}\t%2"
7082   [(set_attr "type" "imul")
7083    (set_attr "length_immediate" "0")
7084    (set (attr "athlon_decode")
7085      (if_then_else (eq_attr "cpu" "athlon")
7086         (const_string "vector")
7087         (const_string "direct")))
7088    (set_attr "mode" "QI")])
7089
7090 (define_expand "mulqihi3"
7091   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7092                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7093                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7094               (clobber (reg:CC FLAGS_REG))])]
7095   "TARGET_QIMODE_MATH"
7096   "")
7097
7098 (define_insn "*mulqihi3_insn"
7099   [(set (match_operand:HI 0 "register_operand" "=a")
7100         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7101                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7102    (clobber (reg:CC FLAGS_REG))]
7103   "TARGET_QIMODE_MATH
7104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7105   "imul{b}\t%2"
7106   [(set_attr "type" "imul")
7107    (set_attr "length_immediate" "0")
7108    (set (attr "athlon_decode")
7109      (if_then_else (eq_attr "cpu" "athlon")
7110         (const_string "vector")
7111         (const_string "direct")))
7112    (set_attr "mode" "QI")])
7113
7114 (define_expand "umulditi3"
7115   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7116                    (mult:TI (zero_extend:TI
7117                               (match_operand:DI 1 "nonimmediate_operand" ""))
7118                             (zero_extend:TI
7119                               (match_operand:DI 2 "register_operand" ""))))
7120               (clobber (reg:CC FLAGS_REG))])]
7121   "TARGET_64BIT"
7122   "")
7123
7124 (define_insn "*umulditi3_insn"
7125   [(set (match_operand:TI 0 "register_operand" "=A")
7126         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7127                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7128    (clobber (reg:CC FLAGS_REG))]
7129   "TARGET_64BIT
7130    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7131   "mul{q}\t%2"
7132   [(set_attr "type" "imul")
7133    (set_attr "length_immediate" "0")
7134    (set (attr "athlon_decode")
7135      (if_then_else (eq_attr "cpu" "athlon")
7136         (const_string "vector")
7137         (const_string "double")))
7138    (set_attr "mode" "DI")])
7139
7140 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7141 (define_expand "umulsidi3"
7142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7143                    (mult:DI (zero_extend:DI
7144                               (match_operand:SI 1 "nonimmediate_operand" ""))
7145                             (zero_extend:DI
7146                               (match_operand:SI 2 "register_operand" ""))))
7147               (clobber (reg:CC FLAGS_REG))])]
7148   "!TARGET_64BIT"
7149   "")
7150
7151 (define_insn "*umulsidi3_insn"
7152   [(set (match_operand:DI 0 "register_operand" "=A")
7153         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7154                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7155    (clobber (reg:CC FLAGS_REG))]
7156   "!TARGET_64BIT
7157    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7158   "mul{l}\t%2"
7159   [(set_attr "type" "imul")
7160    (set_attr "length_immediate" "0")
7161    (set (attr "athlon_decode")
7162      (if_then_else (eq_attr "cpu" "athlon")
7163         (const_string "vector")
7164         (const_string "double")))
7165    (set_attr "mode" "SI")])
7166
7167 (define_expand "mulditi3"
7168   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7169                    (mult:TI (sign_extend:TI
7170                               (match_operand:DI 1 "nonimmediate_operand" ""))
7171                             (sign_extend:TI
7172                               (match_operand:DI 2 "register_operand" ""))))
7173               (clobber (reg:CC FLAGS_REG))])]
7174   "TARGET_64BIT"
7175   "")
7176
7177 (define_insn "*mulditi3_insn"
7178   [(set (match_operand:TI 0 "register_operand" "=A")
7179         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7180                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7181    (clobber (reg:CC FLAGS_REG))]
7182   "TARGET_64BIT
7183    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7184   "imul{q}\t%2"
7185   [(set_attr "type" "imul")
7186    (set_attr "length_immediate" "0")
7187    (set (attr "athlon_decode")
7188      (if_then_else (eq_attr "cpu" "athlon")
7189         (const_string "vector")
7190         (const_string "double")))
7191    (set_attr "mode" "DI")])
7192
7193 (define_expand "mulsidi3"
7194   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7195                    (mult:DI (sign_extend:DI
7196                               (match_operand:SI 1 "nonimmediate_operand" ""))
7197                             (sign_extend:DI
7198                               (match_operand:SI 2 "register_operand" ""))))
7199               (clobber (reg:CC FLAGS_REG))])]
7200   "!TARGET_64BIT"
7201   "")
7202
7203 (define_insn "*mulsidi3_insn"
7204   [(set (match_operand:DI 0 "register_operand" "=A")
7205         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7206                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "!TARGET_64BIT
7209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7210   "imul{l}\t%2"
7211   [(set_attr "type" "imul")
7212    (set_attr "length_immediate" "0")
7213    (set (attr "athlon_decode")
7214      (if_then_else (eq_attr "cpu" "athlon")
7215         (const_string "vector")
7216         (const_string "double")))
7217    (set_attr "mode" "SI")])
7218
7219 (define_expand "umuldi3_highpart"
7220   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7221                    (truncate:DI
7222                      (lshiftrt:TI
7223                        (mult:TI (zero_extend:TI
7224                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7225                                 (zero_extend:TI
7226                                   (match_operand:DI 2 "register_operand" "")))
7227                        (const_int 64))))
7228               (clobber (match_scratch:DI 3 ""))
7229               (clobber (reg:CC FLAGS_REG))])]
7230   "TARGET_64BIT"
7231   "")
7232
7233 (define_insn "*umuldi3_highpart_rex64"
7234   [(set (match_operand:DI 0 "register_operand" "=d")
7235         (truncate:DI
7236           (lshiftrt:TI
7237             (mult:TI (zero_extend:TI
7238                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7239                      (zero_extend:TI
7240                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7241             (const_int 64))))
7242    (clobber (match_scratch:DI 3 "=1"))
7243    (clobber (reg:CC FLAGS_REG))]
7244   "TARGET_64BIT
7245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7246   "mul{q}\t%2"
7247   [(set_attr "type" "imul")
7248    (set_attr "length_immediate" "0")
7249    (set (attr "athlon_decode")
7250      (if_then_else (eq_attr "cpu" "athlon")
7251         (const_string "vector")
7252         (const_string "double")))
7253    (set_attr "mode" "DI")])
7254
7255 (define_expand "umulsi3_highpart"
7256   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7257                    (truncate:SI
7258                      (lshiftrt:DI
7259                        (mult:DI (zero_extend:DI
7260                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7261                                 (zero_extend:DI
7262                                   (match_operand:SI 2 "register_operand" "")))
7263                        (const_int 32))))
7264               (clobber (match_scratch:SI 3 ""))
7265               (clobber (reg:CC FLAGS_REG))])]
7266   ""
7267   "")
7268
7269 (define_insn "*umulsi3_highpart_insn"
7270   [(set (match_operand:SI 0 "register_operand" "=d")
7271         (truncate:SI
7272           (lshiftrt:DI
7273             (mult:DI (zero_extend:DI
7274                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7275                      (zero_extend:DI
7276                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7277             (const_int 32))))
7278    (clobber (match_scratch:SI 3 "=1"))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7281   "mul{l}\t%2"
7282   [(set_attr "type" "imul")
7283    (set_attr "length_immediate" "0")
7284    (set (attr "athlon_decode")
7285      (if_then_else (eq_attr "cpu" "athlon")
7286         (const_string "vector")
7287         (const_string "double")))
7288    (set_attr "mode" "SI")])
7289
7290 (define_insn "*umulsi3_highpart_zext"
7291   [(set (match_operand:DI 0 "register_operand" "=d")
7292         (zero_extend:DI (truncate:SI
7293           (lshiftrt:DI
7294             (mult:DI (zero_extend:DI
7295                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7296                      (zero_extend:DI
7297                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7298             (const_int 32)))))
7299    (clobber (match_scratch:SI 3 "=1"))
7300    (clobber (reg:CC FLAGS_REG))]
7301   "TARGET_64BIT
7302    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7303   "mul{l}\t%2"
7304   [(set_attr "type" "imul")
7305    (set_attr "length_immediate" "0")
7306    (set (attr "athlon_decode")
7307      (if_then_else (eq_attr "cpu" "athlon")
7308         (const_string "vector")
7309         (const_string "double")))
7310    (set_attr "mode" "SI")])
7311
7312 (define_expand "smuldi3_highpart"
7313   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7314                    (truncate:DI
7315                      (lshiftrt:TI
7316                        (mult:TI (sign_extend:TI
7317                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7318                                 (sign_extend:TI
7319                                   (match_operand:DI 2 "register_operand" "")))
7320                        (const_int 64))))
7321               (clobber (match_scratch:DI 3 ""))
7322               (clobber (reg:CC FLAGS_REG))])]
7323   "TARGET_64BIT"
7324   "")
7325
7326 (define_insn "*smuldi3_highpart_rex64"
7327   [(set (match_operand:DI 0 "register_operand" "=d")
7328         (truncate:DI
7329           (lshiftrt:TI
7330             (mult:TI (sign_extend:TI
7331                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7332                      (sign_extend:TI
7333                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7334             (const_int 64))))
7335    (clobber (match_scratch:DI 3 "=1"))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_64BIT
7338    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7339   "imul{q}\t%2"
7340   [(set_attr "type" "imul")
7341    (set (attr "athlon_decode")
7342      (if_then_else (eq_attr "cpu" "athlon")
7343         (const_string "vector")
7344         (const_string "double")))
7345    (set_attr "mode" "DI")])
7346
7347 (define_expand "smulsi3_highpart"
7348   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7349                    (truncate:SI
7350                      (lshiftrt:DI
7351                        (mult:DI (sign_extend:DI
7352                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7353                                 (sign_extend:DI
7354                                   (match_operand:SI 2 "register_operand" "")))
7355                        (const_int 32))))
7356               (clobber (match_scratch:SI 3 ""))
7357               (clobber (reg:CC FLAGS_REG))])]
7358   ""
7359   "")
7360
7361 (define_insn "*smulsi3_highpart_insn"
7362   [(set (match_operand:SI 0 "register_operand" "=d")
7363         (truncate:SI
7364           (lshiftrt:DI
7365             (mult:DI (sign_extend:DI
7366                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367                      (sign_extend:DI
7368                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369             (const_int 32))))
7370    (clobber (match_scratch:SI 3 "=1"))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7373   "imul{l}\t%2"
7374   [(set_attr "type" "imul")
7375    (set (attr "athlon_decode")
7376      (if_then_else (eq_attr "cpu" "athlon")
7377         (const_string "vector")
7378         (const_string "double")))
7379    (set_attr "mode" "SI")])
7380
7381 (define_insn "*smulsi3_highpart_zext"
7382   [(set (match_operand:DI 0 "register_operand" "=d")
7383         (zero_extend:DI (truncate:SI
7384           (lshiftrt:DI
7385             (mult:DI (sign_extend:DI
7386                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7387                      (sign_extend:DI
7388                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7389             (const_int 32)))))
7390    (clobber (match_scratch:SI 3 "=1"))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "TARGET_64BIT
7393    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7394   "imul{l}\t%2"
7395   [(set_attr "type" "imul")
7396    (set (attr "athlon_decode")
7397      (if_then_else (eq_attr "cpu" "athlon")
7398         (const_string "vector")
7399         (const_string "double")))
7400    (set_attr "mode" "SI")])
7401
7402 ;; The patterns that match these are at the end of this file.
7403
7404 (define_expand "mulxf3"
7405   [(set (match_operand:XF 0 "register_operand" "")
7406         (mult:XF (match_operand:XF 1 "register_operand" "")
7407                  (match_operand:XF 2 "register_operand" "")))]
7408   "TARGET_80387"
7409   "")
7410
7411 (define_expand "muldf3"
7412   [(set (match_operand:DF 0 "register_operand" "")
7413         (mult:DF (match_operand:DF 1 "register_operand" "")
7414                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7415   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7416   "")
7417
7418 (define_expand "mulsf3"
7419   [(set (match_operand:SF 0 "register_operand" "")
7420         (mult:SF (match_operand:SF 1 "register_operand" "")
7421                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7422   "TARGET_80387 || TARGET_SSE_MATH"
7423   "")
7424 \f
7425 ;; Divide instructions
7426
7427 (define_insn "divqi3"
7428   [(set (match_operand:QI 0 "register_operand" "=a")
7429         (div:QI (match_operand:HI 1 "register_operand" "0")
7430                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7431    (clobber (reg:CC FLAGS_REG))]
7432   "TARGET_QIMODE_MATH"
7433   "idiv{b}\t%2"
7434   [(set_attr "type" "idiv")
7435    (set_attr "mode" "QI")])
7436
7437 (define_insn "udivqi3"
7438   [(set (match_operand:QI 0 "register_operand" "=a")
7439         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7440                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "TARGET_QIMODE_MATH"
7443   "div{b}\t%2"
7444   [(set_attr "type" "idiv")
7445    (set_attr "mode" "QI")])
7446
7447 ;; The patterns that match these are at the end of this file.
7448
7449 (define_expand "divxf3"
7450   [(set (match_operand:XF 0 "register_operand" "")
7451         (div:XF (match_operand:XF 1 "register_operand" "")
7452                 (match_operand:XF 2 "register_operand" "")))]
7453   "TARGET_80387"
7454   "")
7455
7456 (define_expand "divdf3"
7457   [(set (match_operand:DF 0 "register_operand" "")
7458         (div:DF (match_operand:DF 1 "register_operand" "")
7459                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7460    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7461    "")
7462  
7463 (define_expand "divsf3"
7464   [(set (match_operand:SF 0 "register_operand" "")
7465         (div:SF (match_operand:SF 1 "register_operand" "")
7466                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7467   "TARGET_80387 || TARGET_SSE_MATH"
7468   "")
7469 \f
7470 ;; Remainder instructions.
7471
7472 (define_expand "divmoddi4"
7473   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7474                    (div:DI (match_operand:DI 1 "register_operand" "")
7475                            (match_operand:DI 2 "nonimmediate_operand" "")))
7476               (set (match_operand:DI 3 "register_operand" "")
7477                    (mod:DI (match_dup 1) (match_dup 2)))
7478               (clobber (reg:CC FLAGS_REG))])]
7479   "TARGET_64BIT"
7480   "")
7481
7482 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7483 ;; Penalize eax case slightly because it results in worse scheduling
7484 ;; of code.
7485 (define_insn "*divmoddi4_nocltd_rex64"
7486   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7487         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7488                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7489    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7490         (mod:DI (match_dup 2) (match_dup 3)))
7491    (clobber (reg:CC FLAGS_REG))]
7492   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7493   "#"
7494   [(set_attr "type" "multi")])
7495
7496 (define_insn "*divmoddi4_cltd_rex64"
7497   [(set (match_operand:DI 0 "register_operand" "=a")
7498         (div:DI (match_operand:DI 2 "register_operand" "a")
7499                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7500    (set (match_operand:DI 1 "register_operand" "=&d")
7501         (mod:DI (match_dup 2) (match_dup 3)))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7504   "#"
7505   [(set_attr "type" "multi")])
7506
7507 (define_insn "*divmoddi_noext_rex64"
7508   [(set (match_operand:DI 0 "register_operand" "=a")
7509         (div:DI (match_operand:DI 1 "register_operand" "0")
7510                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7511    (set (match_operand:DI 3 "register_operand" "=d")
7512         (mod:DI (match_dup 1) (match_dup 2)))
7513    (use (match_operand:DI 4 "register_operand" "3"))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "TARGET_64BIT"
7516   "idiv{q}\t%2"
7517   [(set_attr "type" "idiv")
7518    (set_attr "mode" "DI")])
7519
7520 (define_split
7521   [(set (match_operand:DI 0 "register_operand" "")
7522         (div:DI (match_operand:DI 1 "register_operand" "")
7523                 (match_operand:DI 2 "nonimmediate_operand" "")))
7524    (set (match_operand:DI 3 "register_operand" "")
7525         (mod:DI (match_dup 1) (match_dup 2)))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_64BIT && reload_completed"
7528   [(parallel [(set (match_dup 3)
7529                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7530               (clobber (reg:CC FLAGS_REG))])
7531    (parallel [(set (match_dup 0)
7532                    (div:DI (reg:DI 0) (match_dup 2)))
7533               (set (match_dup 3)
7534                    (mod:DI (reg:DI 0) (match_dup 2)))
7535               (use (match_dup 3))
7536               (clobber (reg:CC FLAGS_REG))])]
7537 {
7538   /* Avoid use of cltd in favor of a mov+shift.  */
7539   if (!TARGET_USE_CLTD && !optimize_size)
7540     {
7541       if (true_regnum (operands[1]))
7542         emit_move_insn (operands[0], operands[1]);
7543       else
7544         emit_move_insn (operands[3], operands[1]);
7545       operands[4] = operands[3];
7546     }
7547   else
7548     {
7549       if (true_regnum (operands[1]))
7550         abort();
7551       operands[4] = operands[1];
7552     }
7553 })
7554
7555
7556 (define_expand "divmodsi4"
7557   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7558                    (div:SI (match_operand:SI 1 "register_operand" "")
7559                            (match_operand:SI 2 "nonimmediate_operand" "")))
7560               (set (match_operand:SI 3 "register_operand" "")
7561                    (mod:SI (match_dup 1) (match_dup 2)))
7562               (clobber (reg:CC FLAGS_REG))])]
7563   ""
7564   "")
7565
7566 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7567 ;; Penalize eax case slightly because it results in worse scheduling
7568 ;; of code.
7569 (define_insn "*divmodsi4_nocltd"
7570   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7571         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7572                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7573    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7574         (mod:SI (match_dup 2) (match_dup 3)))
7575    (clobber (reg:CC FLAGS_REG))]
7576   "!optimize_size && !TARGET_USE_CLTD"
7577   "#"
7578   [(set_attr "type" "multi")])
7579
7580 (define_insn "*divmodsi4_cltd"
7581   [(set (match_operand:SI 0 "register_operand" "=a")
7582         (div:SI (match_operand:SI 2 "register_operand" "a")
7583                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7584    (set (match_operand:SI 1 "register_operand" "=&d")
7585         (mod:SI (match_dup 2) (match_dup 3)))
7586    (clobber (reg:CC FLAGS_REG))]
7587   "optimize_size || TARGET_USE_CLTD"
7588   "#"
7589   [(set_attr "type" "multi")])
7590
7591 (define_insn "*divmodsi_noext"
7592   [(set (match_operand:SI 0 "register_operand" "=a")
7593         (div:SI (match_operand:SI 1 "register_operand" "0")
7594                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7595    (set (match_operand:SI 3 "register_operand" "=d")
7596         (mod:SI (match_dup 1) (match_dup 2)))
7597    (use (match_operand:SI 4 "register_operand" "3"))
7598    (clobber (reg:CC FLAGS_REG))]
7599   ""
7600   "idiv{l}\t%2"
7601   [(set_attr "type" "idiv")
7602    (set_attr "mode" "SI")])
7603
7604 (define_split
7605   [(set (match_operand:SI 0 "register_operand" "")
7606         (div:SI (match_operand:SI 1 "register_operand" "")
7607                 (match_operand:SI 2 "nonimmediate_operand" "")))
7608    (set (match_operand:SI 3 "register_operand" "")
7609         (mod:SI (match_dup 1) (match_dup 2)))
7610    (clobber (reg:CC FLAGS_REG))]
7611   "reload_completed"
7612   [(parallel [(set (match_dup 3)
7613                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7614               (clobber (reg:CC FLAGS_REG))])
7615    (parallel [(set (match_dup 0)
7616                    (div:SI (reg:SI 0) (match_dup 2)))
7617               (set (match_dup 3)
7618                    (mod:SI (reg:SI 0) (match_dup 2)))
7619               (use (match_dup 3))
7620               (clobber (reg:CC FLAGS_REG))])]
7621 {
7622   /* Avoid use of cltd in favor of a mov+shift.  */
7623   if (!TARGET_USE_CLTD && !optimize_size)
7624     {
7625       if (true_regnum (operands[1]))
7626         emit_move_insn (operands[0], operands[1]);
7627       else
7628         emit_move_insn (operands[3], operands[1]);
7629       operands[4] = operands[3];
7630     }
7631   else
7632     {
7633       if (true_regnum (operands[1]))
7634         abort();
7635       operands[4] = operands[1];
7636     }
7637 })
7638 ;; %%% Split me.
7639 (define_insn "divmodhi4"
7640   [(set (match_operand:HI 0 "register_operand" "=a")
7641         (div:HI (match_operand:HI 1 "register_operand" "0")
7642                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7643    (set (match_operand:HI 3 "register_operand" "=&d")
7644         (mod:HI (match_dup 1) (match_dup 2)))
7645    (clobber (reg:CC FLAGS_REG))]
7646   "TARGET_HIMODE_MATH"
7647   "cwtd\;idiv{w}\t%2"
7648   [(set_attr "type" "multi")
7649    (set_attr "length_immediate" "0")
7650    (set_attr "mode" "SI")])
7651
7652 (define_insn "udivmoddi4"
7653   [(set (match_operand:DI 0 "register_operand" "=a")
7654         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7655                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7656    (set (match_operand:DI 3 "register_operand" "=&d")
7657         (umod:DI (match_dup 1) (match_dup 2)))
7658    (clobber (reg:CC FLAGS_REG))]
7659   "TARGET_64BIT"
7660   "xor{q}\t%3, %3\;div{q}\t%2"
7661   [(set_attr "type" "multi")
7662    (set_attr "length_immediate" "0")
7663    (set_attr "mode" "DI")])
7664
7665 (define_insn "*udivmoddi4_noext"
7666   [(set (match_operand:DI 0 "register_operand" "=a")
7667         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7668                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7669    (set (match_operand:DI 3 "register_operand" "=d")
7670         (umod:DI (match_dup 1) (match_dup 2)))
7671    (use (match_dup 3))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "TARGET_64BIT"
7674   "div{q}\t%2"
7675   [(set_attr "type" "idiv")
7676    (set_attr "mode" "DI")])
7677
7678 (define_split
7679   [(set (match_operand:DI 0 "register_operand" "")
7680         (udiv:DI (match_operand:DI 1 "register_operand" "")
7681                  (match_operand:DI 2 "nonimmediate_operand" "")))
7682    (set (match_operand:DI 3 "register_operand" "")
7683         (umod:DI (match_dup 1) (match_dup 2)))
7684    (clobber (reg:CC FLAGS_REG))]
7685   "TARGET_64BIT && reload_completed"
7686   [(set (match_dup 3) (const_int 0))
7687    (parallel [(set (match_dup 0)
7688                    (udiv:DI (match_dup 1) (match_dup 2)))
7689               (set (match_dup 3)
7690                    (umod:DI (match_dup 1) (match_dup 2)))
7691               (use (match_dup 3))
7692               (clobber (reg:CC FLAGS_REG))])]
7693   "")
7694
7695 (define_insn "udivmodsi4"
7696   [(set (match_operand:SI 0 "register_operand" "=a")
7697         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7698                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7699    (set (match_operand:SI 3 "register_operand" "=&d")
7700         (umod:SI (match_dup 1) (match_dup 2)))
7701    (clobber (reg:CC FLAGS_REG))]
7702   ""
7703   "xor{l}\t%3, %3\;div{l}\t%2"
7704   [(set_attr "type" "multi")
7705    (set_attr "length_immediate" "0")
7706    (set_attr "mode" "SI")])
7707
7708 (define_insn "*udivmodsi4_noext"
7709   [(set (match_operand:SI 0 "register_operand" "=a")
7710         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7711                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7712    (set (match_operand:SI 3 "register_operand" "=d")
7713         (umod:SI (match_dup 1) (match_dup 2)))
7714    (use (match_dup 3))
7715    (clobber (reg:CC FLAGS_REG))]
7716   ""
7717   "div{l}\t%2"
7718   [(set_attr "type" "idiv")
7719    (set_attr "mode" "SI")])
7720
7721 (define_split
7722   [(set (match_operand:SI 0 "register_operand" "")
7723         (udiv:SI (match_operand:SI 1 "register_operand" "")
7724                  (match_operand:SI 2 "nonimmediate_operand" "")))
7725    (set (match_operand:SI 3 "register_operand" "")
7726         (umod:SI (match_dup 1) (match_dup 2)))
7727    (clobber (reg:CC FLAGS_REG))]
7728   "reload_completed"
7729   [(set (match_dup 3) (const_int 0))
7730    (parallel [(set (match_dup 0)
7731                    (udiv:SI (match_dup 1) (match_dup 2)))
7732               (set (match_dup 3)
7733                    (umod:SI (match_dup 1) (match_dup 2)))
7734               (use (match_dup 3))
7735               (clobber (reg:CC FLAGS_REG))])]
7736   "")
7737
7738 (define_expand "udivmodhi4"
7739   [(set (match_dup 4) (const_int 0))
7740    (parallel [(set (match_operand:HI 0 "register_operand" "")
7741                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7742                             (match_operand:HI 2 "nonimmediate_operand" "")))
7743               (set (match_operand:HI 3 "register_operand" "")
7744                    (umod:HI (match_dup 1) (match_dup 2)))
7745               (use (match_dup 4))
7746               (clobber (reg:CC FLAGS_REG))])]
7747   "TARGET_HIMODE_MATH"
7748   "operands[4] = gen_reg_rtx (HImode);")
7749
7750 (define_insn "*udivmodhi_noext"
7751   [(set (match_operand:HI 0 "register_operand" "=a")
7752         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7753                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7754    (set (match_operand:HI 3 "register_operand" "=d")
7755         (umod:HI (match_dup 1) (match_dup 2)))
7756    (use (match_operand:HI 4 "register_operand" "3"))
7757    (clobber (reg:CC FLAGS_REG))]
7758   ""
7759   "div{w}\t%2"
7760   [(set_attr "type" "idiv")
7761    (set_attr "mode" "HI")])
7762
7763 ;; We cannot use div/idiv for double division, because it causes
7764 ;; "division by zero" on the overflow and that's not what we expect
7765 ;; from truncate.  Because true (non truncating) double division is
7766 ;; never generated, we can't create this insn anyway.
7767 ;
7768 ;(define_insn ""
7769 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7770 ;       (truncate:SI
7771 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7772 ;                  (zero_extend:DI
7773 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7774 ;   (set (match_operand:SI 3 "register_operand" "=d")
7775 ;       (truncate:SI
7776 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7777 ;   (clobber (reg:CC FLAGS_REG))]
7778 ;  ""
7779 ;  "div{l}\t{%2, %0|%0, %2}"
7780 ;  [(set_attr "type" "idiv")])
7781 \f
7782 ;;- Logical AND instructions
7783
7784 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7785 ;; Note that this excludes ah.
7786
7787 (define_insn "*testdi_1_rex64"
7788   [(set (reg FLAGS_REG)
7789         (compare
7790           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7791                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7792           (const_int 0)))]
7793   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7794    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7795   "@
7796    test{l}\t{%k1, %k0|%k0, %k1}
7797    test{l}\t{%k1, %k0|%k0, %k1}
7798    test{q}\t{%1, %0|%0, %1}
7799    test{q}\t{%1, %0|%0, %1}
7800    test{q}\t{%1, %0|%0, %1}"
7801   [(set_attr "type" "test")
7802    (set_attr "modrm" "0,1,0,1,1")
7803    (set_attr "mode" "SI,SI,DI,DI,DI")
7804    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7805
7806 (define_insn "testsi_1"
7807   [(set (reg FLAGS_REG)
7808         (compare
7809           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7810                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7811           (const_int 0)))]
7812   "ix86_match_ccmode (insn, CCNOmode)
7813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7814   "test{l}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,1")
7817    (set_attr "mode" "SI")
7818    (set_attr "pent_pair" "uv,np,uv")])
7819
7820 (define_expand "testsi_ccno_1"
7821   [(set (reg:CCNO FLAGS_REG)
7822         (compare:CCNO
7823           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7824                   (match_operand:SI 1 "nonmemory_operand" ""))
7825           (const_int 0)))]
7826   ""
7827   "")
7828
7829 (define_insn "*testhi_1"
7830   [(set (reg FLAGS_REG)
7831         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7832                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7833                  (const_int 0)))]
7834   "ix86_match_ccmode (insn, CCNOmode)
7835    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836   "test{w}\t{%1, %0|%0, %1}"
7837   [(set_attr "type" "test")
7838    (set_attr "modrm" "0,1,1")
7839    (set_attr "mode" "HI")
7840    (set_attr "pent_pair" "uv,np,uv")])
7841
7842 (define_expand "testqi_ccz_1"
7843   [(set (reg:CCZ FLAGS_REG)
7844         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7845                              (match_operand:QI 1 "nonmemory_operand" ""))
7846                  (const_int 0)))]
7847   ""
7848   "")
7849
7850 (define_insn "*testqi_1_maybe_si"
7851   [(set (reg FLAGS_REG)
7852         (compare
7853           (and:QI
7854             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7855             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7856           (const_int 0)))]
7857    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7858     && ix86_match_ccmode (insn,
7859                          GET_CODE (operands[1]) == CONST_INT
7860                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7861 {
7862   if (which_alternative == 3)
7863     {
7864       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7865         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7866       return "test{l}\t{%1, %k0|%k0, %1}";
7867     }
7868   return "test{b}\t{%1, %0|%0, %1}";
7869 }
7870   [(set_attr "type" "test")
7871    (set_attr "modrm" "0,1,1,1")
7872    (set_attr "mode" "QI,QI,QI,SI")
7873    (set_attr "pent_pair" "uv,np,uv,np")])
7874
7875 (define_insn "*testqi_1"
7876   [(set (reg FLAGS_REG)
7877         (compare
7878           (and:QI
7879             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7880             (match_operand:QI 1 "general_operand" "n,n,qn"))
7881           (const_int 0)))]
7882   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7883    && ix86_match_ccmode (insn, CCNOmode)"
7884   "test{b}\t{%1, %0|%0, %1}"
7885   [(set_attr "type" "test")
7886    (set_attr "modrm" "0,1,1")
7887    (set_attr "mode" "QI")
7888    (set_attr "pent_pair" "uv,np,uv")])
7889
7890 (define_expand "testqi_ext_ccno_0"
7891   [(set (reg:CCNO FLAGS_REG)
7892         (compare:CCNO
7893           (and:SI
7894             (zero_extract:SI
7895               (match_operand 0 "ext_register_operand" "")
7896               (const_int 8)
7897               (const_int 8))
7898             (match_operand 1 "const_int_operand" ""))
7899           (const_int 0)))]
7900   ""
7901   "")
7902
7903 (define_insn "*testqi_ext_0"
7904   [(set (reg FLAGS_REG)
7905         (compare
7906           (and:SI
7907             (zero_extract:SI
7908               (match_operand 0 "ext_register_operand" "Q")
7909               (const_int 8)
7910               (const_int 8))
7911             (match_operand 1 "const_int_operand" "n"))
7912           (const_int 0)))]
7913   "ix86_match_ccmode (insn, CCNOmode)"
7914   "test{b}\t{%1, %h0|%h0, %1}"
7915   [(set_attr "type" "test")
7916    (set_attr "mode" "QI")
7917    (set_attr "length_immediate" "1")
7918    (set_attr "pent_pair" "np")])
7919
7920 (define_insn "*testqi_ext_1"
7921   [(set (reg FLAGS_REG)
7922         (compare
7923           (and:SI
7924             (zero_extract:SI
7925               (match_operand 0 "ext_register_operand" "Q")
7926               (const_int 8)
7927               (const_int 8))
7928             (zero_extend:SI
7929               (match_operand:QI 1 "general_operand" "Qm")))
7930           (const_int 0)))]
7931   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7932    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7933   "test{b}\t{%1, %h0|%h0, %1}"
7934   [(set_attr "type" "test")
7935    (set_attr "mode" "QI")])
7936
7937 (define_insn "*testqi_ext_1_rex64"
7938   [(set (reg FLAGS_REG)
7939         (compare
7940           (and:SI
7941             (zero_extract:SI
7942               (match_operand 0 "ext_register_operand" "Q")
7943               (const_int 8)
7944               (const_int 8))
7945             (zero_extend:SI
7946               (match_operand:QI 1 "register_operand" "Q")))
7947           (const_int 0)))]
7948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7949   "test{b}\t{%1, %h0|%h0, %1}"
7950   [(set_attr "type" "test")
7951    (set_attr "mode" "QI")])
7952
7953 (define_insn "*testqi_ext_2"
7954   [(set (reg FLAGS_REG)
7955         (compare
7956           (and:SI
7957             (zero_extract:SI
7958               (match_operand 0 "ext_register_operand" "Q")
7959               (const_int 8)
7960               (const_int 8))
7961             (zero_extract:SI
7962               (match_operand 1 "ext_register_operand" "Q")
7963               (const_int 8)
7964               (const_int 8)))
7965           (const_int 0)))]
7966   "ix86_match_ccmode (insn, CCNOmode)"
7967   "test{b}\t{%h1, %h0|%h0, %h1}"
7968   [(set_attr "type" "test")
7969    (set_attr "mode" "QI")])
7970
7971 ;; Combine likes to form bit extractions for some tests.  Humor it.
7972 (define_insn "*testqi_ext_3"
7973   [(set (reg FLAGS_REG)
7974         (compare (zero_extract:SI
7975                    (match_operand 0 "nonimmediate_operand" "rm")
7976                    (match_operand:SI 1 "const_int_operand" "")
7977                    (match_operand:SI 2 "const_int_operand" ""))
7978                  (const_int 0)))]
7979   "ix86_match_ccmode (insn, CCNOmode)
7980    && (GET_MODE (operands[0]) == SImode
7981        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7982        || GET_MODE (operands[0]) == HImode
7983        || GET_MODE (operands[0]) == QImode)"
7984   "#")
7985
7986 (define_insn "*testqi_ext_3_rex64"
7987   [(set (reg FLAGS_REG)
7988         (compare (zero_extract:DI
7989                    (match_operand 0 "nonimmediate_operand" "rm")
7990                    (match_operand:DI 1 "const_int_operand" "")
7991                    (match_operand:DI 2 "const_int_operand" ""))
7992                  (const_int 0)))]
7993   "TARGET_64BIT
7994    && ix86_match_ccmode (insn, CCNOmode)
7995    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7996    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7997    /* Ensure that resulting mask is zero or sign extended operand.  */
7998    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7999        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8000            && INTVAL (operands[1]) > 32))
8001    && (GET_MODE (operands[0]) == SImode
8002        || GET_MODE (operands[0]) == DImode
8003        || GET_MODE (operands[0]) == HImode
8004        || GET_MODE (operands[0]) == QImode)"
8005   "#")
8006
8007 (define_split
8008   [(set (match_operand 0 "flags_reg_operand" "")
8009         (match_operator 1 "compare_operator"
8010           [(zero_extract
8011              (match_operand 2 "nonimmediate_operand" "")
8012              (match_operand 3 "const_int_operand" "")
8013              (match_operand 4 "const_int_operand" ""))
8014            (const_int 0)]))]
8015   "ix86_match_ccmode (insn, CCNOmode)"
8016   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8017 {
8018   rtx val = operands[2];
8019   HOST_WIDE_INT len = INTVAL (operands[3]);
8020   HOST_WIDE_INT pos = INTVAL (operands[4]);
8021   HOST_WIDE_INT mask;
8022   enum machine_mode mode, submode;
8023
8024   mode = GET_MODE (val);
8025   if (GET_CODE (val) == MEM)
8026     {
8027       /* ??? Combine likes to put non-volatile mem extractions in QImode
8028          no matter the size of the test.  So find a mode that works.  */
8029       if (! MEM_VOLATILE_P (val))
8030         {
8031           mode = smallest_mode_for_size (pos + len, MODE_INT);
8032           val = adjust_address (val, mode, 0);
8033         }
8034     }
8035   else if (GET_CODE (val) == SUBREG
8036            && (submode = GET_MODE (SUBREG_REG (val)),
8037                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8038            && pos + len <= GET_MODE_BITSIZE (submode))
8039     {
8040       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8041       mode = submode;
8042       val = SUBREG_REG (val);
8043     }
8044   else if (mode == HImode && pos + len <= 8)
8045     {
8046       /* Small HImode tests can be converted to QImode.  */
8047       mode = QImode;
8048       val = gen_lowpart (QImode, val);
8049     }
8050
8051   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8052   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8053
8054   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8055 })
8056
8057 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8058 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8059 ;; this is relatively important trick.
8060 ;; Do the conversion only post-reload to avoid limiting of the register class
8061 ;; to QI regs.
8062 (define_split
8063   [(set (match_operand 0 "flags_reg_operand" "")
8064         (match_operator 1 "compare_operator"
8065           [(and (match_operand 2 "register_operand" "")
8066                 (match_operand 3 "const_int_operand" ""))
8067            (const_int 0)]))]
8068    "reload_completed
8069     && QI_REG_P (operands[2])
8070     && GET_MODE (operands[2]) != QImode
8071     && ((ix86_match_ccmode (insn, CCZmode)
8072          && !(INTVAL (operands[3]) & ~(255 << 8)))
8073         || (ix86_match_ccmode (insn, CCNOmode)
8074             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8075   [(set (match_dup 0)
8076         (match_op_dup 1
8077           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8078                    (match_dup 3))
8079            (const_int 0)]))]
8080   "operands[2] = gen_lowpart (SImode, operands[2]);
8081    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8082
8083 (define_split
8084   [(set (match_operand 0 "flags_reg_operand" "")
8085         (match_operator 1 "compare_operator"
8086           [(and (match_operand 2 "nonimmediate_operand" "")
8087                 (match_operand 3 "const_int_operand" ""))
8088            (const_int 0)]))]
8089    "reload_completed
8090     && GET_MODE (operands[2]) != QImode
8091     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8092     && ((ix86_match_ccmode (insn, CCZmode)
8093          && !(INTVAL (operands[3]) & ~255))
8094         || (ix86_match_ccmode (insn, CCNOmode)
8095             && !(INTVAL (operands[3]) & ~127)))"
8096   [(set (match_dup 0)
8097         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8098                          (const_int 0)]))]
8099   "operands[2] = gen_lowpart (QImode, operands[2]);
8100    operands[3] = gen_lowpart (QImode, operands[3]);")
8101
8102
8103 ;; %%% This used to optimize known byte-wide and operations to memory,
8104 ;; and sometimes to QImode registers.  If this is considered useful,
8105 ;; it should be done with splitters.
8106
8107 (define_expand "anddi3"
8108   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8109         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8110                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8111    (clobber (reg:CC FLAGS_REG))]
8112   "TARGET_64BIT"
8113   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8114
8115 (define_insn "*anddi_1_rex64"
8116   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8117         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8118                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8121 {
8122   switch (get_attr_type (insn))
8123     {
8124     case TYPE_IMOVX:
8125       {
8126         enum machine_mode mode;
8127
8128         if (GET_CODE (operands[2]) != CONST_INT)
8129           abort ();
8130         if (INTVAL (operands[2]) == 0xff)
8131           mode = QImode;
8132         else if (INTVAL (operands[2]) == 0xffff)
8133           mode = HImode;
8134         else
8135           abort ();
8136         
8137         operands[1] = gen_lowpart (mode, operands[1]);
8138         if (mode == QImode)
8139           return "movz{bq|x}\t{%1,%0|%0, %1}";
8140         else
8141           return "movz{wq|x}\t{%1,%0|%0, %1}";
8142       }
8143
8144     default:
8145       if (! rtx_equal_p (operands[0], operands[1]))
8146         abort ();
8147       if (get_attr_mode (insn) == MODE_SI)
8148         return "and{l}\t{%k2, %k0|%k0, %k2}";
8149       else
8150         return "and{q}\t{%2, %0|%0, %2}";
8151     }
8152 }
8153   [(set_attr "type" "alu,alu,alu,imovx")
8154    (set_attr "length_immediate" "*,*,*,0")
8155    (set_attr "mode" "SI,DI,DI,DI")])
8156
8157 (define_insn "*anddi_2"
8158   [(set (reg FLAGS_REG)
8159         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8160                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8161                  (const_int 0)))
8162    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8163         (and:DI (match_dup 1) (match_dup 2)))]
8164   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8165    && ix86_binary_operator_ok (AND, DImode, operands)"
8166   "@
8167    and{l}\t{%k2, %k0|%k0, %k2}
8168    and{q}\t{%2, %0|%0, %2}
8169    and{q}\t{%2, %0|%0, %2}"
8170   [(set_attr "type" "alu")
8171    (set_attr "mode" "SI,DI,DI")])
8172
8173 (define_expand "andsi3"
8174   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8175         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8176                 (match_operand:SI 2 "general_operand" "")))
8177    (clobber (reg:CC FLAGS_REG))]
8178   ""
8179   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8180
8181 (define_insn "*andsi_1"
8182   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8183         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8184                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8185    (clobber (reg:CC FLAGS_REG))]
8186   "ix86_binary_operator_ok (AND, SImode, operands)"
8187 {
8188   switch (get_attr_type (insn))
8189     {
8190     case TYPE_IMOVX:
8191       {
8192         enum machine_mode mode;
8193
8194         if (GET_CODE (operands[2]) != CONST_INT)
8195           abort ();
8196         if (INTVAL (operands[2]) == 0xff)
8197           mode = QImode;
8198         else if (INTVAL (operands[2]) == 0xffff)
8199           mode = HImode;
8200         else
8201           abort ();
8202         
8203         operands[1] = gen_lowpart (mode, operands[1]);
8204         if (mode == QImode)
8205           return "movz{bl|x}\t{%1,%0|%0, %1}";
8206         else
8207           return "movz{wl|x}\t{%1,%0|%0, %1}";
8208       }
8209
8210     default:
8211       if (! rtx_equal_p (operands[0], operands[1]))
8212         abort ();
8213       return "and{l}\t{%2, %0|%0, %2}";
8214     }
8215 }
8216   [(set_attr "type" "alu,alu,imovx")
8217    (set_attr "length_immediate" "*,*,0")
8218    (set_attr "mode" "SI")])
8219
8220 (define_split
8221   [(set (match_operand 0 "register_operand" "")
8222         (and (match_dup 0)
8223              (const_int -65536)))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8226   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8227   "operands[1] = gen_lowpart (HImode, operands[0]);")
8228
8229 (define_split
8230   [(set (match_operand 0 "ext_register_operand" "")
8231         (and (match_dup 0)
8232              (const_int -256)))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8235   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8236   "operands[1] = gen_lowpart (QImode, operands[0]);")
8237
8238 (define_split
8239   [(set (match_operand 0 "ext_register_operand" "")
8240         (and (match_dup 0)
8241              (const_int -65281)))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8244   [(parallel [(set (zero_extract:SI (match_dup 0)
8245                                     (const_int 8)
8246                                     (const_int 8))
8247                    (xor:SI 
8248                      (zero_extract:SI (match_dup 0)
8249                                       (const_int 8)
8250                                       (const_int 8))
8251                      (zero_extract:SI (match_dup 0)
8252                                       (const_int 8)
8253                                       (const_int 8))))
8254               (clobber (reg:CC FLAGS_REG))])]
8255   "operands[0] = gen_lowpart (SImode, operands[0]);")
8256
8257 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8258 (define_insn "*andsi_1_zext"
8259   [(set (match_operand:DI 0 "register_operand" "=r")
8260         (zero_extend:DI
8261           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8262                   (match_operand:SI 2 "general_operand" "rim"))))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8265   "and{l}\t{%2, %k0|%k0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "SI")])
8268
8269 (define_insn "*andsi_2"
8270   [(set (reg FLAGS_REG)
8271         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8272                          (match_operand:SI 2 "general_operand" "rim,ri"))
8273                  (const_int 0)))
8274    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8275         (and:SI (match_dup 1) (match_dup 2)))]
8276   "ix86_match_ccmode (insn, CCNOmode)
8277    && ix86_binary_operator_ok (AND, SImode, operands)"
8278   "and{l}\t{%2, %0|%0, %2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "mode" "SI")])
8281
8282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8283 (define_insn "*andsi_2_zext"
8284   [(set (reg FLAGS_REG)
8285         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8286                          (match_operand:SI 2 "general_operand" "rim"))
8287                  (const_int 0)))
8288    (set (match_operand:DI 0 "register_operand" "=r")
8289         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8290   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8291    && ix86_binary_operator_ok (AND, SImode, operands)"
8292   "and{l}\t{%2, %k0|%k0, %2}"
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "SI")])
8295
8296 (define_expand "andhi3"
8297   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8298         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8299                 (match_operand:HI 2 "general_operand" "")))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "TARGET_HIMODE_MATH"
8302   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8303
8304 (define_insn "*andhi_1"
8305   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8306         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8307                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8308    (clobber (reg:CC FLAGS_REG))]
8309   "ix86_binary_operator_ok (AND, HImode, operands)"
8310 {
8311   switch (get_attr_type (insn))
8312     {
8313     case TYPE_IMOVX:
8314       if (GET_CODE (operands[2]) != CONST_INT)
8315         abort ();
8316       if (INTVAL (operands[2]) == 0xff)
8317         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8318       abort ();
8319
8320     default:
8321       if (! rtx_equal_p (operands[0], operands[1]))
8322         abort ();
8323
8324       return "and{w}\t{%2, %0|%0, %2}";
8325     }
8326 }
8327   [(set_attr "type" "alu,alu,imovx")
8328    (set_attr "length_immediate" "*,*,0")
8329    (set_attr "mode" "HI,HI,SI")])
8330
8331 (define_insn "*andhi_2"
8332   [(set (reg FLAGS_REG)
8333         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8334                          (match_operand:HI 2 "general_operand" "rim,ri"))
8335                  (const_int 0)))
8336    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8337         (and:HI (match_dup 1) (match_dup 2)))]
8338   "ix86_match_ccmode (insn, CCNOmode)
8339    && ix86_binary_operator_ok (AND, HImode, operands)"
8340   "and{w}\t{%2, %0|%0, %2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "mode" "HI")])
8343
8344 (define_expand "andqi3"
8345   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8346         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8347                 (match_operand:QI 2 "general_operand" "")))
8348    (clobber (reg:CC FLAGS_REG))]
8349   "TARGET_QIMODE_MATH"
8350   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8351
8352 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8353 (define_insn "*andqi_1"
8354   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8355         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8356                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "ix86_binary_operator_ok (AND, QImode, operands)"
8359   "@
8360    and{b}\t{%2, %0|%0, %2}
8361    and{b}\t{%2, %0|%0, %2}
8362    and{l}\t{%k2, %k0|%k0, %k2}"
8363   [(set_attr "type" "alu")
8364    (set_attr "mode" "QI,QI,SI")])
8365
8366 (define_insn "*andqi_1_slp"
8367   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8368         (and:QI (match_dup 0)
8369                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8370    (clobber (reg:CC FLAGS_REG))]
8371   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8372    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8373   "and{b}\t{%1, %0|%0, %1}"
8374   [(set_attr "type" "alu1")
8375    (set_attr "mode" "QI")])
8376
8377 (define_insn "*andqi_2_maybe_si"
8378   [(set (reg FLAGS_REG)
8379         (compare (and:QI
8380                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8381                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8382                  (const_int 0)))
8383    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8384         (and:QI (match_dup 1) (match_dup 2)))]
8385   "ix86_binary_operator_ok (AND, QImode, operands)
8386    && ix86_match_ccmode (insn,
8387                          GET_CODE (operands[2]) == CONST_INT
8388                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8389 {
8390   if (which_alternative == 2)
8391     {
8392       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8393         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8394       return "and{l}\t{%2, %k0|%k0, %2}";
8395     }
8396   return "and{b}\t{%2, %0|%0, %2}";
8397 }
8398   [(set_attr "type" "alu")
8399    (set_attr "mode" "QI,QI,SI")])
8400
8401 (define_insn "*andqi_2"
8402   [(set (reg FLAGS_REG)
8403         (compare (and:QI
8404                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8405                    (match_operand:QI 2 "general_operand" "qim,qi"))
8406                  (const_int 0)))
8407    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8408         (and:QI (match_dup 1) (match_dup 2)))]
8409   "ix86_match_ccmode (insn, CCNOmode)
8410    && ix86_binary_operator_ok (AND, QImode, operands)"
8411   "and{b}\t{%2, %0|%0, %2}"
8412   [(set_attr "type" "alu")
8413    (set_attr "mode" "QI")])
8414
8415 (define_insn "*andqi_2_slp"
8416   [(set (reg FLAGS_REG)
8417         (compare (and:QI
8418                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8419                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8420                  (const_int 0)))
8421    (set (strict_low_part (match_dup 0))
8422         (and:QI (match_dup 0) (match_dup 1)))]
8423   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8424    && ix86_match_ccmode (insn, CCNOmode)
8425    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8426   "and{b}\t{%1, %0|%0, %1}"
8427   [(set_attr "type" "alu1")
8428    (set_attr "mode" "QI")])
8429
8430 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8431 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8432 ;; for a QImode operand, which of course failed.
8433
8434 (define_insn "andqi_ext_0"
8435   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8436                          (const_int 8)
8437                          (const_int 8))
8438         (and:SI 
8439           (zero_extract:SI
8440             (match_operand 1 "ext_register_operand" "0")
8441             (const_int 8)
8442             (const_int 8))
8443           (match_operand 2 "const_int_operand" "n")))
8444    (clobber (reg:CC FLAGS_REG))]
8445   ""
8446   "and{b}\t{%2, %h0|%h0, %2}"
8447   [(set_attr "type" "alu")
8448    (set_attr "length_immediate" "1")
8449    (set_attr "mode" "QI")])
8450
8451 ;; Generated by peephole translating test to and.  This shows up
8452 ;; often in fp comparisons.
8453
8454 (define_insn "*andqi_ext_0_cc"
8455   [(set (reg FLAGS_REG)
8456         (compare
8457           (and:SI
8458             (zero_extract:SI
8459               (match_operand 1 "ext_register_operand" "0")
8460               (const_int 8)
8461               (const_int 8))
8462             (match_operand 2 "const_int_operand" "n"))
8463           (const_int 0)))
8464    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8465                          (const_int 8)
8466                          (const_int 8))
8467         (and:SI 
8468           (zero_extract:SI
8469             (match_dup 1)
8470             (const_int 8)
8471             (const_int 8))
8472           (match_dup 2)))]
8473   "ix86_match_ccmode (insn, CCNOmode)"
8474   "and{b}\t{%2, %h0|%h0, %2}"
8475   [(set_attr "type" "alu")
8476    (set_attr "length_immediate" "1")
8477    (set_attr "mode" "QI")])
8478
8479 (define_insn "*andqi_ext_1"
8480   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481                          (const_int 8)
8482                          (const_int 8))
8483         (and:SI 
8484           (zero_extract:SI
8485             (match_operand 1 "ext_register_operand" "0")
8486             (const_int 8)
8487             (const_int 8))
8488           (zero_extend:SI
8489             (match_operand:QI 2 "general_operand" "Qm"))))
8490    (clobber (reg:CC FLAGS_REG))]
8491   "!TARGET_64BIT"
8492   "and{b}\t{%2, %h0|%h0, %2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "length_immediate" "0")
8495    (set_attr "mode" "QI")])
8496
8497 (define_insn "*andqi_ext_1_rex64"
8498   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8499                          (const_int 8)
8500                          (const_int 8))
8501         (and:SI 
8502           (zero_extract:SI
8503             (match_operand 1 "ext_register_operand" "0")
8504             (const_int 8)
8505             (const_int 8))
8506           (zero_extend:SI
8507             (match_operand 2 "ext_register_operand" "Q"))))
8508    (clobber (reg:CC FLAGS_REG))]
8509   "TARGET_64BIT"
8510   "and{b}\t{%2, %h0|%h0, %2}"
8511   [(set_attr "type" "alu")
8512    (set_attr "length_immediate" "0")
8513    (set_attr "mode" "QI")])
8514
8515 (define_insn "*andqi_ext_2"
8516   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8517                          (const_int 8)
8518                          (const_int 8))
8519         (and:SI
8520           (zero_extract:SI
8521             (match_operand 1 "ext_register_operand" "%0")
8522             (const_int 8)
8523             (const_int 8))
8524           (zero_extract:SI
8525             (match_operand 2 "ext_register_operand" "Q")
8526             (const_int 8)
8527             (const_int 8))))
8528    (clobber (reg:CC FLAGS_REG))]
8529   ""
8530   "and{b}\t{%h2, %h0|%h0, %h2}"
8531   [(set_attr "type" "alu")
8532    (set_attr "length_immediate" "0")
8533    (set_attr "mode" "QI")])
8534
8535 ;; Convert wide AND instructions with immediate operand to shorter QImode
8536 ;; equivalents when possible.
8537 ;; Don't do the splitting with memory operands, since it introduces risk
8538 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8539 ;; for size, but that can (should?) be handled by generic code instead.
8540 (define_split
8541   [(set (match_operand 0 "register_operand" "")
8542         (and (match_operand 1 "register_operand" "")
8543              (match_operand 2 "const_int_operand" "")))
8544    (clobber (reg:CC FLAGS_REG))]
8545    "reload_completed
8546     && QI_REG_P (operands[0])
8547     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548     && !(~INTVAL (operands[2]) & ~(255 << 8))
8549     && GET_MODE (operands[0]) != QImode"
8550   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8551                    (and:SI (zero_extract:SI (match_dup 1)
8552                                             (const_int 8) (const_int 8))
8553                            (match_dup 2)))
8554               (clobber (reg:CC FLAGS_REG))])]
8555   "operands[0] = gen_lowpart (SImode, operands[0]);
8556    operands[1] = gen_lowpart (SImode, operands[1]);
8557    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8558
8559 ;; Since AND can be encoded with sign extended immediate, this is only
8560 ;; profitable when 7th bit is not set.
8561 (define_split
8562   [(set (match_operand 0 "register_operand" "")
8563         (and (match_operand 1 "general_operand" "")
8564              (match_operand 2 "const_int_operand" "")))
8565    (clobber (reg:CC FLAGS_REG))]
8566    "reload_completed
8567     && ANY_QI_REG_P (operands[0])
8568     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8569     && !(~INTVAL (operands[2]) & ~255)
8570     && !(INTVAL (operands[2]) & 128)
8571     && GET_MODE (operands[0]) != QImode"
8572   [(parallel [(set (strict_low_part (match_dup 0))
8573                    (and:QI (match_dup 1)
8574                            (match_dup 2)))
8575               (clobber (reg:CC FLAGS_REG))])]
8576   "operands[0] = gen_lowpart (QImode, operands[0]);
8577    operands[1] = gen_lowpart (QImode, operands[1]);
8578    operands[2] = gen_lowpart (QImode, operands[2]);")
8579 \f
8580 ;; Logical inclusive OR instructions
8581
8582 ;; %%% This used to optimize known byte-wide and operations to memory.
8583 ;; If this is considered useful, it should be done with splitters.
8584
8585 (define_expand "iordi3"
8586   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8587         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8588                 (match_operand:DI 2 "x86_64_general_operand" "")))
8589    (clobber (reg:CC FLAGS_REG))]
8590   "TARGET_64BIT"
8591   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8592
8593 (define_insn "*iordi_1_rex64"
8594   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8595         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8596                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "TARGET_64BIT
8599    && ix86_binary_operator_ok (IOR, DImode, operands)"
8600   "or{q}\t{%2, %0|%0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "DI")])
8603
8604 (define_insn "*iordi_2_rex64"
8605   [(set (reg FLAGS_REG)
8606         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8607                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8608                  (const_int 0)))
8609    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8610         (ior:DI (match_dup 1) (match_dup 2)))]
8611   "TARGET_64BIT
8612    && ix86_match_ccmode (insn, CCNOmode)
8613    && ix86_binary_operator_ok (IOR, DImode, operands)"
8614   "or{q}\t{%2, %0|%0, %2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "mode" "DI")])
8617
8618 (define_insn "*iordi_3_rex64"
8619   [(set (reg FLAGS_REG)
8620         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8621                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8622                  (const_int 0)))
8623    (clobber (match_scratch:DI 0 "=r"))]
8624   "TARGET_64BIT
8625    && ix86_match_ccmode (insn, CCNOmode)
8626    && ix86_binary_operator_ok (IOR, DImode, operands)"
8627   "or{q}\t{%2, %0|%0, %2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "mode" "DI")])
8630
8631
8632 (define_expand "iorsi3"
8633   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8634         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8635                 (match_operand:SI 2 "general_operand" "")))
8636    (clobber (reg:CC FLAGS_REG))]
8637   ""
8638   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8639
8640 (define_insn "*iorsi_1"
8641   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8642         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8643                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "ix86_binary_operator_ok (IOR, SImode, operands)"
8646   "or{l}\t{%2, %0|%0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "SI")])
8649
8650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8651 (define_insn "*iorsi_1_zext"
8652   [(set (match_operand:DI 0 "register_operand" "=rm")
8653         (zero_extend:DI
8654           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8655                   (match_operand:SI 2 "general_operand" "rim"))))
8656    (clobber (reg:CC FLAGS_REG))]
8657   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8658   "or{l}\t{%2, %k0|%k0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "SI")])
8661
8662 (define_insn "*iorsi_1_zext_imm"
8663   [(set (match_operand:DI 0 "register_operand" "=rm")
8664         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8665                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "TARGET_64BIT"
8668   "or{l}\t{%2, %k0|%k0, %2}"
8669   [(set_attr "type" "alu")
8670    (set_attr "mode" "SI")])
8671
8672 (define_insn "*iorsi_2"
8673   [(set (reg FLAGS_REG)
8674         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8675                          (match_operand:SI 2 "general_operand" "rim,ri"))
8676                  (const_int 0)))
8677    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8678         (ior:SI (match_dup 1) (match_dup 2)))]
8679   "ix86_match_ccmode (insn, CCNOmode)
8680    && ix86_binary_operator_ok (IOR, SImode, operands)"
8681   "or{l}\t{%2, %0|%0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "mode" "SI")])
8684
8685 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8686 ;; ??? Special case for immediate operand is missing - it is tricky.
8687 (define_insn "*iorsi_2_zext"
8688   [(set (reg FLAGS_REG)
8689         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8690                          (match_operand:SI 2 "general_operand" "rim"))
8691                  (const_int 0)))
8692    (set (match_operand:DI 0 "register_operand" "=r")
8693         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8694   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8695    && ix86_binary_operator_ok (IOR, SImode, operands)"
8696   "or{l}\t{%2, %k0|%k0, %2}"
8697   [(set_attr "type" "alu")
8698    (set_attr "mode" "SI")])
8699
8700 (define_insn "*iorsi_2_zext_imm"
8701   [(set (reg FLAGS_REG)
8702         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8703                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8704                  (const_int 0)))
8705    (set (match_operand:DI 0 "register_operand" "=r")
8706         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8707   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8708    && ix86_binary_operator_ok (IOR, SImode, operands)"
8709   "or{l}\t{%2, %k0|%k0, %2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "SI")])
8712
8713 (define_insn "*iorsi_3"
8714   [(set (reg FLAGS_REG)
8715         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8716                          (match_operand:SI 2 "general_operand" "rim"))
8717                  (const_int 0)))
8718    (clobber (match_scratch:SI 0 "=r"))]
8719   "ix86_match_ccmode (insn, CCNOmode)
8720    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8721   "or{l}\t{%2, %0|%0, %2}"
8722   [(set_attr "type" "alu")
8723    (set_attr "mode" "SI")])
8724
8725 (define_expand "iorhi3"
8726   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8727         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8728                 (match_operand:HI 2 "general_operand" "")))
8729    (clobber (reg:CC FLAGS_REG))]
8730   "TARGET_HIMODE_MATH"
8731   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8732
8733 (define_insn "*iorhi_1"
8734   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8735         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8736                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8737    (clobber (reg:CC FLAGS_REG))]
8738   "ix86_binary_operator_ok (IOR, HImode, operands)"
8739   "or{w}\t{%2, %0|%0, %2}"
8740   [(set_attr "type" "alu")
8741    (set_attr "mode" "HI")])
8742
8743 (define_insn "*iorhi_2"
8744   [(set (reg FLAGS_REG)
8745         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8746                          (match_operand:HI 2 "general_operand" "rim,ri"))
8747                  (const_int 0)))
8748    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8749         (ior:HI (match_dup 1) (match_dup 2)))]
8750   "ix86_match_ccmode (insn, CCNOmode)
8751    && ix86_binary_operator_ok (IOR, HImode, operands)"
8752   "or{w}\t{%2, %0|%0, %2}"
8753   [(set_attr "type" "alu")
8754    (set_attr "mode" "HI")])
8755
8756 (define_insn "*iorhi_3"
8757   [(set (reg FLAGS_REG)
8758         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8759                          (match_operand:HI 2 "general_operand" "rim"))
8760                  (const_int 0)))
8761    (clobber (match_scratch:HI 0 "=r"))]
8762   "ix86_match_ccmode (insn, CCNOmode)
8763    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8764   "or{w}\t{%2, %0|%0, %2}"
8765   [(set_attr "type" "alu")
8766    (set_attr "mode" "HI")])
8767
8768 (define_expand "iorqi3"
8769   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8770         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8771                 (match_operand:QI 2 "general_operand" "")))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_QIMODE_MATH"
8774   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8775
8776 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8777 (define_insn "*iorqi_1"
8778   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8779         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8780                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8781    (clobber (reg:CC FLAGS_REG))]
8782   "ix86_binary_operator_ok (IOR, QImode, operands)"
8783   "@
8784    or{b}\t{%2, %0|%0, %2}
8785    or{b}\t{%2, %0|%0, %2}
8786    or{l}\t{%k2, %k0|%k0, %k2}"
8787   [(set_attr "type" "alu")
8788    (set_attr "mode" "QI,QI,SI")])
8789
8790 (define_insn "*iorqi_1_slp"
8791   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8792         (ior:QI (match_dup 0)
8793                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8794    (clobber (reg:CC FLAGS_REG))]
8795   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8796    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8797   "or{b}\t{%1, %0|%0, %1}"
8798   [(set_attr "type" "alu1")
8799    (set_attr "mode" "QI")])
8800
8801 (define_insn "*iorqi_2"
8802   [(set (reg FLAGS_REG)
8803         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8804                          (match_operand:QI 2 "general_operand" "qim,qi"))
8805                  (const_int 0)))
8806    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8807         (ior:QI (match_dup 1) (match_dup 2)))]
8808   "ix86_match_ccmode (insn, CCNOmode)
8809    && ix86_binary_operator_ok (IOR, QImode, operands)"
8810   "or{b}\t{%2, %0|%0, %2}"
8811   [(set_attr "type" "alu")
8812    (set_attr "mode" "QI")])
8813
8814 (define_insn "*iorqi_2_slp"
8815   [(set (reg FLAGS_REG)
8816         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8817                          (match_operand:QI 1 "general_operand" "qim,qi"))
8818                  (const_int 0)))
8819    (set (strict_low_part (match_dup 0))
8820         (ior:QI (match_dup 0) (match_dup 1)))]
8821   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8822    && ix86_match_ccmode (insn, CCNOmode)
8823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8824   "or{b}\t{%1, %0|%0, %1}"
8825   [(set_attr "type" "alu1")
8826    (set_attr "mode" "QI")])
8827
8828 (define_insn "*iorqi_3"
8829   [(set (reg FLAGS_REG)
8830         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8831                          (match_operand:QI 2 "general_operand" "qim"))
8832                  (const_int 0)))
8833    (clobber (match_scratch:QI 0 "=q"))]
8834   "ix86_match_ccmode (insn, CCNOmode)
8835    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8836   "or{b}\t{%2, %0|%0, %2}"
8837   [(set_attr "type" "alu")
8838    (set_attr "mode" "QI")])
8839
8840 (define_insn "iorqi_ext_0"
8841   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8842                          (const_int 8)
8843                          (const_int 8))
8844         (ior:SI 
8845           (zero_extract:SI
8846             (match_operand 1 "ext_register_operand" "0")
8847             (const_int 8)
8848             (const_int 8))
8849           (match_operand 2 "const_int_operand" "n")))
8850    (clobber (reg:CC FLAGS_REG))]
8851   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8852   "or{b}\t{%2, %h0|%h0, %2}"
8853   [(set_attr "type" "alu")
8854    (set_attr "length_immediate" "1")
8855    (set_attr "mode" "QI")])
8856
8857 (define_insn "*iorqi_ext_1"
8858   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8859                          (const_int 8)
8860                          (const_int 8))
8861         (ior:SI 
8862           (zero_extract:SI
8863             (match_operand 1 "ext_register_operand" "0")
8864             (const_int 8)
8865             (const_int 8))
8866           (zero_extend:SI
8867             (match_operand:QI 2 "general_operand" "Qm"))))
8868    (clobber (reg:CC FLAGS_REG))]
8869   "!TARGET_64BIT
8870    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8871   "or{b}\t{%2, %h0|%h0, %2}"
8872   [(set_attr "type" "alu")
8873    (set_attr "length_immediate" "0")
8874    (set_attr "mode" "QI")])
8875
8876 (define_insn "*iorqi_ext_1_rex64"
8877   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8878                          (const_int 8)
8879                          (const_int 8))
8880         (ior:SI 
8881           (zero_extract:SI
8882             (match_operand 1 "ext_register_operand" "0")
8883             (const_int 8)
8884             (const_int 8))
8885           (zero_extend:SI
8886             (match_operand 2 "ext_register_operand" "Q"))))
8887    (clobber (reg:CC FLAGS_REG))]
8888   "TARGET_64BIT
8889    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8890   "or{b}\t{%2, %h0|%h0, %2}"
8891   [(set_attr "type" "alu")
8892    (set_attr "length_immediate" "0")
8893    (set_attr "mode" "QI")])
8894
8895 (define_insn "*iorqi_ext_2"
8896   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8897                          (const_int 8)
8898                          (const_int 8))
8899         (ior:SI 
8900           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8901                            (const_int 8)
8902                            (const_int 8))
8903           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8904                            (const_int 8)
8905                            (const_int 8))))
8906    (clobber (reg:CC FLAGS_REG))]
8907   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8908   "ior{b}\t{%h2, %h0|%h0, %h2}"
8909   [(set_attr "type" "alu")
8910    (set_attr "length_immediate" "0")
8911    (set_attr "mode" "QI")])
8912
8913 (define_split
8914   [(set (match_operand 0 "register_operand" "")
8915         (ior (match_operand 1 "register_operand" "")
8916              (match_operand 2 "const_int_operand" "")))
8917    (clobber (reg:CC FLAGS_REG))]
8918    "reload_completed
8919     && QI_REG_P (operands[0])
8920     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921     && !(INTVAL (operands[2]) & ~(255 << 8))
8922     && GET_MODE (operands[0]) != QImode"
8923   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8924                    (ior:SI (zero_extract:SI (match_dup 1)
8925                                             (const_int 8) (const_int 8))
8926                            (match_dup 2)))
8927               (clobber (reg:CC FLAGS_REG))])]
8928   "operands[0] = gen_lowpart (SImode, operands[0]);
8929    operands[1] = gen_lowpart (SImode, operands[1]);
8930    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8931
8932 ;; Since OR can be encoded with sign extended immediate, this is only
8933 ;; profitable when 7th bit is set.
8934 (define_split
8935   [(set (match_operand 0 "register_operand" "")
8936         (ior (match_operand 1 "general_operand" "")
8937              (match_operand 2 "const_int_operand" "")))
8938    (clobber (reg:CC FLAGS_REG))]
8939    "reload_completed
8940     && ANY_QI_REG_P (operands[0])
8941     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8942     && !(INTVAL (operands[2]) & ~255)
8943     && (INTVAL (operands[2]) & 128)
8944     && GET_MODE (operands[0]) != QImode"
8945   [(parallel [(set (strict_low_part (match_dup 0))
8946                    (ior:QI (match_dup 1)
8947                            (match_dup 2)))
8948               (clobber (reg:CC FLAGS_REG))])]
8949   "operands[0] = gen_lowpart (QImode, operands[0]);
8950    operands[1] = gen_lowpart (QImode, operands[1]);
8951    operands[2] = gen_lowpart (QImode, operands[2]);")
8952 \f
8953 ;; Logical XOR instructions
8954
8955 ;; %%% This used to optimize known byte-wide and operations to memory.
8956 ;; If this is considered useful, it should be done with splitters.
8957
8958 (define_expand "xordi3"
8959   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8960         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8961                 (match_operand:DI 2 "x86_64_general_operand" "")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "TARGET_64BIT"
8964   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8965
8966 (define_insn "*xordi_1_rex64"
8967   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8968         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8969                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8970    (clobber (reg:CC FLAGS_REG))]
8971   "TARGET_64BIT
8972    && ix86_binary_operator_ok (XOR, DImode, operands)"
8973   "@
8974    xor{q}\t{%2, %0|%0, %2}
8975    xor{q}\t{%2, %0|%0, %2}"
8976   [(set_attr "type" "alu")
8977    (set_attr "mode" "DI,DI")])
8978
8979 (define_insn "*xordi_2_rex64"
8980   [(set (reg FLAGS_REG)
8981         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8982                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8983                  (const_int 0)))
8984    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8985         (xor:DI (match_dup 1) (match_dup 2)))]
8986   "TARGET_64BIT
8987    && ix86_match_ccmode (insn, CCNOmode)
8988    && ix86_binary_operator_ok (XOR, DImode, operands)"
8989   "@
8990    xor{q}\t{%2, %0|%0, %2}
8991    xor{q}\t{%2, %0|%0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "mode" "DI,DI")])
8994
8995 (define_insn "*xordi_3_rex64"
8996   [(set (reg FLAGS_REG)
8997         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8998                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8999                  (const_int 0)))
9000    (clobber (match_scratch:DI 0 "=r"))]
9001   "TARGET_64BIT
9002    && ix86_match_ccmode (insn, CCNOmode)
9003    && ix86_binary_operator_ok (XOR, DImode, operands)"
9004   "xor{q}\t{%2, %0|%0, %2}"
9005   [(set_attr "type" "alu")
9006    (set_attr "mode" "DI")])
9007
9008 (define_expand "xorsi3"
9009   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9010         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9011                 (match_operand:SI 2 "general_operand" "")))
9012    (clobber (reg:CC FLAGS_REG))]
9013   ""
9014   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9015
9016 (define_insn "*xorsi_1"
9017   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9018         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9019                 (match_operand:SI 2 "general_operand" "ri,rm")))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9025
9026 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9027 ;; Add speccase for immediates
9028 (define_insn "*xorsi_1_zext"
9029   [(set (match_operand:DI 0 "register_operand" "=r")
9030         (zero_extend:DI
9031           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032                   (match_operand:SI 2 "general_operand" "rim"))))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9035   "xor{l}\t{%2, %k0|%k0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9038
9039 (define_insn "*xorsi_1_zext_imm"
9040   [(set (match_operand:DI 0 "register_operand" "=r")
9041         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9042                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9045   "xor{l}\t{%2, %k0|%k0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "SI")])
9048
9049 (define_insn "*xorsi_2"
9050   [(set (reg FLAGS_REG)
9051         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9052                          (match_operand:SI 2 "general_operand" "rim,ri"))
9053                  (const_int 0)))
9054    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9055         (xor:SI (match_dup 1) (match_dup 2)))]
9056   "ix86_match_ccmode (insn, CCNOmode)
9057    && ix86_binary_operator_ok (XOR, SImode, operands)"
9058   "xor{l}\t{%2, %0|%0, %2}"
9059   [(set_attr "type" "alu")
9060    (set_attr "mode" "SI")])
9061
9062 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9063 ;; ??? Special case for immediate operand is missing - it is tricky.
9064 (define_insn "*xorsi_2_zext"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9067                          (match_operand:SI 2 "general_operand" "rim"))
9068                  (const_int 0)))
9069    (set (match_operand:DI 0 "register_operand" "=r")
9070         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9071   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9072    && ix86_binary_operator_ok (XOR, SImode, operands)"
9073   "xor{l}\t{%2, %k0|%k0, %2}"
9074   [(set_attr "type" "alu")
9075    (set_attr "mode" "SI")])
9076
9077 (define_insn "*xorsi_2_zext_imm"
9078   [(set (reg FLAGS_REG)
9079         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9080                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9081                  (const_int 0)))
9082    (set (match_operand:DI 0 "register_operand" "=r")
9083         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9084   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9085    && ix86_binary_operator_ok (XOR, SImode, operands)"
9086   "xor{l}\t{%2, %k0|%k0, %2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "SI")])
9089
9090 (define_insn "*xorsi_3"
9091   [(set (reg FLAGS_REG)
9092         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9093                          (match_operand:SI 2 "general_operand" "rim"))
9094                  (const_int 0)))
9095    (clobber (match_scratch:SI 0 "=r"))]
9096   "ix86_match_ccmode (insn, CCNOmode)
9097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9098   "xor{l}\t{%2, %0|%0, %2}"
9099   [(set_attr "type" "alu")
9100    (set_attr "mode" "SI")])
9101
9102 (define_expand "xorhi3"
9103   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9104         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9105                 (match_operand:HI 2 "general_operand" "")))
9106    (clobber (reg:CC FLAGS_REG))]
9107   "TARGET_HIMODE_MATH"
9108   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9109
9110 (define_insn "*xorhi_1"
9111   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9112         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9113                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "ix86_binary_operator_ok (XOR, HImode, operands)"
9116   "xor{w}\t{%2, %0|%0, %2}"
9117   [(set_attr "type" "alu")
9118    (set_attr "mode" "HI")])
9119
9120 (define_insn "*xorhi_2"
9121   [(set (reg FLAGS_REG)
9122         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9123                          (match_operand:HI 2 "general_operand" "rim,ri"))
9124                  (const_int 0)))
9125    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9126         (xor:HI (match_dup 1) (match_dup 2)))]
9127   "ix86_match_ccmode (insn, CCNOmode)
9128    && ix86_binary_operator_ok (XOR, HImode, operands)"
9129   "xor{w}\t{%2, %0|%0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "HI")])
9132
9133 (define_insn "*xorhi_3"
9134   [(set (reg FLAGS_REG)
9135         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9136                          (match_operand:HI 2 "general_operand" "rim"))
9137                  (const_int 0)))
9138    (clobber (match_scratch:HI 0 "=r"))]
9139   "ix86_match_ccmode (insn, CCNOmode)
9140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9141   "xor{w}\t{%2, %0|%0, %2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "mode" "HI")])
9144
9145 (define_expand "xorqi3"
9146   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9147         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9148                 (match_operand:QI 2 "general_operand" "")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_QIMODE_MATH"
9151   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9152
9153 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9154 (define_insn "*xorqi_1"
9155   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9156         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9157                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9158    (clobber (reg:CC FLAGS_REG))]
9159   "ix86_binary_operator_ok (XOR, QImode, operands)"
9160   "@
9161    xor{b}\t{%2, %0|%0, %2}
9162    xor{b}\t{%2, %0|%0, %2}
9163    xor{l}\t{%k2, %k0|%k0, %k2}"
9164   [(set_attr "type" "alu")
9165    (set_attr "mode" "QI,QI,SI")])
9166
9167 (define_insn "*xorqi_1_slp"
9168   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9169         (xor:QI (match_dup 0)
9170                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9171    (clobber (reg:CC FLAGS_REG))]
9172   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9173    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9174   "xor{b}\t{%1, %0|%0, %1}"
9175   [(set_attr "type" "alu1")
9176    (set_attr "mode" "QI")])
9177
9178 (define_insn "xorqi_ext_0"
9179   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9180                          (const_int 8)
9181                          (const_int 8))
9182         (xor:SI 
9183           (zero_extract:SI
9184             (match_operand 1 "ext_register_operand" "0")
9185             (const_int 8)
9186             (const_int 8))
9187           (match_operand 2 "const_int_operand" "n")))
9188    (clobber (reg:CC FLAGS_REG))]
9189   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9190   "xor{b}\t{%2, %h0|%h0, %2}"
9191   [(set_attr "type" "alu")
9192    (set_attr "length_immediate" "1")
9193    (set_attr "mode" "QI")])
9194
9195 (define_insn "*xorqi_ext_1"
9196   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9197                          (const_int 8)
9198                          (const_int 8))
9199         (xor:SI 
9200           (zero_extract:SI
9201             (match_operand 1 "ext_register_operand" "0")
9202             (const_int 8)
9203             (const_int 8))
9204           (zero_extend:SI
9205             (match_operand:QI 2 "general_operand" "Qm"))))
9206    (clobber (reg:CC FLAGS_REG))]
9207   "!TARGET_64BIT
9208    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9209   "xor{b}\t{%2, %h0|%h0, %2}"
9210   [(set_attr "type" "alu")
9211    (set_attr "length_immediate" "0")
9212    (set_attr "mode" "QI")])
9213
9214 (define_insn "*xorqi_ext_1_rex64"
9215   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216                          (const_int 8)
9217                          (const_int 8))
9218         (xor:SI 
9219           (zero_extract:SI
9220             (match_operand 1 "ext_register_operand" "0")
9221             (const_int 8)
9222             (const_int 8))
9223           (zero_extend:SI
9224             (match_operand 2 "ext_register_operand" "Q"))))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "TARGET_64BIT
9227    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9228   "xor{b}\t{%2, %h0|%h0, %2}"
9229   [(set_attr "type" "alu")
9230    (set_attr "length_immediate" "0")
9231    (set_attr "mode" "QI")])
9232
9233 (define_insn "*xorqi_ext_2"
9234   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9235                          (const_int 8)
9236                          (const_int 8))
9237         (xor:SI 
9238           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9239                            (const_int 8)
9240                            (const_int 8))
9241           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9242                            (const_int 8)
9243                            (const_int 8))))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9246   "xor{b}\t{%h2, %h0|%h0, %h2}"
9247   [(set_attr "type" "alu")
9248    (set_attr "length_immediate" "0")
9249    (set_attr "mode" "QI")])
9250
9251 (define_insn "*xorqi_cc_1"
9252   [(set (reg FLAGS_REG)
9253         (compare
9254           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9255                   (match_operand:QI 2 "general_operand" "qim,qi"))
9256           (const_int 0)))
9257    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9258         (xor:QI (match_dup 1) (match_dup 2)))]
9259   "ix86_match_ccmode (insn, CCNOmode)
9260    && ix86_binary_operator_ok (XOR, QImode, operands)"
9261   "xor{b}\t{%2, %0|%0, %2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "mode" "QI")])
9264
9265 (define_insn "*xorqi_2_slp"
9266   [(set (reg FLAGS_REG)
9267         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9268                          (match_operand:QI 1 "general_operand" "qim,qi"))
9269                  (const_int 0)))
9270    (set (strict_low_part (match_dup 0))
9271         (xor:QI (match_dup 0) (match_dup 1)))]
9272   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9273    && ix86_match_ccmode (insn, CCNOmode)
9274    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9275   "xor{b}\t{%1, %0|%0, %1}"
9276   [(set_attr "type" "alu1")
9277    (set_attr "mode" "QI")])
9278
9279 (define_insn "*xorqi_cc_2"
9280   [(set (reg FLAGS_REG)
9281         (compare
9282           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9283                   (match_operand:QI 2 "general_operand" "qim"))
9284           (const_int 0)))
9285    (clobber (match_scratch:QI 0 "=q"))]
9286   "ix86_match_ccmode (insn, CCNOmode)
9287    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9288   "xor{b}\t{%2, %0|%0, %2}"
9289   [(set_attr "type" "alu")
9290    (set_attr "mode" "QI")])
9291
9292 (define_insn "*xorqi_cc_ext_1"
9293   [(set (reg FLAGS_REG)
9294         (compare
9295           (xor:SI
9296             (zero_extract:SI
9297               (match_operand 1 "ext_register_operand" "0")
9298               (const_int 8)
9299               (const_int 8))
9300             (match_operand:QI 2 "general_operand" "qmn"))
9301           (const_int 0)))
9302    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9303                          (const_int 8)
9304                          (const_int 8))
9305         (xor:SI 
9306           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307           (match_dup 2)))]
9308   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309   "xor{b}\t{%2, %h0|%h0, %2}"
9310   [(set_attr "type" "alu")
9311    (set_attr "mode" "QI")])
9312
9313 (define_insn "*xorqi_cc_ext_1_rex64"
9314   [(set (reg FLAGS_REG)
9315         (compare
9316           (xor:SI
9317             (zero_extract:SI
9318               (match_operand 1 "ext_register_operand" "0")
9319               (const_int 8)
9320               (const_int 8))
9321             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9322           (const_int 0)))
9323    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9324                          (const_int 8)
9325                          (const_int 8))
9326         (xor:SI 
9327           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9328           (match_dup 2)))]
9329   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9330   "xor{b}\t{%2, %h0|%h0, %2}"
9331   [(set_attr "type" "alu")
9332    (set_attr "mode" "QI")])
9333
9334 (define_expand "xorqi_cc_ext_1"
9335   [(parallel [
9336      (set (reg:CCNO FLAGS_REG)
9337           (compare:CCNO
9338             (xor:SI
9339               (zero_extract:SI
9340                 (match_operand 1 "ext_register_operand" "")
9341                 (const_int 8)
9342                 (const_int 8))
9343               (match_operand:QI 2 "general_operand" ""))
9344             (const_int 0)))
9345      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9346                            (const_int 8)
9347                            (const_int 8))
9348           (xor:SI 
9349             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9350             (match_dup 2)))])]
9351   ""
9352   "")
9353
9354 (define_split
9355   [(set (match_operand 0 "register_operand" "")
9356         (xor (match_operand 1 "register_operand" "")
9357              (match_operand 2 "const_int_operand" "")))
9358    (clobber (reg:CC FLAGS_REG))]
9359    "reload_completed
9360     && QI_REG_P (operands[0])
9361     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362     && !(INTVAL (operands[2]) & ~(255 << 8))
9363     && GET_MODE (operands[0]) != QImode"
9364   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9365                    (xor:SI (zero_extract:SI (match_dup 1)
9366                                             (const_int 8) (const_int 8))
9367                            (match_dup 2)))
9368               (clobber (reg:CC FLAGS_REG))])]
9369   "operands[0] = gen_lowpart (SImode, operands[0]);
9370    operands[1] = gen_lowpart (SImode, operands[1]);
9371    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9372
9373 ;; Since XOR can be encoded with sign extended immediate, this is only
9374 ;; profitable when 7th bit is set.
9375 (define_split
9376   [(set (match_operand 0 "register_operand" "")
9377         (xor (match_operand 1 "general_operand" "")
9378              (match_operand 2 "const_int_operand" "")))
9379    (clobber (reg:CC FLAGS_REG))]
9380    "reload_completed
9381     && ANY_QI_REG_P (operands[0])
9382     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9383     && !(INTVAL (operands[2]) & ~255)
9384     && (INTVAL (operands[2]) & 128)
9385     && GET_MODE (operands[0]) != QImode"
9386   [(parallel [(set (strict_low_part (match_dup 0))
9387                    (xor:QI (match_dup 1)
9388                            (match_dup 2)))
9389               (clobber (reg:CC FLAGS_REG))])]
9390   "operands[0] = gen_lowpart (QImode, operands[0]);
9391    operands[1] = gen_lowpart (QImode, operands[1]);
9392    operands[2] = gen_lowpart (QImode, operands[2]);")
9393 \f
9394 ;; Negation instructions
9395
9396 (define_expand "negdi2"
9397   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9398                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9399               (clobber (reg:CC FLAGS_REG))])]
9400   ""
9401   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9402
9403 (define_insn "*negdi2_1"
9404   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9405         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "!TARGET_64BIT
9408    && ix86_unary_operator_ok (NEG, DImode, operands)"
9409   "#")
9410
9411 (define_split
9412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9413         (neg:DI (match_operand:DI 1 "general_operand" "")))
9414    (clobber (reg:CC FLAGS_REG))]
9415   "!TARGET_64BIT && reload_completed"
9416   [(parallel
9417     [(set (reg:CCZ FLAGS_REG)
9418           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9419      (set (match_dup 0) (neg:SI (match_dup 2)))])
9420    (parallel
9421     [(set (match_dup 1)
9422           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9423                             (match_dup 3))
9424                    (const_int 0)))
9425      (clobber (reg:CC FLAGS_REG))])
9426    (parallel
9427     [(set (match_dup 1)
9428           (neg:SI (match_dup 1)))
9429      (clobber (reg:CC FLAGS_REG))])]
9430   "split_di (operands+1, 1, operands+2, operands+3);
9431    split_di (operands+0, 1, operands+0, operands+1);")
9432
9433 (define_insn "*negdi2_1_rex64"
9434   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9435         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9436    (clobber (reg:CC FLAGS_REG))]
9437   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9438   "neg{q}\t%0"
9439   [(set_attr "type" "negnot")
9440    (set_attr "mode" "DI")])
9441
9442 ;; The problem with neg is that it does not perform (compare x 0),
9443 ;; it really performs (compare 0 x), which leaves us with the zero
9444 ;; flag being the only useful item.
9445
9446 (define_insn "*negdi2_cmpz_rex64"
9447   [(set (reg:CCZ FLAGS_REG)
9448         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9449                      (const_int 0)))
9450    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9451         (neg:DI (match_dup 1)))]
9452   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9453   "neg{q}\t%0"
9454   [(set_attr "type" "negnot")
9455    (set_attr "mode" "DI")])
9456
9457
9458 (define_expand "negsi2"
9459   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9460                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9461               (clobber (reg:CC FLAGS_REG))])]
9462   ""
9463   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9464
9465 (define_insn "*negsi2_1"
9466   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9467         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "ix86_unary_operator_ok (NEG, SImode, operands)"
9470   "neg{l}\t%0"
9471   [(set_attr "type" "negnot")
9472    (set_attr "mode" "SI")])
9473
9474 ;; Combine is quite creative about this pattern.
9475 (define_insn "*negsi2_1_zext"
9476   [(set (match_operand:DI 0 "register_operand" "=r")
9477         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9478                                         (const_int 32)))
9479                      (const_int 32)))
9480    (clobber (reg:CC FLAGS_REG))]
9481   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9482   "neg{l}\t%k0"
9483   [(set_attr "type" "negnot")
9484    (set_attr "mode" "SI")])
9485
9486 ;; The problem with neg is that it does not perform (compare x 0),
9487 ;; it really performs (compare 0 x), which leaves us with the zero
9488 ;; flag being the only useful item.
9489
9490 (define_insn "*negsi2_cmpz"
9491   [(set (reg:CCZ FLAGS_REG)
9492         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9493                      (const_int 0)))
9494    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9495         (neg:SI (match_dup 1)))]
9496   "ix86_unary_operator_ok (NEG, SImode, operands)"
9497   "neg{l}\t%0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "SI")])
9500
9501 (define_insn "*negsi2_cmpz_zext"
9502   [(set (reg:CCZ FLAGS_REG)
9503         (compare:CCZ (lshiftrt:DI
9504                        (neg:DI (ashift:DI
9505                                  (match_operand:DI 1 "register_operand" "0")
9506                                  (const_int 32)))
9507                        (const_int 32))
9508                      (const_int 0)))
9509    (set (match_operand:DI 0 "register_operand" "=r")
9510         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9511                                         (const_int 32)))
9512                      (const_int 32)))]
9513   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9514   "neg{l}\t%k0"
9515   [(set_attr "type" "negnot")
9516    (set_attr "mode" "SI")])
9517
9518 (define_expand "neghi2"
9519   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9520                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9521               (clobber (reg:CC FLAGS_REG))])]
9522   "TARGET_HIMODE_MATH"
9523   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9524
9525 (define_insn "*neghi2_1"
9526   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9527         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9528    (clobber (reg:CC FLAGS_REG))]
9529   "ix86_unary_operator_ok (NEG, HImode, operands)"
9530   "neg{w}\t%0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "HI")])
9533
9534 (define_insn "*neghi2_cmpz"
9535   [(set (reg:CCZ FLAGS_REG)
9536         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9537                      (const_int 0)))
9538    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9539         (neg:HI (match_dup 1)))]
9540   "ix86_unary_operator_ok (NEG, HImode, operands)"
9541   "neg{w}\t%0"
9542   [(set_attr "type" "negnot")
9543    (set_attr "mode" "HI")])
9544
9545 (define_expand "negqi2"
9546   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9547                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9548               (clobber (reg:CC FLAGS_REG))])]
9549   "TARGET_QIMODE_MATH"
9550   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9551
9552 (define_insn "*negqi2_1"
9553   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9554         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9555    (clobber (reg:CC FLAGS_REG))]
9556   "ix86_unary_operator_ok (NEG, QImode, operands)"
9557   "neg{b}\t%0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*negqi2_cmpz"
9562   [(set (reg:CCZ FLAGS_REG)
9563         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9564                      (const_int 0)))
9565    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9566         (neg:QI (match_dup 1)))]
9567   "ix86_unary_operator_ok (NEG, QImode, operands)"
9568   "neg{b}\t%0"
9569   [(set_attr "type" "negnot")
9570    (set_attr "mode" "QI")])
9571
9572 ;; Changing of sign for FP values is doable using integer unit too.
9573
9574 (define_expand "negsf2"
9575   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9576         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9577   "TARGET_80387 || TARGET_SSE_MATH"
9578   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9579
9580 (define_expand "abssf2"
9581   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9582         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9583   "TARGET_80387 || TARGET_SSE_MATH"
9584   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9585
9586 (define_insn "*absnegsf2_mixed"
9587   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#fr,x#fr,f#xr,rm#xf")
9588         (match_operator:SF 3 "absneg_operator"
9589           [(match_operand:SF 1 "nonimmediate_operand" "0    ,x#fr,0   ,0")]))
9590    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm   ,0   ,X   ,X"))
9591    (clobber (reg:CC FLAGS_REG))]
9592   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9593    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9594   "#")
9595
9596 (define_insn "*absnegsf2_sse"
9597   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#r,x#r,rm#x")
9598         (match_operator:SF 3 "absneg_operator"
9599           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#r,0")]))
9600    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X"))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "TARGET_SSE_MATH
9603    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9604   "#")
9605
9606 (define_insn "*absnegsf2_i387"
9607   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9608         (match_operator:SF 3 "absneg_operator"
9609           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9610    (use (match_operand 2 "" ""))
9611    (clobber (reg:CC FLAGS_REG))]
9612   "TARGET_80387 && !TARGET_SSE_MATH
9613    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9614   "#")
9615
9616 (define_expand "negdf2"
9617   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9618         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9619   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9620   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9621
9622 (define_expand "absdf2"
9623   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9624         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9625   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9626   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9627
9628 (define_insn "*absnegdf2_mixed"
9629   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#fr,Y#fr,f#Yr,rm#Yf")
9630         (match_operator:DF 3 "absneg_operator"
9631           [(match_operand:DF 1 "nonimmediate_operand" "0    ,Y#fr,0   ,0")]))
9632    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym   ,0   ,X   ,X"))
9633    (clobber (reg:CC FLAGS_REG))]
9634   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9635    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9636   "#")
9637
9638 (define_insn "*absnegdf2_sse"
9639   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#r,Y#r,rm#Y")
9640         (match_operator:DF 3 "absneg_operator"
9641           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#r,0")]))
9642    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X"))
9643    (clobber (reg:CC FLAGS_REG))]
9644   "TARGET_SSE2 && TARGET_SSE_MATH
9645    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9646   "#")
9647
9648 (define_insn "*absnegdf2_i387"
9649   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9650         (match_operator:DF 3 "absneg_operator"
9651           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9652    (use (match_operand 2 "" ""))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9655    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9656   "#")
9657
9658 (define_expand "negxf2"
9659   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9660         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9661   "TARGET_80387"
9662   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9663
9664 (define_expand "absxf2"
9665   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9666         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9667   "TARGET_80387"
9668   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9669
9670 (define_insn "*absnegxf2_i387"
9671   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9672         (match_operator:XF 3 "absneg_operator"
9673           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9674    (use (match_operand 2 "" ""))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "TARGET_80387
9677    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9678   "#")
9679
9680 ;; Splitters for fp abs and neg.
9681
9682 (define_split
9683   [(set (match_operand 0 "fp_register_operand" "")
9684         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9685    (use (match_operand 2 "" ""))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "reload_completed"
9688   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9689
9690 (define_split
9691   [(set (match_operand 0 "register_operand" "")
9692         (match_operator 3 "absneg_operator"
9693           [(match_operand 1 "register_operand" "")]))
9694    (use (match_operand 2 "nonimmediate_operand" ""))
9695    (clobber (reg:CC FLAGS_REG))]
9696   "reload_completed && SSE_REG_P (operands[0])"
9697   [(set (match_dup 0) (match_dup 3))]
9698 {
9699   enum machine_mode mode = GET_MODE (operands[0]);
9700   enum machine_mode vmode = GET_MODE (operands[2]);
9701   rtx tmp;
9702   
9703   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9704   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9705   if (operands_match_p (operands[0], operands[2]))
9706     {
9707       tmp = operands[1];
9708       operands[1] = operands[2];
9709       operands[2] = tmp;
9710     }
9711   if (GET_CODE (operands[3]) == ABS)
9712     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9713   else
9714     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9715   operands[3] = tmp;
9716 })
9717
9718 (define_split
9719   [(set (match_operand:SF 0 "register_operand" "")
9720         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9721    (use (match_operand:V4SF 2 "" ""))
9722    (clobber (reg:CC FLAGS_REG))]
9723   "reload_completed"
9724   [(parallel [(set (match_dup 0) (match_dup 1))
9725               (clobber (reg:CC FLAGS_REG))])]
9726
9727   rtx tmp;
9728   operands[0] = gen_lowpart (SImode, operands[0]);
9729   if (GET_CODE (operands[1]) == ABS)
9730     {
9731       tmp = gen_int_mode (0x7fffffff, SImode);
9732       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9733     }
9734   else
9735     {
9736       tmp = gen_int_mode (0x80000000, SImode);
9737       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9738     }
9739   operands[1] = tmp;
9740 })
9741
9742 (define_split
9743   [(set (match_operand:DF 0 "register_operand" "")
9744         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9745    (use (match_operand 2 "" ""))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "reload_completed"
9748   [(parallel [(set (match_dup 0) (match_dup 1))
9749               (clobber (reg:CC FLAGS_REG))])]
9750 {
9751   rtx tmp;
9752   if (TARGET_64BIT)
9753     {
9754       tmp = gen_lowpart (DImode, operands[0]);
9755       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9756       operands[0] = tmp;
9757
9758       if (GET_CODE (operands[1]) == ABS)
9759         tmp = const0_rtx;
9760       else
9761         tmp = gen_rtx_NOT (DImode, tmp);
9762     }
9763   else
9764     {
9765       operands[0] = gen_highpart (SImode, operands[0]);
9766       if (GET_CODE (operands[1]) == ABS)
9767         {
9768           tmp = gen_int_mode (0x7fffffff, SImode);
9769           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9770         }
9771       else
9772         {
9773           tmp = gen_int_mode (0x80000000, SImode);
9774           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9775         }
9776     }
9777   operands[1] = tmp;
9778 })
9779
9780 (define_split
9781   [(set (match_operand:XF 0 "register_operand" "")
9782         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9783    (use (match_operand 2 "" ""))
9784    (clobber (reg:CC FLAGS_REG))]
9785   "reload_completed"
9786   [(parallel [(set (match_dup 0) (match_dup 1))
9787               (clobber (reg:CC FLAGS_REG))])]
9788 {
9789   rtx tmp;
9790   operands[0] = gen_rtx_REG (SImode,
9791                              true_regnum (operands[0])
9792                              + (TARGET_64BIT ? 1 : 2));
9793   if (GET_CODE (operands[1]) == ABS)
9794     {
9795       tmp = GEN_INT (0x7fff);
9796       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9797     }
9798   else
9799     {
9800       tmp = GEN_INT (0x8000);
9801       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9802     }
9803   operands[1] = tmp;
9804 })
9805
9806 (define_split
9807   [(set (match_operand 0 "memory_operand" "")
9808         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9809    (use (match_operand 2 "" ""))
9810    (clobber (reg:CC FLAGS_REG))]
9811   "reload_completed"
9812   [(parallel [(set (match_dup 0) (match_dup 1))
9813               (clobber (reg:CC FLAGS_REG))])]
9814 {
9815   enum machine_mode mode = GET_MODE (operands[0]);
9816   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9817   rtx tmp;
9818
9819   operands[0] = adjust_address (operands[0], QImode, size - 1);
9820   if (GET_CODE (operands[1]) == ABS)
9821     {
9822       tmp = gen_int_mode (0x7f, QImode);
9823       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9824     }
9825   else
9826     {
9827       tmp = gen_int_mode (0x80, QImode);
9828       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9829     }
9830   operands[1] = tmp;
9831 })
9832
9833 ;; Conditionalize these after reload. If they match before reload, we 
9834 ;; lose the clobber and ability to use integer instructions.
9835
9836 (define_insn "*negsf2_1"
9837   [(set (match_operand:SF 0 "register_operand" "=f")
9838         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9839   "TARGET_80387 && reload_completed"
9840   "fchs"
9841   [(set_attr "type" "fsgn")
9842    (set_attr "mode" "SF")])
9843
9844 (define_insn "*negdf2_1"
9845   [(set (match_operand:DF 0 "register_operand" "=f")
9846         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9847   "TARGET_80387 && reload_completed"
9848   "fchs"
9849   [(set_attr "type" "fsgn")
9850    (set_attr "mode" "DF")])
9851
9852 (define_insn "*negxf2_1"
9853   [(set (match_operand:XF 0 "register_operand" "=f")
9854         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9855   "TARGET_80387 && reload_completed"
9856   "fchs"
9857   [(set_attr "type" "fsgn")
9858    (set_attr "mode" "XF")])
9859
9860 (define_insn "*abssf2_1"
9861   [(set (match_operand:SF 0 "register_operand" "=f")
9862         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9863   "TARGET_80387 && reload_completed"
9864   "fabs"
9865   [(set_attr "type" "fsgn")
9866    (set_attr "mode" "SF")])
9867
9868 (define_insn "*absdf2_1"
9869   [(set (match_operand:DF 0 "register_operand" "=f")
9870         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9871   "TARGET_80387 && reload_completed"
9872   "fabs"
9873   [(set_attr "type" "fsgn")
9874    (set_attr "mode" "DF")])
9875
9876 (define_insn "*absxf2_1"
9877   [(set (match_operand:XF 0 "register_operand" "=f")
9878         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9879   "TARGET_80387 && reload_completed"
9880   "fabs"
9881   [(set_attr "type" "fsgn")
9882    (set_attr "mode" "DF")])
9883
9884 (define_insn "*negextendsfdf2"
9885   [(set (match_operand:DF 0 "register_operand" "=f")
9886         (neg:DF (float_extend:DF
9887                   (match_operand:SF 1 "register_operand" "0"))))]
9888   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9889   "fchs"
9890   [(set_attr "type" "fsgn")
9891    (set_attr "mode" "DF")])
9892
9893 (define_insn "*negextenddfxf2"
9894   [(set (match_operand:XF 0 "register_operand" "=f")
9895         (neg:XF (float_extend:XF
9896                   (match_operand:DF 1 "register_operand" "0"))))]
9897   "TARGET_80387"
9898   "fchs"
9899   [(set_attr "type" "fsgn")
9900    (set_attr "mode" "XF")])
9901
9902 (define_insn "*negextendsfxf2"
9903   [(set (match_operand:XF 0 "register_operand" "=f")
9904         (neg:XF (float_extend:XF
9905                   (match_operand:SF 1 "register_operand" "0"))))]
9906   "TARGET_80387"
9907   "fchs"
9908   [(set_attr "type" "fsgn")
9909    (set_attr "mode" "XF")])
9910
9911 (define_insn "*absextendsfdf2"
9912   [(set (match_operand:DF 0 "register_operand" "=f")
9913         (abs:DF (float_extend:DF
9914                   (match_operand:SF 1 "register_operand" "0"))))]
9915   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9916   "fabs"
9917   [(set_attr "type" "fsgn")
9918    (set_attr "mode" "DF")])
9919
9920 (define_insn "*absextenddfxf2"
9921   [(set (match_operand:XF 0 "register_operand" "=f")
9922         (abs:XF (float_extend:XF
9923           (match_operand:DF 1 "register_operand" "0"))))]
9924   "TARGET_80387"
9925   "fabs"
9926   [(set_attr "type" "fsgn")
9927    (set_attr "mode" "XF")])
9928
9929 (define_insn "*absextendsfxf2"
9930   [(set (match_operand:XF 0 "register_operand" "=f")
9931         (abs:XF (float_extend:XF
9932           (match_operand:SF 1 "register_operand" "0"))))]
9933   "TARGET_80387"
9934   "fabs"
9935   [(set_attr "type" "fsgn")
9936    (set_attr "mode" "XF")])
9937 \f
9938 ;; One complement instructions
9939
9940 (define_expand "one_cmpldi2"
9941   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9942         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9943   "TARGET_64BIT"
9944   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9945
9946 (define_insn "*one_cmpldi2_1_rex64"
9947   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9948         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9949   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9950   "not{q}\t%0"
9951   [(set_attr "type" "negnot")
9952    (set_attr "mode" "DI")])
9953
9954 (define_insn "*one_cmpldi2_2_rex64"
9955   [(set (reg FLAGS_REG)
9956         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9957                  (const_int 0)))
9958    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9959         (not:DI (match_dup 1)))]
9960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9961    && ix86_unary_operator_ok (NOT, DImode, operands)"
9962   "#"
9963   [(set_attr "type" "alu1")
9964    (set_attr "mode" "DI")])
9965
9966 (define_split
9967   [(set (match_operand 0 "flags_reg_operand" "")
9968         (match_operator 2 "compare_operator"
9969           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9970            (const_int 0)]))
9971    (set (match_operand:DI 1 "nonimmediate_operand" "")
9972         (not:DI (match_dup 3)))]
9973   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9974   [(parallel [(set (match_dup 0)
9975                    (match_op_dup 2
9976                      [(xor:DI (match_dup 3) (const_int -1))
9977                       (const_int 0)]))
9978               (set (match_dup 1)
9979                    (xor:DI (match_dup 3) (const_int -1)))])]
9980   "")
9981
9982 (define_expand "one_cmplsi2"
9983   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9984         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9985   ""
9986   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9987
9988 (define_insn "*one_cmplsi2_1"
9989   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9990         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9991   "ix86_unary_operator_ok (NOT, SImode, operands)"
9992   "not{l}\t%0"
9993   [(set_attr "type" "negnot")
9994    (set_attr "mode" "SI")])
9995
9996 ;; ??? Currently never generated - xor is used instead.
9997 (define_insn "*one_cmplsi2_1_zext"
9998   [(set (match_operand:DI 0 "register_operand" "=r")
9999         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10000   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10001   "not{l}\t%k0"
10002   [(set_attr "type" "negnot")
10003    (set_attr "mode" "SI")])
10004
10005 (define_insn "*one_cmplsi2_2"
10006   [(set (reg FLAGS_REG)
10007         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10008                  (const_int 0)))
10009    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10010         (not:SI (match_dup 1)))]
10011   "ix86_match_ccmode (insn, CCNOmode)
10012    && ix86_unary_operator_ok (NOT, SImode, operands)"
10013   "#"
10014   [(set_attr "type" "alu1")
10015    (set_attr "mode" "SI")])
10016
10017 (define_split
10018   [(set (match_operand 0 "flags_reg_operand" "")
10019         (match_operator 2 "compare_operator"
10020           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10021            (const_int 0)]))
10022    (set (match_operand:SI 1 "nonimmediate_operand" "")
10023         (not:SI (match_dup 3)))]
10024   "ix86_match_ccmode (insn, CCNOmode)"
10025   [(parallel [(set (match_dup 0)
10026                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10027                                     (const_int 0)]))
10028               (set (match_dup 1)
10029                    (xor:SI (match_dup 3) (const_int -1)))])]
10030   "")
10031
10032 ;; ??? Currently never generated - xor is used instead.
10033 (define_insn "*one_cmplsi2_2_zext"
10034   [(set (reg FLAGS_REG)
10035         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10036                  (const_int 0)))
10037    (set (match_operand:DI 0 "register_operand" "=r")
10038         (zero_extend:DI (not:SI (match_dup 1))))]
10039   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10040    && ix86_unary_operator_ok (NOT, SImode, operands)"
10041   "#"
10042   [(set_attr "type" "alu1")
10043    (set_attr "mode" "SI")])
10044
10045 (define_split
10046   [(set (match_operand 0 "flags_reg_operand" "")
10047         (match_operator 2 "compare_operator"
10048           [(not:SI (match_operand:SI 3 "register_operand" ""))
10049            (const_int 0)]))
10050    (set (match_operand:DI 1 "register_operand" "")
10051         (zero_extend:DI (not:SI (match_dup 3))))]
10052   "ix86_match_ccmode (insn, CCNOmode)"
10053   [(parallel [(set (match_dup 0)
10054                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10055                                     (const_int 0)]))
10056               (set (match_dup 1)
10057                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10058   "")
10059
10060 (define_expand "one_cmplhi2"
10061   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10062         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10063   "TARGET_HIMODE_MATH"
10064   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10065
10066 (define_insn "*one_cmplhi2_1"
10067   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10068         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10069   "ix86_unary_operator_ok (NOT, HImode, operands)"
10070   "not{w}\t%0"
10071   [(set_attr "type" "negnot")
10072    (set_attr "mode" "HI")])
10073
10074 (define_insn "*one_cmplhi2_2"
10075   [(set (reg FLAGS_REG)
10076         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10077                  (const_int 0)))
10078    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10079         (not:HI (match_dup 1)))]
10080   "ix86_match_ccmode (insn, CCNOmode)
10081    && ix86_unary_operator_ok (NEG, HImode, operands)"
10082   "#"
10083   [(set_attr "type" "alu1")
10084    (set_attr "mode" "HI")])
10085
10086 (define_split
10087   [(set (match_operand 0 "flags_reg_operand" "")
10088         (match_operator 2 "compare_operator"
10089           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10090            (const_int 0)]))
10091    (set (match_operand:HI 1 "nonimmediate_operand" "")
10092         (not:HI (match_dup 3)))]
10093   "ix86_match_ccmode (insn, CCNOmode)"
10094   [(parallel [(set (match_dup 0)
10095                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10096                                     (const_int 0)]))
10097               (set (match_dup 1)
10098                    (xor:HI (match_dup 3) (const_int -1)))])]
10099   "")
10100
10101 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10102 (define_expand "one_cmplqi2"
10103   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10104         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10105   "TARGET_QIMODE_MATH"
10106   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10107
10108 (define_insn "*one_cmplqi2_1"
10109   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10110         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10111   "ix86_unary_operator_ok (NOT, QImode, operands)"
10112   "@
10113    not{b}\t%0
10114    not{l}\t%k0"
10115   [(set_attr "type" "negnot")
10116    (set_attr "mode" "QI,SI")])
10117
10118 (define_insn "*one_cmplqi2_2"
10119   [(set (reg FLAGS_REG)
10120         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10121                  (const_int 0)))
10122    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10123         (not:QI (match_dup 1)))]
10124   "ix86_match_ccmode (insn, CCNOmode)
10125    && ix86_unary_operator_ok (NOT, QImode, operands)"
10126   "#"
10127   [(set_attr "type" "alu1")
10128    (set_attr "mode" "QI")])
10129
10130 (define_split
10131   [(set (match_operand 0 "flags_reg_operand" "")
10132         (match_operator 2 "compare_operator"
10133           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10134            (const_int 0)]))
10135    (set (match_operand:QI 1 "nonimmediate_operand" "")
10136         (not:QI (match_dup 3)))]
10137   "ix86_match_ccmode (insn, CCNOmode)"
10138   [(parallel [(set (match_dup 0)
10139                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10140                                     (const_int 0)]))
10141               (set (match_dup 1)
10142                    (xor:QI (match_dup 3) (const_int -1)))])]
10143   "")
10144 \f
10145 ;; Arithmetic shift instructions
10146
10147 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10148 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10149 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10150 ;; from the assembler input.
10151 ;;
10152 ;; This instruction shifts the target reg/mem as usual, but instead of
10153 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10154 ;; is a left shift double, bits are taken from the high order bits of
10155 ;; reg, else if the insn is a shift right double, bits are taken from the
10156 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10157 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10158 ;;
10159 ;; Since sh[lr]d does not change the `reg' operand, that is done
10160 ;; separately, making all shifts emit pairs of shift double and normal
10161 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10162 ;; support a 63 bit shift, each shift where the count is in a reg expands
10163 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10164 ;;
10165 ;; If the shift count is a constant, we need never emit more than one
10166 ;; shift pair, instead using moves and sign extension for counts greater
10167 ;; than 31.
10168
10169 (define_expand "ashldi3"
10170   [(set (match_operand:DI 0 "shiftdi_operand" "")
10171         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10172                    (match_operand:QI 2 "nonmemory_operand" "")))]
10173   ""
10174   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10175
10176 (define_insn "*ashldi3_1_rex64"
10177   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10178         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10179                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10182 {
10183   switch (get_attr_type (insn))
10184     {
10185     case TYPE_ALU:
10186       if (operands[2] != const1_rtx)
10187         abort ();
10188       if (!rtx_equal_p (operands[0], operands[1]))
10189         abort ();
10190       return "add{q}\t{%0, %0|%0, %0}";
10191
10192     case TYPE_LEA:
10193       if (GET_CODE (operands[2]) != CONST_INT
10194           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10195         abort ();
10196       operands[1] = gen_rtx_MULT (DImode, operands[1],
10197                                   GEN_INT (1 << INTVAL (operands[2])));
10198       return "lea{q}\t{%a1, %0|%0, %a1}";
10199
10200     default:
10201       if (REG_P (operands[2]))
10202         return "sal{q}\t{%b2, %0|%0, %b2}";
10203       else if (operands[2] == const1_rtx
10204                && (TARGET_SHIFT1 || optimize_size))
10205         return "sal{q}\t%0";
10206       else
10207         return "sal{q}\t{%2, %0|%0, %2}";
10208     }
10209 }
10210   [(set (attr "type")
10211      (cond [(eq_attr "alternative" "1")
10212               (const_string "lea")
10213             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10214                           (const_int 0))
10215                       (match_operand 0 "register_operand" ""))
10216                  (match_operand 2 "const1_operand" ""))
10217               (const_string "alu")
10218            ]
10219            (const_string "ishift")))
10220    (set_attr "mode" "DI")])
10221
10222 ;; Convert lea to the lea pattern to avoid flags dependency.
10223 (define_split
10224   [(set (match_operand:DI 0 "register_operand" "")
10225         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10226                    (match_operand:QI 2 "immediate_operand" "")))
10227    (clobber (reg:CC FLAGS_REG))]
10228   "TARGET_64BIT && reload_completed
10229    && true_regnum (operands[0]) != true_regnum (operands[1])"
10230   [(set (match_dup 0)
10231         (mult:DI (match_dup 1)
10232                  (match_dup 2)))]
10233   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10234
10235 ;; This pattern can't accept a variable shift count, since shifts by
10236 ;; zero don't affect the flags.  We assume that shifts by constant
10237 ;; zero are optimized away.
10238 (define_insn "*ashldi3_cmp_rex64"
10239   [(set (reg FLAGS_REG)
10240         (compare
10241           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10242                      (match_operand:QI 2 "immediate_operand" "e"))
10243           (const_int 0)))
10244    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10245         (ashift:DI (match_dup 1) (match_dup 2)))]
10246   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10247    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10248 {
10249   switch (get_attr_type (insn))
10250     {
10251     case TYPE_ALU:
10252       if (operands[2] != const1_rtx)
10253         abort ();
10254       return "add{q}\t{%0, %0|%0, %0}";
10255
10256     default:
10257       if (REG_P (operands[2]))
10258         return "sal{q}\t{%b2, %0|%0, %b2}";
10259       else if (operands[2] == const1_rtx
10260                && (TARGET_SHIFT1 || optimize_size))
10261         return "sal{q}\t%0";
10262       else
10263         return "sal{q}\t{%2, %0|%0, %2}";
10264     }
10265 }
10266   [(set (attr "type")
10267      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10268                           (const_int 0))
10269                       (match_operand 0 "register_operand" ""))
10270                  (match_operand 2 "const1_operand" ""))
10271               (const_string "alu")
10272            ]
10273            (const_string "ishift")))
10274    (set_attr "mode" "DI")])
10275
10276 (define_insn "*ashldi3_1"
10277   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10278         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10279                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "!TARGET_64BIT"
10282   "#"
10283   [(set_attr "type" "multi")])
10284
10285 ;; By default we don't ask for a scratch register, because when DImode
10286 ;; values are manipulated, registers are already at a premium.  But if
10287 ;; we have one handy, we won't turn it away.
10288 (define_peephole2
10289   [(match_scratch:SI 3 "r")
10290    (parallel [(set (match_operand:DI 0 "register_operand" "")
10291                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10292                               (match_operand:QI 2 "nonmemory_operand" "")))
10293               (clobber (reg:CC FLAGS_REG))])
10294    (match_dup 3)]
10295   "!TARGET_64BIT && TARGET_CMOVE"
10296   [(const_int 0)]
10297   "ix86_split_ashldi (operands, operands[3]); DONE;")
10298
10299 (define_split
10300   [(set (match_operand:DI 0 "register_operand" "")
10301         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10302                    (match_operand:QI 2 "nonmemory_operand" "")))
10303    (clobber (reg:CC FLAGS_REG))]
10304   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10305   [(const_int 0)]
10306   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10307
10308 (define_insn "x86_shld_1"
10309   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10310         (ior:SI (ashift:SI (match_dup 0)
10311                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10312                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10313                   (minus:QI (const_int 32) (match_dup 2)))))
10314    (clobber (reg:CC FLAGS_REG))]
10315   ""
10316   "@
10317    shld{l}\t{%2, %1, %0|%0, %1, %2}
10318    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10319   [(set_attr "type" "ishift")
10320    (set_attr "prefix_0f" "1")
10321    (set_attr "mode" "SI")
10322    (set_attr "pent_pair" "np")
10323    (set_attr "athlon_decode" "vector")])
10324
10325 (define_expand "x86_shift_adj_1"
10326   [(set (reg:CCZ FLAGS_REG)
10327         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10328                              (const_int 32))
10329                      (const_int 0)))
10330    (set (match_operand:SI 0 "register_operand" "")
10331         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10332                          (match_operand:SI 1 "register_operand" "")
10333                          (match_dup 0)))
10334    (set (match_dup 1)
10335         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10336                          (match_operand:SI 3 "register_operand" "r")
10337                          (match_dup 1)))]
10338   "TARGET_CMOVE"
10339   "")
10340
10341 (define_expand "x86_shift_adj_2"
10342   [(use (match_operand:SI 0 "register_operand" ""))
10343    (use (match_operand:SI 1 "register_operand" ""))
10344    (use (match_operand:QI 2 "register_operand" ""))]
10345   ""
10346 {
10347   rtx label = gen_label_rtx ();
10348   rtx tmp;
10349
10350   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10351
10352   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10353   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10354   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10355                               gen_rtx_LABEL_REF (VOIDmode, label),
10356                               pc_rtx);
10357   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10358   JUMP_LABEL (tmp) = label;
10359
10360   emit_move_insn (operands[0], operands[1]);
10361   ix86_expand_clear (operands[1]);
10362
10363   emit_label (label);
10364   LABEL_NUSES (label) = 1;
10365
10366   DONE;
10367 })
10368
10369 (define_expand "ashlsi3"
10370   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10371         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10372                    (match_operand:QI 2 "nonmemory_operand" "")))
10373    (clobber (reg:CC FLAGS_REG))]
10374   ""
10375   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10376
10377 (define_insn "*ashlsi3_1"
10378   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10379         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10380                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10381    (clobber (reg:CC FLAGS_REG))]
10382   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10383 {
10384   switch (get_attr_type (insn))
10385     {
10386     case TYPE_ALU:
10387       if (operands[2] != const1_rtx)
10388         abort ();
10389       if (!rtx_equal_p (operands[0], operands[1]))
10390         abort ();
10391       return "add{l}\t{%0, %0|%0, %0}";
10392
10393     case TYPE_LEA:
10394       return "#";
10395
10396     default:
10397       if (REG_P (operands[2]))
10398         return "sal{l}\t{%b2, %0|%0, %b2}";
10399       else if (operands[2] == const1_rtx
10400                && (TARGET_SHIFT1 || optimize_size))
10401         return "sal{l}\t%0";
10402       else
10403         return "sal{l}\t{%2, %0|%0, %2}";
10404     }
10405 }
10406   [(set (attr "type")
10407      (cond [(eq_attr "alternative" "1")
10408               (const_string "lea")
10409             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10410                           (const_int 0))
10411                       (match_operand 0 "register_operand" ""))
10412                  (match_operand 2 "const1_operand" ""))
10413               (const_string "alu")
10414            ]
10415            (const_string "ishift")))
10416    (set_attr "mode" "SI")])
10417
10418 ;; Convert lea to the lea pattern to avoid flags dependency.
10419 (define_split
10420   [(set (match_operand 0 "register_operand" "")
10421         (ashift (match_operand 1 "index_register_operand" "")
10422                 (match_operand:QI 2 "const_int_operand" "")))
10423    (clobber (reg:CC FLAGS_REG))]
10424   "reload_completed
10425    && true_regnum (operands[0]) != true_regnum (operands[1])
10426    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10427   [(const_int 0)]
10428 {
10429   rtx pat;
10430   enum machine_mode mode = GET_MODE (operands[0]);
10431
10432   if (GET_MODE_SIZE (mode) < 4)
10433     operands[0] = gen_lowpart (SImode, operands[0]);
10434   if (mode != Pmode)
10435     operands[1] = gen_lowpart (Pmode, operands[1]);
10436   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10437
10438   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10439   if (Pmode != SImode)
10440     pat = gen_rtx_SUBREG (SImode, pat, 0);
10441   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10442   DONE;
10443 })
10444
10445 ;; Rare case of shifting RSP is handled by generating move and shift
10446 (define_split
10447   [(set (match_operand 0 "register_operand" "")
10448         (ashift (match_operand 1 "register_operand" "")
10449                 (match_operand:QI 2 "const_int_operand" "")))
10450    (clobber (reg:CC FLAGS_REG))]
10451   "reload_completed
10452    && true_regnum (operands[0]) != true_regnum (operands[1])"
10453   [(const_int 0)]
10454 {
10455   rtx pat, clob;
10456   emit_move_insn (operands[1], operands[0]);
10457   pat = gen_rtx_SET (VOIDmode, operands[0],
10458                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10459                                      operands[0], operands[2]));
10460   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10461   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10462   DONE;
10463 })
10464
10465 (define_insn "*ashlsi3_1_zext"
10466   [(set (match_operand:DI 0 "register_operand" "=r,r")
10467         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10468                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10469    (clobber (reg:CC FLAGS_REG))]
10470   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10471 {
10472   switch (get_attr_type (insn))
10473     {
10474     case TYPE_ALU:
10475       if (operands[2] != const1_rtx)
10476         abort ();
10477       return "add{l}\t{%k0, %k0|%k0, %k0}";
10478
10479     case TYPE_LEA:
10480       return "#";
10481
10482     default:
10483       if (REG_P (operands[2]))
10484         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10485       else if (operands[2] == const1_rtx
10486                && (TARGET_SHIFT1 || optimize_size))
10487         return "sal{l}\t%k0";
10488       else
10489         return "sal{l}\t{%2, %k0|%k0, %2}";
10490     }
10491 }
10492   [(set (attr "type")
10493      (cond [(eq_attr "alternative" "1")
10494               (const_string "lea")
10495             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10496                      (const_int 0))
10497                  (match_operand 2 "const1_operand" ""))
10498               (const_string "alu")
10499            ]
10500            (const_string "ishift")))
10501    (set_attr "mode" "SI")])
10502
10503 ;; Convert lea to the lea pattern to avoid flags dependency.
10504 (define_split
10505   [(set (match_operand:DI 0 "register_operand" "")
10506         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10507                                 (match_operand:QI 2 "const_int_operand" ""))))
10508    (clobber (reg:CC FLAGS_REG))]
10509   "TARGET_64BIT && reload_completed
10510    && true_regnum (operands[0]) != true_regnum (operands[1])"
10511   [(set (match_dup 0) (zero_extend:DI
10512                         (subreg:SI (mult:SI (match_dup 1)
10513                                             (match_dup 2)) 0)))]
10514 {
10515   operands[1] = gen_lowpart (Pmode, operands[1]);
10516   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10517 })
10518
10519 ;; This pattern can't accept a variable shift count, since shifts by
10520 ;; zero don't affect the flags.  We assume that shifts by constant
10521 ;; zero are optimized away.
10522 (define_insn "*ashlsi3_cmp"
10523   [(set (reg FLAGS_REG)
10524         (compare
10525           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10526                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10527           (const_int 0)))
10528    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10529         (ashift:SI (match_dup 1) (match_dup 2)))]
10530   "ix86_match_ccmode (insn, CCGOCmode)
10531    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10532 {
10533   switch (get_attr_type (insn))
10534     {
10535     case TYPE_ALU:
10536       if (operands[2] != const1_rtx)
10537         abort ();
10538       return "add{l}\t{%0, %0|%0, %0}";
10539
10540     default:
10541       if (REG_P (operands[2]))
10542         return "sal{l}\t{%b2, %0|%0, %b2}";
10543       else if (operands[2] == const1_rtx
10544                && (TARGET_SHIFT1 || optimize_size))
10545         return "sal{l}\t%0";
10546       else
10547         return "sal{l}\t{%2, %0|%0, %2}";
10548     }
10549 }
10550   [(set (attr "type")
10551      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10552                           (const_int 0))
10553                       (match_operand 0 "register_operand" ""))
10554                  (match_operand 2 "const1_operand" ""))
10555               (const_string "alu")
10556            ]
10557            (const_string "ishift")))
10558    (set_attr "mode" "SI")])
10559
10560 (define_insn "*ashlsi3_cmp_zext"
10561   [(set (reg FLAGS_REG)
10562         (compare
10563           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10564                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10565           (const_int 0)))
10566    (set (match_operand:DI 0 "register_operand" "=r")
10567         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10568   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10569    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10570 {
10571   switch (get_attr_type (insn))
10572     {
10573     case TYPE_ALU:
10574       if (operands[2] != const1_rtx)
10575         abort ();
10576       return "add{l}\t{%k0, %k0|%k0, %k0}";
10577
10578     default:
10579       if (REG_P (operands[2]))
10580         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10581       else if (operands[2] == const1_rtx
10582                && (TARGET_SHIFT1 || optimize_size))
10583         return "sal{l}\t%k0";
10584       else
10585         return "sal{l}\t{%2, %k0|%k0, %2}";
10586     }
10587 }
10588   [(set (attr "type")
10589      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10590                      (const_int 0))
10591                  (match_operand 2 "const1_operand" ""))
10592               (const_string "alu")
10593            ]
10594            (const_string "ishift")))
10595    (set_attr "mode" "SI")])
10596
10597 (define_expand "ashlhi3"
10598   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10599         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10600                    (match_operand:QI 2 "nonmemory_operand" "")))
10601    (clobber (reg:CC FLAGS_REG))]
10602   "TARGET_HIMODE_MATH"
10603   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10604
10605 (define_insn "*ashlhi3_1_lea"
10606   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10607         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10608                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10609    (clobber (reg:CC FLAGS_REG))]
10610   "!TARGET_PARTIAL_REG_STALL
10611    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10612 {
10613   switch (get_attr_type (insn))
10614     {
10615     case TYPE_LEA:
10616       return "#";
10617     case TYPE_ALU:
10618       if (operands[2] != const1_rtx)
10619         abort ();
10620       return "add{w}\t{%0, %0|%0, %0}";
10621
10622     default:
10623       if (REG_P (operands[2]))
10624         return "sal{w}\t{%b2, %0|%0, %b2}";
10625       else if (operands[2] == const1_rtx
10626                && (TARGET_SHIFT1 || optimize_size))
10627         return "sal{w}\t%0";
10628       else
10629         return "sal{w}\t{%2, %0|%0, %2}";
10630     }
10631 }
10632   [(set (attr "type")
10633      (cond [(eq_attr "alternative" "1")
10634               (const_string "lea")
10635             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10636                           (const_int 0))
10637                       (match_operand 0 "register_operand" ""))
10638                  (match_operand 2 "const1_operand" ""))
10639               (const_string "alu")
10640            ]
10641            (const_string "ishift")))
10642    (set_attr "mode" "HI,SI")])
10643
10644 (define_insn "*ashlhi3_1"
10645   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10646         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10647                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10648    (clobber (reg:CC FLAGS_REG))]
10649   "TARGET_PARTIAL_REG_STALL
10650    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10651 {
10652   switch (get_attr_type (insn))
10653     {
10654     case TYPE_ALU:
10655       if (operands[2] != const1_rtx)
10656         abort ();
10657       return "add{w}\t{%0, %0|%0, %0}";
10658
10659     default:
10660       if (REG_P (operands[2]))
10661         return "sal{w}\t{%b2, %0|%0, %b2}";
10662       else if (operands[2] == const1_rtx
10663                && (TARGET_SHIFT1 || optimize_size))
10664         return "sal{w}\t%0";
10665       else
10666         return "sal{w}\t{%2, %0|%0, %2}";
10667     }
10668 }
10669   [(set (attr "type")
10670      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10671                           (const_int 0))
10672                       (match_operand 0 "register_operand" ""))
10673                  (match_operand 2 "const1_operand" ""))
10674               (const_string "alu")
10675            ]
10676            (const_string "ishift")))
10677    (set_attr "mode" "HI")])
10678
10679 ;; This pattern can't accept a variable shift count, since shifts by
10680 ;; zero don't affect the flags.  We assume that shifts by constant
10681 ;; zero are optimized away.
10682 (define_insn "*ashlhi3_cmp"
10683   [(set (reg FLAGS_REG)
10684         (compare
10685           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10686                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10687           (const_int 0)))
10688    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10689         (ashift:HI (match_dup 1) (match_dup 2)))]
10690   "ix86_match_ccmode (insn, CCGOCmode)
10691    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10692 {
10693   switch (get_attr_type (insn))
10694     {
10695     case TYPE_ALU:
10696       if (operands[2] != const1_rtx)
10697         abort ();
10698       return "add{w}\t{%0, %0|%0, %0}";
10699
10700     default:
10701       if (REG_P (operands[2]))
10702         return "sal{w}\t{%b2, %0|%0, %b2}";
10703       else if (operands[2] == const1_rtx
10704                && (TARGET_SHIFT1 || optimize_size))
10705         return "sal{w}\t%0";
10706       else
10707         return "sal{w}\t{%2, %0|%0, %2}";
10708     }
10709 }
10710   [(set (attr "type")
10711      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10712                           (const_int 0))
10713                       (match_operand 0 "register_operand" ""))
10714                  (match_operand 2 "const1_operand" ""))
10715               (const_string "alu")
10716            ]
10717            (const_string "ishift")))
10718    (set_attr "mode" "HI")])
10719
10720 (define_expand "ashlqi3"
10721   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10722         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10723                    (match_operand:QI 2 "nonmemory_operand" "")))
10724    (clobber (reg:CC FLAGS_REG))]
10725   "TARGET_QIMODE_MATH"
10726   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10727
10728 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10729
10730 (define_insn "*ashlqi3_1_lea"
10731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10732         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10733                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10734    (clobber (reg:CC FLAGS_REG))]
10735   "!TARGET_PARTIAL_REG_STALL
10736    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10737 {
10738   switch (get_attr_type (insn))
10739     {
10740     case TYPE_LEA:
10741       return "#";
10742     case TYPE_ALU:
10743       if (operands[2] != const1_rtx)
10744         abort ();
10745       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10746         return "add{l}\t{%k0, %k0|%k0, %k0}";
10747       else
10748         return "add{b}\t{%0, %0|%0, %0}";
10749
10750     default:
10751       if (REG_P (operands[2]))
10752         {
10753           if (get_attr_mode (insn) == MODE_SI)
10754             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10755           else
10756             return "sal{b}\t{%b2, %0|%0, %b2}";
10757         }
10758       else if (operands[2] == const1_rtx
10759                && (TARGET_SHIFT1 || optimize_size))
10760         {
10761           if (get_attr_mode (insn) == MODE_SI)
10762             return "sal{l}\t%0";
10763           else
10764             return "sal{b}\t%0";
10765         }
10766       else
10767         {
10768           if (get_attr_mode (insn) == MODE_SI)
10769             return "sal{l}\t{%2, %k0|%k0, %2}";
10770           else
10771             return "sal{b}\t{%2, %0|%0, %2}";
10772         }
10773     }
10774 }
10775   [(set (attr "type")
10776      (cond [(eq_attr "alternative" "2")
10777               (const_string "lea")
10778             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10779                           (const_int 0))
10780                       (match_operand 0 "register_operand" ""))
10781                  (match_operand 2 "const1_operand" ""))
10782               (const_string "alu")
10783            ]
10784            (const_string "ishift")))
10785    (set_attr "mode" "QI,SI,SI")])
10786
10787 (define_insn "*ashlqi3_1"
10788   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10789         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10790                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10791    (clobber (reg:CC FLAGS_REG))]
10792   "TARGET_PARTIAL_REG_STALL
10793    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10794 {
10795   switch (get_attr_type (insn))
10796     {
10797     case TYPE_ALU:
10798       if (operands[2] != const1_rtx)
10799         abort ();
10800       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10801         return "add{l}\t{%k0, %k0|%k0, %k0}";
10802       else
10803         return "add{b}\t{%0, %0|%0, %0}";
10804
10805     default:
10806       if (REG_P (operands[2]))
10807         {
10808           if (get_attr_mode (insn) == MODE_SI)
10809             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10810           else
10811             return "sal{b}\t{%b2, %0|%0, %b2}";
10812         }
10813       else if (operands[2] == const1_rtx
10814                && (TARGET_SHIFT1 || optimize_size))
10815         {
10816           if (get_attr_mode (insn) == MODE_SI)
10817             return "sal{l}\t%0";
10818           else
10819             return "sal{b}\t%0";
10820         }
10821       else
10822         {
10823           if (get_attr_mode (insn) == MODE_SI)
10824             return "sal{l}\t{%2, %k0|%k0, %2}";
10825           else
10826             return "sal{b}\t{%2, %0|%0, %2}";
10827         }
10828     }
10829 }
10830   [(set (attr "type")
10831      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10832                           (const_int 0))
10833                       (match_operand 0 "register_operand" ""))
10834                  (match_operand 2 "const1_operand" ""))
10835               (const_string "alu")
10836            ]
10837            (const_string "ishift")))
10838    (set_attr "mode" "QI,SI")])
10839
10840 ;; This pattern can't accept a variable shift count, since shifts by
10841 ;; zero don't affect the flags.  We assume that shifts by constant
10842 ;; zero are optimized away.
10843 (define_insn "*ashlqi3_cmp"
10844   [(set (reg FLAGS_REG)
10845         (compare
10846           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10847                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10848           (const_int 0)))
10849    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10850         (ashift:QI (match_dup 1) (match_dup 2)))]
10851   "ix86_match_ccmode (insn, CCGOCmode)
10852    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10853 {
10854   switch (get_attr_type (insn))
10855     {
10856     case TYPE_ALU:
10857       if (operands[2] != const1_rtx)
10858         abort ();
10859       return "add{b}\t{%0, %0|%0, %0}";
10860
10861     default:
10862       if (REG_P (operands[2]))
10863         return "sal{b}\t{%b2, %0|%0, %b2}";
10864       else if (operands[2] == const1_rtx
10865                && (TARGET_SHIFT1 || optimize_size))
10866         return "sal{b}\t%0";
10867       else
10868         return "sal{b}\t{%2, %0|%0, %2}";
10869     }
10870 }
10871   [(set (attr "type")
10872      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10873                           (const_int 0))
10874                       (match_operand 0 "register_operand" ""))
10875                  (match_operand 2 "const1_operand" ""))
10876               (const_string "alu")
10877            ]
10878            (const_string "ishift")))
10879    (set_attr "mode" "QI")])
10880
10881 ;; See comment above `ashldi3' about how this works.
10882
10883 (define_expand "ashrdi3"
10884   [(set (match_operand:DI 0 "shiftdi_operand" "")
10885         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10886                      (match_operand:QI 2 "nonmemory_operand" "")))]
10887   ""
10888   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10889
10890 (define_insn "*ashrdi3_63_rex64"
10891   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10892         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10893                      (match_operand:DI 2 "const_int_operand" "i,i")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_64BIT && INTVAL (operands[2]) == 63
10896    && (TARGET_USE_CLTD || optimize_size)
10897    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10898   "@
10899    {cqto|cqo}
10900    sar{q}\t{%2, %0|%0, %2}"
10901   [(set_attr "type" "imovx,ishift")
10902    (set_attr "prefix_0f" "0,*")
10903    (set_attr "length_immediate" "0,*")
10904    (set_attr "modrm" "0,1")
10905    (set_attr "mode" "DI")])
10906
10907 (define_insn "*ashrdi3_1_one_bit_rex64"
10908   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10909         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10910                      (match_operand:QI 2 "const1_operand" "")))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10913    && (TARGET_SHIFT1 || optimize_size)"
10914   "sar{q}\t%0"
10915   [(set_attr "type" "ishift")
10916    (set (attr "length") 
10917      (if_then_else (match_operand:DI 0 "register_operand" "") 
10918         (const_string "2")
10919         (const_string "*")))])
10920
10921 (define_insn "*ashrdi3_1_rex64"
10922   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10923         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10924                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10925    (clobber (reg:CC FLAGS_REG))]
10926   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10927   "@
10928    sar{q}\t{%2, %0|%0, %2}
10929    sar{q}\t{%b2, %0|%0, %b2}"
10930   [(set_attr "type" "ishift")
10931    (set_attr "mode" "DI")])
10932
10933 ;; This pattern can't accept a variable shift count, since shifts by
10934 ;; zero don't affect the flags.  We assume that shifts by constant
10935 ;; zero are optimized away.
10936 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10937   [(set (reg FLAGS_REG)
10938         (compare
10939           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10940                        (match_operand:QI 2 "const1_operand" ""))
10941           (const_int 0)))
10942    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10943         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10944   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10945    && (TARGET_SHIFT1 || optimize_size)
10946    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10947   "sar{q}\t%0"
10948   [(set_attr "type" "ishift")
10949    (set (attr "length") 
10950      (if_then_else (match_operand:DI 0 "register_operand" "") 
10951         (const_string "2")
10952         (const_string "*")))])
10953
10954 ;; This pattern can't accept a variable shift count, since shifts by
10955 ;; zero don't affect the flags.  We assume that shifts by constant
10956 ;; zero are optimized away.
10957 (define_insn "*ashrdi3_cmp_rex64"
10958   [(set (reg FLAGS_REG)
10959         (compare
10960           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10961                        (match_operand:QI 2 "const_int_operand" "n"))
10962           (const_int 0)))
10963    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10964         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10965   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10966    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10967   "sar{q}\t{%2, %0|%0, %2}"
10968   [(set_attr "type" "ishift")
10969    (set_attr "mode" "DI")])
10970
10971 (define_insn "*ashrdi3_1"
10972   [(set (match_operand:DI 0 "register_operand" "=r")
10973         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10974                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10975    (clobber (reg:CC FLAGS_REG))]
10976   "!TARGET_64BIT"
10977   "#"
10978   [(set_attr "type" "multi")])
10979
10980 ;; By default we don't ask for a scratch register, because when DImode
10981 ;; values are manipulated, registers are already at a premium.  But if
10982 ;; we have one handy, we won't turn it away.
10983 (define_peephole2
10984   [(match_scratch:SI 3 "r")
10985    (parallel [(set (match_operand:DI 0 "register_operand" "")
10986                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10987                                 (match_operand:QI 2 "nonmemory_operand" "")))
10988               (clobber (reg:CC FLAGS_REG))])
10989    (match_dup 3)]
10990   "!TARGET_64BIT && TARGET_CMOVE"
10991   [(const_int 0)]
10992   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10993
10994 (define_split
10995   [(set (match_operand:DI 0 "register_operand" "")
10996         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10997                      (match_operand:QI 2 "nonmemory_operand" "")))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11000   [(const_int 0)]
11001   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11002
11003 (define_insn "x86_shrd_1"
11004   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11005         (ior:SI (ashiftrt:SI (match_dup 0)
11006                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11007                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11008                   (minus:QI (const_int 32) (match_dup 2)))))
11009    (clobber (reg:CC FLAGS_REG))]
11010   ""
11011   "@
11012    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11013    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11014   [(set_attr "type" "ishift")
11015    (set_attr "prefix_0f" "1")
11016    (set_attr "pent_pair" "np")
11017    (set_attr "mode" "SI")])
11018
11019 (define_expand "x86_shift_adj_3"
11020   [(use (match_operand:SI 0 "register_operand" ""))
11021    (use (match_operand:SI 1 "register_operand" ""))
11022    (use (match_operand:QI 2 "register_operand" ""))]
11023   ""
11024 {
11025   rtx label = gen_label_rtx ();
11026   rtx tmp;
11027
11028   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11029
11030   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11031   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11032   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11033                               gen_rtx_LABEL_REF (VOIDmode, label),
11034                               pc_rtx);
11035   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11036   JUMP_LABEL (tmp) = label;
11037
11038   emit_move_insn (operands[0], operands[1]);
11039   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11040
11041   emit_label (label);
11042   LABEL_NUSES (label) = 1;
11043
11044   DONE;
11045 })
11046
11047 (define_insn "ashrsi3_31"
11048   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11049         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11050                      (match_operand:SI 2 "const_int_operand" "i,i")))
11051    (clobber (reg:CC FLAGS_REG))]
11052   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11053    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11054   "@
11055    {cltd|cdq}
11056    sar{l}\t{%2, %0|%0, %2}"
11057   [(set_attr "type" "imovx,ishift")
11058    (set_attr "prefix_0f" "0,*")
11059    (set_attr "length_immediate" "0,*")
11060    (set_attr "modrm" "0,1")
11061    (set_attr "mode" "SI")])
11062
11063 (define_insn "*ashrsi3_31_zext"
11064   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11065         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11066                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11067    (clobber (reg:CC FLAGS_REG))]
11068   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11069    && INTVAL (operands[2]) == 31
11070    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11071   "@
11072    {cltd|cdq}
11073    sar{l}\t{%2, %k0|%k0, %2}"
11074   [(set_attr "type" "imovx,ishift")
11075    (set_attr "prefix_0f" "0,*")
11076    (set_attr "length_immediate" "0,*")
11077    (set_attr "modrm" "0,1")
11078    (set_attr "mode" "SI")])
11079
11080 (define_expand "ashrsi3"
11081   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11082         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11083                      (match_operand:QI 2 "nonmemory_operand" "")))
11084    (clobber (reg:CC FLAGS_REG))]
11085   ""
11086   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11087
11088 (define_insn "*ashrsi3_1_one_bit"
11089   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11090         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11091                      (match_operand:QI 2 "const1_operand" "")))
11092    (clobber (reg:CC FLAGS_REG))]
11093   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11094    && (TARGET_SHIFT1 || optimize_size)"
11095   "sar{l}\t%0"
11096   [(set_attr "type" "ishift")
11097    (set (attr "length") 
11098      (if_then_else (match_operand:SI 0 "register_operand" "") 
11099         (const_string "2")
11100         (const_string "*")))])
11101
11102 (define_insn "*ashrsi3_1_one_bit_zext"
11103   [(set (match_operand:DI 0 "register_operand" "=r")
11104         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11105                                      (match_operand:QI 2 "const1_operand" ""))))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11108    && (TARGET_SHIFT1 || optimize_size)"
11109   "sar{l}\t%k0"
11110   [(set_attr "type" "ishift")
11111    (set_attr "length" "2")])
11112
11113 (define_insn "*ashrsi3_1"
11114   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11115         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11116                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11117    (clobber (reg:CC FLAGS_REG))]
11118   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11119   "@
11120    sar{l}\t{%2, %0|%0, %2}
11121    sar{l}\t{%b2, %0|%0, %b2}"
11122   [(set_attr "type" "ishift")
11123    (set_attr "mode" "SI")])
11124
11125 (define_insn "*ashrsi3_1_zext"
11126   [(set (match_operand:DI 0 "register_operand" "=r,r")
11127         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11128                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11131   "@
11132    sar{l}\t{%2, %k0|%k0, %2}
11133    sar{l}\t{%b2, %k0|%k0, %b2}"
11134   [(set_attr "type" "ishift")
11135    (set_attr "mode" "SI")])
11136
11137 ;; This pattern can't accept a variable shift count, since shifts by
11138 ;; zero don't affect the flags.  We assume that shifts by constant
11139 ;; zero are optimized away.
11140 (define_insn "*ashrsi3_one_bit_cmp"
11141   [(set (reg FLAGS_REG)
11142         (compare
11143           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11144                        (match_operand:QI 2 "const1_operand" ""))
11145           (const_int 0)))
11146    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11147         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11148   "ix86_match_ccmode (insn, CCGOCmode)
11149    && (TARGET_SHIFT1 || optimize_size)
11150    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11151   "sar{l}\t%0"
11152   [(set_attr "type" "ishift")
11153    (set (attr "length") 
11154      (if_then_else (match_operand:SI 0 "register_operand" "") 
11155         (const_string "2")
11156         (const_string "*")))])
11157
11158 (define_insn "*ashrsi3_one_bit_cmp_zext"
11159   [(set (reg FLAGS_REG)
11160         (compare
11161           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11162                        (match_operand:QI 2 "const1_operand" ""))
11163           (const_int 0)))
11164    (set (match_operand:DI 0 "register_operand" "=r")
11165         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11166   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11167    && (TARGET_SHIFT1 || optimize_size)
11168    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11169   "sar{l}\t%k0"
11170   [(set_attr "type" "ishift")
11171    (set_attr "length" "2")])
11172
11173 ;; This pattern can't accept a variable shift count, since shifts by
11174 ;; zero don't affect the flags.  We assume that shifts by constant
11175 ;; zero are optimized away.
11176 (define_insn "*ashrsi3_cmp"
11177   [(set (reg FLAGS_REG)
11178         (compare
11179           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11180                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11181           (const_int 0)))
11182    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11183         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11184   "ix86_match_ccmode (insn, CCGOCmode)
11185    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11186   "sar{l}\t{%2, %0|%0, %2}"
11187   [(set_attr "type" "ishift")
11188    (set_attr "mode" "SI")])
11189
11190 (define_insn "*ashrsi3_cmp_zext"
11191   [(set (reg FLAGS_REG)
11192         (compare
11193           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11194                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11195           (const_int 0)))
11196    (set (match_operand:DI 0 "register_operand" "=r")
11197         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11198   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11199    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11200   "sar{l}\t{%2, %k0|%k0, %2}"
11201   [(set_attr "type" "ishift")
11202    (set_attr "mode" "SI")])
11203
11204 (define_expand "ashrhi3"
11205   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11206         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11207                      (match_operand:QI 2 "nonmemory_operand" "")))
11208    (clobber (reg:CC FLAGS_REG))]
11209   "TARGET_HIMODE_MATH"
11210   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11211
11212 (define_insn "*ashrhi3_1_one_bit"
11213   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11214         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11215                      (match_operand:QI 2 "const1_operand" "")))
11216    (clobber (reg:CC FLAGS_REG))]
11217   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11218    && (TARGET_SHIFT1 || optimize_size)"
11219   "sar{w}\t%0"
11220   [(set_attr "type" "ishift")
11221    (set (attr "length") 
11222      (if_then_else (match_operand 0 "register_operand" "") 
11223         (const_string "2")
11224         (const_string "*")))])
11225
11226 (define_insn "*ashrhi3_1"
11227   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11228         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11229                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11230    (clobber (reg:CC FLAGS_REG))]
11231   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11232   "@
11233    sar{w}\t{%2, %0|%0, %2}
11234    sar{w}\t{%b2, %0|%0, %b2}"
11235   [(set_attr "type" "ishift")
11236    (set_attr "mode" "HI")])
11237
11238 ;; This pattern can't accept a variable shift count, since shifts by
11239 ;; zero don't affect the flags.  We assume that shifts by constant
11240 ;; zero are optimized away.
11241 (define_insn "*ashrhi3_one_bit_cmp"
11242   [(set (reg FLAGS_REG)
11243         (compare
11244           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11245                        (match_operand:QI 2 "const1_operand" ""))
11246           (const_int 0)))
11247    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11248         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11249   "ix86_match_ccmode (insn, CCGOCmode)
11250    && (TARGET_SHIFT1 || optimize_size)
11251    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11252   "sar{w}\t%0"
11253   [(set_attr "type" "ishift")
11254    (set (attr "length") 
11255      (if_then_else (match_operand 0 "register_operand" "") 
11256         (const_string "2")
11257         (const_string "*")))])
11258
11259 ;; This pattern can't accept a variable shift count, since shifts by
11260 ;; zero don't affect the flags.  We assume that shifts by constant
11261 ;; zero are optimized away.
11262 (define_insn "*ashrhi3_cmp"
11263   [(set (reg FLAGS_REG)
11264         (compare
11265           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11266                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11267           (const_int 0)))
11268    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11269         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11270   "ix86_match_ccmode (insn, CCGOCmode)
11271    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11272   "sar{w}\t{%2, %0|%0, %2}"
11273   [(set_attr "type" "ishift")
11274    (set_attr "mode" "HI")])
11275
11276 (define_expand "ashrqi3"
11277   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11278         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11279                      (match_operand:QI 2 "nonmemory_operand" "")))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "TARGET_QIMODE_MATH"
11282   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11283
11284 (define_insn "*ashrqi3_1_one_bit"
11285   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11286         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11287                      (match_operand:QI 2 "const1_operand" "")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11290    && (TARGET_SHIFT1 || optimize_size)"
11291   "sar{b}\t%0"
11292   [(set_attr "type" "ishift")
11293    (set (attr "length") 
11294      (if_then_else (match_operand 0 "register_operand" "") 
11295         (const_string "2")
11296         (const_string "*")))])
11297
11298 (define_insn "*ashrqi3_1_one_bit_slp"
11299   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11300         (ashiftrt:QI (match_dup 0)
11301                      (match_operand:QI 1 "const1_operand" "")))
11302    (clobber (reg:CC FLAGS_REG))]
11303   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11304    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11305    && (TARGET_SHIFT1 || optimize_size)"
11306   "sar{b}\t%0"
11307   [(set_attr "type" "ishift1")
11308    (set (attr "length") 
11309      (if_then_else (match_operand 0 "register_operand" "") 
11310         (const_string "2")
11311         (const_string "*")))])
11312
11313 (define_insn "*ashrqi3_1"
11314   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11315         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11316                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11319   "@
11320    sar{b}\t{%2, %0|%0, %2}
11321    sar{b}\t{%b2, %0|%0, %b2}"
11322   [(set_attr "type" "ishift")
11323    (set_attr "mode" "QI")])
11324
11325 (define_insn "*ashrqi3_1_slp"
11326   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11327         (ashiftrt:QI (match_dup 0)
11328                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11329    (clobber (reg:CC FLAGS_REG))]
11330   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11331    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11332   "@
11333    sar{b}\t{%1, %0|%0, %1}
11334    sar{b}\t{%b1, %0|%0, %b1}"
11335   [(set_attr "type" "ishift1")
11336    (set_attr "mode" "QI")])
11337
11338 ;; This pattern can't accept a variable shift count, since shifts by
11339 ;; zero don't affect the flags.  We assume that shifts by constant
11340 ;; zero are optimized away.
11341 (define_insn "*ashrqi3_one_bit_cmp"
11342   [(set (reg FLAGS_REG)
11343         (compare
11344           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11345                        (match_operand:QI 2 "const1_operand" "I"))
11346           (const_int 0)))
11347    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11348         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11349   "ix86_match_ccmode (insn, CCGOCmode)
11350    && (TARGET_SHIFT1 || optimize_size)
11351    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11352   "sar{b}\t%0"
11353   [(set_attr "type" "ishift")
11354    (set (attr "length") 
11355      (if_then_else (match_operand 0 "register_operand" "") 
11356         (const_string "2")
11357         (const_string "*")))])
11358
11359 ;; This pattern can't accept a variable shift count, since shifts by
11360 ;; zero don't affect the flags.  We assume that shifts by constant
11361 ;; zero are optimized away.
11362 (define_insn "*ashrqi3_cmp"
11363   [(set (reg FLAGS_REG)
11364         (compare
11365           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11366                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11367           (const_int 0)))
11368    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11369         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11370   "ix86_match_ccmode (insn, CCGOCmode)
11371    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11372   "sar{b}\t{%2, %0|%0, %2}"
11373   [(set_attr "type" "ishift")
11374    (set_attr "mode" "QI")])
11375 \f
11376 ;; Logical shift instructions
11377
11378 ;; See comment above `ashldi3' about how this works.
11379
11380 (define_expand "lshrdi3"
11381   [(set (match_operand:DI 0 "shiftdi_operand" "")
11382         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11383                      (match_operand:QI 2 "nonmemory_operand" "")))]
11384   ""
11385   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11386
11387 (define_insn "*lshrdi3_1_one_bit_rex64"
11388   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11389         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390                      (match_operand:QI 2 "const1_operand" "")))
11391    (clobber (reg:CC FLAGS_REG))]
11392   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11393    && (TARGET_SHIFT1 || optimize_size)"
11394   "shr{q}\t%0"
11395   [(set_attr "type" "ishift")
11396    (set (attr "length") 
11397      (if_then_else (match_operand:DI 0 "register_operand" "") 
11398         (const_string "2")
11399         (const_string "*")))])
11400
11401 (define_insn "*lshrdi3_1_rex64"
11402   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11403         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11404                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11407   "@
11408    shr{q}\t{%2, %0|%0, %2}
11409    shr{q}\t{%b2, %0|%0, %b2}"
11410   [(set_attr "type" "ishift")
11411    (set_attr "mode" "DI")])
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 "*lshrdi3_cmp_one_bit_rex64"
11417   [(set (reg FLAGS_REG)
11418         (compare
11419           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11420                        (match_operand:QI 2 "const1_operand" ""))
11421           (const_int 0)))
11422    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11423         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11424   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11425    && (TARGET_SHIFT1 || optimize_size)
11426    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11427   "shr{q}\t%0"
11428   [(set_attr "type" "ishift")
11429    (set (attr "length") 
11430      (if_then_else (match_operand:DI 0 "register_operand" "") 
11431         (const_string "2")
11432         (const_string "*")))])
11433
11434 ;; This pattern can't accept a variable shift count, since shifts by
11435 ;; zero don't affect the flags.  We assume that shifts by constant
11436 ;; zero are optimized away.
11437 (define_insn "*lshrdi3_cmp_rex64"
11438   [(set (reg FLAGS_REG)
11439         (compare
11440           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11441                        (match_operand:QI 2 "const_int_operand" "e"))
11442           (const_int 0)))
11443    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11444         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11445   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11446    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11447   "shr{q}\t{%2, %0|%0, %2}"
11448   [(set_attr "type" "ishift")
11449    (set_attr "mode" "DI")])
11450
11451 (define_insn "*lshrdi3_1"
11452   [(set (match_operand:DI 0 "register_operand" "=r")
11453         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11454                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11455    (clobber (reg:CC FLAGS_REG))]
11456   "!TARGET_64BIT"
11457   "#"
11458   [(set_attr "type" "multi")])
11459
11460 ;; By default we don't ask for a scratch register, because when DImode
11461 ;; values are manipulated, registers are already at a premium.  But if
11462 ;; we have one handy, we won't turn it away.
11463 (define_peephole2
11464   [(match_scratch:SI 3 "r")
11465    (parallel [(set (match_operand:DI 0 "register_operand" "")
11466                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11467                                 (match_operand:QI 2 "nonmemory_operand" "")))
11468               (clobber (reg:CC FLAGS_REG))])
11469    (match_dup 3)]
11470   "!TARGET_64BIT && TARGET_CMOVE"
11471   [(const_int 0)]
11472   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11473
11474 (define_split 
11475   [(set (match_operand:DI 0 "register_operand" "")
11476         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11477                      (match_operand:QI 2 "nonmemory_operand" "")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11480   [(const_int 0)]
11481   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11482
11483 (define_expand "lshrsi3"
11484   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11485         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11486                      (match_operand:QI 2 "nonmemory_operand" "")))
11487    (clobber (reg:CC FLAGS_REG))]
11488   ""
11489   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11490
11491 (define_insn "*lshrsi3_1_one_bit"
11492   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11493         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11494                      (match_operand:QI 2 "const1_operand" "")))
11495    (clobber (reg:CC FLAGS_REG))]
11496   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11497    && (TARGET_SHIFT1 || optimize_size)"
11498   "shr{l}\t%0"
11499   [(set_attr "type" "ishift")
11500    (set (attr "length") 
11501      (if_then_else (match_operand:SI 0 "register_operand" "") 
11502         (const_string "2")
11503         (const_string "*")))])
11504
11505 (define_insn "*lshrsi3_1_one_bit_zext"
11506   [(set (match_operand:DI 0 "register_operand" "=r")
11507         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11508                      (match_operand:QI 2 "const1_operand" "")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11511    && (TARGET_SHIFT1 || optimize_size)"
11512   "shr{l}\t%k0"
11513   [(set_attr "type" "ishift")
11514    (set_attr "length" "2")])
11515
11516 (define_insn "*lshrsi3_1"
11517   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11518         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11519                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11522   "@
11523    shr{l}\t{%2, %0|%0, %2}
11524    shr{l}\t{%b2, %0|%0, %b2}"
11525   [(set_attr "type" "ishift")
11526    (set_attr "mode" "SI")])
11527
11528 (define_insn "*lshrsi3_1_zext"
11529   [(set (match_operand:DI 0 "register_operand" "=r,r")
11530         (zero_extend:DI
11531           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11532                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11535   "@
11536    shr{l}\t{%2, %k0|%k0, %2}
11537    shr{l}\t{%b2, %k0|%k0, %b2}"
11538   [(set_attr "type" "ishift")
11539    (set_attr "mode" "SI")])
11540
11541 ;; This pattern can't accept a variable shift count, since shifts by
11542 ;; zero don't affect the flags.  We assume that shifts by constant
11543 ;; zero are optimized away.
11544 (define_insn "*lshrsi3_one_bit_cmp"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11548                        (match_operand:QI 2 "const1_operand" ""))
11549           (const_int 0)))
11550    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11551         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11552   "ix86_match_ccmode (insn, CCGOCmode)
11553    && (TARGET_SHIFT1 || optimize_size)
11554    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11555   "shr{l}\t%0"
11556   [(set_attr "type" "ishift")
11557    (set (attr "length") 
11558      (if_then_else (match_operand:SI 0 "register_operand" "") 
11559         (const_string "2")
11560         (const_string "*")))])
11561
11562 (define_insn "*lshrsi3_cmp_one_bit_zext"
11563   [(set (reg FLAGS_REG)
11564         (compare
11565           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11566                        (match_operand:QI 2 "const1_operand" ""))
11567           (const_int 0)))
11568    (set (match_operand:DI 0 "register_operand" "=r")
11569         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11570   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11571    && (TARGET_SHIFT1 || optimize_size)
11572    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11573   "shr{l}\t%k0"
11574   [(set_attr "type" "ishift")
11575    (set_attr "length" "2")])
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 "*lshrsi3_cmp"
11581   [(set (reg FLAGS_REG)
11582         (compare
11583           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11584                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11585           (const_int 0)))
11586    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11587         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11588   "ix86_match_ccmode (insn, CCGOCmode)
11589    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11590   "shr{l}\t{%2, %0|%0, %2}"
11591   [(set_attr "type" "ishift")
11592    (set_attr "mode" "SI")])
11593
11594 (define_insn "*lshrsi3_cmp_zext"
11595   [(set (reg FLAGS_REG)
11596         (compare
11597           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11598                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11599           (const_int 0)))
11600    (set (match_operand:DI 0 "register_operand" "=r")
11601         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11602   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11603    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11604   "shr{l}\t{%2, %k0|%k0, %2}"
11605   [(set_attr "type" "ishift")
11606    (set_attr "mode" "SI")])
11607
11608 (define_expand "lshrhi3"
11609   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11610         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11611                      (match_operand:QI 2 "nonmemory_operand" "")))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "TARGET_HIMODE_MATH"
11614   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11615
11616 (define_insn "*lshrhi3_1_one_bit"
11617   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11618         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11619                      (match_operand:QI 2 "const1_operand" "")))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11622    && (TARGET_SHIFT1 || optimize_size)"
11623   "shr{w}\t%0"
11624   [(set_attr "type" "ishift")
11625    (set (attr "length") 
11626      (if_then_else (match_operand 0 "register_operand" "") 
11627         (const_string "2")
11628         (const_string "*")))])
11629
11630 (define_insn "*lshrhi3_1"
11631   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11632         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11633                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11636   "@
11637    shr{w}\t{%2, %0|%0, %2}
11638    shr{w}\t{%b2, %0|%0, %b2}"
11639   [(set_attr "type" "ishift")
11640    (set_attr "mode" "HI")])
11641
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags.  We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*lshrhi3_one_bit_cmp"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const1_operand" ""))
11650           (const_int 0)))
11651    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11652         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11653   "ix86_match_ccmode (insn, CCGOCmode)
11654    && (TARGET_SHIFT1 || optimize_size)
11655    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11656   "shr{w}\t%0"
11657   [(set_attr "type" "ishift")
11658    (set (attr "length") 
11659      (if_then_else (match_operand:SI 0 "register_operand" "") 
11660         (const_string "2")
11661         (const_string "*")))])
11662
11663 ;; This pattern can't accept a variable shift count, since shifts by
11664 ;; zero don't affect the flags.  We assume that shifts by constant
11665 ;; zero are optimized away.
11666 (define_insn "*lshrhi3_cmp"
11667   [(set (reg FLAGS_REG)
11668         (compare
11669           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11670                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11671           (const_int 0)))
11672    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11673         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11674   "ix86_match_ccmode (insn, CCGOCmode)
11675    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11676   "shr{w}\t{%2, %0|%0, %2}"
11677   [(set_attr "type" "ishift")
11678    (set_attr "mode" "HI")])
11679
11680 (define_expand "lshrqi3"
11681   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11682         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11683                      (match_operand:QI 2 "nonmemory_operand" "")))
11684    (clobber (reg:CC FLAGS_REG))]
11685   "TARGET_QIMODE_MATH"
11686   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11687
11688 (define_insn "*lshrqi3_1_one_bit"
11689   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11690         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11691                      (match_operand:QI 2 "const1_operand" "")))
11692    (clobber (reg:CC FLAGS_REG))]
11693   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11694    && (TARGET_SHIFT1 || optimize_size)"
11695   "shr{b}\t%0"
11696   [(set_attr "type" "ishift")
11697    (set (attr "length") 
11698      (if_then_else (match_operand 0 "register_operand" "") 
11699         (const_string "2")
11700         (const_string "*")))])
11701
11702 (define_insn "*lshrqi3_1_one_bit_slp"
11703   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11704         (lshiftrt:QI (match_dup 0)
11705                      (match_operand:QI 1 "const1_operand" "")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11708    && (TARGET_SHIFT1 || optimize_size)"
11709   "shr{b}\t%0"
11710   [(set_attr "type" "ishift1")
11711    (set (attr "length") 
11712      (if_then_else (match_operand 0 "register_operand" "") 
11713         (const_string "2")
11714         (const_string "*")))])
11715
11716 (define_insn "*lshrqi3_1"
11717   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11718         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11719                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11722   "@
11723    shr{b}\t{%2, %0|%0, %2}
11724    shr{b}\t{%b2, %0|%0, %b2}"
11725   [(set_attr "type" "ishift")
11726    (set_attr "mode" "QI")])
11727
11728 (define_insn "*lshrqi3_1_slp"
11729   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11730         (lshiftrt:QI (match_dup 0)
11731                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11734    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11735   "@
11736    shr{b}\t{%1, %0|%0, %1}
11737    shr{b}\t{%b1, %0|%0, %b1}"
11738   [(set_attr "type" "ishift1")
11739    (set_attr "mode" "QI")])
11740
11741 ;; This pattern can't accept a variable shift count, since shifts by
11742 ;; zero don't affect the flags.  We assume that shifts by constant
11743 ;; zero are optimized away.
11744 (define_insn "*lshrqi2_one_bit_cmp"
11745   [(set (reg FLAGS_REG)
11746         (compare
11747           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11748                        (match_operand:QI 2 "const1_operand" ""))
11749           (const_int 0)))
11750    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11751         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11752   "ix86_match_ccmode (insn, CCGOCmode)
11753    && (TARGET_SHIFT1 || optimize_size)
11754    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11755   "shr{b}\t%0"
11756   [(set_attr "type" "ishift")
11757    (set (attr "length") 
11758      (if_then_else (match_operand:SI 0 "register_operand" "") 
11759         (const_string "2")
11760         (const_string "*")))])
11761
11762 ;; This pattern can't accept a variable shift count, since shifts by
11763 ;; zero don't affect the flags.  We assume that shifts by constant
11764 ;; zero are optimized away.
11765 (define_insn "*lshrqi2_cmp"
11766   [(set (reg FLAGS_REG)
11767         (compare
11768           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11769                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11770           (const_int 0)))
11771    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11772         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11773   "ix86_match_ccmode (insn, CCGOCmode)
11774    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11775   "shr{b}\t{%2, %0|%0, %2}"
11776   [(set_attr "type" "ishift")
11777    (set_attr "mode" "QI")])
11778 \f
11779 ;; Rotate instructions
11780
11781 (define_expand "rotldi3"
11782   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11783         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11784                    (match_operand:QI 2 "nonmemory_operand" "")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "TARGET_64BIT"
11787   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11788
11789 (define_insn "*rotlsi3_1_one_bit_rex64"
11790   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11791         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11792                    (match_operand:QI 2 "const1_operand" "")))
11793    (clobber (reg:CC FLAGS_REG))]
11794   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11795    && (TARGET_SHIFT1 || optimize_size)"
11796   "rol{q}\t%0"
11797   [(set_attr "type" "rotate")
11798    (set (attr "length") 
11799      (if_then_else (match_operand:DI 0 "register_operand" "") 
11800         (const_string "2")
11801         (const_string "*")))])
11802
11803 (define_insn "*rotldi3_1_rex64"
11804   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11805         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11806                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11809   "@
11810    rol{q}\t{%2, %0|%0, %2}
11811    rol{q}\t{%b2, %0|%0, %b2}"
11812   [(set_attr "type" "rotate")
11813    (set_attr "mode" "DI")])
11814
11815 (define_expand "rotlsi3"
11816   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11817         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11818                    (match_operand:QI 2 "nonmemory_operand" "")))
11819    (clobber (reg:CC FLAGS_REG))]
11820   ""
11821   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11822
11823 (define_insn "*rotlsi3_1_one_bit"
11824   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11825         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11826                    (match_operand:QI 2 "const1_operand" "")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11829    && (TARGET_SHIFT1 || optimize_size)"
11830   "rol{l}\t%0"
11831   [(set_attr "type" "rotate")
11832    (set (attr "length") 
11833      (if_then_else (match_operand:SI 0 "register_operand" "") 
11834         (const_string "2")
11835         (const_string "*")))])
11836
11837 (define_insn "*rotlsi3_1_one_bit_zext"
11838   [(set (match_operand:DI 0 "register_operand" "=r")
11839         (zero_extend:DI
11840           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11841                      (match_operand:QI 2 "const1_operand" ""))))
11842    (clobber (reg:CC FLAGS_REG))]
11843   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11844    && (TARGET_SHIFT1 || optimize_size)"
11845   "rol{l}\t%k0"
11846   [(set_attr "type" "rotate")
11847    (set_attr "length" "2")])
11848
11849 (define_insn "*rotlsi3_1"
11850   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11851         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11852                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11855   "@
11856    rol{l}\t{%2, %0|%0, %2}
11857    rol{l}\t{%b2, %0|%0, %b2}"
11858   [(set_attr "type" "rotate")
11859    (set_attr "mode" "SI")])
11860
11861 (define_insn "*rotlsi3_1_zext"
11862   [(set (match_operand:DI 0 "register_operand" "=r,r")
11863         (zero_extend:DI
11864           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11865                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11868   "@
11869    rol{l}\t{%2, %k0|%k0, %2}
11870    rol{l}\t{%b2, %k0|%k0, %b2}"
11871   [(set_attr "type" "rotate")
11872    (set_attr "mode" "SI")])
11873
11874 (define_expand "rotlhi3"
11875   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11876         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11877                    (match_operand:QI 2 "nonmemory_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_HIMODE_MATH"
11880   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11881
11882 (define_insn "*rotlhi3_1_one_bit"
11883   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11885                    (match_operand:QI 2 "const1_operand" "")))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "rol{w}\t%0"
11890   [(set_attr "type" "rotate")
11891    (set (attr "length") 
11892      (if_then_else (match_operand 0 "register_operand" "") 
11893         (const_string "2")
11894         (const_string "*")))])
11895
11896 (define_insn "*rotlhi3_1"
11897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11898         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11899                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11902   "@
11903    rol{w}\t{%2, %0|%0, %2}
11904    rol{w}\t{%b2, %0|%0, %b2}"
11905   [(set_attr "type" "rotate")
11906    (set_attr "mode" "HI")])
11907
11908 (define_expand "rotlqi3"
11909   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11910         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11911                    (match_operand:QI 2 "nonmemory_operand" "")))
11912    (clobber (reg:CC FLAGS_REG))]
11913   "TARGET_QIMODE_MATH"
11914   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11915
11916 (define_insn "*rotlqi3_1_one_bit_slp"
11917   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11918         (rotate:QI (match_dup 0)
11919                    (match_operand:QI 1 "const1_operand" "")))
11920    (clobber (reg:CC FLAGS_REG))]
11921   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11922    && (TARGET_SHIFT1 || optimize_size)"
11923   "rol{b}\t%0"
11924   [(set_attr "type" "rotate1")
11925    (set (attr "length") 
11926      (if_then_else (match_operand 0 "register_operand" "") 
11927         (const_string "2")
11928         (const_string "*")))])
11929
11930 (define_insn "*rotlqi3_1_one_bit"
11931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11932         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11933                    (match_operand:QI 2 "const1_operand" "")))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11936    && (TARGET_SHIFT1 || optimize_size)"
11937   "rol{b}\t%0"
11938   [(set_attr "type" "rotate")
11939    (set (attr "length") 
11940      (if_then_else (match_operand 0 "register_operand" "") 
11941         (const_string "2")
11942         (const_string "*")))])
11943
11944 (define_insn "*rotlqi3_1_slp"
11945   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11946         (rotate:QI (match_dup 0)
11947                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11950    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11951   "@
11952    rol{b}\t{%1, %0|%0, %1}
11953    rol{b}\t{%b1, %0|%0, %b1}"
11954   [(set_attr "type" "rotate1")
11955    (set_attr "mode" "QI")])
11956
11957 (define_insn "*rotlqi3_1"
11958   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11959         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11960                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11963   "@
11964    rol{b}\t{%2, %0|%0, %2}
11965    rol{b}\t{%b2, %0|%0, %b2}"
11966   [(set_attr "type" "rotate")
11967    (set_attr "mode" "QI")])
11968
11969 (define_expand "rotrdi3"
11970   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11971         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11972                      (match_operand:QI 2 "nonmemory_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "TARGET_64BIT"
11975   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11976
11977 (define_insn "*rotrdi3_1_one_bit_rex64"
11978   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11979         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11980                      (match_operand:QI 2 "const1_operand" "")))
11981    (clobber (reg:CC FLAGS_REG))]
11982   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11983    && (TARGET_SHIFT1 || optimize_size)"
11984   "ror{q}\t%0"
11985   [(set_attr "type" "rotate")
11986    (set (attr "length") 
11987      (if_then_else (match_operand:DI 0 "register_operand" "") 
11988         (const_string "2")
11989         (const_string "*")))])
11990
11991 (define_insn "*rotrdi3_1_rex64"
11992   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11993         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11994                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11997   "@
11998    ror{q}\t{%2, %0|%0, %2}
11999    ror{q}\t{%b2, %0|%0, %b2}"
12000   [(set_attr "type" "rotate")
12001    (set_attr "mode" "DI")])
12002
12003 (define_expand "rotrsi3"
12004   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12005         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12006                      (match_operand:QI 2 "nonmemory_operand" "")))
12007    (clobber (reg:CC FLAGS_REG))]
12008   ""
12009   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12010
12011 (define_insn "*rotrsi3_1_one_bit"
12012   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12013         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12014                      (match_operand:QI 2 "const1_operand" "")))
12015    (clobber (reg:CC FLAGS_REG))]
12016   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12017    && (TARGET_SHIFT1 || optimize_size)"
12018   "ror{l}\t%0"
12019   [(set_attr "type" "rotate")
12020    (set (attr "length") 
12021      (if_then_else (match_operand:SI 0 "register_operand" "") 
12022         (const_string "2")
12023         (const_string "*")))])
12024
12025 (define_insn "*rotrsi3_1_one_bit_zext"
12026   [(set (match_operand:DI 0 "register_operand" "=r")
12027         (zero_extend:DI
12028           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12029                        (match_operand:QI 2 "const1_operand" ""))))
12030    (clobber (reg:CC FLAGS_REG))]
12031   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12032    && (TARGET_SHIFT1 || optimize_size)"
12033   "ror{l}\t%k0"
12034   [(set_attr "type" "rotate")
12035    (set (attr "length") 
12036      (if_then_else (match_operand:SI 0 "register_operand" "") 
12037         (const_string "2")
12038         (const_string "*")))])
12039
12040 (define_insn "*rotrsi3_1"
12041   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12042         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12043                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12044    (clobber (reg:CC FLAGS_REG))]
12045   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12046   "@
12047    ror{l}\t{%2, %0|%0, %2}
12048    ror{l}\t{%b2, %0|%0, %b2}"
12049   [(set_attr "type" "rotate")
12050    (set_attr "mode" "SI")])
12051
12052 (define_insn "*rotrsi3_1_zext"
12053   [(set (match_operand:DI 0 "register_operand" "=r,r")
12054         (zero_extend:DI
12055           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12056                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12057    (clobber (reg:CC FLAGS_REG))]
12058   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12059   "@
12060    ror{l}\t{%2, %k0|%k0, %2}
12061    ror{l}\t{%b2, %k0|%k0, %b2}"
12062   [(set_attr "type" "rotate")
12063    (set_attr "mode" "SI")])
12064
12065 (define_expand "rotrhi3"
12066   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12067         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12068                      (match_operand:QI 2 "nonmemory_operand" "")))
12069    (clobber (reg:CC FLAGS_REG))]
12070   "TARGET_HIMODE_MATH"
12071   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12072
12073 (define_insn "*rotrhi3_one_bit"
12074   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12075         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076                      (match_operand:QI 2 "const1_operand" "")))
12077    (clobber (reg:CC FLAGS_REG))]
12078   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12079    && (TARGET_SHIFT1 || optimize_size)"
12080   "ror{w}\t%0"
12081   [(set_attr "type" "rotate")
12082    (set (attr "length") 
12083      (if_then_else (match_operand 0 "register_operand" "") 
12084         (const_string "2")
12085         (const_string "*")))])
12086
12087 (define_insn "*rotrhi3"
12088   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12089         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12090                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12093   "@
12094    ror{w}\t{%2, %0|%0, %2}
12095    ror{w}\t{%b2, %0|%0, %b2}"
12096   [(set_attr "type" "rotate")
12097    (set_attr "mode" "HI")])
12098
12099 (define_expand "rotrqi3"
12100   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12101         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12102                      (match_operand:QI 2 "nonmemory_operand" "")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_QIMODE_MATH"
12105   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12106
12107 (define_insn "*rotrqi3_1_one_bit"
12108   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12109         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12110                      (match_operand:QI 2 "const1_operand" "")))
12111    (clobber (reg:CC FLAGS_REG))]
12112   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12113    && (TARGET_SHIFT1 || optimize_size)"
12114   "ror{b}\t%0"
12115   [(set_attr "type" "rotate")
12116    (set (attr "length") 
12117      (if_then_else (match_operand 0 "register_operand" "") 
12118         (const_string "2")
12119         (const_string "*")))])
12120
12121 (define_insn "*rotrqi3_1_one_bit_slp"
12122   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12123         (rotatert:QI (match_dup 0)
12124                      (match_operand:QI 1 "const1_operand" "")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12127    && (TARGET_SHIFT1 || optimize_size)"
12128   "ror{b}\t%0"
12129   [(set_attr "type" "rotate1")
12130    (set (attr "length") 
12131      (if_then_else (match_operand 0 "register_operand" "") 
12132         (const_string "2")
12133         (const_string "*")))])
12134
12135 (define_insn "*rotrqi3_1"
12136   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12137         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12138                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12141   "@
12142    ror{b}\t{%2, %0|%0, %2}
12143    ror{b}\t{%b2, %0|%0, %b2}"
12144   [(set_attr "type" "rotate")
12145    (set_attr "mode" "QI")])
12146
12147 (define_insn "*rotrqi3_1_slp"
12148   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12149         (rotatert:QI (match_dup 0)
12150                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12153    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12154   "@
12155    ror{b}\t{%1, %0|%0, %1}
12156    ror{b}\t{%b1, %0|%0, %b1}"
12157   [(set_attr "type" "rotate1")
12158    (set_attr "mode" "QI")])
12159 \f
12160 ;; Bit set / bit test instructions
12161
12162 (define_expand "extv"
12163   [(set (match_operand:SI 0 "register_operand" "")
12164         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12165                          (match_operand:SI 2 "immediate_operand" "")
12166                          (match_operand:SI 3 "immediate_operand" "")))]
12167   ""
12168 {
12169   /* Handle extractions from %ah et al.  */
12170   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12171     FAIL;
12172
12173   /* From mips.md: extract_bit_field doesn't verify that our source
12174      matches the predicate, so check it again here.  */
12175   if (! ext_register_operand (operands[1], VOIDmode))
12176     FAIL;
12177 })
12178
12179 (define_expand "extzv"
12180   [(set (match_operand:SI 0 "register_operand" "")
12181         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12182                          (match_operand:SI 2 "immediate_operand" "")
12183                          (match_operand:SI 3 "immediate_operand" "")))]
12184   ""
12185 {
12186   /* Handle extractions from %ah et al.  */
12187   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12188     FAIL;
12189
12190   /* From mips.md: extract_bit_field doesn't verify that our source
12191      matches the predicate, so check it again here.  */
12192   if (! ext_register_operand (operands[1], VOIDmode))
12193     FAIL;
12194 })
12195
12196 (define_expand "insv"
12197   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12198                       (match_operand 1 "immediate_operand" "")
12199                       (match_operand 2 "immediate_operand" ""))
12200         (match_operand 3 "register_operand" ""))]
12201   ""
12202 {
12203   /* Handle extractions from %ah et al.  */
12204   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12205     FAIL;
12206
12207   /* From mips.md: insert_bit_field doesn't verify that our source
12208      matches the predicate, so check it again here.  */
12209   if (! ext_register_operand (operands[0], VOIDmode))
12210     FAIL;
12211
12212   if (TARGET_64BIT)
12213     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12214   else
12215     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12216
12217   DONE;
12218 })
12219
12220 ;; %%% bts, btr, btc, bt.
12221 ;; In general these instructions are *slow* when applied to memory,
12222 ;; since they enforce atomic operation.  When applied to registers,
12223 ;; it depends on the cpu implementation.  They're never faster than
12224 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12225 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12226 ;; within the instruction itself, so operating on bits in the high
12227 ;; 32-bits of a register becomes easier.
12228 ;;
12229 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12230 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12231 ;; negdf respectively, so they can never be disabled entirely.
12232
12233 (define_insn "*btsq"
12234   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12235                          (const_int 1)
12236                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12237         (const_int 1))
12238    (clobber (reg:CC FLAGS_REG))]
12239   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12240   "bts{q} %1,%0"
12241   [(set_attr "type" "alu1")])
12242
12243 (define_insn "*btrq"
12244   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12245                          (const_int 1)
12246                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12247         (const_int 0))
12248    (clobber (reg:CC FLAGS_REG))]
12249   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12250   "btr{q} %1,%0"
12251   [(set_attr "type" "alu1")])
12252
12253 (define_insn "*btcq"
12254   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12255                          (const_int 1)
12256                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12257         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12258    (clobber (reg:CC FLAGS_REG))]
12259   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12260   "btc{q} %1,%0"
12261   [(set_attr "type" "alu1")])
12262
12263 ;; Allow Nocona to avoid these instructions if a register is available.
12264
12265 (define_peephole2
12266   [(match_scratch:DI 2 "r")
12267    (parallel [(set (zero_extract:DI
12268                      (match_operand:DI 0 "register_operand" "")
12269                      (const_int 1)
12270                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12271                    (const_int 1))
12272               (clobber (reg:CC FLAGS_REG))])]
12273   "TARGET_64BIT && !TARGET_USE_BT"
12274   [(const_int 0)]
12275 {
12276   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12277   rtx op1;
12278
12279   if (HOST_BITS_PER_WIDE_INT >= 64)
12280     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12281   else if (i < HOST_BITS_PER_WIDE_INT)
12282     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12283   else
12284     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12285
12286   op1 = immed_double_const (lo, hi, DImode);
12287   if (i >= 31)
12288     {
12289       emit_move_insn (operands[2], op1);
12290       op1 = operands[2];
12291     }
12292
12293   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12294   DONE;
12295 })
12296
12297 (define_peephole2
12298   [(match_scratch:DI 2 "r")
12299    (parallel [(set (zero_extract:DI
12300                      (match_operand:DI 0 "register_operand" "")
12301                      (const_int 1)
12302                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12303                    (const_int 0))
12304               (clobber (reg:CC FLAGS_REG))])]
12305   "TARGET_64BIT && !TARGET_USE_BT"
12306   [(const_int 0)]
12307 {
12308   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12309   rtx op1;
12310
12311   if (HOST_BITS_PER_WIDE_INT >= 64)
12312     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12313   else if (i < HOST_BITS_PER_WIDE_INT)
12314     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12315   else
12316     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12317
12318   op1 = immed_double_const (~lo, ~hi, DImode);
12319   if (i >= 32)
12320     {
12321       emit_move_insn (operands[2], op1);
12322       op1 = operands[2];
12323     }
12324
12325   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12326   DONE;
12327 })
12328
12329 (define_peephole2
12330   [(match_scratch:DI 2 "r")
12331    (parallel [(set (zero_extract:DI
12332                      (match_operand:DI 0 "register_operand" "")
12333                      (const_int 1)
12334                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12335               (not:DI (zero_extract:DI
12336                         (match_dup 0) (const_int 1) (match_dup 1))))
12337               (clobber (reg:CC FLAGS_REG))])]
12338   "TARGET_64BIT && !TARGET_USE_BT"
12339   [(const_int 0)]
12340 {
12341   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12342   rtx op1;
12343
12344   if (HOST_BITS_PER_WIDE_INT >= 64)
12345     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12346   else if (i < HOST_BITS_PER_WIDE_INT)
12347     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12348   else
12349     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12350
12351   op1 = immed_double_const (lo, hi, DImode);
12352   if (i >= 31)
12353     {
12354       emit_move_insn (operands[2], op1);
12355       op1 = operands[2];
12356     }
12357
12358   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12359   DONE;
12360 })
12361 \f
12362 ;; Store-flag instructions.
12363
12364 ;; For all sCOND expanders, also expand the compare or test insn that
12365 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12366
12367 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12368 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12369 ;; way, which can later delete the movzx if only QImode is needed.
12370
12371 (define_expand "seq"
12372   [(set (match_operand:QI 0 "register_operand" "")
12373         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12374   ""
12375   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12376
12377 (define_expand "sne"
12378   [(set (match_operand:QI 0 "register_operand" "")
12379         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12380   ""
12381   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12382
12383 (define_expand "sgt"
12384   [(set (match_operand:QI 0 "register_operand" "")
12385         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12386   ""
12387   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12388
12389 (define_expand "sgtu"
12390   [(set (match_operand:QI 0 "register_operand" "")
12391         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12392   ""
12393   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12394
12395 (define_expand "slt"
12396   [(set (match_operand:QI 0 "register_operand" "")
12397         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12398   ""
12399   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12400
12401 (define_expand "sltu"
12402   [(set (match_operand:QI 0 "register_operand" "")
12403         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12404   ""
12405   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12406
12407 (define_expand "sge"
12408   [(set (match_operand:QI 0 "register_operand" "")
12409         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12410   ""
12411   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12412
12413 (define_expand "sgeu"
12414   [(set (match_operand:QI 0 "register_operand" "")
12415         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12416   ""
12417   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12418
12419 (define_expand "sle"
12420   [(set (match_operand:QI 0 "register_operand" "")
12421         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12422   ""
12423   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12424
12425 (define_expand "sleu"
12426   [(set (match_operand:QI 0 "register_operand" "")
12427         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12428   ""
12429   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12430
12431 (define_expand "sunordered"
12432   [(set (match_operand:QI 0 "register_operand" "")
12433         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12434   "TARGET_80387 || TARGET_SSE"
12435   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12436
12437 (define_expand "sordered"
12438   [(set (match_operand:QI 0 "register_operand" "")
12439         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12440   "TARGET_80387"
12441   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12442
12443 (define_expand "suneq"
12444   [(set (match_operand:QI 0 "register_operand" "")
12445         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12446   "TARGET_80387 || TARGET_SSE"
12447   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12448
12449 (define_expand "sunge"
12450   [(set (match_operand:QI 0 "register_operand" "")
12451         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12452   "TARGET_80387 || TARGET_SSE"
12453   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12454
12455 (define_expand "sungt"
12456   [(set (match_operand:QI 0 "register_operand" "")
12457         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12458   "TARGET_80387 || TARGET_SSE"
12459   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12460
12461 (define_expand "sunle"
12462   [(set (match_operand:QI 0 "register_operand" "")
12463         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12464   "TARGET_80387 || TARGET_SSE"
12465   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12466
12467 (define_expand "sunlt"
12468   [(set (match_operand:QI 0 "register_operand" "")
12469         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12470   "TARGET_80387 || TARGET_SSE"
12471   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12472
12473 (define_expand "sltgt"
12474   [(set (match_operand:QI 0 "register_operand" "")
12475         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12476   "TARGET_80387 || TARGET_SSE"
12477   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12478
12479 (define_insn "*setcc_1"
12480   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12481         (match_operator:QI 1 "ix86_comparison_operator"
12482           [(reg FLAGS_REG) (const_int 0)]))]
12483   ""
12484   "set%C1\t%0"
12485   [(set_attr "type" "setcc")
12486    (set_attr "mode" "QI")])
12487
12488 (define_insn "*setcc_2"
12489   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12490         (match_operator:QI 1 "ix86_comparison_operator"
12491           [(reg FLAGS_REG) (const_int 0)]))]
12492   ""
12493   "set%C1\t%0"
12494   [(set_attr "type" "setcc")
12495    (set_attr "mode" "QI")])
12496
12497 ;; In general it is not safe to assume too much about CCmode registers,
12498 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12499 ;; conditions this is safe on x86, so help combine not create
12500 ;;
12501 ;;      seta    %al
12502 ;;      testb   %al, %al
12503 ;;      sete    %al
12504
12505 (define_split 
12506   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12507         (ne:QI (match_operator 1 "ix86_comparison_operator"
12508                  [(reg FLAGS_REG) (const_int 0)])
12509             (const_int 0)))]
12510   ""
12511   [(set (match_dup 0) (match_dup 1))]
12512 {
12513   PUT_MODE (operands[1], QImode);
12514 })
12515
12516 (define_split 
12517   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12518         (ne:QI (match_operator 1 "ix86_comparison_operator"
12519                  [(reg FLAGS_REG) (const_int 0)])
12520             (const_int 0)))]
12521   ""
12522   [(set (match_dup 0) (match_dup 1))]
12523 {
12524   PUT_MODE (operands[1], QImode);
12525 })
12526
12527 (define_split 
12528   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12529         (eq:QI (match_operator 1 "ix86_comparison_operator"
12530                  [(reg FLAGS_REG) (const_int 0)])
12531             (const_int 0)))]
12532   ""
12533   [(set (match_dup 0) (match_dup 1))]
12534 {
12535   rtx new_op1 = copy_rtx (operands[1]);
12536   operands[1] = new_op1;
12537   PUT_MODE (new_op1, QImode);
12538   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12539                                              GET_MODE (XEXP (new_op1, 0))));
12540
12541   /* Make sure that (a) the CCmode we have for the flags is strong
12542      enough for the reversed compare or (b) we have a valid FP compare.  */
12543   if (! ix86_comparison_operator (new_op1, VOIDmode))
12544     FAIL;
12545 })
12546
12547 (define_split 
12548   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12549         (eq:QI (match_operator 1 "ix86_comparison_operator"
12550                  [(reg FLAGS_REG) (const_int 0)])
12551             (const_int 0)))]
12552   ""
12553   [(set (match_dup 0) (match_dup 1))]
12554 {
12555   rtx new_op1 = copy_rtx (operands[1]);
12556   operands[1] = new_op1;
12557   PUT_MODE (new_op1, QImode);
12558   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12559                                              GET_MODE (XEXP (new_op1, 0))));
12560
12561   /* Make sure that (a) the CCmode we have for the flags is strong
12562      enough for the reversed compare or (b) we have a valid FP compare.  */
12563   if (! ix86_comparison_operator (new_op1, VOIDmode))
12564     FAIL;
12565 })
12566
12567 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12568 ;; subsequent logical operations are used to imitate conditional moves.
12569 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12570 ;; it directly.  Further holding this value in pseudo register might bring
12571 ;; problem in implicit normalization in spill code.
12572 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12573 ;; instructions after reload by splitting the conditional move patterns.
12574
12575 (define_insn "*sse_setccsf"
12576   [(set (match_operand:SF 0 "register_operand" "=x")
12577         (match_operator:SF 1 "sse_comparison_operator"
12578           [(match_operand:SF 2 "register_operand" "0")
12579            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12580   "TARGET_SSE && reload_completed"
12581   "cmp%D1ss\t{%3, %0|%0, %3}"
12582   [(set_attr "type" "ssecmp")
12583    (set_attr "mode" "SF")])
12584
12585 (define_insn "*sse_setccdf"
12586   [(set (match_operand:DF 0 "register_operand" "=Y")
12587         (match_operator:DF 1 "sse_comparison_operator"
12588           [(match_operand:DF 2 "register_operand" "0")
12589            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12590   "TARGET_SSE2 && reload_completed"
12591   "cmp%D1sd\t{%3, %0|%0, %3}"
12592   [(set_attr "type" "ssecmp")
12593    (set_attr "mode" "DF")])
12594 \f
12595 ;; Basic conditional jump instructions.
12596 ;; We ignore the overflow flag for signed branch instructions.
12597
12598 ;; For all bCOND expanders, also expand the compare or test insn that
12599 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12600
12601 (define_expand "beq"
12602   [(set (pc)
12603         (if_then_else (match_dup 1)
12604                       (label_ref (match_operand 0 "" ""))
12605                       (pc)))]
12606   ""
12607   "ix86_expand_branch (EQ, operands[0]); DONE;")
12608
12609 (define_expand "bne"
12610   [(set (pc)
12611         (if_then_else (match_dup 1)
12612                       (label_ref (match_operand 0 "" ""))
12613                       (pc)))]
12614   ""
12615   "ix86_expand_branch (NE, operands[0]); DONE;")
12616
12617 (define_expand "bgt"
12618   [(set (pc)
12619         (if_then_else (match_dup 1)
12620                       (label_ref (match_operand 0 "" ""))
12621                       (pc)))]
12622   ""
12623   "ix86_expand_branch (GT, operands[0]); DONE;")
12624
12625 (define_expand "bgtu"
12626   [(set (pc)
12627         (if_then_else (match_dup 1)
12628                       (label_ref (match_operand 0 "" ""))
12629                       (pc)))]
12630   ""
12631   "ix86_expand_branch (GTU, operands[0]); DONE;")
12632
12633 (define_expand "blt"
12634   [(set (pc)
12635         (if_then_else (match_dup 1)
12636                       (label_ref (match_operand 0 "" ""))
12637                       (pc)))]
12638   ""
12639   "ix86_expand_branch (LT, operands[0]); DONE;")
12640
12641 (define_expand "bltu"
12642   [(set (pc)
12643         (if_then_else (match_dup 1)
12644                       (label_ref (match_operand 0 "" ""))
12645                       (pc)))]
12646   ""
12647   "ix86_expand_branch (LTU, operands[0]); DONE;")
12648
12649 (define_expand "bge"
12650   [(set (pc)
12651         (if_then_else (match_dup 1)
12652                       (label_ref (match_operand 0 "" ""))
12653                       (pc)))]
12654   ""
12655   "ix86_expand_branch (GE, operands[0]); DONE;")
12656
12657 (define_expand "bgeu"
12658   [(set (pc)
12659         (if_then_else (match_dup 1)
12660                       (label_ref (match_operand 0 "" ""))
12661                       (pc)))]
12662   ""
12663   "ix86_expand_branch (GEU, operands[0]); DONE;")
12664
12665 (define_expand "ble"
12666   [(set (pc)
12667         (if_then_else (match_dup 1)
12668                       (label_ref (match_operand 0 "" ""))
12669                       (pc)))]
12670   ""
12671   "ix86_expand_branch (LE, operands[0]); DONE;")
12672
12673 (define_expand "bleu"
12674   [(set (pc)
12675         (if_then_else (match_dup 1)
12676                       (label_ref (match_operand 0 "" ""))
12677                       (pc)))]
12678   ""
12679   "ix86_expand_branch (LEU, operands[0]); DONE;")
12680
12681 (define_expand "bunordered"
12682   [(set (pc)
12683         (if_then_else (match_dup 1)
12684                       (label_ref (match_operand 0 "" ""))
12685                       (pc)))]
12686   "TARGET_80387 || TARGET_SSE"
12687   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12688
12689 (define_expand "bordered"
12690   [(set (pc)
12691         (if_then_else (match_dup 1)
12692                       (label_ref (match_operand 0 "" ""))
12693                       (pc)))]
12694   "TARGET_80387 || TARGET_SSE"
12695   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12696
12697 (define_expand "buneq"
12698   [(set (pc)
12699         (if_then_else (match_dup 1)
12700                       (label_ref (match_operand 0 "" ""))
12701                       (pc)))]
12702   "TARGET_80387 || TARGET_SSE"
12703   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12704
12705 (define_expand "bunge"
12706   [(set (pc)
12707         (if_then_else (match_dup 1)
12708                       (label_ref (match_operand 0 "" ""))
12709                       (pc)))]
12710   "TARGET_80387 || TARGET_SSE"
12711   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12712
12713 (define_expand "bungt"
12714   [(set (pc)
12715         (if_then_else (match_dup 1)
12716                       (label_ref (match_operand 0 "" ""))
12717                       (pc)))]
12718   "TARGET_80387 || TARGET_SSE"
12719   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12720
12721 (define_expand "bunle"
12722   [(set (pc)
12723         (if_then_else (match_dup 1)
12724                       (label_ref (match_operand 0 "" ""))
12725                       (pc)))]
12726   "TARGET_80387 || TARGET_SSE"
12727   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12728
12729 (define_expand "bunlt"
12730   [(set (pc)
12731         (if_then_else (match_dup 1)
12732                       (label_ref (match_operand 0 "" ""))
12733                       (pc)))]
12734   "TARGET_80387 || TARGET_SSE"
12735   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12736
12737 (define_expand "bltgt"
12738   [(set (pc)
12739         (if_then_else (match_dup 1)
12740                       (label_ref (match_operand 0 "" ""))
12741                       (pc)))]
12742   "TARGET_80387 || TARGET_SSE"
12743   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12744
12745 (define_insn "*jcc_1"
12746   [(set (pc)
12747         (if_then_else (match_operator 1 "ix86_comparison_operator"
12748                                       [(reg FLAGS_REG) (const_int 0)])
12749                       (label_ref (match_operand 0 "" ""))
12750                       (pc)))]
12751   ""
12752   "%+j%C1\t%l0"
12753   [(set_attr "type" "ibr")
12754    (set_attr "modrm" "0")
12755    (set (attr "length")
12756            (if_then_else (and (ge (minus (match_dup 0) (pc))
12757                                   (const_int -126))
12758                               (lt (minus (match_dup 0) (pc))
12759                                   (const_int 128)))
12760              (const_int 2)
12761              (const_int 6)))])
12762
12763 (define_insn "*jcc_2"
12764   [(set (pc)
12765         (if_then_else (match_operator 1 "ix86_comparison_operator"
12766                                       [(reg FLAGS_REG) (const_int 0)])
12767                       (pc)
12768                       (label_ref (match_operand 0 "" ""))))]
12769   ""
12770   "%+j%c1\t%l0"
12771   [(set_attr "type" "ibr")
12772    (set_attr "modrm" "0")
12773    (set (attr "length")
12774            (if_then_else (and (ge (minus (match_dup 0) (pc))
12775                                   (const_int -126))
12776                               (lt (minus (match_dup 0) (pc))
12777                                   (const_int 128)))
12778              (const_int 2)
12779              (const_int 6)))])
12780
12781 ;; In general it is not safe to assume too much about CCmode registers,
12782 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12783 ;; conditions this is safe on x86, so help combine not create
12784 ;;
12785 ;;      seta    %al
12786 ;;      testb   %al, %al
12787 ;;      je      Lfoo
12788
12789 (define_split 
12790   [(set (pc)
12791         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12792                                       [(reg FLAGS_REG) (const_int 0)])
12793                           (const_int 0))
12794                       (label_ref (match_operand 1 "" ""))
12795                       (pc)))]
12796   ""
12797   [(set (pc)
12798         (if_then_else (match_dup 0)
12799                       (label_ref (match_dup 1))
12800                       (pc)))]
12801 {
12802   PUT_MODE (operands[0], VOIDmode);
12803 })
12804   
12805 (define_split 
12806   [(set (pc)
12807         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12808                                       [(reg FLAGS_REG) (const_int 0)])
12809                           (const_int 0))
12810                       (label_ref (match_operand 1 "" ""))
12811                       (pc)))]
12812   ""
12813   [(set (pc)
12814         (if_then_else (match_dup 0)
12815                       (label_ref (match_dup 1))
12816                       (pc)))]
12817 {
12818   rtx new_op0 = copy_rtx (operands[0]);
12819   operands[0] = new_op0;
12820   PUT_MODE (new_op0, VOIDmode);
12821   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12822                                              GET_MODE (XEXP (new_op0, 0))));
12823
12824   /* Make sure that (a) the CCmode we have for the flags is strong
12825      enough for the reversed compare or (b) we have a valid FP compare.  */
12826   if (! ix86_comparison_operator (new_op0, VOIDmode))
12827     FAIL;
12828 })
12829
12830 ;; Define combination compare-and-branch fp compare instructions to use
12831 ;; during early optimization.  Splitting the operation apart early makes
12832 ;; for bad code when we want to reverse the operation.
12833
12834 (define_insn "*fp_jcc_1"
12835   [(set (pc)
12836         (if_then_else (match_operator 0 "comparison_operator"
12837                         [(match_operand 1 "register_operand" "f")
12838                          (match_operand 2 "register_operand" "f")])
12839           (label_ref (match_operand 3 "" ""))
12840           (pc)))
12841    (clobber (reg:CCFP FPSR_REG))
12842    (clobber (reg:CCFP FLAGS_REG))]
12843   "TARGET_CMOVE && TARGET_80387
12844    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12845    && FLOAT_MODE_P (GET_MODE (operands[1]))
12846    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12847    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12848   "#")
12849
12850 (define_insn "*fp_jcc_1_sse"
12851   [(set (pc)
12852         (if_then_else (match_operator 0 "comparison_operator"
12853                         [(match_operand 1 "register_operand" "f#x,x#f")
12854                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12855           (label_ref (match_operand 3 "" ""))
12856           (pc)))
12857    (clobber (reg:CCFP FPSR_REG))
12858    (clobber (reg:CCFP FLAGS_REG))]
12859   "TARGET_80387
12860    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12861    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12862    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12863   "#")
12864
12865 (define_insn "*fp_jcc_1_sse_only"
12866   [(set (pc)
12867         (if_then_else (match_operator 0 "comparison_operator"
12868                         [(match_operand 1 "register_operand" "x")
12869                          (match_operand 2 "nonimmediate_operand" "xm")])
12870           (label_ref (match_operand 3 "" ""))
12871           (pc)))
12872    (clobber (reg:CCFP FPSR_REG))
12873    (clobber (reg:CCFP FLAGS_REG))]
12874   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12875    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12876    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12877   "#")
12878
12879 (define_insn "*fp_jcc_2"
12880   [(set (pc)
12881         (if_then_else (match_operator 0 "comparison_operator"
12882                         [(match_operand 1 "register_operand" "f")
12883                          (match_operand 2 "register_operand" "f")])
12884           (pc)
12885           (label_ref (match_operand 3 "" ""))))
12886    (clobber (reg:CCFP FPSR_REG))
12887    (clobber (reg:CCFP FLAGS_REG))]
12888   "TARGET_CMOVE && TARGET_80387
12889    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12890    && FLOAT_MODE_P (GET_MODE (operands[1]))
12891    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12892    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12893   "#")
12894
12895 (define_insn "*fp_jcc_2_sse"
12896   [(set (pc)
12897         (if_then_else (match_operator 0 "comparison_operator"
12898                         [(match_operand 1 "register_operand" "f#x,x#f")
12899                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12900           (pc)
12901           (label_ref (match_operand 3 "" ""))))
12902    (clobber (reg:CCFP FPSR_REG))
12903    (clobber (reg:CCFP FLAGS_REG))]
12904   "TARGET_80387
12905    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12906    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12907    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12908   "#")
12909
12910 (define_insn "*fp_jcc_2_sse_only"
12911   [(set (pc)
12912         (if_then_else (match_operator 0 "comparison_operator"
12913                         [(match_operand 1 "register_operand" "x")
12914                          (match_operand 2 "nonimmediate_operand" "xm")])
12915           (pc)
12916           (label_ref (match_operand 3 "" ""))))
12917    (clobber (reg:CCFP FPSR_REG))
12918    (clobber (reg:CCFP FLAGS_REG))]
12919   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12920    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12921    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12922   "#")
12923
12924 (define_insn "*fp_jcc_3"
12925   [(set (pc)
12926         (if_then_else (match_operator 0 "comparison_operator"
12927                         [(match_operand 1 "register_operand" "f")
12928                          (match_operand 2 "nonimmediate_operand" "fm")])
12929           (label_ref (match_operand 3 "" ""))
12930           (pc)))
12931    (clobber (reg:CCFP FPSR_REG))
12932    (clobber (reg:CCFP FLAGS_REG))
12933    (clobber (match_scratch:HI 4 "=a"))]
12934   "TARGET_80387
12935    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12936    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12937    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12938    && SELECT_CC_MODE (GET_CODE (operands[0]),
12939                       operands[1], operands[2]) == CCFPmode
12940    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12941   "#")
12942
12943 (define_insn "*fp_jcc_4"
12944   [(set (pc)
12945         (if_then_else (match_operator 0 "comparison_operator"
12946                         [(match_operand 1 "register_operand" "f")
12947                          (match_operand 2 "nonimmediate_operand" "fm")])
12948           (pc)
12949           (label_ref (match_operand 3 "" ""))))
12950    (clobber (reg:CCFP FPSR_REG))
12951    (clobber (reg:CCFP FLAGS_REG))
12952    (clobber (match_scratch:HI 4 "=a"))]
12953   "TARGET_80387
12954    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12955    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12956    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12957    && SELECT_CC_MODE (GET_CODE (operands[0]),
12958                       operands[1], operands[2]) == CCFPmode
12959    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12960   "#")
12961
12962 (define_insn "*fp_jcc_5"
12963   [(set (pc)
12964         (if_then_else (match_operator 0 "comparison_operator"
12965                         [(match_operand 1 "register_operand" "f")
12966                          (match_operand 2 "register_operand" "f")])
12967           (label_ref (match_operand 3 "" ""))
12968           (pc)))
12969    (clobber (reg:CCFP FPSR_REG))
12970    (clobber (reg:CCFP FLAGS_REG))
12971    (clobber (match_scratch:HI 4 "=a"))]
12972   "TARGET_80387
12973    && FLOAT_MODE_P (GET_MODE (operands[1]))
12974    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12975    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12976   "#")
12977
12978 (define_insn "*fp_jcc_6"
12979   [(set (pc)
12980         (if_then_else (match_operator 0 "comparison_operator"
12981                         [(match_operand 1 "register_operand" "f")
12982                          (match_operand 2 "register_operand" "f")])
12983           (pc)
12984           (label_ref (match_operand 3 "" ""))))
12985    (clobber (reg:CCFP FPSR_REG))
12986    (clobber (reg:CCFP FLAGS_REG))
12987    (clobber (match_scratch:HI 4 "=a"))]
12988   "TARGET_80387
12989    && FLOAT_MODE_P (GET_MODE (operands[1]))
12990    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12991    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12992   "#")
12993
12994 (define_insn "*fp_jcc_7"
12995   [(set (pc)
12996         (if_then_else (match_operator 0 "comparison_operator"
12997                         [(match_operand 1 "register_operand" "f")
12998                          (match_operand 2 "const_double_operand" "C")])
12999           (label_ref (match_operand 3 "" ""))
13000           (pc)))
13001    (clobber (reg:CCFP FPSR_REG))
13002    (clobber (reg:CCFP FLAGS_REG))
13003    (clobber (match_scratch:HI 4 "=a"))]
13004   "TARGET_80387
13005    && FLOAT_MODE_P (GET_MODE (operands[1]))
13006    && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13007    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13008    && SELECT_CC_MODE (GET_CODE (operands[0]),
13009                       operands[1], operands[2]) == CCFPmode
13010    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13011   "#")
13012
13013 ;; The order of operands in *fp_jcc_8 is forced by combine in
13014 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13015 ;; with a precedence over other operators and is always put in the first
13016 ;; place. Swap condition and operands to match ficom instruction.
13017
13018 (define_insn "*fp_jcc_8"
13019   [(set (pc)
13020         (if_then_else (match_operator 0 "comparison_operator"
13021                         [(match_operator 1 "float_operator"
13022                            [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13023                            (match_operand 3 "register_operand" "f,f")])
13024           (label_ref (match_operand 4 "" ""))
13025           (pc)))
13026    (clobber (reg:CCFP FPSR_REG))
13027    (clobber (reg:CCFP FLAGS_REG))
13028    (clobber (match_scratch:HI 5 "=a,a"))]
13029   "TARGET_80387 && TARGET_USE_FIOP
13030    && FLOAT_MODE_P (GET_MODE (operands[3]))
13031    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13032    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13033    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13034    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13035   "#")
13036
13037 (define_split
13038   [(set (pc)
13039         (if_then_else (match_operator 0 "comparison_operator"
13040                         [(match_operand 1 "register_operand" "")
13041                          (match_operand 2 "nonimmediate_operand" "")])
13042           (match_operand 3 "" "")
13043           (match_operand 4 "" "")))
13044    (clobber (reg:CCFP FPSR_REG))
13045    (clobber (reg:CCFP FLAGS_REG))]
13046   "reload_completed"
13047   [(const_int 0)]
13048 {
13049   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13050                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13051   DONE;
13052 })
13053
13054 (define_split
13055   [(set (pc)
13056         (if_then_else (match_operator 0 "comparison_operator"
13057                         [(match_operand 1 "register_operand" "")
13058                          (match_operand 2 "general_operand" "")])
13059           (match_operand 3 "" "")
13060           (match_operand 4 "" "")))
13061    (clobber (reg:CCFP FPSR_REG))
13062    (clobber (reg:CCFP FLAGS_REG))
13063    (clobber (match_scratch:HI 5 "=a"))]
13064   "reload_completed"
13065   [(const_int 0)]
13066 {
13067   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13068                         operands[3], operands[4], operands[5], NULL_RTX);
13069   DONE;
13070 })
13071
13072 (define_split
13073   [(set (pc)
13074         (if_then_else (match_operator 0 "comparison_operator"
13075                         [(match_operator 1 "float_operator"
13076                            [(match_operand:SI 2 "memory_operand" "")])
13077                            (match_operand 3 "register_operand" "")])
13078           (match_operand 4 "" "")
13079           (match_operand 5 "" "")))
13080    (clobber (reg:CCFP FPSR_REG))
13081    (clobber (reg:CCFP FLAGS_REG))
13082    (clobber (match_scratch:HI 6 "=a"))]
13083   "reload_completed"
13084   [(const_int 0)]
13085 {
13086   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13087   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13088                         operands[3], operands[7],
13089                         operands[4], operands[5], operands[6], NULL_RTX);
13090   DONE;
13091 })
13092
13093 ;; %%% Kill this when reload knows how to do it.
13094 (define_split
13095   [(set (pc)
13096         (if_then_else (match_operator 0 "comparison_operator"
13097                         [(match_operator 1 "float_operator"
13098                            [(match_operand:SI 2 "register_operand" "")])
13099                            (match_operand 3 "register_operand" "")])
13100           (match_operand 4 "" "")
13101           (match_operand 5 "" "")))
13102    (clobber (reg:CCFP FPSR_REG))
13103    (clobber (reg:CCFP FLAGS_REG))
13104    (clobber (match_scratch:HI 6 "=a"))]
13105   "reload_completed"
13106   [(const_int 0)]
13107 {
13108   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13109   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13110   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13111                         operands[3], operands[7],
13112                         operands[4], operands[5], operands[6], operands[2]);
13113   DONE;
13114 })
13115 \f
13116 ;; Unconditional and other jump instructions
13117
13118 (define_insn "jump"
13119   [(set (pc)
13120         (label_ref (match_operand 0 "" "")))]
13121   ""
13122   "jmp\t%l0"
13123   [(set_attr "type" "ibr")
13124    (set (attr "length")
13125            (if_then_else (and (ge (minus (match_dup 0) (pc))
13126                                   (const_int -126))
13127                               (lt (minus (match_dup 0) (pc))
13128                                   (const_int 128)))
13129              (const_int 2)
13130              (const_int 5)))
13131    (set_attr "modrm" "0")])
13132
13133 (define_expand "indirect_jump"
13134   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13135   ""
13136   "")
13137
13138 (define_insn "*indirect_jump"
13139   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13140   "!TARGET_64BIT"
13141   "jmp\t%A0"
13142   [(set_attr "type" "ibr")
13143    (set_attr "length_immediate" "0")])
13144
13145 (define_insn "*indirect_jump_rtx64"
13146   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13147   "TARGET_64BIT"
13148   "jmp\t%A0"
13149   [(set_attr "type" "ibr")
13150    (set_attr "length_immediate" "0")])
13151
13152 (define_expand "tablejump"
13153   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13154               (use (label_ref (match_operand 1 "" "")))])]
13155   ""
13156 {
13157   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13158      relative.  Convert the relative address to an absolute address.  */
13159   if (flag_pic)
13160     {
13161       rtx op0, op1;
13162       enum rtx_code code;
13163
13164       if (TARGET_64BIT)
13165         {
13166           code = PLUS;
13167           op0 = operands[0];
13168           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13169         }
13170       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13171         {
13172           code = PLUS;
13173           op0 = operands[0];
13174           op1 = pic_offset_table_rtx;
13175         }
13176       else
13177         {
13178           code = MINUS;
13179           op0 = pic_offset_table_rtx;
13180           op1 = operands[0];
13181         }
13182
13183       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13184                                          OPTAB_DIRECT);
13185     }
13186 })
13187
13188 (define_insn "*tablejump_1"
13189   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13190    (use (label_ref (match_operand 1 "" "")))]
13191   "!TARGET_64BIT"
13192   "jmp\t%A0"
13193   [(set_attr "type" "ibr")
13194    (set_attr "length_immediate" "0")])
13195
13196 (define_insn "*tablejump_1_rtx64"
13197   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13198    (use (label_ref (match_operand 1 "" "")))]
13199   "TARGET_64BIT"
13200   "jmp\t%A0"
13201   [(set_attr "type" "ibr")
13202    (set_attr "length_immediate" "0")])
13203 \f
13204 ;; Loop instruction
13205 ;;
13206 ;; This is all complicated by the fact that since this is a jump insn
13207 ;; we must handle our own reloads.
13208
13209 (define_expand "doloop_end"
13210   [(use (match_operand 0 "" ""))        ; loop pseudo
13211    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13212    (use (match_operand 2 "" ""))        ; max iterations
13213    (use (match_operand 3 "" ""))        ; loop level 
13214    (use (match_operand 4 "" ""))]       ; label
13215   "!TARGET_64BIT && TARGET_USE_LOOP"
13216   "                                 
13217 {
13218   /* Only use cloop on innermost loops.  */
13219   if (INTVAL (operands[3]) > 1)
13220     FAIL;
13221   if (GET_MODE (operands[0]) != SImode)
13222     FAIL;
13223   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13224                                            operands[0]));
13225   DONE;
13226 }")
13227
13228 (define_insn "doloop_end_internal"
13229   [(set (pc)
13230         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13231                           (const_int 1))
13232                       (label_ref (match_operand 0 "" ""))
13233                       (pc)))
13234    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13235         (plus:SI (match_dup 1)
13236                  (const_int -1)))
13237    (clobber (match_scratch:SI 3 "=X,X,r"))
13238    (clobber (reg:CC FLAGS_REG))]
13239   "!TARGET_64BIT && TARGET_USE_LOOP
13240    && (reload_in_progress || reload_completed
13241        || register_operand (operands[2], VOIDmode))"
13242 {
13243   if (which_alternative != 0)
13244     return "#";
13245   if (get_attr_length (insn) == 2)
13246     return "%+loop\t%l0";
13247   else
13248     return "dec{l}\t%1\;%+jne\t%l0";
13249 }
13250   [(set (attr "length")
13251         (if_then_else (and (eq_attr "alternative" "0")
13252                            (and (ge (minus (match_dup 0) (pc))
13253                                     (const_int -126))
13254                                 (lt (minus (match_dup 0) (pc))
13255                                     (const_int 128))))
13256                       (const_int 2)
13257                       (const_int 16)))
13258    ;; We don't know the type before shorten branches.  Optimistically expect
13259    ;; the loop instruction to match.
13260    (set (attr "type") (const_string "ibr"))])
13261
13262 (define_split
13263   [(set (pc)
13264         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13265                           (const_int 1))
13266                       (match_operand 0 "" "")
13267                       (pc)))
13268    (set (match_dup 1)
13269         (plus:SI (match_dup 1)
13270                  (const_int -1)))
13271    (clobber (match_scratch:SI 2 ""))
13272    (clobber (reg:CC FLAGS_REG))]
13273   "!TARGET_64BIT && TARGET_USE_LOOP
13274    && reload_completed
13275    && REGNO (operands[1]) != 2"
13276   [(parallel [(set (reg:CCZ FLAGS_REG)
13277                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13278                                  (const_int 0)))
13279               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13280    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13281                            (match_dup 0)
13282                            (pc)))]
13283   "")
13284   
13285 (define_split
13286   [(set (pc)
13287         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13288                           (const_int 1))
13289                       (match_operand 0 "" "")
13290                       (pc)))
13291    (set (match_operand:SI 2 "nonimmediate_operand" "")
13292         (plus:SI (match_dup 1)
13293                  (const_int -1)))
13294    (clobber (match_scratch:SI 3 ""))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "!TARGET_64BIT && TARGET_USE_LOOP
13297    && reload_completed
13298    && (! REG_P (operands[2])
13299        || ! rtx_equal_p (operands[1], operands[2]))"
13300   [(set (match_dup 3) (match_dup 1))
13301    (parallel [(set (reg:CCZ FLAGS_REG)
13302                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13303                                 (const_int 0)))
13304               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13305    (set (match_dup 2) (match_dup 3))
13306    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13307                            (match_dup 0)
13308                            (pc)))]
13309   "")
13310
13311 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13312
13313 (define_peephole2
13314   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13315    (set (match_operand:QI 1 "register_operand" "")
13316         (match_operator:QI 2 "ix86_comparison_operator"
13317           [(reg FLAGS_REG) (const_int 0)]))
13318    (set (match_operand 3 "q_regs_operand" "")
13319         (zero_extend (match_dup 1)))]
13320   "(peep2_reg_dead_p (3, operands[1])
13321     || operands_match_p (operands[1], operands[3]))
13322    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13323   [(set (match_dup 4) (match_dup 0))
13324    (set (strict_low_part (match_dup 5))
13325         (match_dup 2))]
13326 {
13327   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13328   operands[5] = gen_lowpart (QImode, operands[3]);
13329   ix86_expand_clear (operands[3]);
13330 })
13331
13332 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13333
13334 (define_peephole2
13335   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13336    (set (match_operand:QI 1 "register_operand" "")
13337         (match_operator:QI 2 "ix86_comparison_operator"
13338           [(reg FLAGS_REG) (const_int 0)]))
13339    (parallel [(set (match_operand 3 "q_regs_operand" "")
13340                    (zero_extend (match_dup 1)))
13341               (clobber (reg:CC FLAGS_REG))])]
13342   "(peep2_reg_dead_p (3, operands[1])
13343     || operands_match_p (operands[1], operands[3]))
13344    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13345   [(set (match_dup 4) (match_dup 0))
13346    (set (strict_low_part (match_dup 5))
13347         (match_dup 2))]
13348 {
13349   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13350   operands[5] = gen_lowpart (QImode, operands[3]);
13351   ix86_expand_clear (operands[3]);
13352 })
13353 \f
13354 ;; Call instructions.
13355
13356 ;; The predicates normally associated with named expanders are not properly
13357 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13358 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13359
13360 ;; Call subroutine returning no value.
13361
13362 (define_expand "call_pop"
13363   [(parallel [(call (match_operand:QI 0 "" "")
13364                     (match_operand:SI 1 "" ""))
13365               (set (reg:SI SP_REG)
13366                    (plus:SI (reg:SI SP_REG)
13367                             (match_operand:SI 3 "" "")))])]
13368   "!TARGET_64BIT"
13369 {
13370   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13371   DONE;
13372 })
13373
13374 (define_insn "*call_pop_0"
13375   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13376          (match_operand:SI 1 "" ""))
13377    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13378                             (match_operand:SI 2 "immediate_operand" "")))]
13379   "!TARGET_64BIT"
13380 {
13381   if (SIBLING_CALL_P (insn))
13382     return "jmp\t%P0";
13383   else
13384     return "call\t%P0";
13385 }
13386   [(set_attr "type" "call")])
13387   
13388 (define_insn "*call_pop_1"
13389   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13390          (match_operand:SI 1 "" ""))
13391    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13392                             (match_operand:SI 2 "immediate_operand" "i")))]
13393   "!TARGET_64BIT"
13394 {
13395   if (constant_call_address_operand (operands[0], Pmode))
13396     {
13397       if (SIBLING_CALL_P (insn))
13398         return "jmp\t%P0";
13399       else
13400         return "call\t%P0";
13401     }
13402   if (SIBLING_CALL_P (insn))
13403     return "jmp\t%A0";
13404   else
13405     return "call\t%A0";
13406 }
13407   [(set_attr "type" "call")])
13408
13409 (define_expand "call"
13410   [(call (match_operand:QI 0 "" "")
13411          (match_operand 1 "" ""))
13412    (use (match_operand 2 "" ""))]
13413   ""
13414 {
13415   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13416   DONE;
13417 })
13418
13419 (define_expand "sibcall"
13420   [(call (match_operand:QI 0 "" "")
13421          (match_operand 1 "" ""))
13422    (use (match_operand 2 "" ""))]
13423   ""
13424 {
13425   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13426   DONE;
13427 })
13428
13429 (define_insn "*call_0"
13430   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13431          (match_operand 1 "" ""))]
13432   ""
13433 {
13434   if (SIBLING_CALL_P (insn))
13435     return "jmp\t%P0";
13436   else
13437     return "call\t%P0";
13438 }
13439   [(set_attr "type" "call")])
13440
13441 (define_insn "*call_1"
13442   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13443          (match_operand 1 "" ""))]
13444   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13445 {
13446   if (constant_call_address_operand (operands[0], Pmode))
13447     return "call\t%P0";
13448   return "call\t%A0";
13449 }
13450   [(set_attr "type" "call")])
13451
13452 (define_insn "*sibcall_1"
13453   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13454          (match_operand 1 "" ""))]
13455   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13456 {
13457   if (constant_call_address_operand (operands[0], Pmode))
13458     return "jmp\t%P0";
13459   return "jmp\t%A0";
13460 }
13461   [(set_attr "type" "call")])
13462
13463 (define_insn "*call_1_rex64"
13464   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13465          (match_operand 1 "" ""))]
13466   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13467 {
13468   if (constant_call_address_operand (operands[0], Pmode))
13469     return "call\t%P0";
13470   return "call\t%A0";
13471 }
13472   [(set_attr "type" "call")])
13473
13474 (define_insn "*sibcall_1_rex64"
13475   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13476          (match_operand 1 "" ""))]
13477   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13478   "jmp\t%P0"
13479   [(set_attr "type" "call")])
13480
13481 (define_insn "*sibcall_1_rex64_v"
13482   [(call (mem:QI (reg:DI 40))
13483          (match_operand 0 "" ""))]
13484   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13485   "jmp\t*%%r11"
13486   [(set_attr "type" "call")])
13487
13488
13489 ;; Call subroutine, returning value in operand 0
13490
13491 (define_expand "call_value_pop"
13492   [(parallel [(set (match_operand 0 "" "")
13493                    (call (match_operand:QI 1 "" "")
13494                          (match_operand:SI 2 "" "")))
13495               (set (reg:SI SP_REG)
13496                    (plus:SI (reg:SI SP_REG)
13497                             (match_operand:SI 4 "" "")))])]
13498   "!TARGET_64BIT"
13499 {
13500   ix86_expand_call (operands[0], operands[1], operands[2],
13501                     operands[3], operands[4], 0);
13502   DONE;
13503 })
13504
13505 (define_expand "call_value"
13506   [(set (match_operand 0 "" "")
13507         (call (match_operand:QI 1 "" "")
13508               (match_operand:SI 2 "" "")))
13509    (use (match_operand:SI 3 "" ""))]
13510   ;; Operand 2 not used on the i386.
13511   ""
13512 {
13513   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13514   DONE;
13515 })
13516
13517 (define_expand "sibcall_value"
13518   [(set (match_operand 0 "" "")
13519         (call (match_operand:QI 1 "" "")
13520               (match_operand:SI 2 "" "")))
13521    (use (match_operand:SI 3 "" ""))]
13522   ;; Operand 2 not used on the i386.
13523   ""
13524 {
13525   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13526   DONE;
13527 })
13528
13529 ;; Call subroutine returning any type.
13530
13531 (define_expand "untyped_call"
13532   [(parallel [(call (match_operand 0 "" "")
13533                     (const_int 0))
13534               (match_operand 1 "" "")
13535               (match_operand 2 "" "")])]
13536   ""
13537 {
13538   int i;
13539
13540   /* In order to give reg-stack an easier job in validating two
13541      coprocessor registers as containing a possible return value,
13542      simply pretend the untyped call returns a complex long double
13543      value.  */
13544
13545   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13546                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13547                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13548                     NULL, 0);
13549
13550   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13551     {
13552       rtx set = XVECEXP (operands[2], 0, i);
13553       emit_move_insn (SET_DEST (set), SET_SRC (set));
13554     }
13555
13556   /* The optimizer does not know that the call sets the function value
13557      registers we stored in the result block.  We avoid problems by
13558      claiming that all hard registers are used and clobbered at this
13559      point.  */
13560   emit_insn (gen_blockage (const0_rtx));
13561
13562   DONE;
13563 })
13564 \f
13565 ;; Prologue and epilogue instructions
13566
13567 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13568 ;; all of memory.  This blocks insns from being moved across this point.
13569
13570 (define_insn "blockage"
13571   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13572   ""
13573   ""
13574   [(set_attr "length" "0")])
13575
13576 ;; Insn emitted into the body of a function to return from a function.
13577 ;; This is only done if the function's epilogue is known to be simple.
13578 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13579
13580 (define_expand "return"
13581   [(return)]
13582   "ix86_can_use_return_insn_p ()"
13583 {
13584   if (current_function_pops_args)
13585     {
13586       rtx popc = GEN_INT (current_function_pops_args);
13587       emit_jump_insn (gen_return_pop_internal (popc));
13588       DONE;
13589     }
13590 })
13591
13592 (define_insn "return_internal"
13593   [(return)]
13594   "reload_completed"
13595   "ret"
13596   [(set_attr "length" "1")
13597    (set_attr "length_immediate" "0")
13598    (set_attr "modrm" "0")])
13599
13600 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13601 ;; instruction Athlon and K8 have.
13602
13603 (define_insn "return_internal_long"
13604   [(return)
13605    (unspec [(const_int 0)] UNSPEC_REP)]
13606   "reload_completed"
13607   "rep {;} ret"
13608   [(set_attr "length" "1")
13609    (set_attr "length_immediate" "0")
13610    (set_attr "prefix_rep" "1")
13611    (set_attr "modrm" "0")])
13612
13613 (define_insn "return_pop_internal"
13614   [(return)
13615    (use (match_operand:SI 0 "const_int_operand" ""))]
13616   "reload_completed"
13617   "ret\t%0"
13618   [(set_attr "length" "3")
13619    (set_attr "length_immediate" "2")
13620    (set_attr "modrm" "0")])
13621
13622 (define_insn "return_indirect_internal"
13623   [(return)
13624    (use (match_operand:SI 0 "register_operand" "r"))]
13625   "reload_completed"
13626   "jmp\t%A0"
13627   [(set_attr "type" "ibr")
13628    (set_attr "length_immediate" "0")])
13629
13630 (define_insn "nop"
13631   [(const_int 0)]
13632   ""
13633   "nop"
13634   [(set_attr "length" "1")
13635    (set_attr "length_immediate" "0")
13636    (set_attr "modrm" "0")])
13637
13638 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13639 ;; branch prediction penalty for the third jump in a 16-byte
13640 ;; block on K8.
13641
13642 (define_insn "align"
13643   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13644   ""
13645 {
13646 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13647   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13648 #else
13649   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13650      The align insn is used to avoid 3 jump instructions in the row to improve
13651      branch prediction and the benefits hardly outweight the cost of extra 8
13652      nops on the average inserted by full alignment pseudo operation.  */
13653 #endif
13654   return "";
13655 }
13656   [(set_attr "length" "16")])
13657
13658 (define_expand "prologue"
13659   [(const_int 1)]
13660   ""
13661   "ix86_expand_prologue (); DONE;")
13662
13663 (define_insn "set_got"
13664   [(set (match_operand:SI 0 "register_operand" "=r")
13665         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13666    (clobber (reg:CC FLAGS_REG))]
13667   "!TARGET_64BIT"
13668   { return output_set_got (operands[0]); }
13669   [(set_attr "type" "multi")
13670    (set_attr "length" "12")])
13671
13672 (define_expand "epilogue"
13673   [(const_int 1)]
13674   ""
13675   "ix86_expand_epilogue (1); DONE;")
13676
13677 (define_expand "sibcall_epilogue"
13678   [(const_int 1)]
13679   ""
13680   "ix86_expand_epilogue (0); DONE;")
13681
13682 (define_expand "eh_return"
13683   [(use (match_operand 0 "register_operand" ""))]
13684   ""
13685 {
13686   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13687
13688   /* Tricky bit: we write the address of the handler to which we will
13689      be returning into someone else's stack frame, one word below the
13690      stack address we wish to restore.  */
13691   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13692   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13693   tmp = gen_rtx_MEM (Pmode, tmp);
13694   emit_move_insn (tmp, ra);
13695
13696   if (Pmode == SImode)
13697     emit_jump_insn (gen_eh_return_si (sa));
13698   else
13699     emit_jump_insn (gen_eh_return_di (sa));
13700   emit_barrier ();
13701   DONE;
13702 })
13703
13704 (define_insn_and_split "eh_return_si"
13705   [(set (pc) 
13706         (unspec [(match_operand:SI 0 "register_operand" "c")]
13707                  UNSPEC_EH_RETURN))]
13708   "!TARGET_64BIT"
13709   "#"
13710   "reload_completed"
13711   [(const_int 1)]
13712   "ix86_expand_epilogue (2); DONE;")
13713
13714 (define_insn_and_split "eh_return_di"
13715   [(set (pc) 
13716         (unspec [(match_operand:DI 0 "register_operand" "c")]
13717                  UNSPEC_EH_RETURN))]
13718   "TARGET_64BIT"
13719   "#"
13720   "reload_completed"
13721   [(const_int 1)]
13722   "ix86_expand_epilogue (2); DONE;")
13723
13724 (define_insn "leave"
13725   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13726    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13727    (clobber (mem:BLK (scratch)))]
13728   "!TARGET_64BIT"
13729   "leave"
13730   [(set_attr "type" "leave")])
13731
13732 (define_insn "leave_rex64"
13733   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13734    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13735    (clobber (mem:BLK (scratch)))]
13736   "TARGET_64BIT"
13737   "leave"
13738   [(set_attr "type" "leave")])
13739 \f
13740 (define_expand "ffssi2"
13741   [(parallel
13742      [(set (match_operand:SI 0 "register_operand" "") 
13743            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13744       (clobber (match_scratch:SI 2 ""))
13745       (clobber (reg:CC FLAGS_REG))])]
13746   ""
13747   "")
13748
13749 (define_insn_and_split "*ffs_cmove"
13750   [(set (match_operand:SI 0 "register_operand" "=r") 
13751         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13752    (clobber (match_scratch:SI 2 "=&r"))
13753    (clobber (reg:CC FLAGS_REG))]
13754   "TARGET_CMOVE"
13755   "#"
13756   "&& reload_completed"
13757   [(set (match_dup 2) (const_int -1))
13758    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13759               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13760    (set (match_dup 0) (if_then_else:SI
13761                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13762                         (match_dup 2)
13763                         (match_dup 0)))
13764    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13765               (clobber (reg:CC FLAGS_REG))])]
13766   "")
13767
13768 (define_insn_and_split "*ffs_no_cmove"
13769   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13770         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13771    (clobber (match_scratch:SI 2 "=&q"))
13772    (clobber (reg:CC FLAGS_REG))]
13773   ""
13774   "#"
13775   "reload_completed"
13776   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13777               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13778    (set (strict_low_part (match_dup 3))
13779         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13780    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13781               (clobber (reg:CC FLAGS_REG))])
13782    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13783               (clobber (reg:CC FLAGS_REG))])
13784    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13785               (clobber (reg:CC FLAGS_REG))])]
13786 {
13787   operands[3] = gen_lowpart (QImode, operands[2]);
13788   ix86_expand_clear (operands[2]);
13789 })
13790
13791 (define_insn "*ffssi_1"
13792   [(set (reg:CCZ FLAGS_REG)
13793         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13794                      (const_int 0)))
13795    (set (match_operand:SI 0 "register_operand" "=r")
13796         (ctz:SI (match_dup 1)))]
13797   ""
13798   "bsf{l}\t{%1, %0|%0, %1}"
13799   [(set_attr "prefix_0f" "1")])
13800
13801 (define_expand "ffsdi2"
13802   [(parallel
13803      [(set (match_operand:DI 0 "register_operand" "") 
13804            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13805       (clobber (match_scratch:DI 2 ""))
13806       (clobber (reg:CC FLAGS_REG))])]
13807   "TARGET_64BIT && TARGET_CMOVE"
13808   "")
13809
13810 (define_insn_and_split "*ffs_rex64"
13811   [(set (match_operand:DI 0 "register_operand" "=r") 
13812         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13813    (clobber (match_scratch:DI 2 "=&r"))
13814    (clobber (reg:CC FLAGS_REG))]
13815   "TARGET_64BIT && TARGET_CMOVE"
13816   "#"
13817   "&& reload_completed"
13818   [(set (match_dup 2) (const_int -1))
13819    (parallel [(set (reg:CCZ FLAGS_REG)
13820                    (compare:CCZ (match_dup 1) (const_int 0)))
13821               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13822    (set (match_dup 0) (if_then_else:DI
13823                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13824                         (match_dup 2)
13825                         (match_dup 0)))
13826    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13827               (clobber (reg:CC FLAGS_REG))])]
13828   "")
13829
13830 (define_insn "*ffsdi_1"
13831   [(set (reg:CCZ FLAGS_REG)
13832         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13833                      (const_int 0)))
13834    (set (match_operand:DI 0 "register_operand" "=r")
13835         (ctz:DI (match_dup 1)))]
13836   "TARGET_64BIT"
13837   "bsf{q}\t{%1, %0|%0, %1}"
13838   [(set_attr "prefix_0f" "1")])
13839
13840 (define_insn "ctzsi2"
13841   [(set (match_operand:SI 0 "register_operand" "=r")
13842         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13843    (clobber (reg:CC FLAGS_REG))]
13844   ""
13845   "bsf{l}\t{%1, %0|%0, %1}"
13846   [(set_attr "prefix_0f" "1")])
13847
13848 (define_insn "ctzdi2"
13849   [(set (match_operand:DI 0 "register_operand" "=r")
13850         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13851    (clobber (reg:CC FLAGS_REG))]
13852   "TARGET_64BIT"
13853   "bsf{q}\t{%1, %0|%0, %1}"
13854   [(set_attr "prefix_0f" "1")])
13855
13856 (define_expand "clzsi2"
13857   [(parallel
13858      [(set (match_operand:SI 0 "register_operand" "")
13859            (minus:SI (const_int 31)
13860                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13861       (clobber (reg:CC FLAGS_REG))])
13862    (parallel
13863      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13864       (clobber (reg:CC FLAGS_REG))])]
13865   ""
13866   "")
13867
13868 (define_insn "*bsr"
13869   [(set (match_operand:SI 0 "register_operand" "=r")
13870         (minus:SI (const_int 31)
13871                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13872    (clobber (reg:CC FLAGS_REG))]
13873   ""
13874   "bsr{l}\t{%1, %0|%0, %1}"
13875   [(set_attr "prefix_0f" "1")])
13876
13877 (define_expand "clzdi2"
13878   [(parallel
13879      [(set (match_operand:DI 0 "register_operand" "")
13880            (minus:DI (const_int 63)
13881                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13882       (clobber (reg:CC FLAGS_REG))])
13883    (parallel
13884      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13885       (clobber (reg:CC FLAGS_REG))])]
13886   "TARGET_64BIT"
13887   "")
13888
13889 (define_insn "*bsr_rex64"
13890   [(set (match_operand:DI 0 "register_operand" "=r")
13891         (minus:DI (const_int 63)
13892                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13893    (clobber (reg:CC FLAGS_REG))]
13894   "TARGET_64BIT"
13895   "bsr{q}\t{%1, %0|%0, %1}"
13896   [(set_attr "prefix_0f" "1")])
13897 \f
13898 ;; Thread-local storage patterns for ELF.
13899 ;;
13900 ;; Note that these code sequences must appear exactly as shown
13901 ;; in order to allow linker relaxation.
13902
13903 (define_insn "*tls_global_dynamic_32_gnu"
13904   [(set (match_operand:SI 0 "register_operand" "=a")
13905         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13906                     (match_operand:SI 2 "tls_symbolic_operand" "")
13907                     (match_operand:SI 3 "call_insn_operand" "")]
13908                     UNSPEC_TLS_GD))
13909    (clobber (match_scratch:SI 4 "=d"))
13910    (clobber (match_scratch:SI 5 "=c"))
13911    (clobber (reg:CC FLAGS_REG))]
13912   "!TARGET_64BIT && TARGET_GNU_TLS"
13913   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13914   [(set_attr "type" "multi")
13915    (set_attr "length" "12")])
13916
13917 (define_insn "*tls_global_dynamic_32_sun"
13918   [(set (match_operand:SI 0 "register_operand" "=a")
13919         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13920                     (match_operand:SI 2 "tls_symbolic_operand" "")
13921                     (match_operand:SI 3 "call_insn_operand" "")]
13922                     UNSPEC_TLS_GD))
13923    (clobber (match_scratch:SI 4 "=d"))
13924    (clobber (match_scratch:SI 5 "=c"))
13925    (clobber (reg:CC FLAGS_REG))]
13926   "!TARGET_64BIT && TARGET_SUN_TLS"
13927   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13928         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13929   [(set_attr "type" "multi")
13930    (set_attr "length" "14")])
13931
13932 (define_expand "tls_global_dynamic_32"
13933   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13934                    (unspec:SI
13935                     [(match_dup 2)
13936                      (match_operand:SI 1 "tls_symbolic_operand" "")
13937                      (match_dup 3)]
13938                     UNSPEC_TLS_GD))
13939               (clobber (match_scratch:SI 4 ""))
13940               (clobber (match_scratch:SI 5 ""))
13941               (clobber (reg:CC FLAGS_REG))])]
13942   ""
13943 {
13944   if (flag_pic)
13945     operands[2] = pic_offset_table_rtx;
13946   else
13947     {
13948       operands[2] = gen_reg_rtx (Pmode);
13949       emit_insn (gen_set_got (operands[2]));
13950     }
13951   operands[3] = ix86_tls_get_addr ();
13952 })
13953
13954 (define_insn "*tls_global_dynamic_64"
13955   [(set (match_operand:DI 0 "register_operand" "=a")
13956         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13957                       (match_operand:DI 3 "" "")))
13958    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13959               UNSPEC_TLS_GD)]
13960   "TARGET_64BIT"
13961   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13962   [(set_attr "type" "multi")
13963    (set_attr "length" "16")])
13964
13965 (define_expand "tls_global_dynamic_64"
13966   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13967                    (call (mem:QI (match_dup 2)) (const_int 0)))
13968               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13969                          UNSPEC_TLS_GD)])]
13970   ""
13971 {
13972   operands[2] = ix86_tls_get_addr ();
13973 })
13974
13975 (define_insn "*tls_local_dynamic_base_32_gnu"
13976   [(set (match_operand:SI 0 "register_operand" "=a")
13977         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13978                     (match_operand:SI 2 "call_insn_operand" "")]
13979                    UNSPEC_TLS_LD_BASE))
13980    (clobber (match_scratch:SI 3 "=d"))
13981    (clobber (match_scratch:SI 4 "=c"))
13982    (clobber (reg:CC FLAGS_REG))]
13983   "!TARGET_64BIT && TARGET_GNU_TLS"
13984   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13985   [(set_attr "type" "multi")
13986    (set_attr "length" "11")])
13987
13988 (define_insn "*tls_local_dynamic_base_32_sun"
13989   [(set (match_operand:SI 0 "register_operand" "=a")
13990         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13991                     (match_operand:SI 2 "call_insn_operand" "")]
13992                    UNSPEC_TLS_LD_BASE))
13993    (clobber (match_scratch:SI 3 "=d"))
13994    (clobber (match_scratch:SI 4 "=c"))
13995    (clobber (reg:CC FLAGS_REG))]
13996   "!TARGET_64BIT && TARGET_SUN_TLS"
13997   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13998         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13999   [(set_attr "type" "multi")
14000    (set_attr "length" "13")])
14001
14002 (define_expand "tls_local_dynamic_base_32"
14003   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14004                    (unspec:SI [(match_dup 1) (match_dup 2)]
14005                               UNSPEC_TLS_LD_BASE))
14006               (clobber (match_scratch:SI 3 ""))
14007               (clobber (match_scratch:SI 4 ""))
14008               (clobber (reg:CC FLAGS_REG))])]
14009   ""
14010 {
14011   if (flag_pic)
14012     operands[1] = pic_offset_table_rtx;
14013   else
14014     {
14015       operands[1] = gen_reg_rtx (Pmode);
14016       emit_insn (gen_set_got (operands[1]));
14017     }
14018   operands[2] = ix86_tls_get_addr ();
14019 })
14020
14021 (define_insn "*tls_local_dynamic_base_64"
14022   [(set (match_operand:DI 0 "register_operand" "=a")
14023         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14024                       (match_operand:DI 2 "" "")))
14025    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14026   "TARGET_64BIT"
14027   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14028   [(set_attr "type" "multi")
14029    (set_attr "length" "12")])
14030
14031 (define_expand "tls_local_dynamic_base_64"
14032   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14033                    (call (mem:QI (match_dup 1)) (const_int 0)))
14034               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14035   ""
14036 {
14037   operands[1] = ix86_tls_get_addr ();
14038 })
14039
14040 ;; Local dynamic of a single variable is a lose.  Show combine how
14041 ;; to convert that back to global dynamic.
14042
14043 (define_insn_and_split "*tls_local_dynamic_32_once"
14044   [(set (match_operand:SI 0 "register_operand" "=a")
14045         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14046                              (match_operand:SI 2 "call_insn_operand" "")]
14047                             UNSPEC_TLS_LD_BASE)
14048                  (const:SI (unspec:SI
14049                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14050                             UNSPEC_DTPOFF))))
14051    (clobber (match_scratch:SI 4 "=d"))
14052    (clobber (match_scratch:SI 5 "=c"))
14053    (clobber (reg:CC FLAGS_REG))]
14054   ""
14055   "#"
14056   ""
14057   [(parallel [(set (match_dup 0)
14058                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14059                               UNSPEC_TLS_GD))
14060               (clobber (match_dup 4))
14061               (clobber (match_dup 5))
14062               (clobber (reg:CC FLAGS_REG))])]
14063   "")
14064
14065 ;; Load and add the thread base pointer from %gs:0.
14066
14067 (define_insn "*load_tp_si"
14068   [(set (match_operand:SI 0 "register_operand" "=r")
14069         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14070   "!TARGET_64BIT"
14071   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14072   [(set_attr "type" "imov")
14073    (set_attr "modrm" "0")
14074    (set_attr "length" "7")
14075    (set_attr "memory" "load")
14076    (set_attr "imm_disp" "false")])
14077
14078 (define_insn "*add_tp_si"
14079   [(set (match_operand:SI 0 "register_operand" "=r")
14080         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14081                  (match_operand:SI 1 "register_operand" "0")))
14082    (clobber (reg:CC FLAGS_REG))]
14083   "!TARGET_64BIT"
14084   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14085   [(set_attr "type" "alu")
14086    (set_attr "modrm" "0")
14087    (set_attr "length" "7")
14088    (set_attr "memory" "load")
14089    (set_attr "imm_disp" "false")])
14090
14091 (define_insn "*load_tp_di"
14092   [(set (match_operand:DI 0 "register_operand" "=r")
14093         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14094   "TARGET_64BIT"
14095   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14096   [(set_attr "type" "imov")
14097    (set_attr "modrm" "0")
14098    (set_attr "length" "7")
14099    (set_attr "memory" "load")
14100    (set_attr "imm_disp" "false")])
14101
14102 (define_insn "*add_tp_di"
14103   [(set (match_operand:DI 0 "register_operand" "=r")
14104         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14105                  (match_operand:DI 1 "register_operand" "0")))
14106    (clobber (reg:CC FLAGS_REG))]
14107   "TARGET_64BIT"
14108   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14109   [(set_attr "type" "alu")
14110    (set_attr "modrm" "0")
14111    (set_attr "length" "7")
14112    (set_attr "memory" "load")
14113    (set_attr "imm_disp" "false")])
14114 \f
14115 ;; These patterns match the binary 387 instructions for addM3, subM3,
14116 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14117 ;; SFmode.  The first is the normal insn, the second the same insn but
14118 ;; with one operand a conversion, and the third the same insn but with
14119 ;; the other operand a conversion.  The conversion may be SFmode or
14120 ;; SImode if the target mode DFmode, but only SImode if the target mode
14121 ;; is SFmode.
14122
14123 ;; Gcc is slightly more smart about handling normal two address instructions
14124 ;; so use special patterns for add and mull.
14125
14126 (define_insn "*fop_sf_comm_mixed"
14127   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14128         (match_operator:SF 3 "binary_fp_operator"
14129                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14130                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14131   "TARGET_MIX_SSE_I387
14132    && COMMUTATIVE_ARITH_P (operands[3])
14133    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14134   "* return output_387_binary_op (insn, operands);"
14135   [(set (attr "type") 
14136         (if_then_else (eq_attr "alternative" "1")
14137            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14138               (const_string "ssemul")
14139               (const_string "sseadd"))
14140            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14141               (const_string "fmul")
14142               (const_string "fop"))))
14143    (set_attr "mode" "SF")])
14144
14145 (define_insn "*fop_sf_comm_sse"
14146   [(set (match_operand:SF 0 "register_operand" "=x")
14147         (match_operator:SF 3 "binary_fp_operator"
14148                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14149                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14150   "TARGET_SSE_MATH
14151    && COMMUTATIVE_ARITH_P (operands[3])
14152    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14153   "* return output_387_binary_op (insn, operands);"
14154   [(set (attr "type") 
14155         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14156            (const_string "ssemul")
14157            (const_string "sseadd")))
14158    (set_attr "mode" "SF")])
14159
14160 (define_insn "*fop_sf_comm_i387"
14161   [(set (match_operand:SF 0 "register_operand" "=f")
14162         (match_operator:SF 3 "binary_fp_operator"
14163                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14164                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14165   "TARGET_80387
14166    && COMMUTATIVE_ARITH_P (operands[3])
14167    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14168   "* return output_387_binary_op (insn, operands);"
14169   [(set (attr "type") 
14170         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14171            (const_string "fmul")
14172            (const_string "fop")))
14173    (set_attr "mode" "SF")])
14174
14175 (define_insn "*fop_sf_1_mixed"
14176   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14177         (match_operator:SF 3 "binary_fp_operator"
14178                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14179                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14180   "TARGET_MIX_SSE_I387
14181    && !COMMUTATIVE_ARITH_P (operands[3])
14182    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14183   "* return output_387_binary_op (insn, operands);"
14184   [(set (attr "type") 
14185         (cond [(and (eq_attr "alternative" "2")
14186                     (match_operand:SF 3 "mult_operator" ""))
14187                  (const_string "ssemul")
14188                (and (eq_attr "alternative" "2")
14189                     (match_operand:SF 3 "div_operator" ""))
14190                  (const_string "ssediv")
14191                (eq_attr "alternative" "2")
14192                  (const_string "sseadd")
14193                (match_operand:SF 3 "mult_operator" "") 
14194                  (const_string "fmul")
14195                (match_operand:SF 3 "div_operator" "") 
14196                  (const_string "fdiv")
14197               ]
14198               (const_string "fop")))
14199    (set_attr "mode" "SF")])
14200
14201 (define_insn "*fop_sf_1_sse"
14202   [(set (match_operand:SF 0 "register_operand" "=x")
14203         (match_operator:SF 3 "binary_fp_operator"
14204                         [(match_operand:SF 1 "register_operand" "0")
14205                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14206   "TARGET_SSE_MATH
14207    && !COMMUTATIVE_ARITH_P (operands[3])"
14208   "* return output_387_binary_op (insn, operands);"
14209   [(set (attr "type") 
14210         (cond [(match_operand:SF 3 "mult_operator" "")
14211                  (const_string "ssemul")
14212                (match_operand:SF 3 "div_operator" "")
14213                  (const_string "ssediv")
14214               ]
14215               (const_string "sseadd")))
14216    (set_attr "mode" "SF")])
14217
14218 ;; This pattern is not fully shadowed by the pattern above.
14219 (define_insn "*fop_sf_1_i387"
14220   [(set (match_operand:SF 0 "register_operand" "=f,f")
14221         (match_operator:SF 3 "binary_fp_operator"
14222                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14223                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14224   "TARGET_80387 && !TARGET_SSE_MATH
14225    && !COMMUTATIVE_ARITH_P (operands[3])
14226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14227   "* return output_387_binary_op (insn, operands);"
14228   [(set (attr "type") 
14229         (cond [(match_operand:SF 3 "mult_operator" "") 
14230                  (const_string "fmul")
14231                (match_operand:SF 3 "div_operator" "") 
14232                  (const_string "fdiv")
14233               ]
14234               (const_string "fop")))
14235    (set_attr "mode" "SF")])
14236
14237
14238 ;; ??? Add SSE splitters for these!
14239 (define_insn "*fop_sf_2_i387"
14240   [(set (match_operand:SF 0 "register_operand" "=f,f")
14241         (match_operator:SF 3 "binary_fp_operator"
14242           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14243            (match_operand:SF 2 "register_operand" "0,0")]))]
14244   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14245   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14246   [(set (attr "type") 
14247         (cond [(match_operand:SF 3 "mult_operator" "") 
14248                  (const_string "fmul")
14249                (match_operand:SF 3 "div_operator" "") 
14250                  (const_string "fdiv")
14251               ]
14252               (const_string "fop")))
14253    (set_attr "fp_int_src" "true")
14254    (set_attr "mode" "SI")])
14255
14256 (define_insn "*fop_sf_3_i387"
14257   [(set (match_operand:SF 0 "register_operand" "=f,f")
14258         (match_operator:SF 3 "binary_fp_operator"
14259           [(match_operand:SF 1 "register_operand" "0,0")
14260            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14261   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14262   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14263   [(set (attr "type") 
14264         (cond [(match_operand:SF 3 "mult_operator" "") 
14265                  (const_string "fmul")
14266                (match_operand:SF 3 "div_operator" "") 
14267                  (const_string "fdiv")
14268               ]
14269               (const_string "fop")))
14270    (set_attr "fp_int_src" "true")
14271    (set_attr "mode" "SI")])
14272
14273 (define_insn "*fop_df_comm_mixed"
14274   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14275         (match_operator:DF 3 "binary_fp_operator"
14276                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14277                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14278   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14279    && COMMUTATIVE_ARITH_P (operands[3])
14280    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14281   "* return output_387_binary_op (insn, operands);"
14282   [(set (attr "type") 
14283         (if_then_else (eq_attr "alternative" "1")
14284            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14285               (const_string "ssemul")
14286               (const_string "sseadd"))
14287            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14288               (const_string "fmul")
14289               (const_string "fop"))))
14290    (set_attr "mode" "DF")])
14291
14292 (define_insn "*fop_df_comm_sse"
14293   [(set (match_operand:DF 0 "register_operand" "=Y")
14294         (match_operator:DF 3 "binary_fp_operator"
14295                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14296                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14297   "TARGET_SSE2 && TARGET_SSE_MATH
14298    && COMMUTATIVE_ARITH_P (operands[3])
14299    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14300   "* return output_387_binary_op (insn, operands);"
14301   [(set (attr "type") 
14302         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14303            (const_string "ssemul")
14304            (const_string "sseadd")))
14305    (set_attr "mode" "DF")])
14306
14307 (define_insn "*fop_df_comm_i387"
14308   [(set (match_operand:DF 0 "register_operand" "=f")
14309         (match_operator:DF 3 "binary_fp_operator"
14310                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14311                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14312   "TARGET_80387
14313    && COMMUTATIVE_ARITH_P (operands[3])
14314    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14315   "* return output_387_binary_op (insn, operands);"
14316   [(set (attr "type") 
14317         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14318            (const_string "fmul")
14319            (const_string "fop")))
14320    (set_attr "mode" "DF")])
14321
14322 (define_insn "*fop_df_1_mixed"
14323   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14324         (match_operator:DF 3 "binary_fp_operator"
14325                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14326                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14327   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14328    && !COMMUTATIVE_ARITH_P (operands[3])
14329    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14330   "* return output_387_binary_op (insn, operands);"
14331   [(set (attr "type") 
14332         (cond [(and (eq_attr "alternative" "2")
14333                     (match_operand:SF 3 "mult_operator" ""))
14334                  (const_string "ssemul")
14335                (and (eq_attr "alternative" "2")
14336                     (match_operand:SF 3 "div_operator" ""))
14337                  (const_string "ssediv")
14338                (eq_attr "alternative" "2")
14339                  (const_string "sseadd")
14340                (match_operand:DF 3 "mult_operator" "") 
14341                  (const_string "fmul")
14342                (match_operand:DF 3 "div_operator" "") 
14343                  (const_string "fdiv")
14344               ]
14345               (const_string "fop")))
14346    (set_attr "mode" "DF")])
14347
14348 (define_insn "*fop_df_1_sse"
14349   [(set (match_operand:DF 0 "register_operand" "=Y")
14350         (match_operator:DF 3 "binary_fp_operator"
14351                         [(match_operand:DF 1 "register_operand" "0")
14352                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14353   "TARGET_SSE2 && TARGET_SSE_MATH
14354    && !COMMUTATIVE_ARITH_P (operands[3])"
14355   "* return output_387_binary_op (insn, operands);"
14356   [(set_attr "mode" "DF")
14357    (set (attr "type") 
14358         (cond [(match_operand:SF 3 "mult_operator" "")
14359                  (const_string "ssemul")
14360                (match_operand:SF 3 "div_operator" "")
14361                  (const_string "ssediv")
14362               ]
14363               (const_string "sseadd")))])
14364
14365 ;; This pattern is not fully shadowed by the pattern above.
14366 (define_insn "*fop_df_1_i387"
14367   [(set (match_operand:DF 0 "register_operand" "=f,f")
14368         (match_operator:DF 3 "binary_fp_operator"
14369                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14370                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14371   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14372    && !COMMUTATIVE_ARITH_P (operands[3])
14373    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374   "* return output_387_binary_op (insn, operands);"
14375   [(set (attr "type") 
14376         (cond [(match_operand:DF 3 "mult_operator" "") 
14377                  (const_string "fmul")
14378                (match_operand:DF 3 "div_operator" "")
14379                  (const_string "fdiv")
14380               ]
14381               (const_string "fop")))
14382    (set_attr "mode" "DF")])
14383
14384 ;; ??? Add SSE splitters for these!
14385 (define_insn "*fop_df_2_i387"
14386   [(set (match_operand:DF 0 "register_operand" "=f,f")
14387         (match_operator:DF 3 "binary_fp_operator"
14388            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14389             (match_operand:DF 2 "register_operand" "0,0")]))]
14390   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14391   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14392   [(set (attr "type") 
14393         (cond [(match_operand:DF 3 "mult_operator" "") 
14394                  (const_string "fmul")
14395                (match_operand:DF 3 "div_operator" "") 
14396                  (const_string "fdiv")
14397               ]
14398               (const_string "fop")))
14399    (set_attr "fp_int_src" "true")
14400    (set_attr "mode" "SI")])
14401
14402 (define_insn "*fop_df_3_i387"
14403   [(set (match_operand:DF 0 "register_operand" "=f,f")
14404         (match_operator:DF 3 "binary_fp_operator"
14405            [(match_operand:DF 1 "register_operand" "0,0")
14406             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14407   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14408   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14409   [(set (attr "type") 
14410         (cond [(match_operand:DF 3 "mult_operator" "") 
14411                  (const_string "fmul")
14412                (match_operand:DF 3 "div_operator" "") 
14413                  (const_string "fdiv")
14414               ]
14415               (const_string "fop")))
14416    (set_attr "fp_int_src" "true")
14417    (set_attr "mode" "SI")])
14418
14419 (define_insn "*fop_df_4_i387"
14420   [(set (match_operand:DF 0 "register_operand" "=f,f")
14421         (match_operator:DF 3 "binary_fp_operator"
14422            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14423             (match_operand:DF 2 "register_operand" "0,f")]))]
14424   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14425    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14426   "* return output_387_binary_op (insn, operands);"
14427   [(set (attr "type") 
14428         (cond [(match_operand:DF 3 "mult_operator" "") 
14429                  (const_string "fmul")
14430                (match_operand:DF 3 "div_operator" "") 
14431                  (const_string "fdiv")
14432               ]
14433               (const_string "fop")))
14434    (set_attr "mode" "SF")])
14435
14436 (define_insn "*fop_df_5_i387"
14437   [(set (match_operand:DF 0 "register_operand" "=f,f")
14438         (match_operator:DF 3 "binary_fp_operator"
14439           [(match_operand:DF 1 "register_operand" "0,f")
14440            (float_extend:DF
14441             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14442   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14443   "* return output_387_binary_op (insn, operands);"
14444   [(set (attr "type") 
14445         (cond [(match_operand:DF 3 "mult_operator" "") 
14446                  (const_string "fmul")
14447                (match_operand:DF 3 "div_operator" "") 
14448                  (const_string "fdiv")
14449               ]
14450               (const_string "fop")))
14451    (set_attr "mode" "SF")])
14452
14453 (define_insn "*fop_df_6_i387"
14454   [(set (match_operand:DF 0 "register_operand" "=f,f")
14455         (match_operator:DF 3 "binary_fp_operator"
14456           [(float_extend:DF
14457             (match_operand:SF 1 "register_operand" "0,f"))
14458            (float_extend:DF
14459             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14460   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14461   "* return output_387_binary_op (insn, operands);"
14462   [(set (attr "type") 
14463         (cond [(match_operand:DF 3 "mult_operator" "") 
14464                  (const_string "fmul")
14465                (match_operand:DF 3 "div_operator" "") 
14466                  (const_string "fdiv")
14467               ]
14468               (const_string "fop")))
14469    (set_attr "mode" "SF")])
14470
14471 (define_insn "*fop_xf_comm_i387"
14472   [(set (match_operand:XF 0 "register_operand" "=f")
14473         (match_operator:XF 3 "binary_fp_operator"
14474                         [(match_operand:XF 1 "register_operand" "%0")
14475                          (match_operand:XF 2 "register_operand" "f")]))]
14476   "TARGET_80387
14477    && COMMUTATIVE_ARITH_P (operands[3])"
14478   "* return output_387_binary_op (insn, operands);"
14479   [(set (attr "type") 
14480         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14481            (const_string "fmul")
14482            (const_string "fop")))
14483    (set_attr "mode" "XF")])
14484
14485 (define_insn "*fop_xf_1_i387"
14486   [(set (match_operand:XF 0 "register_operand" "=f,f")
14487         (match_operator:XF 3 "binary_fp_operator"
14488                         [(match_operand:XF 1 "register_operand" "0,f")
14489                          (match_operand:XF 2 "register_operand" "f,0")]))]
14490   "TARGET_80387
14491    && !COMMUTATIVE_ARITH_P (operands[3])"
14492   "* return output_387_binary_op (insn, operands);"
14493   [(set (attr "type") 
14494         (cond [(match_operand:XF 3 "mult_operator" "") 
14495                  (const_string "fmul")
14496                (match_operand:XF 3 "div_operator" "") 
14497                  (const_string "fdiv")
14498               ]
14499               (const_string "fop")))
14500    (set_attr "mode" "XF")])
14501
14502 (define_insn "*fop_xf_2_i387"
14503   [(set (match_operand:XF 0 "register_operand" "=f,f")
14504         (match_operator:XF 3 "binary_fp_operator"
14505            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14506             (match_operand:XF 2 "register_operand" "0,0")]))]
14507   "TARGET_80387 && TARGET_USE_FIOP"
14508   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14509   [(set (attr "type") 
14510         (cond [(match_operand:XF 3 "mult_operator" "") 
14511                  (const_string "fmul")
14512                (match_operand:XF 3 "div_operator" "") 
14513                  (const_string "fdiv")
14514               ]
14515               (const_string "fop")))
14516    (set_attr "fp_int_src" "true")
14517    (set_attr "mode" "SI")])
14518
14519 (define_insn "*fop_xf_3_i387"
14520   [(set (match_operand:XF 0 "register_operand" "=f,f")
14521         (match_operator:XF 3 "binary_fp_operator"
14522           [(match_operand:XF 1 "register_operand" "0,0")
14523            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14524   "TARGET_80387 && TARGET_USE_FIOP"
14525   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14526   [(set (attr "type") 
14527         (cond [(match_operand:XF 3 "mult_operator" "") 
14528                  (const_string "fmul")
14529                (match_operand:XF 3 "div_operator" "") 
14530                  (const_string "fdiv")
14531               ]
14532               (const_string "fop")))
14533    (set_attr "fp_int_src" "true")
14534    (set_attr "mode" "SI")])
14535
14536 (define_insn "*fop_xf_4_i387"
14537   [(set (match_operand:XF 0 "register_operand" "=f,f")
14538         (match_operator:XF 3 "binary_fp_operator"
14539            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14540             (match_operand:XF 2 "register_operand" "0,f")]))]
14541   "TARGET_80387"
14542   "* return output_387_binary_op (insn, operands);"
14543   [(set (attr "type") 
14544         (cond [(match_operand:XF 3 "mult_operator" "") 
14545                  (const_string "fmul")
14546                (match_operand:XF 3 "div_operator" "") 
14547                  (const_string "fdiv")
14548               ]
14549               (const_string "fop")))
14550    (set_attr "mode" "SF")])
14551
14552 (define_insn "*fop_xf_5_i387"
14553   [(set (match_operand:XF 0 "register_operand" "=f,f")
14554         (match_operator:XF 3 "binary_fp_operator"
14555           [(match_operand:XF 1 "register_operand" "0,f")
14556            (float_extend:XF
14557             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14558   "TARGET_80387"
14559   "* return output_387_binary_op (insn, operands);"
14560   [(set (attr "type") 
14561         (cond [(match_operand:XF 3 "mult_operator" "") 
14562                  (const_string "fmul")
14563                (match_operand:XF 3 "div_operator" "") 
14564                  (const_string "fdiv")
14565               ]
14566               (const_string "fop")))
14567    (set_attr "mode" "SF")])
14568
14569 (define_insn "*fop_xf_6_i387"
14570   [(set (match_operand:XF 0 "register_operand" "=f,f")
14571         (match_operator:XF 3 "binary_fp_operator"
14572           [(float_extend:XF
14573             (match_operand 1 "register_operand" "0,f"))
14574            (float_extend:XF
14575             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14576   "TARGET_80387"
14577   "* return output_387_binary_op (insn, operands);"
14578   [(set (attr "type") 
14579         (cond [(match_operand:XF 3 "mult_operator" "") 
14580                  (const_string "fmul")
14581                (match_operand:XF 3 "div_operator" "") 
14582                  (const_string "fdiv")
14583               ]
14584               (const_string "fop")))
14585    (set_attr "mode" "SF")])
14586
14587 (define_split
14588   [(set (match_operand 0 "register_operand" "")
14589         (match_operator 3 "binary_fp_operator"
14590            [(float (match_operand:SI 1 "register_operand" ""))
14591             (match_operand 2 "register_operand" "")]))]
14592   "TARGET_80387 && reload_completed
14593    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14594   [(const_int 0)]
14595
14596   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14597   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14598   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14599                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14600                                           GET_MODE (operands[3]),
14601                                           operands[4],
14602                                           operands[2])));
14603   ix86_free_from_memory (GET_MODE (operands[1]));
14604   DONE;
14605 })
14606
14607 (define_split
14608   [(set (match_operand 0 "register_operand" "")
14609         (match_operator 3 "binary_fp_operator"
14610            [(match_operand 1 "register_operand" "")
14611             (float (match_operand:SI 2 "register_operand" ""))]))]
14612   "TARGET_80387 && reload_completed
14613    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14614   [(const_int 0)]
14615 {
14616   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14617   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14618   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14619                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14620                                           GET_MODE (operands[3]),
14621                                           operands[1],
14622                                           operands[4])));
14623   ix86_free_from_memory (GET_MODE (operands[2]));
14624   DONE;
14625 })
14626 \f
14627 ;; FPU special functions.
14628
14629 (define_expand "sqrtsf2"
14630   [(set (match_operand:SF 0 "register_operand" "")
14631         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14632   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14633 {
14634   if (!TARGET_SSE_MATH)
14635     operands[1] = force_reg (SFmode, operands[1]);
14636 })
14637
14638 (define_insn "*sqrtsf2_mixed"
14639   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14640         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14641   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14642   "@
14643    fsqrt
14644    sqrtss\t{%1, %0|%0, %1}"
14645   [(set_attr "type" "fpspc,sse")
14646    (set_attr "mode" "SF,SF")
14647    (set_attr "athlon_decode" "direct,*")])
14648
14649 (define_insn "*sqrtsf2_sse"
14650   [(set (match_operand:SF 0 "register_operand" "=x")
14651         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14652   "TARGET_SSE_MATH"
14653   "sqrtss\t{%1, %0|%0, %1}"
14654   [(set_attr "type" "sse")
14655    (set_attr "mode" "SF")
14656    (set_attr "athlon_decode" "*")])
14657
14658 (define_insn "*sqrtsf2_i387"
14659   [(set (match_operand:SF 0 "register_operand" "=f")
14660         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14661   "TARGET_USE_FANCY_MATH_387"
14662   "fsqrt"
14663   [(set_attr "type" "fpspc")
14664    (set_attr "mode" "SF")
14665    (set_attr "athlon_decode" "direct")])
14666
14667 (define_expand "sqrtdf2"
14668   [(set (match_operand:DF 0 "register_operand" "")
14669         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14670   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14671 {
14672   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14673     operands[1] = force_reg (DFmode, operands[1]);
14674 })
14675
14676 (define_insn "*sqrtdf2_mixed"
14677   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14678         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14679   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14680   "@
14681    fsqrt
14682    sqrtsd\t{%1, %0|%0, %1}"
14683   [(set_attr "type" "fpspc,sse")
14684    (set_attr "mode" "DF,DF")
14685    (set_attr "athlon_decode" "direct,*")])
14686
14687 (define_insn "*sqrtdf2_sse"
14688   [(set (match_operand:DF 0 "register_operand" "=Y")
14689         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14690   "TARGET_SSE2 && TARGET_SSE_MATH"
14691   "sqrtsd\t{%1, %0|%0, %1}"
14692   [(set_attr "type" "sse")
14693    (set_attr "mode" "DF")
14694    (set_attr "athlon_decode" "*")])
14695
14696 (define_insn "*sqrtdf2_i387"
14697   [(set (match_operand:DF 0 "register_operand" "=f")
14698         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14699   "TARGET_USE_FANCY_MATH_387"
14700   "fsqrt"
14701   [(set_attr "type" "fpspc")
14702    (set_attr "mode" "DF")
14703    (set_attr "athlon_decode" "direct")])
14704
14705 (define_insn "*sqrtextendsfdf2_i387"
14706   [(set (match_operand:DF 0 "register_operand" "=f")
14707         (sqrt:DF (float_extend:DF
14708                   (match_operand:SF 1 "register_operand" "0"))))]
14709   "TARGET_USE_FANCY_MATH_387
14710    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14711   "fsqrt"
14712   [(set_attr "type" "fpspc")
14713    (set_attr "mode" "DF")
14714    (set_attr "athlon_decode" "direct")])
14715
14716 (define_insn "sqrtxf2"
14717   [(set (match_operand:XF 0 "register_operand" "=f")
14718         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14719   "TARGET_USE_FANCY_MATH_387 
14720    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14721   "fsqrt"
14722   [(set_attr "type" "fpspc")
14723    (set_attr "mode" "XF")
14724    (set_attr "athlon_decode" "direct")])
14725
14726 (define_insn "*sqrtextendsfxf2_i387"
14727   [(set (match_operand:XF 0 "register_operand" "=f")
14728         (sqrt:XF (float_extend:XF
14729                   (match_operand:SF 1 "register_operand" "0"))))]
14730   "TARGET_USE_FANCY_MATH_387"
14731   "fsqrt"
14732   [(set_attr "type" "fpspc")
14733    (set_attr "mode" "XF")
14734    (set_attr "athlon_decode" "direct")])
14735
14736 (define_insn "*sqrtextenddfxf2_i387"
14737   [(set (match_operand:XF 0 "register_operand" "=f")
14738         (sqrt:XF (float_extend:XF
14739                   (match_operand:DF 1 "register_operand" "0"))))]
14740   "TARGET_USE_FANCY_MATH_387"
14741   "fsqrt"
14742   [(set_attr "type" "fpspc")
14743    (set_attr "mode" "XF")
14744    (set_attr "athlon_decode" "direct")])
14745
14746 (define_insn "fpremxf4"
14747   [(set (match_operand:XF 0 "register_operand" "=f")
14748         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14749                     (match_operand:XF 3 "register_operand" "1")]
14750                    UNSPEC_FPREM_F))
14751    (set (match_operand:XF 1 "register_operand" "=u")
14752         (unspec:XF [(match_dup 2) (match_dup 3)]
14753                    UNSPEC_FPREM_U))
14754    (set (reg:CCFP FPSR_REG)
14755         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14756   "TARGET_USE_FANCY_MATH_387
14757    && flag_unsafe_math_optimizations"
14758   "fprem"
14759   [(set_attr "type" "fpspc")
14760    (set_attr "mode" "XF")])
14761
14762 (define_expand "fmodsf3"
14763   [(use (match_operand:SF 0 "register_operand" ""))
14764    (use (match_operand:SF 1 "register_operand" ""))
14765    (use (match_operand:SF 2 "register_operand" ""))]
14766   "TARGET_USE_FANCY_MATH_387
14767    && flag_unsafe_math_optimizations"
14768 {
14769   rtx label = gen_label_rtx ();
14770
14771   rtx op1 = gen_reg_rtx (XFmode);
14772   rtx op2 = gen_reg_rtx (XFmode);
14773
14774   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14775   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14776
14777   emit_label (label);
14778
14779   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14780   ix86_emit_fp_unordered_jump (label);
14781
14782   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14783   DONE;
14784 })
14785
14786 (define_expand "fmoddf3"
14787   [(use (match_operand:DF 0 "register_operand" ""))
14788    (use (match_operand:DF 1 "register_operand" ""))
14789    (use (match_operand:DF 2 "register_operand" ""))]
14790   "TARGET_USE_FANCY_MATH_387
14791    && flag_unsafe_math_optimizations"
14792 {
14793   rtx label = gen_label_rtx ();
14794
14795   rtx op1 = gen_reg_rtx (XFmode);
14796   rtx op2 = gen_reg_rtx (XFmode);
14797
14798   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14799   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14800
14801   emit_label (label);
14802
14803   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14804   ix86_emit_fp_unordered_jump (label);
14805
14806   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14807   DONE;
14808 })
14809
14810 (define_expand "fmodxf3"
14811   [(use (match_operand:XF 0 "register_operand" ""))
14812    (use (match_operand:XF 1 "register_operand" ""))
14813    (use (match_operand:XF 2 "register_operand" ""))]
14814   "TARGET_USE_FANCY_MATH_387
14815    && flag_unsafe_math_optimizations"
14816 {
14817   rtx label = gen_label_rtx ();
14818
14819   emit_label (label);
14820
14821   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14822                            operands[1], operands[2]));
14823   ix86_emit_fp_unordered_jump (label);
14824
14825   emit_move_insn (operands[0], operands[1]);
14826   DONE;
14827 })
14828
14829 (define_insn "fprem1xf4"
14830   [(set (match_operand:XF 0 "register_operand" "=f")
14831         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14832                     (match_operand:XF 3 "register_operand" "1")]
14833                    UNSPEC_FPREM1_F))
14834    (set (match_operand:XF 1 "register_operand" "=u")
14835         (unspec:XF [(match_dup 2) (match_dup 3)]
14836                    UNSPEC_FPREM1_U))
14837    (set (reg:CCFP FPSR_REG)
14838         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14839   "TARGET_USE_FANCY_MATH_387
14840    && flag_unsafe_math_optimizations"
14841   "fprem1"
14842   [(set_attr "type" "fpspc")
14843    (set_attr "mode" "XF")])
14844
14845 (define_expand "dremsf3"
14846   [(use (match_operand:SF 0 "register_operand" ""))
14847    (use (match_operand:SF 1 "register_operand" ""))
14848    (use (match_operand:SF 2 "register_operand" ""))]
14849   "TARGET_USE_FANCY_MATH_387
14850    && flag_unsafe_math_optimizations"
14851 {
14852   rtx label = gen_label_rtx ();
14853
14854   rtx op1 = gen_reg_rtx (XFmode);
14855   rtx op2 = gen_reg_rtx (XFmode);
14856
14857   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14858   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14859
14860   emit_label (label);
14861
14862   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14863   ix86_emit_fp_unordered_jump (label);
14864
14865   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14866   DONE;
14867 })
14868
14869 (define_expand "dremdf3"
14870   [(use (match_operand:DF 0 "register_operand" ""))
14871    (use (match_operand:DF 1 "register_operand" ""))
14872    (use (match_operand:DF 2 "register_operand" ""))]
14873   "TARGET_USE_FANCY_MATH_387
14874    && flag_unsafe_math_optimizations"
14875 {
14876   rtx label = gen_label_rtx ();
14877
14878   rtx op1 = gen_reg_rtx (XFmode);
14879   rtx op2 = gen_reg_rtx (XFmode);
14880
14881   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14882   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14883
14884   emit_label (label);
14885
14886   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14887   ix86_emit_fp_unordered_jump (label);
14888
14889   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14890   DONE;
14891 })
14892
14893 (define_expand "dremxf3"
14894   [(use (match_operand:XF 0 "register_operand" ""))
14895    (use (match_operand:XF 1 "register_operand" ""))
14896    (use (match_operand:XF 2 "register_operand" ""))]
14897   "TARGET_USE_FANCY_MATH_387
14898    && flag_unsafe_math_optimizations"
14899 {
14900   rtx label = gen_label_rtx ();
14901
14902   emit_label (label);
14903
14904   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14905                             operands[1], operands[2]));
14906   ix86_emit_fp_unordered_jump (label);
14907
14908   emit_move_insn (operands[0], operands[1]);
14909   DONE;
14910 })
14911
14912 (define_insn "*sindf2"
14913   [(set (match_operand:DF 0 "register_operand" "=f")
14914         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && flag_unsafe_math_optimizations"
14917   "fsin"
14918   [(set_attr "type" "fpspc")
14919    (set_attr "mode" "DF")])
14920
14921 (define_insn "*sinsf2"
14922   [(set (match_operand:SF 0 "register_operand" "=f")
14923         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14924   "TARGET_USE_FANCY_MATH_387
14925    && flag_unsafe_math_optimizations"
14926   "fsin"
14927   [(set_attr "type" "fpspc")
14928    (set_attr "mode" "SF")])
14929
14930 (define_insn "*sinextendsfdf2"
14931   [(set (match_operand:DF 0 "register_operand" "=f")
14932         (unspec:DF [(float_extend:DF
14933                      (match_operand:SF 1 "register_operand" "0"))]
14934                    UNSPEC_SIN))]
14935   "TARGET_USE_FANCY_MATH_387
14936    && flag_unsafe_math_optimizations"
14937   "fsin"
14938   [(set_attr "type" "fpspc")
14939    (set_attr "mode" "DF")])
14940
14941 (define_insn "*sinxf2"
14942   [(set (match_operand:XF 0 "register_operand" "=f")
14943         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14944   "TARGET_USE_FANCY_MATH_387
14945    && flag_unsafe_math_optimizations"
14946   "fsin"
14947   [(set_attr "type" "fpspc")
14948    (set_attr "mode" "XF")])
14949
14950 (define_insn "*cosdf2"
14951   [(set (match_operand:DF 0 "register_operand" "=f")
14952         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14953   "TARGET_USE_FANCY_MATH_387
14954    && flag_unsafe_math_optimizations"
14955   "fcos"
14956   [(set_attr "type" "fpspc")
14957    (set_attr "mode" "DF")])
14958
14959 (define_insn "*cossf2"
14960   [(set (match_operand:SF 0 "register_operand" "=f")
14961         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14962   "TARGET_USE_FANCY_MATH_387
14963    && flag_unsafe_math_optimizations"
14964   "fcos"
14965   [(set_attr "type" "fpspc")
14966    (set_attr "mode" "SF")])
14967
14968 (define_insn "*cosextendsfdf2"
14969   [(set (match_operand:DF 0 "register_operand" "=f")
14970         (unspec:DF [(float_extend:DF
14971                      (match_operand:SF 1 "register_operand" "0"))]
14972                    UNSPEC_COS))]
14973   "TARGET_USE_FANCY_MATH_387
14974    && flag_unsafe_math_optimizations"
14975   "fcos"
14976   [(set_attr "type" "fpspc")
14977    (set_attr "mode" "DF")])
14978
14979 (define_insn "*cosxf2"
14980   [(set (match_operand:XF 0 "register_operand" "=f")
14981         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14982   "TARGET_USE_FANCY_MATH_387
14983    && flag_unsafe_math_optimizations"
14984   "fcos"
14985   [(set_attr "type" "fpspc")
14986    (set_attr "mode" "XF")])
14987
14988 ;; With sincos pattern defined, sin and cos builtin function will be
14989 ;; expanded to sincos pattern with one of its outputs left unused. 
14990 ;; Cse pass  will detected, if two sincos patterns can be combined,
14991 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14992 ;; depending on the unused output.
14993
14994 (define_insn "sincosdf3"
14995   [(set (match_operand:DF 0 "register_operand" "=f")
14996         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14997                    UNSPEC_SINCOS_COS))
14998    (set (match_operand:DF 1 "register_operand" "=u")
14999         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15000   "TARGET_USE_FANCY_MATH_387
15001    && flag_unsafe_math_optimizations"
15002   "fsincos"
15003   [(set_attr "type" "fpspc")
15004    (set_attr "mode" "DF")])
15005
15006 (define_split
15007   [(set (match_operand:DF 0 "register_operand" "")
15008         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15009                    UNSPEC_SINCOS_COS))
15010    (set (match_operand:DF 1 "register_operand" "")
15011         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15012   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15013    && !reload_completed && !reload_in_progress"
15014   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15015   "")
15016
15017 (define_split
15018   [(set (match_operand:DF 0 "register_operand" "")
15019         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15020                    UNSPEC_SINCOS_COS))
15021    (set (match_operand:DF 1 "register_operand" "")
15022         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15023   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15024    && !reload_completed && !reload_in_progress"
15025   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15026   "")
15027
15028 (define_insn "sincossf3"
15029   [(set (match_operand:SF 0 "register_operand" "=f")
15030         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15031                    UNSPEC_SINCOS_COS))
15032    (set (match_operand:SF 1 "register_operand" "=u")
15033         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15034   "TARGET_USE_FANCY_MATH_387
15035    && flag_unsafe_math_optimizations"
15036   "fsincos"
15037   [(set_attr "type" "fpspc")
15038    (set_attr "mode" "SF")])
15039
15040 (define_split
15041   [(set (match_operand:SF 0 "register_operand" "")
15042         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15043                    UNSPEC_SINCOS_COS))
15044    (set (match_operand:SF 1 "register_operand" "")
15045         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15046   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15047    && !reload_completed && !reload_in_progress"
15048   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15049   "")
15050
15051 (define_split
15052   [(set (match_operand:SF 0 "register_operand" "")
15053         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15054                    UNSPEC_SINCOS_COS))
15055    (set (match_operand:SF 1 "register_operand" "")
15056         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15057   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15058    && !reload_completed && !reload_in_progress"
15059   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15060   "")
15061
15062 (define_insn "*sincosextendsfdf3"
15063   [(set (match_operand:DF 0 "register_operand" "=f")
15064         (unspec:DF [(float_extend:DF
15065                      (match_operand:SF 2 "register_operand" "0"))]
15066                    UNSPEC_SINCOS_COS))
15067    (set (match_operand:DF 1 "register_operand" "=u")
15068         (unspec:DF [(float_extend:DF
15069                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15070   "TARGET_USE_FANCY_MATH_387
15071    && flag_unsafe_math_optimizations"
15072   "fsincos"
15073   [(set_attr "type" "fpspc")
15074    (set_attr "mode" "DF")])
15075
15076 (define_split
15077   [(set (match_operand:DF 0 "register_operand" "")
15078         (unspec:DF [(float_extend:DF
15079                      (match_operand:SF 2 "register_operand" ""))]
15080                    UNSPEC_SINCOS_COS))
15081    (set (match_operand:DF 1 "register_operand" "")
15082         (unspec:DF [(float_extend:DF
15083                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15084   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15085    && !reload_completed && !reload_in_progress"
15086   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15087                                    (match_dup 2))] UNSPEC_SIN))]
15088   "")
15089
15090 (define_split
15091   [(set (match_operand:DF 0 "register_operand" "")
15092         (unspec:DF [(float_extend:DF
15093                      (match_operand:SF 2 "register_operand" ""))]
15094                    UNSPEC_SINCOS_COS))
15095    (set (match_operand:DF 1 "register_operand" "")
15096         (unspec:DF [(float_extend:DF
15097                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15098   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15099    && !reload_completed && !reload_in_progress"
15100   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15101                                    (match_dup 2))] UNSPEC_COS))]
15102   "")
15103
15104 (define_insn "sincosxf3"
15105   [(set (match_operand:XF 0 "register_operand" "=f")
15106         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15107                    UNSPEC_SINCOS_COS))
15108    (set (match_operand:XF 1 "register_operand" "=u")
15109         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && flag_unsafe_math_optimizations"
15112   "fsincos"
15113   [(set_attr "type" "fpspc")
15114    (set_attr "mode" "XF")])
15115
15116 (define_split
15117   [(set (match_operand:XF 0 "register_operand" "")
15118         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15119                    UNSPEC_SINCOS_COS))
15120    (set (match_operand:XF 1 "register_operand" "")
15121         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15122   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15123    && !reload_completed && !reload_in_progress"
15124   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15125   "")
15126
15127 (define_split
15128   [(set (match_operand:XF 0 "register_operand" "")
15129         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15130                    UNSPEC_SINCOS_COS))
15131    (set (match_operand:XF 1 "register_operand" "")
15132         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15133   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15134    && !reload_completed && !reload_in_progress"
15135   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15136   "")
15137
15138 (define_insn "*tandf3_1"
15139   [(set (match_operand:DF 0 "register_operand" "=f")
15140         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15141                    UNSPEC_TAN_ONE))
15142    (set (match_operand:DF 1 "register_operand" "=u")
15143         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15144   "TARGET_USE_FANCY_MATH_387
15145    && flag_unsafe_math_optimizations"
15146   "fptan"
15147   [(set_attr "type" "fpspc")
15148    (set_attr "mode" "DF")])
15149
15150 ;; optimize sequence: fptan
15151 ;;                    fstp    %st(0)
15152 ;;                    fld1
15153 ;; into fptan insn.
15154
15155 (define_peephole2
15156   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15157                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15158                              UNSPEC_TAN_ONE))
15159              (set (match_operand:DF 1 "register_operand" "")
15160                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15161    (set (match_dup 0)
15162         (match_operand:DF 3 "immediate_operand" ""))]
15163   "standard_80387_constant_p (operands[3]) == 2"
15164   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15165              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15166   "")
15167
15168 (define_expand "tandf2"
15169   [(parallel [(set (match_dup 2)
15170                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15171                               UNSPEC_TAN_ONE))
15172               (set (match_operand:DF 0 "register_operand" "")
15173                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15174   "TARGET_USE_FANCY_MATH_387
15175    && flag_unsafe_math_optimizations"
15176 {
15177   operands[2] = gen_reg_rtx (DFmode);
15178 })
15179
15180 (define_insn "*tansf3_1"
15181   [(set (match_operand:SF 0 "register_operand" "=f")
15182         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15183                    UNSPEC_TAN_ONE))
15184    (set (match_operand:SF 1 "register_operand" "=u")
15185         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15186   "TARGET_USE_FANCY_MATH_387
15187    && flag_unsafe_math_optimizations"
15188   "fptan"
15189   [(set_attr "type" "fpspc")
15190    (set_attr "mode" "SF")])
15191
15192 ;; optimize sequence: fptan
15193 ;;                    fstp    %st(0)
15194 ;;                    fld1
15195 ;; into fptan insn.
15196
15197 (define_peephole2
15198   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15199                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15200                              UNSPEC_TAN_ONE))
15201              (set (match_operand:SF 1 "register_operand" "")
15202                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15203    (set (match_dup 0)
15204         (match_operand:SF 3 "immediate_operand" ""))]
15205   "standard_80387_constant_p (operands[3]) == 2"
15206   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15207              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15208   "")
15209
15210 (define_expand "tansf2"
15211   [(parallel [(set (match_dup 2)
15212                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15213                               UNSPEC_TAN_ONE))
15214               (set (match_operand:SF 0 "register_operand" "")
15215                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15216   "TARGET_USE_FANCY_MATH_387
15217    && flag_unsafe_math_optimizations"
15218 {
15219   operands[2] = gen_reg_rtx (SFmode);
15220 })
15221
15222 (define_insn "*tanxf3_1"
15223   [(set (match_operand:XF 0 "register_operand" "=f")
15224         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15225                    UNSPEC_TAN_ONE))
15226    (set (match_operand:XF 1 "register_operand" "=u")
15227         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15228   "TARGET_USE_FANCY_MATH_387
15229    && flag_unsafe_math_optimizations"
15230   "fptan"
15231   [(set_attr "type" "fpspc")
15232    (set_attr "mode" "XF")])
15233
15234 ;; optimize sequence: fptan
15235 ;;                    fstp    %st(0)
15236 ;;                    fld1
15237 ;; into fptan insn.
15238
15239 (define_peephole2
15240   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15241                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15242                              UNSPEC_TAN_ONE))
15243              (set (match_operand:XF 1 "register_operand" "")
15244                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15245    (set (match_dup 0)
15246         (match_operand:XF 3 "immediate_operand" ""))]
15247   "standard_80387_constant_p (operands[3]) == 2"
15248   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15249              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15250   "")
15251
15252 (define_expand "tanxf2"
15253   [(parallel [(set (match_dup 2)
15254                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15255                               UNSPEC_TAN_ONE))
15256               (set (match_operand:XF 0 "register_operand" "")
15257                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15258   "TARGET_USE_FANCY_MATH_387
15259    && flag_unsafe_math_optimizations"
15260 {
15261   operands[2] = gen_reg_rtx (XFmode);
15262 })
15263
15264 (define_insn "atan2df3_1"
15265   [(set (match_operand:DF 0 "register_operand" "=f")
15266         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15267                     (match_operand:DF 1 "register_operand" "u")]
15268                    UNSPEC_FPATAN))
15269    (clobber (match_scratch:DF 3 "=1"))]
15270   "TARGET_USE_FANCY_MATH_387
15271    && flag_unsafe_math_optimizations"
15272   "fpatan"
15273   [(set_attr "type" "fpspc")
15274    (set_attr "mode" "DF")])
15275
15276 (define_expand "atan2df3"
15277   [(use (match_operand:DF 0 "register_operand" "=f"))
15278    (use (match_operand:DF 2 "register_operand" "0"))
15279    (use (match_operand:DF 1 "register_operand" "u"))]
15280   "TARGET_USE_FANCY_MATH_387
15281    && flag_unsafe_math_optimizations"
15282 {
15283   rtx copy = gen_reg_rtx (DFmode);
15284   emit_move_insn (copy, operands[1]);
15285   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15286   DONE;
15287 })
15288
15289 (define_expand "atandf2"
15290   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15291                    (unspec:DF [(match_dup 2)
15292                                (match_operand:DF 1 "register_operand" "")]
15293                     UNSPEC_FPATAN))
15294               (clobber (match_scratch:DF 3 ""))])]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations"
15297 {
15298   operands[2] = gen_reg_rtx (DFmode);
15299   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15300 })
15301
15302 (define_insn "atan2sf3_1"
15303   [(set (match_operand:SF 0 "register_operand" "=f")
15304         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15305                     (match_operand:SF 1 "register_operand" "u")]
15306                    UNSPEC_FPATAN))
15307    (clobber (match_scratch:SF 3 "=1"))]
15308   "TARGET_USE_FANCY_MATH_387
15309    && flag_unsafe_math_optimizations"
15310   "fpatan"
15311   [(set_attr "type" "fpspc")
15312    (set_attr "mode" "SF")])
15313
15314 (define_expand "atan2sf3"
15315   [(use (match_operand:SF 0 "register_operand" "=f"))
15316    (use (match_operand:SF 2 "register_operand" "0"))
15317    (use (match_operand:SF 1 "register_operand" "u"))]
15318   "TARGET_USE_FANCY_MATH_387
15319    && flag_unsafe_math_optimizations"
15320 {
15321   rtx copy = gen_reg_rtx (SFmode);
15322   emit_move_insn (copy, operands[1]);
15323   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15324   DONE;
15325 })
15326
15327 (define_expand "atansf2"
15328   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15329                    (unspec:SF [(match_dup 2)
15330                                (match_operand:SF 1 "register_operand" "")]
15331                     UNSPEC_FPATAN))
15332               (clobber (match_scratch:SF 3 ""))])]
15333   "TARGET_USE_FANCY_MATH_387
15334    && flag_unsafe_math_optimizations"
15335 {
15336   operands[2] = gen_reg_rtx (SFmode);
15337   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15338 })
15339
15340 (define_insn "atan2xf3_1"
15341   [(set (match_operand:XF 0 "register_operand" "=f")
15342         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15343                     (match_operand:XF 1 "register_operand" "u")]
15344                    UNSPEC_FPATAN))
15345    (clobber (match_scratch:XF 3 "=1"))]
15346   "TARGET_USE_FANCY_MATH_387
15347    && flag_unsafe_math_optimizations"
15348   "fpatan"
15349   [(set_attr "type" "fpspc")
15350    (set_attr "mode" "XF")])
15351
15352 (define_expand "atan2xf3"
15353   [(use (match_operand:XF 0 "register_operand" "=f"))
15354    (use (match_operand:XF 2 "register_operand" "0"))
15355    (use (match_operand:XF 1 "register_operand" "u"))]
15356   "TARGET_USE_FANCY_MATH_387
15357    && flag_unsafe_math_optimizations"
15358 {
15359   rtx copy = gen_reg_rtx (XFmode);
15360   emit_move_insn (copy, operands[1]);
15361   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15362   DONE;
15363 })
15364
15365 (define_expand "atanxf2"
15366   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15367                    (unspec:XF [(match_dup 2)
15368                                (match_operand:XF 1 "register_operand" "")]
15369                     UNSPEC_FPATAN))
15370               (clobber (match_scratch:XF 3 ""))])]
15371   "TARGET_USE_FANCY_MATH_387
15372    && flag_unsafe_math_optimizations"
15373 {
15374   operands[2] = gen_reg_rtx (XFmode);
15375   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15376 })
15377
15378 (define_expand "asindf2"
15379   [(set (match_dup 2)
15380         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15381    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15382    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15383    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15384    (parallel [(set (match_dup 7)
15385                    (unspec:XF [(match_dup 6) (match_dup 2)]
15386                               UNSPEC_FPATAN))
15387               (clobber (match_scratch:XF 8 ""))])
15388    (set (match_operand:DF 0 "register_operand" "")
15389         (float_truncate:DF (match_dup 7)))]
15390   "TARGET_USE_FANCY_MATH_387
15391    && flag_unsafe_math_optimizations"
15392 {
15393   int i;
15394
15395   for (i=2; i<8; i++)
15396     operands[i] = gen_reg_rtx (XFmode);
15397
15398   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15399 })
15400
15401 (define_expand "asinsf2"
15402   [(set (match_dup 2)
15403         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15404    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15405    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15406    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15407    (parallel [(set (match_dup 7)
15408                    (unspec:XF [(match_dup 6) (match_dup 2)]
15409                               UNSPEC_FPATAN))
15410               (clobber (match_scratch:XF 8 ""))])
15411    (set (match_operand:SF 0 "register_operand" "")
15412         (float_truncate:SF (match_dup 7)))]
15413   "TARGET_USE_FANCY_MATH_387
15414    && flag_unsafe_math_optimizations"
15415 {
15416   int i;
15417
15418   for (i=2; i<8; i++)
15419     operands[i] = gen_reg_rtx (XFmode);
15420
15421   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15422 })
15423
15424 (define_expand "asinxf2"
15425   [(set (match_dup 2)
15426         (mult:XF (match_operand:XF 1 "register_operand" "")
15427                  (match_dup 1)))
15428    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15429    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15430    (parallel [(set (match_operand:XF 0 "register_operand" "")
15431                    (unspec:XF [(match_dup 5) (match_dup 1)]
15432                               UNSPEC_FPATAN))
15433               (clobber (match_scratch:XF 6 ""))])]
15434   "TARGET_USE_FANCY_MATH_387
15435    && flag_unsafe_math_optimizations"
15436 {
15437   int i;
15438
15439   for (i=2; i<6; i++)
15440     operands[i] = gen_reg_rtx (XFmode);
15441
15442   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15443 })
15444
15445 (define_expand "acosdf2"
15446   [(set (match_dup 2)
15447         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15448    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15449    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15450    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15451    (parallel [(set (match_dup 7)
15452                    (unspec:XF [(match_dup 2) (match_dup 6)]
15453                               UNSPEC_FPATAN))
15454               (clobber (match_scratch:XF 8 ""))])
15455    (set (match_operand:DF 0 "register_operand" "")
15456         (float_truncate:DF (match_dup 7)))]
15457   "TARGET_USE_FANCY_MATH_387
15458    && flag_unsafe_math_optimizations"
15459 {
15460   int i;
15461
15462   for (i=2; i<8; i++)
15463     operands[i] = gen_reg_rtx (XFmode);
15464
15465   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15466 })
15467
15468 (define_expand "acossf2"
15469   [(set (match_dup 2)
15470         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15471    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15472    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15473    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15474    (parallel [(set (match_dup 7)
15475                    (unspec:XF [(match_dup 2) (match_dup 6)]
15476                               UNSPEC_FPATAN))
15477               (clobber (match_scratch:XF 8 ""))])
15478    (set (match_operand:SF 0 "register_operand" "")
15479         (float_truncate:SF (match_dup 7)))]
15480   "TARGET_USE_FANCY_MATH_387
15481    && flag_unsafe_math_optimizations"
15482 {
15483   int i;
15484
15485   for (i=2; i<8; i++)
15486     operands[i] = gen_reg_rtx (XFmode);
15487
15488   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15489 })
15490
15491 (define_expand "acosxf2"
15492   [(set (match_dup 2)
15493         (mult:XF (match_operand:XF 1 "register_operand" "")
15494                  (match_dup 1)))
15495    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15496    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15497    (parallel [(set (match_operand:XF 0 "register_operand" "")
15498                    (unspec:XF [(match_dup 1) (match_dup 5)]
15499                               UNSPEC_FPATAN))
15500               (clobber (match_scratch:XF 6 ""))])]
15501   "TARGET_USE_FANCY_MATH_387
15502    && flag_unsafe_math_optimizations"
15503 {
15504   int i;
15505
15506   for (i=2; i<6; i++)
15507     operands[i] = gen_reg_rtx (XFmode);
15508
15509   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15510 })
15511
15512 (define_insn "fyl2x_xf3"
15513   [(set (match_operand:XF 0 "register_operand" "=f")
15514         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15515                     (match_operand:XF 1 "register_operand" "u")]
15516                    UNSPEC_FYL2X))
15517    (clobber (match_scratch:XF 3 "=1"))]
15518   "TARGET_USE_FANCY_MATH_387
15519    && flag_unsafe_math_optimizations"
15520   "fyl2x"
15521   [(set_attr "type" "fpspc")
15522    (set_attr "mode" "XF")])
15523
15524 (define_expand "logsf2"
15525   [(set (match_dup 2)
15526         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15527    (parallel [(set (match_dup 4)
15528                    (unspec:XF [(match_dup 2)
15529                                (match_dup 3)] UNSPEC_FYL2X))
15530               (clobber (match_scratch:XF 5 ""))])
15531    (set (match_operand:SF 0 "register_operand" "")
15532         (float_truncate:SF (match_dup 4)))]
15533   "TARGET_USE_FANCY_MATH_387
15534    && flag_unsafe_math_optimizations"
15535 {
15536   rtx temp;
15537
15538   operands[2] = gen_reg_rtx (XFmode);
15539   operands[3] = gen_reg_rtx (XFmode);
15540   operands[4] = gen_reg_rtx (XFmode);
15541
15542   temp = standard_80387_constant_rtx (4); /* fldln2 */
15543   emit_move_insn (operands[3], temp);
15544 })
15545
15546 (define_expand "logdf2"
15547   [(set (match_dup 2)
15548         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15549    (parallel [(set (match_dup 4)
15550                    (unspec:XF [(match_dup 2)
15551                                (match_dup 3)] UNSPEC_FYL2X))
15552               (clobber (match_scratch:XF 5 ""))])
15553    (set (match_operand:DF 0 "register_operand" "")
15554         (float_truncate:DF (match_dup 4)))]
15555   "TARGET_USE_FANCY_MATH_387
15556    && flag_unsafe_math_optimizations"
15557 {
15558   rtx temp;
15559
15560   operands[2] = gen_reg_rtx (XFmode);
15561   operands[3] = gen_reg_rtx (XFmode);
15562   operands[4] = gen_reg_rtx (XFmode);
15563
15564   temp = standard_80387_constant_rtx (4); /* fldln2 */
15565   emit_move_insn (operands[3], temp);
15566 })
15567
15568 (define_expand "logxf2"
15569   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15570                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15571                                (match_dup 2)] UNSPEC_FYL2X))
15572               (clobber (match_scratch:XF 3 ""))])]
15573   "TARGET_USE_FANCY_MATH_387
15574    && flag_unsafe_math_optimizations"
15575 {
15576   rtx temp;
15577
15578   operands[2] = gen_reg_rtx (XFmode);
15579   temp = standard_80387_constant_rtx (4); /* fldln2 */
15580   emit_move_insn (operands[2], temp);
15581 })
15582
15583 (define_expand "log10sf2"
15584   [(set (match_dup 2)
15585         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15586    (parallel [(set (match_dup 4)
15587                    (unspec:XF [(match_dup 2)
15588                                (match_dup 3)] UNSPEC_FYL2X))
15589               (clobber (match_scratch:XF 5 ""))])
15590    (set (match_operand:SF 0 "register_operand" "")
15591         (float_truncate:SF (match_dup 4)))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && flag_unsafe_math_optimizations"
15594 {
15595   rtx temp;
15596
15597   operands[2] = gen_reg_rtx (XFmode);
15598   operands[3] = gen_reg_rtx (XFmode);
15599   operands[4] = gen_reg_rtx (XFmode);
15600
15601   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15602   emit_move_insn (operands[3], temp);
15603 })
15604
15605 (define_expand "log10df2"
15606   [(set (match_dup 2)
15607         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15608    (parallel [(set (match_dup 4)
15609                    (unspec:XF [(match_dup 2)
15610                                (match_dup 3)] UNSPEC_FYL2X))
15611               (clobber (match_scratch:XF 5 ""))])
15612    (set (match_operand:DF 0 "register_operand" "")
15613         (float_truncate:DF (match_dup 4)))]
15614   "TARGET_USE_FANCY_MATH_387
15615    && flag_unsafe_math_optimizations"
15616 {
15617   rtx temp;
15618
15619   operands[2] = gen_reg_rtx (XFmode);
15620   operands[3] = gen_reg_rtx (XFmode);
15621   operands[4] = gen_reg_rtx (XFmode);
15622
15623   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15624   emit_move_insn (operands[3], temp);
15625 })
15626
15627 (define_expand "log10xf2"
15628   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15629                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15630                                (match_dup 2)] UNSPEC_FYL2X))
15631               (clobber (match_scratch:XF 3 ""))])]
15632   "TARGET_USE_FANCY_MATH_387
15633    && flag_unsafe_math_optimizations"
15634 {
15635   rtx temp;
15636
15637   operands[2] = gen_reg_rtx (XFmode);
15638   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15639   emit_move_insn (operands[2], temp);
15640 })
15641
15642 (define_expand "log2sf2"
15643   [(set (match_dup 2)
15644         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15645    (parallel [(set (match_dup 4)
15646                    (unspec:XF [(match_dup 2)
15647                                (match_dup 3)] UNSPEC_FYL2X))
15648               (clobber (match_scratch:XF 5 ""))])
15649    (set (match_operand:SF 0 "register_operand" "")
15650         (float_truncate:SF (match_dup 4)))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && flag_unsafe_math_optimizations"
15653 {
15654   operands[2] = gen_reg_rtx (XFmode);
15655   operands[3] = gen_reg_rtx (XFmode);
15656   operands[4] = gen_reg_rtx (XFmode);
15657
15658   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15659 })
15660
15661 (define_expand "log2df2"
15662   [(set (match_dup 2)
15663         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15664    (parallel [(set (match_dup 4)
15665                    (unspec:XF [(match_dup 2)
15666                                (match_dup 3)] UNSPEC_FYL2X))
15667               (clobber (match_scratch:XF 5 ""))])
15668    (set (match_operand:DF 0 "register_operand" "")
15669         (float_truncate:DF (match_dup 4)))]
15670   "TARGET_USE_FANCY_MATH_387
15671    && flag_unsafe_math_optimizations"
15672 {
15673   operands[2] = gen_reg_rtx (XFmode);
15674   operands[3] = gen_reg_rtx (XFmode);
15675   operands[4] = gen_reg_rtx (XFmode);
15676
15677   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15678 })
15679
15680 (define_expand "log2xf2"
15681   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15682                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15683                                (match_dup 2)] UNSPEC_FYL2X))
15684               (clobber (match_scratch:XF 3 ""))])]
15685   "TARGET_USE_FANCY_MATH_387
15686    && flag_unsafe_math_optimizations"
15687 {
15688   operands[2] = gen_reg_rtx (XFmode);
15689   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15690 })
15691
15692 (define_insn "fyl2xp1_xf3"
15693   [(set (match_operand:XF 0 "register_operand" "=f")
15694         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15695                     (match_operand:XF 1 "register_operand" "u")]
15696                    UNSPEC_FYL2XP1))
15697    (clobber (match_scratch:XF 3 "=1"))]
15698   "TARGET_USE_FANCY_MATH_387
15699    && flag_unsafe_math_optimizations"
15700   "fyl2xp1"
15701   [(set_attr "type" "fpspc")
15702    (set_attr "mode" "XF")])
15703
15704 (define_expand "log1psf2"
15705   [(use (match_operand:SF 0 "register_operand" ""))
15706    (use (match_operand:SF 1 "register_operand" ""))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && flag_unsafe_math_optimizations"
15709 {
15710   rtx op0 = gen_reg_rtx (XFmode);
15711   rtx op1 = gen_reg_rtx (XFmode);
15712
15713   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15714   ix86_emit_i387_log1p (op0, op1);
15715   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15716   DONE;
15717 })
15718
15719 (define_expand "log1pdf2"
15720   [(use (match_operand:DF 0 "register_operand" ""))
15721    (use (match_operand:DF 1 "register_operand" ""))]
15722   "TARGET_USE_FANCY_MATH_387
15723    && flag_unsafe_math_optimizations"
15724 {
15725   rtx op0 = gen_reg_rtx (XFmode);
15726   rtx op1 = gen_reg_rtx (XFmode);
15727
15728   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15729   ix86_emit_i387_log1p (op0, op1);
15730   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15731   DONE;
15732 })
15733
15734 (define_expand "log1pxf2"
15735   [(use (match_operand:XF 0 "register_operand" ""))
15736    (use (match_operand:XF 1 "register_operand" ""))]
15737   "TARGET_USE_FANCY_MATH_387
15738    && flag_unsafe_math_optimizations"
15739 {
15740   ix86_emit_i387_log1p (operands[0], operands[1]);
15741   DONE;
15742 })
15743
15744 (define_insn "*fxtractxf3"
15745   [(set (match_operand:XF 0 "register_operand" "=f")
15746         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15747                    UNSPEC_XTRACT_FRACT))
15748    (set (match_operand:XF 1 "register_operand" "=u")
15749         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15750   "TARGET_USE_FANCY_MATH_387
15751    && flag_unsafe_math_optimizations"
15752   "fxtract"
15753   [(set_attr "type" "fpspc")
15754    (set_attr "mode" "XF")])
15755
15756 (define_expand "logbsf2"
15757   [(set (match_dup 2)
15758         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15759    (parallel [(set (match_dup 3)
15760                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15761               (set (match_dup 4)
15762                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15763    (set (match_operand:SF 0 "register_operand" "")
15764         (float_truncate:SF (match_dup 4)))]
15765   "TARGET_USE_FANCY_MATH_387
15766    && flag_unsafe_math_optimizations"
15767 {
15768   operands[2] = gen_reg_rtx (XFmode);
15769   operands[3] = gen_reg_rtx (XFmode);
15770   operands[4] = gen_reg_rtx (XFmode);
15771 })
15772
15773 (define_expand "logbdf2"
15774   [(set (match_dup 2)
15775         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15776    (parallel [(set (match_dup 3)
15777                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15778               (set (match_dup 4)
15779                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15780    (set (match_operand:DF 0 "register_operand" "")
15781         (float_truncate:DF (match_dup 4)))]
15782   "TARGET_USE_FANCY_MATH_387
15783    && flag_unsafe_math_optimizations"
15784 {
15785   operands[2] = gen_reg_rtx (XFmode);
15786   operands[3] = gen_reg_rtx (XFmode);
15787   operands[4] = gen_reg_rtx (XFmode);
15788 })
15789
15790 (define_expand "logbxf2"
15791   [(parallel [(set (match_dup 2)
15792                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15793                               UNSPEC_XTRACT_FRACT))
15794               (set (match_operand:XF 0 "register_operand" "")
15795                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15796   "TARGET_USE_FANCY_MATH_387
15797    && flag_unsafe_math_optimizations"
15798 {
15799   operands[2] = gen_reg_rtx (XFmode);
15800 })
15801
15802 (define_expand "ilogbsi2"
15803   [(parallel [(set (match_dup 2)
15804                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15805                               UNSPEC_XTRACT_FRACT))
15806               (set (match_operand:XF 3 "register_operand" "")
15807                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15808    (parallel [(set (match_operand:SI 0 "register_operand" "")
15809                    (fix:SI (match_dup 3)))
15810               (clobber (reg:CC FLAGS_REG))])]
15811   "TARGET_USE_FANCY_MATH_387
15812    && flag_unsafe_math_optimizations"
15813 {
15814   operands[2] = gen_reg_rtx (XFmode);
15815   operands[3] = gen_reg_rtx (XFmode);
15816 })
15817
15818 (define_insn "*f2xm1xf2"
15819   [(set (match_operand:XF 0 "register_operand" "=f")
15820         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15821          UNSPEC_F2XM1))]
15822   "TARGET_USE_FANCY_MATH_387
15823    && flag_unsafe_math_optimizations"
15824   "f2xm1"
15825   [(set_attr "type" "fpspc")
15826    (set_attr "mode" "XF")])
15827
15828 (define_insn "*fscalexf4"
15829   [(set (match_operand:XF 0 "register_operand" "=f")
15830         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15831                     (match_operand:XF 3 "register_operand" "1")]
15832                    UNSPEC_FSCALE_FRACT))
15833    (set (match_operand:XF 1 "register_operand" "=u")
15834         (unspec:XF [(match_dup 2) (match_dup 3)]
15835                    UNSPEC_FSCALE_EXP))]
15836   "TARGET_USE_FANCY_MATH_387
15837    && flag_unsafe_math_optimizations"
15838   "fscale"
15839   [(set_attr "type" "fpspc")
15840    (set_attr "mode" "XF")])
15841
15842 (define_expand "expsf2"
15843   [(set (match_dup 2)
15844         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15845    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15846    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15847    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15848    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15849    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15850    (parallel [(set (match_dup 10)
15851                    (unspec:XF [(match_dup 9) (match_dup 5)]
15852                               UNSPEC_FSCALE_FRACT))
15853               (set (match_dup 11)
15854                    (unspec:XF [(match_dup 9) (match_dup 5)]
15855                               UNSPEC_FSCALE_EXP))])
15856    (set (match_operand:SF 0 "register_operand" "")
15857         (float_truncate:SF (match_dup 10)))]
15858   "TARGET_USE_FANCY_MATH_387
15859    && flag_unsafe_math_optimizations"
15860 {
15861   rtx temp;
15862   int i;
15863
15864   for (i=2; i<12; i++)
15865     operands[i] = gen_reg_rtx (XFmode);
15866   temp = standard_80387_constant_rtx (5); /* fldl2e */
15867   emit_move_insn (operands[3], temp);
15868   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15869 })
15870
15871 (define_expand "expdf2"
15872   [(set (match_dup 2)
15873         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15874    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15875    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15876    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15877    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15878    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15879    (parallel [(set (match_dup 10)
15880                    (unspec:XF [(match_dup 9) (match_dup 5)]
15881                               UNSPEC_FSCALE_FRACT))
15882               (set (match_dup 11)
15883                    (unspec:XF [(match_dup 9) (match_dup 5)]
15884                               UNSPEC_FSCALE_EXP))])
15885    (set (match_operand:DF 0 "register_operand" "")
15886         (float_truncate:DF (match_dup 10)))]
15887   "TARGET_USE_FANCY_MATH_387
15888    && flag_unsafe_math_optimizations"
15889 {
15890   rtx temp;
15891   int i;
15892
15893   for (i=2; i<12; i++)
15894     operands[i] = gen_reg_rtx (XFmode);
15895   temp = standard_80387_constant_rtx (5); /* fldl2e */
15896   emit_move_insn (operands[3], temp);
15897   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15898 })
15899
15900 (define_expand "expxf2"
15901   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15902                                (match_dup 2)))
15903    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15904    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15905    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15906    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15907    (parallel [(set (match_operand:XF 0 "register_operand" "")
15908                    (unspec:XF [(match_dup 8) (match_dup 4)]
15909                               UNSPEC_FSCALE_FRACT))
15910               (set (match_dup 9)
15911                    (unspec:XF [(match_dup 8) (match_dup 4)]
15912                               UNSPEC_FSCALE_EXP))])]
15913   "TARGET_USE_FANCY_MATH_387
15914    && flag_unsafe_math_optimizations"
15915 {
15916   rtx temp;
15917   int i;
15918
15919   for (i=2; i<10; i++)
15920     operands[i] = gen_reg_rtx (XFmode);
15921   temp = standard_80387_constant_rtx (5); /* fldl2e */
15922   emit_move_insn (operands[2], temp);
15923   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15924 })
15925
15926 (define_expand "exp10sf2"
15927   [(set (match_dup 2)
15928         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15929    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15930    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15931    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15932    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15933    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15934    (parallel [(set (match_dup 10)
15935                    (unspec:XF [(match_dup 9) (match_dup 5)]
15936                               UNSPEC_FSCALE_FRACT))
15937               (set (match_dup 11)
15938                    (unspec:XF [(match_dup 9) (match_dup 5)]
15939                               UNSPEC_FSCALE_EXP))])
15940    (set (match_operand:SF 0 "register_operand" "")
15941         (float_truncate:SF (match_dup 10)))]
15942   "TARGET_USE_FANCY_MATH_387
15943    && flag_unsafe_math_optimizations"
15944 {
15945   rtx temp;
15946   int i;
15947
15948   for (i=2; i<12; i++)
15949     operands[i] = gen_reg_rtx (XFmode);
15950   temp = standard_80387_constant_rtx (6); /* fldl2t */
15951   emit_move_insn (operands[3], temp);
15952   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15953 })
15954
15955 (define_expand "exp10df2"
15956   [(set (match_dup 2)
15957         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15958    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15959    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15960    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15961    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15962    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15963    (parallel [(set (match_dup 10)
15964                    (unspec:XF [(match_dup 9) (match_dup 5)]
15965                               UNSPEC_FSCALE_FRACT))
15966               (set (match_dup 11)
15967                    (unspec:XF [(match_dup 9) (match_dup 5)]
15968                               UNSPEC_FSCALE_EXP))])
15969    (set (match_operand:DF 0 "register_operand" "")
15970         (float_truncate:DF (match_dup 10)))]
15971   "TARGET_USE_FANCY_MATH_387
15972    && flag_unsafe_math_optimizations"
15973 {
15974   rtx temp;
15975   int i;
15976
15977   for (i=2; i<12; i++)
15978     operands[i] = gen_reg_rtx (XFmode);
15979   temp = standard_80387_constant_rtx (6); /* fldl2t */
15980   emit_move_insn (operands[3], temp);
15981   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15982 })
15983
15984 (define_expand "exp10xf2"
15985   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15986                                (match_dup 2)))
15987    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15988    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15989    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15990    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15991    (parallel [(set (match_operand:XF 0 "register_operand" "")
15992                    (unspec:XF [(match_dup 8) (match_dup 4)]
15993                               UNSPEC_FSCALE_FRACT))
15994               (set (match_dup 9)
15995                    (unspec:XF [(match_dup 8) (match_dup 4)]
15996                               UNSPEC_FSCALE_EXP))])]
15997   "TARGET_USE_FANCY_MATH_387
15998    && flag_unsafe_math_optimizations"
15999 {
16000   rtx temp;
16001   int i;
16002
16003   for (i=2; i<10; i++)
16004     operands[i] = gen_reg_rtx (XFmode);
16005   temp = standard_80387_constant_rtx (6); /* fldl2t */
16006   emit_move_insn (operands[2], temp);
16007   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16008 })
16009
16010 (define_expand "exp2sf2"
16011   [(set (match_dup 2)
16012         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16013    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16014    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16015    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16016    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16017    (parallel [(set (match_dup 8)
16018                    (unspec:XF [(match_dup 7) (match_dup 3)]
16019                               UNSPEC_FSCALE_FRACT))
16020               (set (match_dup 9)
16021                    (unspec:XF [(match_dup 7) (match_dup 3)]
16022                               UNSPEC_FSCALE_EXP))])
16023    (set (match_operand:SF 0 "register_operand" "")
16024         (float_truncate:SF (match_dup 8)))]
16025   "TARGET_USE_FANCY_MATH_387
16026    && flag_unsafe_math_optimizations"
16027 {
16028   int i;
16029
16030   for (i=2; i<10; i++)
16031     operands[i] = gen_reg_rtx (XFmode);
16032   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16033 })
16034
16035 (define_expand "exp2df2"
16036   [(set (match_dup 2)
16037         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16038    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16039    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16040    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16041    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16042    (parallel [(set (match_dup 8)
16043                    (unspec:XF [(match_dup 7) (match_dup 3)]
16044                               UNSPEC_FSCALE_FRACT))
16045               (set (match_dup 9)
16046                    (unspec:XF [(match_dup 7) (match_dup 3)]
16047                               UNSPEC_FSCALE_EXP))])
16048    (set (match_operand:DF 0 "register_operand" "")
16049         (float_truncate:DF (match_dup 8)))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && flag_unsafe_math_optimizations"
16052 {
16053   int i;
16054
16055   for (i=2; i<10; i++)
16056     operands[i] = gen_reg_rtx (XFmode);
16057   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16058 })
16059
16060 (define_expand "exp2xf2"
16061   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16062    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16063    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16064    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16065    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16066    (parallel [(set (match_operand:XF 0 "register_operand" "")
16067                    (unspec:XF [(match_dup 7) (match_dup 3)]
16068                               UNSPEC_FSCALE_FRACT))
16069               (set (match_dup 8)
16070                    (unspec:XF [(match_dup 7) (match_dup 3)]
16071                               UNSPEC_FSCALE_EXP))])]
16072   "TARGET_USE_FANCY_MATH_387
16073    && flag_unsafe_math_optimizations"
16074 {
16075   int i;
16076
16077   for (i=2; i<9; i++)
16078     operands[i] = gen_reg_rtx (XFmode);
16079   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16080 })
16081
16082 (define_expand "expm1df2"
16083   [(set (match_dup 2)
16084         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16085    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16086    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16087    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16088    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16089    (parallel [(set (match_dup 8)
16090                    (unspec:XF [(match_dup 7) (match_dup 5)]
16091                               UNSPEC_FSCALE_FRACT))
16092                    (set (match_dup 9)
16093                    (unspec:XF [(match_dup 7) (match_dup 5)]
16094                               UNSPEC_FSCALE_EXP))])
16095    (parallel [(set (match_dup 11)
16096                    (unspec:XF [(match_dup 10) (match_dup 9)]
16097                               UNSPEC_FSCALE_FRACT))
16098               (set (match_dup 12)
16099                    (unspec:XF [(match_dup 10) (match_dup 9)]
16100                               UNSPEC_FSCALE_EXP))])
16101    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16102    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16103    (set (match_operand:DF 0 "register_operand" "")
16104         (float_truncate:DF (match_dup 14)))]
16105   "TARGET_USE_FANCY_MATH_387
16106    && flag_unsafe_math_optimizations"
16107 {
16108   rtx temp;
16109   int i;
16110
16111   for (i=2; i<15; i++)
16112     operands[i] = gen_reg_rtx (XFmode);
16113   temp = standard_80387_constant_rtx (5); /* fldl2e */
16114   emit_move_insn (operands[3], temp);
16115   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16116 })
16117
16118 (define_expand "expm1sf2"
16119   [(set (match_dup 2)
16120         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16121    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16122    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16123    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16124    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16125    (parallel [(set (match_dup 8)
16126                    (unspec:XF [(match_dup 7) (match_dup 5)]
16127                               UNSPEC_FSCALE_FRACT))
16128                    (set (match_dup 9)
16129                    (unspec:XF [(match_dup 7) (match_dup 5)]
16130                               UNSPEC_FSCALE_EXP))])
16131    (parallel [(set (match_dup 11)
16132                    (unspec:XF [(match_dup 10) (match_dup 9)]
16133                               UNSPEC_FSCALE_FRACT))
16134               (set (match_dup 12)
16135                    (unspec:XF [(match_dup 10) (match_dup 9)]
16136                               UNSPEC_FSCALE_EXP))])
16137    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16138    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16139    (set (match_operand:SF 0 "register_operand" "")
16140         (float_truncate:SF (match_dup 14)))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && flag_unsafe_math_optimizations"
16143 {
16144   rtx temp;
16145   int i;
16146
16147   for (i=2; i<15; i++)
16148     operands[i] = gen_reg_rtx (XFmode);
16149   temp = standard_80387_constant_rtx (5); /* fldl2e */
16150   emit_move_insn (operands[3], temp);
16151   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16152 })
16153
16154 (define_expand "expm1xf2"
16155   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16156                                (match_dup 2)))
16157    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16158    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16159    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16160    (parallel [(set (match_dup 7)
16161                    (unspec:XF [(match_dup 6) (match_dup 4)]
16162                               UNSPEC_FSCALE_FRACT))
16163                    (set (match_dup 8)
16164                    (unspec:XF [(match_dup 6) (match_dup 4)]
16165                               UNSPEC_FSCALE_EXP))])
16166    (parallel [(set (match_dup 10)
16167                    (unspec:XF [(match_dup 9) (match_dup 8)]
16168                               UNSPEC_FSCALE_FRACT))
16169               (set (match_dup 11)
16170                    (unspec:XF [(match_dup 9) (match_dup 8)]
16171                               UNSPEC_FSCALE_EXP))])
16172    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16173    (set (match_operand:XF 0 "register_operand" "")
16174         (plus:XF (match_dup 12) (match_dup 7)))]
16175   "TARGET_USE_FANCY_MATH_387
16176    && flag_unsafe_math_optimizations"
16177 {
16178   rtx temp;
16179   int i;
16180
16181   for (i=2; i<13; i++)
16182     operands[i] = gen_reg_rtx (XFmode);
16183   temp = standard_80387_constant_rtx (5); /* fldl2e */
16184   emit_move_insn (operands[2], temp);
16185   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16186 })
16187 \f
16188
16189 (define_insn "frndintxf2"
16190   [(set (match_operand:XF 0 "register_operand" "=f")
16191         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16192          UNSPEC_FRNDINT))]
16193   "TARGET_USE_FANCY_MATH_387
16194    && flag_unsafe_math_optimizations"
16195   "frndint"
16196   [(set_attr "type" "fpspc")
16197    (set_attr "mode" "XF")])
16198
16199 (define_expand "rintdf2"
16200   [(use (match_operand:DF 0 "register_operand" ""))
16201    (use (match_operand:DF 1 "register_operand" ""))]
16202   "TARGET_USE_FANCY_MATH_387
16203    && flag_unsafe_math_optimizations"
16204 {
16205   rtx op0 = gen_reg_rtx (XFmode);
16206   rtx op1 = gen_reg_rtx (XFmode);
16207
16208   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16209   emit_insn (gen_frndintxf2 (op0, op1));
16210
16211   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16212   DONE;
16213 })
16214
16215 (define_expand "rintsf2"
16216   [(use (match_operand:SF 0 "register_operand" ""))
16217    (use (match_operand:SF 1 "register_operand" ""))]
16218   "TARGET_USE_FANCY_MATH_387
16219    && flag_unsafe_math_optimizations"
16220 {
16221   rtx op0 = gen_reg_rtx (XFmode);
16222   rtx op1 = gen_reg_rtx (XFmode);
16223
16224   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16225   emit_insn (gen_frndintxf2 (op0, op1));
16226
16227   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16228   DONE;
16229 })
16230
16231 (define_expand "rintxf2"
16232   [(use (match_operand:XF 0 "register_operand" ""))
16233    (use (match_operand:XF 1 "register_operand" ""))]
16234   "TARGET_USE_FANCY_MATH_387
16235    && flag_unsafe_math_optimizations"
16236 {
16237   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16238   DONE;
16239 })
16240
16241 (define_insn "frndintxf2_floor"
16242   [(set (match_operand:XF 0 "register_operand" "=f")
16243         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16244          UNSPEC_FRNDINT_FLOOR))
16245    (use (match_operand:HI 2 "memory_operand" "m"))
16246    (use (match_operand:HI 3 "memory_operand" "m"))]
16247   "TARGET_USE_FANCY_MATH_387
16248    && flag_unsafe_math_optimizations"
16249   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16250   [(set_attr "type" "frndint")
16251    (set_attr "i387_cw" "floor")
16252    (set_attr "mode" "XF")])
16253
16254 (define_expand "floordf2"
16255   [(use (match_operand:DF 0 "register_operand" ""))
16256    (use (match_operand:DF 1 "register_operand" ""))]
16257   "TARGET_USE_FANCY_MATH_387
16258    && flag_unsafe_math_optimizations"
16259 {
16260   rtx op0 = gen_reg_rtx (XFmode);
16261   rtx op1 = gen_reg_rtx (XFmode);
16262   rtx op2 = assign_386_stack_local (HImode, 1);
16263   rtx op3 = assign_386_stack_local (HImode, 2);
16264         
16265   ix86_optimize_mode_switching = 1;
16266
16267   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16268   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16269
16270   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16271   DONE;
16272 })
16273
16274 (define_expand "floorsf2"
16275   [(use (match_operand:SF 0 "register_operand" ""))
16276    (use (match_operand:SF 1 "register_operand" ""))]
16277   "TARGET_USE_FANCY_MATH_387
16278    && flag_unsafe_math_optimizations"
16279 {
16280   rtx op0 = gen_reg_rtx (XFmode);
16281   rtx op1 = gen_reg_rtx (XFmode);
16282   rtx op2 = assign_386_stack_local (HImode, 1);
16283   rtx op3 = assign_386_stack_local (HImode, 2);
16284         
16285   ix86_optimize_mode_switching = 1;
16286
16287   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16288   emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16289
16290   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16291   DONE;
16292 })
16293
16294 (define_expand "floorxf2"
16295   [(use (match_operand:XF 0 "register_operand" ""))
16296    (use (match_operand:XF 1 "register_operand" ""))]
16297   "TARGET_USE_FANCY_MATH_387
16298    && flag_unsafe_math_optimizations"
16299 {
16300   rtx op2 = assign_386_stack_local (HImode, 1);
16301   rtx op3 = assign_386_stack_local (HImode, 2);
16302         
16303   ix86_optimize_mode_switching = 1;
16304
16305   emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16306   DONE;
16307 })
16308
16309 (define_insn "frndintxf2_ceil"
16310   [(set (match_operand:XF 0 "register_operand" "=f")
16311         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16312          UNSPEC_FRNDINT_CEIL))
16313    (use (match_operand:HI 2 "memory_operand" "m"))
16314    (use (match_operand:HI 3 "memory_operand" "m"))]
16315   "TARGET_USE_FANCY_MATH_387
16316    && flag_unsafe_math_optimizations"
16317   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16318   [(set_attr "type" "frndint")
16319    (set_attr "i387_cw" "ceil")
16320    (set_attr "mode" "XF")])
16321
16322 (define_expand "ceildf2"
16323   [(use (match_operand:DF 0 "register_operand" ""))
16324    (use (match_operand:DF 1 "register_operand" ""))]
16325   "TARGET_USE_FANCY_MATH_387
16326    && flag_unsafe_math_optimizations"
16327 {
16328   rtx op0 = gen_reg_rtx (XFmode);
16329   rtx op1 = gen_reg_rtx (XFmode);
16330   rtx op2 = assign_386_stack_local (HImode, 1);
16331   rtx op3 = assign_386_stack_local (HImode, 2);
16332         
16333   ix86_optimize_mode_switching = 1;
16334
16335   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16336   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16337
16338   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16339   DONE;
16340 })
16341
16342 (define_expand "ceilsf2"
16343   [(use (match_operand:SF 0 "register_operand" ""))
16344    (use (match_operand:SF 1 "register_operand" ""))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && flag_unsafe_math_optimizations"
16347 {
16348   rtx op0 = gen_reg_rtx (XFmode);
16349   rtx op1 = gen_reg_rtx (XFmode);
16350   rtx op2 = assign_386_stack_local (HImode, 1);
16351   rtx op3 = assign_386_stack_local (HImode, 2);
16352         
16353   ix86_optimize_mode_switching = 1;
16354
16355   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16356   emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16357
16358   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16359   DONE;
16360 })
16361
16362 (define_expand "ceilxf2"
16363   [(use (match_operand:XF 0 "register_operand" ""))
16364    (use (match_operand:XF 1 "register_operand" ""))]
16365   "TARGET_USE_FANCY_MATH_387
16366    && flag_unsafe_math_optimizations"
16367 {
16368   rtx op2 = assign_386_stack_local (HImode, 1);
16369   rtx op3 = assign_386_stack_local (HImode, 2);
16370         
16371   ix86_optimize_mode_switching = 1;
16372
16373   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16374   DONE;
16375 })
16376
16377 (define_insn "frndintxf2_trunc"
16378   [(set (match_operand:XF 0 "register_operand" "=f")
16379         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16380          UNSPEC_FRNDINT_TRUNC))
16381    (use (match_operand:HI 2 "memory_operand" "m"))
16382    (use (match_operand:HI 3 "memory_operand" "m"))]
16383   "TARGET_USE_FANCY_MATH_387
16384    && flag_unsafe_math_optimizations"
16385   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16386   [(set_attr "type" "frndint")
16387    (set_attr "i387_cw" "trunc")
16388    (set_attr "mode" "XF")])
16389
16390 (define_expand "btruncdf2"
16391   [(use (match_operand:DF 0 "register_operand" ""))
16392    (use (match_operand:DF 1 "register_operand" ""))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && flag_unsafe_math_optimizations"
16395 {
16396   rtx op0 = gen_reg_rtx (XFmode);
16397   rtx op1 = gen_reg_rtx (XFmode);
16398   rtx op2 = assign_386_stack_local (HImode, 1);
16399   rtx op3 = assign_386_stack_local (HImode, 2);
16400         
16401   ix86_optimize_mode_switching = 1;
16402
16403   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16404   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16405
16406   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16407   DONE;
16408 })
16409
16410 (define_expand "btruncsf2"
16411   [(use (match_operand:SF 0 "register_operand" ""))
16412    (use (match_operand:SF 1 "register_operand" ""))]
16413   "TARGET_USE_FANCY_MATH_387
16414    && flag_unsafe_math_optimizations"
16415 {
16416   rtx op0 = gen_reg_rtx (XFmode);
16417   rtx op1 = gen_reg_rtx (XFmode);
16418   rtx op2 = assign_386_stack_local (HImode, 1);
16419   rtx op3 = assign_386_stack_local (HImode, 2);
16420         
16421   ix86_optimize_mode_switching = 1;
16422
16423   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16424   emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16425
16426   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16427   DONE;
16428 })
16429
16430 (define_expand "btruncxf2"
16431   [(use (match_operand:XF 0 "register_operand" ""))
16432    (use (match_operand:XF 1 "register_operand" ""))]
16433   "TARGET_USE_FANCY_MATH_387
16434    && flag_unsafe_math_optimizations"
16435 {
16436   rtx op2 = assign_386_stack_local (HImode, 1);
16437   rtx op3 = assign_386_stack_local (HImode, 2);
16438         
16439   ix86_optimize_mode_switching = 1;
16440
16441   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16442   DONE;
16443 })
16444
16445 (define_insn "frndintxf2_mask_pm"
16446   [(set (match_operand:XF 0 "register_operand" "=f")
16447         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16448          UNSPEC_FRNDINT_MASK_PM))
16449    (use (match_operand:HI 2 "memory_operand" "m"))
16450    (use (match_operand:HI 3 "memory_operand" "m"))]
16451   "TARGET_USE_FANCY_MATH_387
16452    && flag_unsafe_math_optimizations"
16453   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16454   [(set_attr "type" "frndint")
16455    (set_attr "i387_cw" "mask_pm")
16456    (set_attr "mode" "XF")])
16457
16458 (define_expand "nearbyintdf2"
16459   [(use (match_operand:DF 0 "register_operand" ""))
16460    (use (match_operand:DF 1 "register_operand" ""))]
16461   "TARGET_USE_FANCY_MATH_387
16462    && flag_unsafe_math_optimizations"
16463 {
16464   rtx op0 = gen_reg_rtx (XFmode);
16465   rtx op1 = gen_reg_rtx (XFmode);
16466   rtx op2 = assign_386_stack_local (HImode, 1);
16467   rtx op3 = assign_386_stack_local (HImode, 2);
16468         
16469   ix86_optimize_mode_switching = 1;
16470
16471   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16472   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16473
16474   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16475   DONE;
16476 })
16477
16478 (define_expand "nearbyintsf2"
16479   [(use (match_operand:SF 0 "register_operand" ""))
16480    (use (match_operand:SF 1 "register_operand" ""))]
16481   "TARGET_USE_FANCY_MATH_387
16482    && flag_unsafe_math_optimizations"
16483 {
16484   rtx op0 = gen_reg_rtx (XFmode);
16485   rtx op1 = gen_reg_rtx (XFmode);
16486   rtx op2 = assign_386_stack_local (HImode, 1);
16487   rtx op3 = assign_386_stack_local (HImode, 2);
16488         
16489   ix86_optimize_mode_switching = 1;
16490
16491   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16492   emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16493
16494   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16495   DONE;
16496 })
16497
16498 (define_expand "nearbyintxf2"
16499   [(use (match_operand:XF 0 "register_operand" ""))
16500    (use (match_operand:XF 1 "register_operand" ""))]
16501   "TARGET_USE_FANCY_MATH_387
16502    && flag_unsafe_math_optimizations"
16503 {
16504   rtx op2 = assign_386_stack_local (HImode, 1);
16505   rtx op3 = assign_386_stack_local (HImode, 2);
16506         
16507   ix86_optimize_mode_switching = 1;
16508
16509   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16510                                      op2, op3));
16511   DONE;
16512 })
16513
16514 \f
16515 ;; Block operation instructions
16516
16517 (define_insn "cld"
16518  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16519  ""
16520  "cld"
16521   [(set_attr "type" "cld")])
16522
16523 (define_expand "movmemsi"
16524   [(use (match_operand:BLK 0 "memory_operand" ""))
16525    (use (match_operand:BLK 1 "memory_operand" ""))
16526    (use (match_operand:SI 2 "nonmemory_operand" ""))
16527    (use (match_operand:SI 3 "const_int_operand" ""))]
16528   "! optimize_size"
16529 {
16530  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16531    DONE;
16532  else
16533    FAIL;
16534 })
16535
16536 (define_expand "movmemdi"
16537   [(use (match_operand:BLK 0 "memory_operand" ""))
16538    (use (match_operand:BLK 1 "memory_operand" ""))
16539    (use (match_operand:DI 2 "nonmemory_operand" ""))
16540    (use (match_operand:DI 3 "const_int_operand" ""))]
16541   "TARGET_64BIT"
16542 {
16543  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16544    DONE;
16545  else
16546    FAIL;
16547 })
16548
16549 ;; Most CPUs don't like single string operations
16550 ;; Handle this case here to simplify previous expander.
16551
16552 (define_expand "strmov"
16553   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16554    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16555    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16556               (clobber (reg:CC FLAGS_REG))])
16557    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16558               (clobber (reg:CC FLAGS_REG))])]
16559   ""
16560 {
16561   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16562
16563   /* If .md ever supports :P for Pmode, these can be directly
16564      in the pattern above.  */
16565   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16566   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16567
16568   if (TARGET_SINGLE_STRINGOP || optimize_size)
16569     {
16570       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16571                                       operands[2], operands[3],
16572                                       operands[5], operands[6]));
16573       DONE;
16574     }
16575
16576   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16577 })
16578
16579 (define_expand "strmov_singleop"
16580   [(parallel [(set (match_operand 1 "memory_operand" "")
16581                    (match_operand 3 "memory_operand" ""))
16582               (set (match_operand 0 "register_operand" "")
16583                    (match_operand 4 "" ""))
16584               (set (match_operand 2 "register_operand" "")
16585                    (match_operand 5 "" ""))
16586               (use (reg:SI DIRFLAG_REG))])]
16587   "TARGET_SINGLE_STRINGOP || optimize_size"
16588   "")
16589
16590 (define_insn "*strmovdi_rex_1"
16591   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16592         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16593    (set (match_operand:DI 0 "register_operand" "=D")
16594         (plus:DI (match_dup 2)
16595                  (const_int 8)))
16596    (set (match_operand:DI 1 "register_operand" "=S")
16597         (plus:DI (match_dup 3)
16598                  (const_int 8)))
16599    (use (reg:SI DIRFLAG_REG))]
16600   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16601   "movsq"
16602   [(set_attr "type" "str")
16603    (set_attr "mode" "DI")
16604    (set_attr "memory" "both")])
16605
16606 (define_insn "*strmovsi_1"
16607   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16608         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16609    (set (match_operand:SI 0 "register_operand" "=D")
16610         (plus:SI (match_dup 2)
16611                  (const_int 4)))
16612    (set (match_operand:SI 1 "register_operand" "=S")
16613         (plus:SI (match_dup 3)
16614                  (const_int 4)))
16615    (use (reg:SI DIRFLAG_REG))]
16616   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16617   "{movsl|movsd}"
16618   [(set_attr "type" "str")
16619    (set_attr "mode" "SI")
16620    (set_attr "memory" "both")])
16621
16622 (define_insn "*strmovsi_rex_1"
16623   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16624         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16625    (set (match_operand:DI 0 "register_operand" "=D")
16626         (plus:DI (match_dup 2)
16627                  (const_int 4)))
16628    (set (match_operand:DI 1 "register_operand" "=S")
16629         (plus:DI (match_dup 3)
16630                  (const_int 4)))
16631    (use (reg:SI DIRFLAG_REG))]
16632   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16633   "{movsl|movsd}"
16634   [(set_attr "type" "str")
16635    (set_attr "mode" "SI")
16636    (set_attr "memory" "both")])
16637
16638 (define_insn "*strmovhi_1"
16639   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16640         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16641    (set (match_operand:SI 0 "register_operand" "=D")
16642         (plus:SI (match_dup 2)
16643                  (const_int 2)))
16644    (set (match_operand:SI 1 "register_operand" "=S")
16645         (plus:SI (match_dup 3)
16646                  (const_int 2)))
16647    (use (reg:SI DIRFLAG_REG))]
16648   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16649   "movsw"
16650   [(set_attr "type" "str")
16651    (set_attr "memory" "both")
16652    (set_attr "mode" "HI")])
16653
16654 (define_insn "*strmovhi_rex_1"
16655   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16656         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16657    (set (match_operand:DI 0 "register_operand" "=D")
16658         (plus:DI (match_dup 2)
16659                  (const_int 2)))
16660    (set (match_operand:DI 1 "register_operand" "=S")
16661         (plus:DI (match_dup 3)
16662                  (const_int 2)))
16663    (use (reg:SI DIRFLAG_REG))]
16664   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16665   "movsw"
16666   [(set_attr "type" "str")
16667    (set_attr "memory" "both")
16668    (set_attr "mode" "HI")])
16669
16670 (define_insn "*strmovqi_1"
16671   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16672         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16673    (set (match_operand:SI 0 "register_operand" "=D")
16674         (plus:SI (match_dup 2)
16675                  (const_int 1)))
16676    (set (match_operand:SI 1 "register_operand" "=S")
16677         (plus:SI (match_dup 3)
16678                  (const_int 1)))
16679    (use (reg:SI DIRFLAG_REG))]
16680   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16681   "movsb"
16682   [(set_attr "type" "str")
16683    (set_attr "memory" "both")
16684    (set_attr "mode" "QI")])
16685
16686 (define_insn "*strmovqi_rex_1"
16687   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16688         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16689    (set (match_operand:DI 0 "register_operand" "=D")
16690         (plus:DI (match_dup 2)
16691                  (const_int 1)))
16692    (set (match_operand:DI 1 "register_operand" "=S")
16693         (plus:DI (match_dup 3)
16694                  (const_int 1)))
16695    (use (reg:SI DIRFLAG_REG))]
16696   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16697   "movsb"
16698   [(set_attr "type" "str")
16699    (set_attr "memory" "both")
16700    (set_attr "mode" "QI")])
16701
16702 (define_expand "rep_mov"
16703   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16704               (set (match_operand 0 "register_operand" "")
16705                    (match_operand 5 "" ""))
16706               (set (match_operand 2 "register_operand" "")
16707                    (match_operand 6 "" ""))
16708               (set (match_operand 1 "memory_operand" "")
16709                    (match_operand 3 "memory_operand" ""))
16710               (use (match_dup 4))
16711               (use (reg:SI DIRFLAG_REG))])]
16712   ""
16713   "")
16714
16715 (define_insn "*rep_movdi_rex64"
16716   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16717    (set (match_operand:DI 0 "register_operand" "=D") 
16718         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16719                             (const_int 3))
16720                  (match_operand:DI 3 "register_operand" "0")))
16721    (set (match_operand:DI 1 "register_operand" "=S") 
16722         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16723                  (match_operand:DI 4 "register_operand" "1")))
16724    (set (mem:BLK (match_dup 3))
16725         (mem:BLK (match_dup 4)))
16726    (use (match_dup 5))
16727    (use (reg:SI DIRFLAG_REG))]
16728   "TARGET_64BIT"
16729   "{rep\;movsq|rep movsq}"
16730   [(set_attr "type" "str")
16731    (set_attr "prefix_rep" "1")
16732    (set_attr "memory" "both")
16733    (set_attr "mode" "DI")])
16734
16735 (define_insn "*rep_movsi"
16736   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16737    (set (match_operand:SI 0 "register_operand" "=D") 
16738         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16739                             (const_int 2))
16740                  (match_operand:SI 3 "register_operand" "0")))
16741    (set (match_operand:SI 1 "register_operand" "=S") 
16742         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16743                  (match_operand:SI 4 "register_operand" "1")))
16744    (set (mem:BLK (match_dup 3))
16745         (mem:BLK (match_dup 4)))
16746    (use (match_dup 5))
16747    (use (reg:SI DIRFLAG_REG))]
16748   "!TARGET_64BIT"
16749   "{rep\;movsl|rep movsd}"
16750   [(set_attr "type" "str")
16751    (set_attr "prefix_rep" "1")
16752    (set_attr "memory" "both")
16753    (set_attr "mode" "SI")])
16754
16755 (define_insn "*rep_movsi_rex64"
16756   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16757    (set (match_operand:DI 0 "register_operand" "=D") 
16758         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16759                             (const_int 2))
16760                  (match_operand:DI 3 "register_operand" "0")))
16761    (set (match_operand:DI 1 "register_operand" "=S") 
16762         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16763                  (match_operand:DI 4 "register_operand" "1")))
16764    (set (mem:BLK (match_dup 3))
16765         (mem:BLK (match_dup 4)))
16766    (use (match_dup 5))
16767    (use (reg:SI DIRFLAG_REG))]
16768   "TARGET_64BIT"
16769   "{rep\;movsl|rep movsd}"
16770   [(set_attr "type" "str")
16771    (set_attr "prefix_rep" "1")
16772    (set_attr "memory" "both")
16773    (set_attr "mode" "SI")])
16774
16775 (define_insn "*rep_movqi"
16776   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16777    (set (match_operand:SI 0 "register_operand" "=D") 
16778         (plus:SI (match_operand:SI 3 "register_operand" "0")
16779                  (match_operand:SI 5 "register_operand" "2")))
16780    (set (match_operand:SI 1 "register_operand" "=S") 
16781         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16782    (set (mem:BLK (match_dup 3))
16783         (mem:BLK (match_dup 4)))
16784    (use (match_dup 5))
16785    (use (reg:SI DIRFLAG_REG))]
16786   "!TARGET_64BIT"
16787   "{rep\;movsb|rep movsb}"
16788   [(set_attr "type" "str")
16789    (set_attr "prefix_rep" "1")
16790    (set_attr "memory" "both")
16791    (set_attr "mode" "SI")])
16792
16793 (define_insn "*rep_movqi_rex64"
16794   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16795    (set (match_operand:DI 0 "register_operand" "=D") 
16796         (plus:DI (match_operand:DI 3 "register_operand" "0")
16797                  (match_operand:DI 5 "register_operand" "2")))
16798    (set (match_operand:DI 1 "register_operand" "=S") 
16799         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16800    (set (mem:BLK (match_dup 3))
16801         (mem:BLK (match_dup 4)))
16802    (use (match_dup 5))
16803    (use (reg:SI DIRFLAG_REG))]
16804   "TARGET_64BIT"
16805   "{rep\;movsb|rep movsb}"
16806   [(set_attr "type" "str")
16807    (set_attr "prefix_rep" "1")
16808    (set_attr "memory" "both")
16809    (set_attr "mode" "SI")])
16810
16811 (define_expand "clrmemsi"
16812    [(use (match_operand:BLK 0 "memory_operand" ""))
16813     (use (match_operand:SI 1 "nonmemory_operand" ""))
16814     (use (match_operand 2 "const_int_operand" ""))]
16815   ""
16816 {
16817  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16818    DONE;
16819  else
16820    FAIL;
16821 })
16822
16823 (define_expand "clrmemdi"
16824    [(use (match_operand:BLK 0 "memory_operand" ""))
16825     (use (match_operand:DI 1 "nonmemory_operand" ""))
16826     (use (match_operand 2 "const_int_operand" ""))]
16827   "TARGET_64BIT"
16828 {
16829  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16830    DONE;
16831  else
16832    FAIL;
16833 })
16834
16835 ;; Most CPUs don't like single string operations
16836 ;; Handle this case here to simplify previous expander.
16837
16838 (define_expand "strset"
16839   [(set (match_operand 1 "memory_operand" "")
16840         (match_operand 2 "register_operand" ""))
16841    (parallel [(set (match_operand 0 "register_operand" "")
16842                    (match_dup 3))
16843               (clobber (reg:CC FLAGS_REG))])]
16844   ""
16845 {
16846   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16847     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16848
16849   /* If .md ever supports :P for Pmode, this can be directly
16850      in the pattern above.  */
16851   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16852                               GEN_INT (GET_MODE_SIZE (GET_MODE
16853                                                       (operands[2]))));
16854   if (TARGET_SINGLE_STRINGOP || optimize_size)
16855     {
16856       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16857                                       operands[3]));
16858       DONE;
16859     }
16860 })
16861
16862 (define_expand "strset_singleop"
16863   [(parallel [(set (match_operand 1 "memory_operand" "")
16864                    (match_operand 2 "register_operand" ""))
16865               (set (match_operand 0 "register_operand" "")
16866                    (match_operand 3 "" ""))
16867               (use (reg:SI DIRFLAG_REG))])]
16868   "TARGET_SINGLE_STRINGOP || optimize_size"
16869   "")
16870
16871 (define_insn "*strsetdi_rex_1"
16872   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16873         (match_operand:DI 2 "register_operand" "a"))
16874    (set (match_operand:DI 0 "register_operand" "=D")
16875         (plus:DI (match_dup 1)
16876                  (const_int 8)))
16877    (use (reg:SI DIRFLAG_REG))]
16878   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16879   "stosq"
16880   [(set_attr "type" "str")
16881    (set_attr "memory" "store")
16882    (set_attr "mode" "DI")])
16883
16884 (define_insn "*strsetsi_1"
16885   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16886         (match_operand:SI 2 "register_operand" "a"))
16887    (set (match_operand:SI 0 "register_operand" "=D")
16888         (plus:SI (match_dup 1)
16889                  (const_int 4)))
16890    (use (reg:SI DIRFLAG_REG))]
16891   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16892   "{stosl|stosd}"
16893   [(set_attr "type" "str")
16894    (set_attr "memory" "store")
16895    (set_attr "mode" "SI")])
16896
16897 (define_insn "*strsetsi_rex_1"
16898   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16899         (match_operand:SI 2 "register_operand" "a"))
16900    (set (match_operand:DI 0 "register_operand" "=D")
16901         (plus:DI (match_dup 1)
16902                  (const_int 4)))
16903    (use (reg:SI DIRFLAG_REG))]
16904   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16905   "{stosl|stosd}"
16906   [(set_attr "type" "str")
16907    (set_attr "memory" "store")
16908    (set_attr "mode" "SI")])
16909
16910 (define_insn "*strsethi_1"
16911   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16912         (match_operand:HI 2 "register_operand" "a"))
16913    (set (match_operand:SI 0 "register_operand" "=D")
16914         (plus:SI (match_dup 1)
16915                  (const_int 2)))
16916    (use (reg:SI DIRFLAG_REG))]
16917   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16918   "stosw"
16919   [(set_attr "type" "str")
16920    (set_attr "memory" "store")
16921    (set_attr "mode" "HI")])
16922
16923 (define_insn "*strsethi_rex_1"
16924   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16925         (match_operand:HI 2 "register_operand" "a"))
16926    (set (match_operand:DI 0 "register_operand" "=D")
16927         (plus:DI (match_dup 1)
16928                  (const_int 2)))
16929    (use (reg:SI DIRFLAG_REG))]
16930   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16931   "stosw"
16932   [(set_attr "type" "str")
16933    (set_attr "memory" "store")
16934    (set_attr "mode" "HI")])
16935
16936 (define_insn "*strsetqi_1"
16937   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16938         (match_operand:QI 2 "register_operand" "a"))
16939    (set (match_operand:SI 0 "register_operand" "=D")
16940         (plus:SI (match_dup 1)
16941                  (const_int 1)))
16942    (use (reg:SI DIRFLAG_REG))]
16943   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16944   "stosb"
16945   [(set_attr "type" "str")
16946    (set_attr "memory" "store")
16947    (set_attr "mode" "QI")])
16948
16949 (define_insn "*strsetqi_rex_1"
16950   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16951         (match_operand:QI 2 "register_operand" "a"))
16952    (set (match_operand:DI 0 "register_operand" "=D")
16953         (plus:DI (match_dup 1)
16954                  (const_int 1)))
16955    (use (reg:SI DIRFLAG_REG))]
16956   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16957   "stosb"
16958   [(set_attr "type" "str")
16959    (set_attr "memory" "store")
16960    (set_attr "mode" "QI")])
16961
16962 (define_expand "rep_stos"
16963   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16964               (set (match_operand 0 "register_operand" "")
16965                    (match_operand 4 "" ""))
16966               (set (match_operand 2 "memory_operand" "") (const_int 0))
16967               (use (match_operand 3 "register_operand" ""))
16968               (use (match_dup 1))
16969               (use (reg:SI DIRFLAG_REG))])]
16970   ""
16971   "")
16972
16973 (define_insn "*rep_stosdi_rex64"
16974   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16975    (set (match_operand:DI 0 "register_operand" "=D") 
16976         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16977                             (const_int 3))
16978                  (match_operand:DI 3 "register_operand" "0")))
16979    (set (mem:BLK (match_dup 3))
16980         (const_int 0))
16981    (use (match_operand:DI 2 "register_operand" "a"))
16982    (use (match_dup 4))
16983    (use (reg:SI DIRFLAG_REG))]
16984   "TARGET_64BIT"
16985   "{rep\;stosq|rep stosq}"
16986   [(set_attr "type" "str")
16987    (set_attr "prefix_rep" "1")
16988    (set_attr "memory" "store")
16989    (set_attr "mode" "DI")])
16990
16991 (define_insn "*rep_stossi"
16992   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16993    (set (match_operand:SI 0 "register_operand" "=D") 
16994         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16995                             (const_int 2))
16996                  (match_operand:SI 3 "register_operand" "0")))
16997    (set (mem:BLK (match_dup 3))
16998         (const_int 0))
16999    (use (match_operand:SI 2 "register_operand" "a"))
17000    (use (match_dup 4))
17001    (use (reg:SI DIRFLAG_REG))]
17002   "!TARGET_64BIT"
17003   "{rep\;stosl|rep stosd}"
17004   [(set_attr "type" "str")
17005    (set_attr "prefix_rep" "1")
17006    (set_attr "memory" "store")
17007    (set_attr "mode" "SI")])
17008
17009 (define_insn "*rep_stossi_rex64"
17010   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17011    (set (match_operand:DI 0 "register_operand" "=D") 
17012         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17013                             (const_int 2))
17014                  (match_operand:DI 3 "register_operand" "0")))
17015    (set (mem:BLK (match_dup 3))
17016         (const_int 0))
17017    (use (match_operand:SI 2 "register_operand" "a"))
17018    (use (match_dup 4))
17019    (use (reg:SI DIRFLAG_REG))]
17020   "TARGET_64BIT"
17021   "{rep\;stosl|rep stosd}"
17022   [(set_attr "type" "str")
17023    (set_attr "prefix_rep" "1")
17024    (set_attr "memory" "store")
17025    (set_attr "mode" "SI")])
17026
17027 (define_insn "*rep_stosqi"
17028   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17029    (set (match_operand:SI 0 "register_operand" "=D") 
17030         (plus:SI (match_operand:SI 3 "register_operand" "0")
17031                  (match_operand:SI 4 "register_operand" "1")))
17032    (set (mem:BLK (match_dup 3))
17033         (const_int 0))
17034    (use (match_operand:QI 2 "register_operand" "a"))
17035    (use (match_dup 4))
17036    (use (reg:SI DIRFLAG_REG))]
17037   "!TARGET_64BIT"
17038   "{rep\;stosb|rep stosb}"
17039   [(set_attr "type" "str")
17040    (set_attr "prefix_rep" "1")
17041    (set_attr "memory" "store")
17042    (set_attr "mode" "QI")])
17043
17044 (define_insn "*rep_stosqi_rex64"
17045   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17046    (set (match_operand:DI 0 "register_operand" "=D") 
17047         (plus:DI (match_operand:DI 3 "register_operand" "0")
17048                  (match_operand:DI 4 "register_operand" "1")))
17049    (set (mem:BLK (match_dup 3))
17050         (const_int 0))
17051    (use (match_operand:QI 2 "register_operand" "a"))
17052    (use (match_dup 4))
17053    (use (reg:SI DIRFLAG_REG))]
17054   "TARGET_64BIT"
17055   "{rep\;stosb|rep stosb}"
17056   [(set_attr "type" "str")
17057    (set_attr "prefix_rep" "1")
17058    (set_attr "memory" "store")
17059    (set_attr "mode" "QI")])
17060
17061 (define_expand "cmpstrsi"
17062   [(set (match_operand:SI 0 "register_operand" "")
17063         (compare:SI (match_operand:BLK 1 "general_operand" "")
17064                     (match_operand:BLK 2 "general_operand" "")))
17065    (use (match_operand 3 "general_operand" ""))
17066    (use (match_operand 4 "immediate_operand" ""))]
17067   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17068 {
17069   rtx addr1, addr2, out, outlow, count, countreg, align;
17070
17071   /* Can't use this if the user has appropriated esi or edi.  */
17072   if (global_regs[4] || global_regs[5])
17073     FAIL;
17074
17075   out = operands[0];
17076   if (GET_CODE (out) != REG)
17077     out = gen_reg_rtx (SImode);
17078
17079   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17080   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17081   if (addr1 != XEXP (operands[1], 0))
17082     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17083   if (addr2 != XEXP (operands[2], 0))
17084     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17085
17086   count = operands[3];
17087   countreg = ix86_zero_extend_to_Pmode (count);
17088
17089   /* %%% Iff we are testing strict equality, we can use known alignment
17090      to good advantage.  This may be possible with combine, particularly
17091      once cc0 is dead.  */
17092   align = operands[4];
17093
17094   emit_insn (gen_cld ());
17095   if (GET_CODE (count) == CONST_INT)
17096     {
17097       if (INTVAL (count) == 0)
17098         {
17099           emit_move_insn (operands[0], const0_rtx);
17100           DONE;
17101         }
17102       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17103                                     operands[1], operands[2]));
17104     }
17105   else
17106     {
17107       if (TARGET_64BIT)
17108         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17109       else
17110         emit_insn (gen_cmpsi_1 (countreg, countreg));
17111       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17112                                  operands[1], operands[2]));
17113     }
17114
17115   outlow = gen_lowpart (QImode, out);
17116   emit_insn (gen_cmpintqi (outlow));
17117   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17118
17119   if (operands[0] != out)
17120     emit_move_insn (operands[0], out);
17121
17122   DONE;
17123 })
17124
17125 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17126
17127 (define_expand "cmpintqi"
17128   [(set (match_dup 1)
17129         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17130    (set (match_dup 2)
17131         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17132    (parallel [(set (match_operand:QI 0 "register_operand" "")
17133                    (minus:QI (match_dup 1)
17134                              (match_dup 2)))
17135               (clobber (reg:CC FLAGS_REG))])]
17136   ""
17137   "operands[1] = gen_reg_rtx (QImode);
17138    operands[2] = gen_reg_rtx (QImode);")
17139
17140 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17141 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17142
17143 (define_expand "cmpstrqi_nz_1"
17144   [(parallel [(set (reg:CC FLAGS_REG)
17145                    (compare:CC (match_operand 4 "memory_operand" "")
17146                                (match_operand 5 "memory_operand" "")))
17147               (use (match_operand 2 "register_operand" ""))
17148               (use (match_operand:SI 3 "immediate_operand" ""))
17149               (use (reg:SI DIRFLAG_REG))
17150               (clobber (match_operand 0 "register_operand" ""))
17151               (clobber (match_operand 1 "register_operand" ""))
17152               (clobber (match_dup 2))])]
17153   ""
17154   "")
17155
17156 (define_insn "*cmpstrqi_nz_1"
17157   [(set (reg:CC FLAGS_REG)
17158         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17159                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17160    (use (match_operand:SI 6 "register_operand" "2"))
17161    (use (match_operand:SI 3 "immediate_operand" "i"))
17162    (use (reg:SI DIRFLAG_REG))
17163    (clobber (match_operand:SI 0 "register_operand" "=S"))
17164    (clobber (match_operand:SI 1 "register_operand" "=D"))
17165    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17166   "!TARGET_64BIT"
17167   "repz{\;| }cmpsb"
17168   [(set_attr "type" "str")
17169    (set_attr "mode" "QI")
17170    (set_attr "prefix_rep" "1")])
17171
17172 (define_insn "*cmpstrqi_nz_rex_1"
17173   [(set (reg:CC FLAGS_REG)
17174         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17175                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17176    (use (match_operand:DI 6 "register_operand" "2"))
17177    (use (match_operand:SI 3 "immediate_operand" "i"))
17178    (use (reg:SI DIRFLAG_REG))
17179    (clobber (match_operand:DI 0 "register_operand" "=S"))
17180    (clobber (match_operand:DI 1 "register_operand" "=D"))
17181    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17182   "TARGET_64BIT"
17183   "repz{\;| }cmpsb"
17184   [(set_attr "type" "str")
17185    (set_attr "mode" "QI")
17186    (set_attr "prefix_rep" "1")])
17187
17188 ;; The same, but the count is not known to not be zero.
17189
17190 (define_expand "cmpstrqi_1"
17191   [(parallel [(set (reg:CC FLAGS_REG)
17192                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17193                                      (const_int 0))
17194                   (compare:CC (match_operand 4 "memory_operand" "")
17195                               (match_operand 5 "memory_operand" ""))
17196                   (const_int 0)))
17197               (use (match_operand:SI 3 "immediate_operand" ""))
17198               (use (reg:CC FLAGS_REG))
17199               (use (reg:SI DIRFLAG_REG))
17200               (clobber (match_operand 0 "register_operand" ""))
17201               (clobber (match_operand 1 "register_operand" ""))
17202               (clobber (match_dup 2))])]
17203   ""
17204   "")
17205
17206 (define_insn "*cmpstrqi_1"
17207   [(set (reg:CC FLAGS_REG)
17208         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17209                              (const_int 0))
17210           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17211                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17212           (const_int 0)))
17213    (use (match_operand:SI 3 "immediate_operand" "i"))
17214    (use (reg:CC FLAGS_REG))
17215    (use (reg:SI DIRFLAG_REG))
17216    (clobber (match_operand:SI 0 "register_operand" "=S"))
17217    (clobber (match_operand:SI 1 "register_operand" "=D"))
17218    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17219   "!TARGET_64BIT"
17220   "repz{\;| }cmpsb"
17221   [(set_attr "type" "str")
17222    (set_attr "mode" "QI")
17223    (set_attr "prefix_rep" "1")])
17224
17225 (define_insn "*cmpstrqi_rex_1"
17226   [(set (reg:CC FLAGS_REG)
17227         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17228                              (const_int 0))
17229           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17230                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17231           (const_int 0)))
17232    (use (match_operand:SI 3 "immediate_operand" "i"))
17233    (use (reg:CC FLAGS_REG))
17234    (use (reg:SI DIRFLAG_REG))
17235    (clobber (match_operand:DI 0 "register_operand" "=S"))
17236    (clobber (match_operand:DI 1 "register_operand" "=D"))
17237    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17238   "TARGET_64BIT"
17239   "repz{\;| }cmpsb"
17240   [(set_attr "type" "str")
17241    (set_attr "mode" "QI")
17242    (set_attr "prefix_rep" "1")])
17243
17244 (define_expand "strlensi"
17245   [(set (match_operand:SI 0 "register_operand" "")
17246         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17247                     (match_operand:QI 2 "immediate_operand" "")
17248                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17249   ""
17250 {
17251  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17252    DONE;
17253  else
17254    FAIL;
17255 })
17256
17257 (define_expand "strlendi"
17258   [(set (match_operand:DI 0 "register_operand" "")
17259         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17260                     (match_operand:QI 2 "immediate_operand" "")
17261                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17262   ""
17263 {
17264  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17265    DONE;
17266  else
17267    FAIL;
17268 })
17269
17270 (define_expand "strlenqi_1"
17271   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17272               (use (reg:SI DIRFLAG_REG))
17273               (clobber (match_operand 1 "register_operand" ""))
17274               (clobber (reg:CC FLAGS_REG))])]
17275   ""
17276   "")
17277
17278 (define_insn "*strlenqi_1"
17279   [(set (match_operand:SI 0 "register_operand" "=&c")
17280         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17281                     (match_operand:QI 2 "register_operand" "a")
17282                     (match_operand:SI 3 "immediate_operand" "i")
17283                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17284    (use (reg:SI DIRFLAG_REG))
17285    (clobber (match_operand:SI 1 "register_operand" "=D"))
17286    (clobber (reg:CC FLAGS_REG))]
17287   "!TARGET_64BIT"
17288   "repnz{\;| }scasb"
17289   [(set_attr "type" "str")
17290    (set_attr "mode" "QI")
17291    (set_attr "prefix_rep" "1")])
17292
17293 (define_insn "*strlenqi_rex_1"
17294   [(set (match_operand:DI 0 "register_operand" "=&c")
17295         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17296                     (match_operand:QI 2 "register_operand" "a")
17297                     (match_operand:DI 3 "immediate_operand" "i")
17298                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17299    (use (reg:SI DIRFLAG_REG))
17300    (clobber (match_operand:DI 1 "register_operand" "=D"))
17301    (clobber (reg:CC FLAGS_REG))]
17302   "TARGET_64BIT"
17303   "repnz{\;| }scasb"
17304   [(set_attr "type" "str")
17305    (set_attr "mode" "QI")
17306    (set_attr "prefix_rep" "1")])
17307
17308 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17309 ;; handled in combine, but it is not currently up to the task.
17310 ;; When used for their truth value, the cmpstr* expanders generate
17311 ;; code like this:
17312 ;;
17313 ;;   repz cmpsb
17314 ;;   seta       %al
17315 ;;   setb       %dl
17316 ;;   cmpb       %al, %dl
17317 ;;   jcc        label
17318 ;;
17319 ;; The intermediate three instructions are unnecessary.
17320
17321 ;; This one handles cmpstr*_nz_1...
17322 (define_peephole2
17323   [(parallel[
17324      (set (reg:CC FLAGS_REG)
17325           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17326                       (mem:BLK (match_operand 5 "register_operand" ""))))
17327      (use (match_operand 6 "register_operand" ""))
17328      (use (match_operand:SI 3 "immediate_operand" ""))
17329      (use (reg:SI DIRFLAG_REG))
17330      (clobber (match_operand 0 "register_operand" ""))
17331      (clobber (match_operand 1 "register_operand" ""))
17332      (clobber (match_operand 2 "register_operand" ""))])
17333    (set (match_operand:QI 7 "register_operand" "")
17334         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17335    (set (match_operand:QI 8 "register_operand" "")
17336         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17337    (set (reg FLAGS_REG)
17338         (compare (match_dup 7) (match_dup 8)))
17339   ]
17340   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17341   [(parallel[
17342      (set (reg:CC FLAGS_REG)
17343           (compare:CC (mem:BLK (match_dup 4))
17344                       (mem:BLK (match_dup 5))))
17345      (use (match_dup 6))
17346      (use (match_dup 3))
17347      (use (reg:SI DIRFLAG_REG))
17348      (clobber (match_dup 0))
17349      (clobber (match_dup 1))
17350      (clobber (match_dup 2))])]
17351   "")
17352
17353 ;; ...and this one handles cmpstr*_1.
17354 (define_peephole2
17355   [(parallel[
17356      (set (reg:CC FLAGS_REG)
17357           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17358                                (const_int 0))
17359             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17360                         (mem:BLK (match_operand 5 "register_operand" "")))
17361             (const_int 0)))
17362      (use (match_operand:SI 3 "immediate_operand" ""))
17363      (use (reg:CC FLAGS_REG))
17364      (use (reg:SI DIRFLAG_REG))
17365      (clobber (match_operand 0 "register_operand" ""))
17366      (clobber (match_operand 1 "register_operand" ""))
17367      (clobber (match_operand 2 "register_operand" ""))])
17368    (set (match_operand:QI 7 "register_operand" "")
17369         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17370    (set (match_operand:QI 8 "register_operand" "")
17371         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17372    (set (reg FLAGS_REG)
17373         (compare (match_dup 7) (match_dup 8)))
17374   ]
17375   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17376   [(parallel[
17377      (set (reg:CC FLAGS_REG)
17378           (if_then_else:CC (ne (match_dup 6)
17379                                (const_int 0))
17380             (compare:CC (mem:BLK (match_dup 4))
17381                         (mem:BLK (match_dup 5)))
17382             (const_int 0)))
17383      (use (match_dup 3))
17384      (use (reg:CC FLAGS_REG))
17385      (use (reg:SI DIRFLAG_REG))
17386      (clobber (match_dup 0))
17387      (clobber (match_dup 1))
17388      (clobber (match_dup 2))])]
17389   "")
17390
17391
17392 \f
17393 ;; Conditional move instructions.
17394
17395 (define_expand "movdicc"
17396   [(set (match_operand:DI 0 "register_operand" "")
17397         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17398                          (match_operand:DI 2 "general_operand" "")
17399                          (match_operand:DI 3 "general_operand" "")))]
17400   "TARGET_64BIT"
17401   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17402
17403 (define_insn "x86_movdicc_0_m1_rex64"
17404   [(set (match_operand:DI 0 "register_operand" "=r")
17405         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17406           (const_int -1)
17407           (const_int 0)))
17408    (clobber (reg:CC FLAGS_REG))]
17409   "TARGET_64BIT"
17410   "sbb{q}\t%0, %0"
17411   ; Since we don't have the proper number of operands for an alu insn,
17412   ; fill in all the blanks.
17413   [(set_attr "type" "alu")
17414    (set_attr "pent_pair" "pu")
17415    (set_attr "memory" "none")
17416    (set_attr "imm_disp" "false")
17417    (set_attr "mode" "DI")
17418    (set_attr "length_immediate" "0")])
17419
17420 (define_insn "movdicc_c_rex64"
17421   [(set (match_operand:DI 0 "register_operand" "=r,r")
17422         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17423                                 [(reg FLAGS_REG) (const_int 0)])
17424                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17425                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17426   "TARGET_64BIT && TARGET_CMOVE
17427    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17428   "@
17429    cmov%O2%C1\t{%2, %0|%0, %2}
17430    cmov%O2%c1\t{%3, %0|%0, %3}"
17431   [(set_attr "type" "icmov")
17432    (set_attr "mode" "DI")])
17433
17434 (define_expand "movsicc"
17435   [(set (match_operand:SI 0 "register_operand" "")
17436         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17437                          (match_operand:SI 2 "general_operand" "")
17438                          (match_operand:SI 3 "general_operand" "")))]
17439   ""
17440   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17441
17442 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17443 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17444 ;; So just document what we're doing explicitly.
17445
17446 (define_insn "x86_movsicc_0_m1"
17447   [(set (match_operand:SI 0 "register_operand" "=r")
17448         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17449           (const_int -1)
17450           (const_int 0)))
17451    (clobber (reg:CC FLAGS_REG))]
17452   ""
17453   "sbb{l}\t%0, %0"
17454   ; Since we don't have the proper number of operands for an alu insn,
17455   ; fill in all the blanks.
17456   [(set_attr "type" "alu")
17457    (set_attr "pent_pair" "pu")
17458    (set_attr "memory" "none")
17459    (set_attr "imm_disp" "false")
17460    (set_attr "mode" "SI")
17461    (set_attr "length_immediate" "0")])
17462
17463 (define_insn "*movsicc_noc"
17464   [(set (match_operand:SI 0 "register_operand" "=r,r")
17465         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17466                                 [(reg FLAGS_REG) (const_int 0)])
17467                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17468                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17469   "TARGET_CMOVE
17470    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17471   "@
17472    cmov%O2%C1\t{%2, %0|%0, %2}
17473    cmov%O2%c1\t{%3, %0|%0, %3}"
17474   [(set_attr "type" "icmov")
17475    (set_attr "mode" "SI")])
17476
17477 (define_expand "movhicc"
17478   [(set (match_operand:HI 0 "register_operand" "")
17479         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17480                          (match_operand:HI 2 "general_operand" "")
17481                          (match_operand:HI 3 "general_operand" "")))]
17482   "TARGET_HIMODE_MATH"
17483   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17484
17485 (define_insn "*movhicc_noc"
17486   [(set (match_operand:HI 0 "register_operand" "=r,r")
17487         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17488                                 [(reg FLAGS_REG) (const_int 0)])
17489                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17490                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17491   "TARGET_CMOVE
17492    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17493   "@
17494    cmov%O2%C1\t{%2, %0|%0, %2}
17495    cmov%O2%c1\t{%3, %0|%0, %3}"
17496   [(set_attr "type" "icmov")
17497    (set_attr "mode" "HI")])
17498
17499 (define_expand "movqicc"
17500   [(set (match_operand:QI 0 "register_operand" "")
17501         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17502                          (match_operand:QI 2 "general_operand" "")
17503                          (match_operand:QI 3 "general_operand" "")))]
17504   "TARGET_QIMODE_MATH"
17505   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17506
17507 (define_insn_and_split "*movqicc_noc"
17508   [(set (match_operand:QI 0 "register_operand" "=r,r")
17509         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17510                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17511                       (match_operand:QI 2 "register_operand" "r,0")
17512                       (match_operand:QI 3 "register_operand" "0,r")))]
17513   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17514   "#"
17515   "&& reload_completed"
17516   [(set (match_dup 0)
17517         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17518                       (match_dup 2)
17519                       (match_dup 3)))]
17520   "operands[0] = gen_lowpart (SImode, operands[0]);
17521    operands[2] = gen_lowpart (SImode, operands[2]);
17522    operands[3] = gen_lowpart (SImode, operands[3]);"
17523   [(set_attr "type" "icmov")
17524    (set_attr "mode" "SI")])
17525
17526 (define_expand "movsfcc"
17527   [(set (match_operand:SF 0 "register_operand" "")
17528         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17529                          (match_operand:SF 2 "register_operand" "")
17530                          (match_operand:SF 3 "register_operand" "")))]
17531   "TARGET_CMOVE"
17532   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17533
17534 (define_insn "*movsfcc_1"
17535   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17536         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17537                                 [(reg FLAGS_REG) (const_int 0)])
17538                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17539                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17540   "TARGET_CMOVE
17541    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17542   "@
17543    fcmov%F1\t{%2, %0|%0, %2}
17544    fcmov%f1\t{%3, %0|%0, %3}
17545    cmov%O2%C1\t{%2, %0|%0, %2}
17546    cmov%O2%c1\t{%3, %0|%0, %3}"
17547   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17548    (set_attr "mode" "SF,SF,SI,SI")])
17549
17550 (define_expand "movdfcc"
17551   [(set (match_operand:DF 0 "register_operand" "")
17552         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17553                          (match_operand:DF 2 "register_operand" "")
17554                          (match_operand:DF 3 "register_operand" "")))]
17555   "TARGET_CMOVE"
17556   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17557
17558 (define_insn "*movdfcc_1"
17559   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17560         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17561                                 [(reg FLAGS_REG) (const_int 0)])
17562                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17563                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17564   "!TARGET_64BIT && TARGET_CMOVE
17565    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17566   "@
17567    fcmov%F1\t{%2, %0|%0, %2}
17568    fcmov%f1\t{%3, %0|%0, %3}
17569    #
17570    #"
17571   [(set_attr "type" "fcmov,fcmov,multi,multi")
17572    (set_attr "mode" "DF")])
17573
17574 (define_insn "*movdfcc_1_rex64"
17575   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17576         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17577                                 [(reg FLAGS_REG) (const_int 0)])
17578                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17579                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17580   "TARGET_64BIT && TARGET_CMOVE
17581    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17582   "@
17583    fcmov%F1\t{%2, %0|%0, %2}
17584    fcmov%f1\t{%3, %0|%0, %3}
17585    cmov%O2%C1\t{%2, %0|%0, %2}
17586    cmov%O2%c1\t{%3, %0|%0, %3}"
17587   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17588    (set_attr "mode" "DF")])
17589
17590 (define_split
17591   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17592         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17593                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17594                       (match_operand:DF 2 "nonimmediate_operand" "")
17595                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17596   "!TARGET_64BIT && reload_completed"
17597   [(set (match_dup 2)
17598         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17599                       (match_dup 5)
17600                       (match_dup 7)))
17601    (set (match_dup 3)
17602         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17603                       (match_dup 6)
17604                       (match_dup 8)))]
17605   "split_di (operands+2, 1, operands+5, operands+6);
17606    split_di (operands+3, 1, operands+7, operands+8);
17607    split_di (operands, 1, operands+2, operands+3);")
17608
17609 (define_expand "movxfcc"
17610   [(set (match_operand:XF 0 "register_operand" "")
17611         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17612                          (match_operand:XF 2 "register_operand" "")
17613                          (match_operand:XF 3 "register_operand" "")))]
17614   "TARGET_CMOVE"
17615   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17616
17617 (define_insn "*movxfcc_1"
17618   [(set (match_operand:XF 0 "register_operand" "=f,f")
17619         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17620                                 [(reg FLAGS_REG) (const_int 0)])
17621                       (match_operand:XF 2 "register_operand" "f,0")
17622                       (match_operand:XF 3 "register_operand" "0,f")))]
17623   "TARGET_CMOVE"
17624   "@
17625    fcmov%F1\t{%2, %0|%0, %2}
17626    fcmov%f1\t{%3, %0|%0, %3}"
17627   [(set_attr "type" "fcmov")
17628    (set_attr "mode" "XF")])
17629
17630 (define_expand "minsf3"
17631   [(parallel [
17632      (set (match_operand:SF 0 "register_operand" "")
17633           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17634                                (match_operand:SF 2 "nonimmediate_operand" ""))
17635                            (match_dup 1)
17636                            (match_dup 2)))
17637      (clobber (reg:CC FLAGS_REG))])]
17638   "TARGET_SSE"
17639   "")
17640
17641 (define_insn "*minsf"
17642   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17643         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17644                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17645                          (match_dup 1)
17646                          (match_dup 2)))
17647    (clobber (reg:CC FLAGS_REG))]
17648   "TARGET_SSE && TARGET_IEEE_FP"
17649   "#")
17650
17651 (define_insn "*minsf_nonieee"
17652   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17653         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17654                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17655                          (match_dup 1)
17656                          (match_dup 2)))
17657    (clobber (reg:CC FLAGS_REG))]
17658   "TARGET_SSE && !TARGET_IEEE_FP
17659    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17660   "#")
17661
17662 (define_split
17663   [(set (match_operand:SF 0 "register_operand" "")
17664         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17665                              (match_operand:SF 2 "nonimmediate_operand" ""))
17666                          (match_operand:SF 3 "register_operand" "")
17667                          (match_operand:SF 4 "nonimmediate_operand" "")))
17668    (clobber (reg:CC FLAGS_REG))]
17669   "SSE_REG_P (operands[0]) && reload_completed
17670    && ((operands_match_p (operands[1], operands[3])
17671         && operands_match_p (operands[2], operands[4]))
17672        || (operands_match_p (operands[1], operands[4])
17673            && operands_match_p (operands[2], operands[3])))"
17674   [(set (match_dup 0)
17675         (if_then_else:SF (lt (match_dup 1)
17676                              (match_dup 2))
17677                          (match_dup 1)
17678                          (match_dup 2)))])
17679
17680 ;; Conditional addition patterns
17681 (define_expand "addqicc"
17682   [(match_operand:QI 0 "register_operand" "")
17683    (match_operand 1 "comparison_operator" "")
17684    (match_operand:QI 2 "register_operand" "")
17685    (match_operand:QI 3 "const_int_operand" "")]
17686   ""
17687   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17688
17689 (define_expand "addhicc"
17690   [(match_operand:HI 0 "register_operand" "")
17691    (match_operand 1 "comparison_operator" "")
17692    (match_operand:HI 2 "register_operand" "")
17693    (match_operand:HI 3 "const_int_operand" "")]
17694   ""
17695   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17696
17697 (define_expand "addsicc"
17698   [(match_operand:SI 0 "register_operand" "")
17699    (match_operand 1 "comparison_operator" "")
17700    (match_operand:SI 2 "register_operand" "")
17701    (match_operand:SI 3 "const_int_operand" "")]
17702   ""
17703   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17704
17705 (define_expand "adddicc"
17706   [(match_operand:DI 0 "register_operand" "")
17707    (match_operand 1 "comparison_operator" "")
17708    (match_operand:DI 2 "register_operand" "")
17709    (match_operand:DI 3 "const_int_operand" "")]
17710   "TARGET_64BIT"
17711   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17712
17713 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17714
17715 (define_split
17716   [(set (match_operand:SF 0 "fp_register_operand" "")
17717         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17718                              (match_operand:SF 2 "register_operand" ""))
17719                          (match_operand:SF 3 "register_operand" "")
17720                          (match_operand:SF 4 "register_operand" "")))
17721    (clobber (reg:CC FLAGS_REG))]
17722   "reload_completed
17723    && ((operands_match_p (operands[1], operands[3])
17724         && operands_match_p (operands[2], operands[4]))
17725        || (operands_match_p (operands[1], operands[4])
17726            && operands_match_p (operands[2], operands[3])))"
17727   [(set (reg:CCFP FLAGS_REG)
17728         (compare:CCFP (match_dup 2)
17729                       (match_dup 1)))
17730    (set (match_dup 0)
17731         (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17732                          (match_dup 1)
17733                          (match_dup 2)))])
17734
17735 (define_insn "*minsf_sse"
17736   [(set (match_operand:SF 0 "register_operand" "=x")
17737         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17738                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17739                          (match_dup 1)
17740                          (match_dup 2)))]
17741   "TARGET_SSE && reload_completed"
17742   "minss\t{%2, %0|%0, %2}"
17743   [(set_attr "type" "sse")
17744    (set_attr "mode" "SF")])
17745
17746 (define_expand "mindf3"
17747   [(parallel [
17748      (set (match_operand:DF 0 "register_operand" "")
17749           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17750                                (match_operand:DF 2 "nonimmediate_operand" ""))
17751                            (match_dup 1)
17752                            (match_dup 2)))
17753      (clobber (reg:CC FLAGS_REG))])]
17754   "TARGET_SSE2 && TARGET_SSE_MATH"
17755   "#")
17756
17757 (define_insn "*mindf"
17758   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17759         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17760                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17761                          (match_dup 1)
17762                          (match_dup 2)))
17763    (clobber (reg:CC FLAGS_REG))]
17764   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17765   "#")
17766
17767 (define_insn "*mindf_nonieee"
17768   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17769         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17770                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17771                          (match_dup 1)
17772                          (match_dup 2)))
17773    (clobber (reg:CC FLAGS_REG))]
17774   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17775    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17776   "#")
17777
17778 (define_split
17779   [(set (match_operand:DF 0 "register_operand" "")
17780         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17781                              (match_operand:DF 2 "nonimmediate_operand" ""))
17782                          (match_operand:DF 3 "register_operand" "")
17783                          (match_operand:DF 4 "nonimmediate_operand" "")))
17784    (clobber (reg:CC FLAGS_REG))]
17785   "SSE_REG_P (operands[0]) && reload_completed
17786    && ((operands_match_p (operands[1], operands[3])
17787         && operands_match_p (operands[2], operands[4]))
17788        || (operands_match_p (operands[1], operands[4])
17789            && operands_match_p (operands[2], operands[3])))"
17790   [(set (match_dup 0)
17791         (if_then_else:DF (lt (match_dup 1)
17792                              (match_dup 2))
17793                          (match_dup 1)
17794                          (match_dup 2)))])
17795
17796 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17797 (define_split
17798   [(set (match_operand:DF 0 "fp_register_operand" "")
17799         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17800                              (match_operand:DF 2 "register_operand" ""))
17801                          (match_operand:DF 3 "register_operand" "")
17802                          (match_operand:DF 4 "register_operand" "")))
17803    (clobber (reg:CC FLAGS_REG))]
17804   "reload_completed
17805    && ((operands_match_p (operands[1], operands[3])
17806         && operands_match_p (operands[2], operands[4]))
17807        || (operands_match_p (operands[1], operands[4])
17808            && operands_match_p (operands[2], operands[3])))"
17809   [(set (reg:CCFP FLAGS_REG)
17810         (compare:CCFP (match_dup 2)
17811                       (match_dup 1)))
17812    (set (match_dup 0)
17813         (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17814                          (match_dup 1)
17815                          (match_dup 2)))])
17816
17817 (define_insn "*mindf_sse"
17818   [(set (match_operand:DF 0 "register_operand" "=Y")
17819         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17820                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17821                          (match_dup 1)
17822                          (match_dup 2)))]
17823   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17824   "minsd\t{%2, %0|%0, %2}"
17825   [(set_attr "type" "sse")
17826    (set_attr "mode" "DF")])
17827
17828 (define_expand "maxsf3"
17829   [(parallel [
17830      (set (match_operand:SF 0 "register_operand" "")
17831           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17832                                (match_operand:SF 2 "nonimmediate_operand" ""))
17833                            (match_dup 1)
17834                            (match_dup 2)))
17835      (clobber (reg:CC FLAGS_REG))])]
17836   "TARGET_SSE"
17837   "#")
17838
17839 (define_insn "*maxsf"
17840   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17841         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17842                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17843                          (match_dup 1)
17844                          (match_dup 2)))
17845    (clobber (reg:CC FLAGS_REG))]
17846   "TARGET_SSE && TARGET_IEEE_FP"
17847   "#")
17848
17849 (define_insn "*maxsf_nonieee"
17850   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17851         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17852                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17853                          (match_dup 1)
17854                          (match_dup 2)))
17855    (clobber (reg:CC FLAGS_REG))]
17856   "TARGET_SSE && !TARGET_IEEE_FP
17857    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17858   "#")
17859
17860 (define_split
17861   [(set (match_operand:SF 0 "register_operand" "")
17862         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17863                              (match_operand:SF 2 "nonimmediate_operand" ""))
17864                          (match_operand:SF 3 "register_operand" "")
17865                          (match_operand:SF 4 "nonimmediate_operand" "")))
17866    (clobber (reg:CC FLAGS_REG))]
17867   "SSE_REG_P (operands[0]) && reload_completed
17868    && ((operands_match_p (operands[1], operands[3])
17869         && operands_match_p (operands[2], operands[4]))
17870        || (operands_match_p (operands[1], operands[4])
17871            && operands_match_p (operands[2], operands[3])))"
17872   [(set (match_dup 0)
17873         (if_then_else:SF (gt (match_dup 1)
17874                              (match_dup 2))
17875                          (match_dup 1)
17876                          (match_dup 2)))])
17877
17878 (define_split
17879   [(set (match_operand:SF 0 "fp_register_operand" "")
17880         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17881                              (match_operand:SF 2 "register_operand" ""))
17882                          (match_operand:SF 3 "register_operand" "")
17883                          (match_operand:SF 4 "register_operand" "")))
17884    (clobber (reg:CC FLAGS_REG))]
17885   "reload_completed
17886    && ((operands_match_p (operands[1], operands[3])
17887         && operands_match_p (operands[2], operands[4]))
17888        || (operands_match_p (operands[1], operands[4])
17889            && operands_match_p (operands[2], operands[3])))"
17890   [(set (reg:CCFP FLAGS_REG)
17891         (compare:CCFP (match_dup 1)
17892                       (match_dup 2)))
17893    (set (match_dup 0)
17894         (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17895                          (match_dup 1)
17896                          (match_dup 2)))])
17897
17898 (define_insn "*maxsf_sse"
17899   [(set (match_operand:SF 0 "register_operand" "=x")
17900         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17901                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17902                          (match_dup 1)
17903                          (match_dup 2)))]
17904   "TARGET_SSE && reload_completed"
17905   "maxss\t{%2, %0|%0, %2}"
17906   [(set_attr "type" "sse")
17907    (set_attr "mode" "SF")])
17908
17909 (define_expand "maxdf3"
17910   [(parallel [
17911      (set (match_operand:DF 0 "register_operand" "")
17912           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17913                                (match_operand:DF 2 "nonimmediate_operand" ""))
17914                            (match_dup 1)
17915                            (match_dup 2)))
17916      (clobber (reg:CC FLAGS_REG))])]
17917   "TARGET_SSE2 && TARGET_SSE_MATH"
17918   "#")
17919
17920 (define_insn "*maxdf"
17921   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17922         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17923                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17924                          (match_dup 1)
17925                          (match_dup 2)))
17926    (clobber (reg:CC FLAGS_REG))]
17927   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17928   "#")
17929
17930 (define_insn "*maxdf_nonieee"
17931   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17932         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17933                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17934                          (match_dup 1)
17935                          (match_dup 2)))
17936    (clobber (reg:CC FLAGS_REG))]
17937   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17938    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17939   "#")
17940
17941 (define_split
17942   [(set (match_operand:DF 0 "register_operand" "")
17943         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17944                              (match_operand:DF 2 "nonimmediate_operand" ""))
17945                          (match_operand:DF 3 "register_operand" "")
17946                          (match_operand:DF 4 "nonimmediate_operand" "")))
17947    (clobber (reg:CC FLAGS_REG))]
17948   "SSE_REG_P (operands[0]) && reload_completed
17949    && ((operands_match_p (operands[1], operands[3])
17950         && operands_match_p (operands[2], operands[4]))
17951        || (operands_match_p (operands[1], operands[4])
17952            && operands_match_p (operands[2], operands[3])))"
17953   [(set (match_dup 0)
17954         (if_then_else:DF (gt (match_dup 1)
17955                              (match_dup 2))
17956                          (match_dup 1)
17957                          (match_dup 2)))])
17958
17959 (define_split
17960   [(set (match_operand:DF 0 "fp_register_operand" "")
17961         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17962                              (match_operand:DF 2 "register_operand" ""))
17963                          (match_operand:DF 3 "register_operand" "")
17964                          (match_operand:DF 4 "register_operand" "")))
17965    (clobber (reg:CC FLAGS_REG))]
17966   "reload_completed
17967    && ((operands_match_p (operands[1], operands[3])
17968         && operands_match_p (operands[2], operands[4]))
17969        || (operands_match_p (operands[1], operands[4])
17970            && operands_match_p (operands[2], operands[3])))"
17971   [(set (reg:CCFP FLAGS_REG)
17972         (compare:CCFP (match_dup 1)
17973                       (match_dup 2)))
17974    (set (match_dup 0)
17975         (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17976                          (match_dup 1)
17977                          (match_dup 2)))])
17978
17979 (define_insn "*maxdf_sse"
17980   [(set (match_operand:DF 0 "register_operand" "=Y")
17981         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17982                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17983                          (match_dup 1)
17984                          (match_dup 2)))]
17985   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17986   "maxsd\t{%2, %0|%0, %2}"
17987   [(set_attr "type" "sse")
17988    (set_attr "mode" "DF")])
17989 \f
17990 ;; Misc patterns (?)
17991
17992 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17993 ;; Otherwise there will be nothing to keep
17994 ;; 
17995 ;; [(set (reg ebp) (reg esp))]
17996 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17997 ;;  (clobber (eflags)]
17998 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17999 ;;
18000 ;; in proper program order.
18001 (define_insn "pro_epilogue_adjust_stack_1"
18002   [(set (match_operand:SI 0 "register_operand" "=r,r")
18003         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18004                  (match_operand:SI 2 "immediate_operand" "i,i")))
18005    (clobber (reg:CC FLAGS_REG))
18006    (clobber (mem:BLK (scratch)))]
18007   "!TARGET_64BIT"
18008 {
18009   switch (get_attr_type (insn))
18010     {
18011     case TYPE_IMOV:
18012       return "mov{l}\t{%1, %0|%0, %1}";
18013
18014     case TYPE_ALU:
18015       if (GET_CODE (operands[2]) == CONST_INT
18016           && (INTVAL (operands[2]) == 128
18017               || (INTVAL (operands[2]) < 0
18018                   && INTVAL (operands[2]) != -128)))
18019         {
18020           operands[2] = GEN_INT (-INTVAL (operands[2]));
18021           return "sub{l}\t{%2, %0|%0, %2}";
18022         }
18023       return "add{l}\t{%2, %0|%0, %2}";
18024
18025     case TYPE_LEA:
18026       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18027       return "lea{l}\t{%a2, %0|%0, %a2}";
18028
18029     default:
18030       abort ();
18031     }
18032 }
18033   [(set (attr "type")
18034         (cond [(eq_attr "alternative" "0")
18035                  (const_string "alu")
18036                (match_operand:SI 2 "const0_operand" "")
18037                  (const_string "imov")
18038               ]
18039               (const_string "lea")))
18040    (set_attr "mode" "SI")])
18041
18042 (define_insn "pro_epilogue_adjust_stack_rex64"
18043   [(set (match_operand:DI 0 "register_operand" "=r,r")
18044         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18045                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18046    (clobber (reg:CC FLAGS_REG))
18047    (clobber (mem:BLK (scratch)))]
18048   "TARGET_64BIT"
18049 {
18050   switch (get_attr_type (insn))
18051     {
18052     case TYPE_IMOV:
18053       return "mov{q}\t{%1, %0|%0, %1}";
18054
18055     case TYPE_ALU:
18056       if (GET_CODE (operands[2]) == CONST_INT
18057           /* Avoid overflows.  */
18058           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18059           && (INTVAL (operands[2]) == 128
18060               || (INTVAL (operands[2]) < 0
18061                   && INTVAL (operands[2]) != -128)))
18062         {
18063           operands[2] = GEN_INT (-INTVAL (operands[2]));
18064           return "sub{q}\t{%2, %0|%0, %2}";
18065         }
18066       return "add{q}\t{%2, %0|%0, %2}";
18067
18068     case TYPE_LEA:
18069       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18070       return "lea{q}\t{%a2, %0|%0, %a2}";
18071
18072     default:
18073       abort ();
18074     }
18075 }
18076   [(set (attr "type")
18077         (cond [(eq_attr "alternative" "0")
18078                  (const_string "alu")
18079                (match_operand:DI 2 "const0_operand" "")
18080                  (const_string "imov")
18081               ]
18082               (const_string "lea")))
18083    (set_attr "mode" "DI")])
18084
18085 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18086   [(set (match_operand:DI 0 "register_operand" "=r,r")
18087         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18088                  (match_operand:DI 3 "immediate_operand" "i,i")))
18089    (use (match_operand:DI 2 "register_operand" "r,r"))
18090    (clobber (reg:CC FLAGS_REG))
18091    (clobber (mem:BLK (scratch)))]
18092   "TARGET_64BIT"
18093 {
18094   switch (get_attr_type (insn))
18095     {
18096     case TYPE_ALU:
18097       return "add{q}\t{%2, %0|%0, %2}";
18098
18099     case TYPE_LEA:
18100       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18101       return "lea{q}\t{%a2, %0|%0, %a2}";
18102
18103     default:
18104       abort ();
18105     }
18106 }
18107   [(set_attr "type" "alu,lea")
18108    (set_attr "mode" "DI")])
18109
18110 ;; Placeholder for the conditional moves.  This one is split either to SSE
18111 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
18112 ;; fact is that compares supported by the cmp??ss instructions are exactly
18113 ;; swapped of those supported by cmove sequence.
18114 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18115 ;; supported by i387 comparisons and we do need to emit two conditional moves
18116 ;; in tandem.
18117
18118 (define_insn "sse_movsfcc"
18119   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
18120         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18121                         [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
18122                          (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
18123                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
18124                       (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
18125    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18126    (clobber (reg:CC FLAGS_REG))]
18127   "TARGET_SSE
18128    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18129    /* Avoid combine from being smart and converting min/max
18130       instruction patterns into conditional moves.  */
18131    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18132         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18133        || !rtx_equal_p (operands[4], operands[2])
18134        || !rtx_equal_p (operands[5], operands[3]))
18135    && (!TARGET_IEEE_FP
18136        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18137   "#")
18138
18139 (define_insn "sse_movsfcc_eq"
18140   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18141         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18142                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18143                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18144                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18145    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18146    (clobber (reg:CC FLAGS_REG))]
18147   "TARGET_SSE
18148    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18149   "#")
18150
18151 (define_insn "sse_movdfcc"
18152   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
18153         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18154                         [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
18155                          (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
18156                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
18157                       (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
18158    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18159    (clobber (reg:CC FLAGS_REG))]
18160   "TARGET_SSE2
18161    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18162    /* Avoid combine from being smart and converting min/max
18163       instruction patterns into conditional moves.  */
18164    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18165         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18166        || !rtx_equal_p (operands[4], operands[2])
18167        || !rtx_equal_p (operands[5], operands[3]))
18168    && (!TARGET_IEEE_FP
18169        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18170   "#")
18171
18172 (define_insn "sse_movdfcc_eq"
18173   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18174         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18175                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18176                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18177                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18178    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18179    (clobber (reg:CC FLAGS_REG))]
18180   "TARGET_SSE
18181    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18182   "#")
18183
18184 ;; For non-sse moves just expand the usual cmove sequence.
18185 (define_split
18186   [(set (match_operand 0 "register_operand" "")
18187         (if_then_else (match_operator 1 "comparison_operator"
18188                         [(match_operand 4 "nonimmediate_operand" "")
18189                          (match_operand 5 "register_operand" "")])
18190                       (match_operand 2 "nonimmediate_operand" "")
18191                       (match_operand 3 "nonimmediate_operand" "")))
18192    (clobber (match_operand 6 "" ""))
18193    (clobber (reg:CC FLAGS_REG))]
18194   "!SSE_REG_P (operands[0]) && reload_completed
18195    && (GET_MODE (operands[0]) == SFmode
18196        || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
18197   [(const_int 0)]
18198 {
18199    ix86_compare_op0 = operands[5];
18200    ix86_compare_op1 = operands[4];
18201    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18202                                  VOIDmode, operands[5], operands[4]);
18203    ix86_expand_fp_movcc (operands);
18204    DONE;
18205 })
18206
18207 ;; Split SSE based conditional move into sequence:
18208 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
18209 ;; and   op2, op0   -  zero op2 if comparison was false
18210 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
18211 ;; or    op2, op0   -  get the nonzero one into the result.
18212 (define_split
18213   [(set (match_operand:SF 0 "register_operand" "")
18214         (if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
18215                            [(match_operand:SF 4 "register_operand" "")
18216                             (match_operand:SF 5 "nonimmediate_operand" "")])
18217                          (match_operand:SF 2 "register_operand" "")
18218                          (match_operand:SF 3 "register_operand" "")))
18219    (clobber (match_operand 6 "" ""))
18220    (clobber (reg:CC FLAGS_REG))]
18221   "SSE_REG_P (operands[0]) && reload_completed"
18222   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18223    (set (match_dup 2) (and:V4SF (match_dup 2)
18224                                 (match_dup 8)))
18225    (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18226                                           (match_dup 3)))
18227    (set (match_dup 0) (ior:V4SF (match_dup 6)
18228                                 (match_dup 7)))]
18229 {
18230   /* If op2 == op3, op3 would be clobbered before it is used.  */
18231   if (operands_match_p (operands[2], operands[3]))
18232     {
18233       emit_move_insn (operands[0], operands[2]);
18234       DONE;
18235     }
18236
18237   PUT_MODE (operands[1], GET_MODE (operands[0]));
18238   if (operands_match_p (operands[0], operands[4]))
18239     operands[6] = operands[4], operands[7] = operands[2];
18240   else
18241     operands[6] = operands[2], operands[7] = operands[4];
18242   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18243   operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18244   operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18245   operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18246   operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18247   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18248 })
18249
18250 (define_split
18251   [(set (match_operand:DF 0 "register_operand" "")
18252         (if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
18253                            [(match_operand:DF 4 "register_operand" "")
18254                             (match_operand:DF 5 "nonimmediate_operand" "")])
18255                          (match_operand:DF 2 "register_operand" "")
18256                          (match_operand:DF 3 "register_operand" "")))
18257    (clobber (match_operand 6 "" ""))
18258    (clobber (reg:CC FLAGS_REG))]
18259   "SSE_REG_P (operands[0]) && reload_completed"
18260   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18261    (set (match_dup 2) (and:V2DF (match_dup 2)
18262                                 (match_dup 8)))
18263    (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18264                                           (match_dup 3)))
18265    (set (match_dup 0) (ior:V2DF (match_dup 6)
18266                                 (match_dup 7)))]
18267 {
18268   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18269     {
18270       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18271       emit_insn (gen_sse2_unpcklpd (op, op, op));
18272       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18273       emit_insn (gen_sse2_unpcklpd (op, op, op));
18274     }
18275
18276   /* If op2 == op3, op3 would be clobbered before it is used.  */
18277   if (operands_match_p (operands[2], operands[3]))
18278     {
18279       emit_move_insn (operands[0], operands[2]);
18280       DONE;
18281     }
18282
18283   PUT_MODE (operands[1], GET_MODE (operands[0]));
18284   if (operands_match_p (operands[0], operands[4]))
18285     operands[6] = operands[4], operands[7] = operands[2];
18286   else
18287     operands[6] = operands[2], operands[7] = operands[4];
18288   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18289   operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18290   operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18291   operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18292   operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18293   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18294 })
18295
18296 ;; Special case of conditional move we can handle effectively.
18297 ;; Do not brother with the integer/floating point case, since these are
18298 ;; bot considerably slower, unlike in the generic case.
18299 (define_insn "*sse_movsfcc_const0_1"
18300   [(set (match_operand:SF 0 "register_operand" "=&x")
18301         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18302                         [(match_operand:SF 4 "register_operand" "0")
18303                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18304                       (match_operand:SF 2 "register_operand" "x")
18305                       (match_operand:SF 3 "const0_operand" "X")))]
18306   "TARGET_SSE"
18307   "#")
18308
18309 (define_insn "*sse_movsfcc_const0_2"
18310   [(set (match_operand:SF 0 "register_operand" "=&x")
18311         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18312                         [(match_operand:SF 4 "register_operand" "0")
18313                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
18314                       (match_operand:SF 2 "const0_operand" "X")
18315                       (match_operand:SF 3 "register_operand" "x")))]
18316   "TARGET_SSE"
18317   "#")
18318
18319 (define_insn "*sse_movsfcc_const0_3"
18320   [(set (match_operand:SF 0 "register_operand" "=&x")
18321         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18322                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18323                          (match_operand:SF 5 "register_operand" "0")])
18324                       (match_operand:SF 2 "register_operand" "x")
18325                       (match_operand:SF 3 "const0_operand" "X")))]
18326   "TARGET_SSE"
18327   "#")
18328
18329 (define_insn "*sse_movsfcc_const0_4"
18330   [(set (match_operand:SF 0 "register_operand" "=&x")
18331         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18332                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
18333                          (match_operand:SF 5 "register_operand" "0")])
18334                       (match_operand:SF 2 "const0_operand" "X")
18335                       (match_operand:SF 3 "register_operand" "x")))]
18336   "TARGET_SSE"
18337   "#")
18338
18339 (define_insn "*sse_movdfcc_const0_1"
18340   [(set (match_operand:DF 0 "register_operand" "=&Y")
18341         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18342                         [(match_operand:DF 4 "register_operand" "0")
18343                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18344                       (match_operand:DF 2 "register_operand" "Y")
18345                       (match_operand:DF 3 "const0_operand" "X")))]
18346   "TARGET_SSE2"
18347   "#")
18348
18349 (define_insn "*sse_movdfcc_const0_2"
18350   [(set (match_operand:DF 0 "register_operand" "=&Y")
18351         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18352                         [(match_operand:DF 4 "register_operand" "0")
18353                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18354                       (match_operand:DF 2 "const0_operand" "X")
18355                       (match_operand:DF 3 "register_operand" "Y")))]
18356   "TARGET_SSE2"
18357   "#")
18358
18359 (define_insn "*sse_movdfcc_const0_3"
18360   [(set (match_operand:DF 0 "register_operand" "=&Y")
18361         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18362                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18363                          (match_operand:DF 5 "register_operand" "0")])
18364                       (match_operand:DF 2 "register_operand" "Y")
18365                       (match_operand:DF 3 "const0_operand" "X")))]
18366   "TARGET_SSE2"
18367   "#")
18368
18369 (define_insn "*sse_movdfcc_const0_4"
18370   [(set (match_operand:DF 0 "register_operand" "=&Y")
18371         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18372                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18373                          (match_operand:DF 5 "register_operand" "0")])
18374                       (match_operand:DF 2 "const0_operand" "X")
18375                       (match_operand:DF 3 "register_operand" "Y")))]
18376   "TARGET_SSE2"
18377   "#")
18378
18379 (define_split
18380   [(set (match_operand:SF 0 "register_operand" "")
18381         (if_then_else:SF (match_operator 1 "comparison_operator"
18382                            [(match_operand:SF 4 "nonimmediate_operand" "")
18383                             (match_operand:SF 5 "nonimmediate_operand" "")])
18384                          (match_operand:SF 2 "nonmemory_operand" "")
18385                          (match_operand:SF 3 "nonmemory_operand" "")))]
18386   "SSE_REG_P (operands[0]) && reload_completed
18387    && (const0_operand (operands[2], GET_MODE (operands[0]))
18388        || const0_operand (operands[3], GET_MODE (operands[0])))"
18389   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18390    (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18391 {
18392   PUT_MODE (operands[1], GET_MODE (operands[0]));
18393   if (!sse_comparison_operator (operands[1], VOIDmode)
18394       || !rtx_equal_p (operands[0], operands[4]))
18395     {
18396       rtx tmp = operands[5];
18397       operands[5] = operands[4];
18398       operands[4] = tmp;
18399       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18400     }
18401   if (!rtx_equal_p (operands[0], operands[4]))
18402     abort ();
18403   operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18404   if (const0_operand (operands[2], GET_MODE (operands[2])))
18405     {
18406       operands[7] = operands[3];
18407       operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18408     }
18409   else
18410     {
18411       operands[7] = operands[2];
18412       operands[6] = operands[8];
18413     }
18414   operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18415 })
18416
18417 (define_split
18418   [(set (match_operand:DF 0 "register_operand" "")
18419         (if_then_else:DF (match_operator 1 "comparison_operator"
18420                            [(match_operand:DF 4 "nonimmediate_operand" "")
18421                             (match_operand:DF 5 "nonimmediate_operand" "")])
18422                          (match_operand:DF 2 "nonmemory_operand" "")
18423                          (match_operand:DF 3 "nonmemory_operand" "")))]
18424   "SSE_REG_P (operands[0]) && reload_completed
18425    && (const0_operand (operands[2], GET_MODE (operands[0]))
18426        || const0_operand (operands[3], GET_MODE (operands[0])))"
18427   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18428    (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18429 {
18430   if (TARGET_SSE_SPLIT_REGS && !optimize_size)
18431     {
18432       if (REG_P (operands[2]))
18433         {
18434           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18435           emit_insn (gen_sse2_unpcklpd (op, op, op));
18436         }
18437       if (REG_P (operands[3]))
18438         {
18439           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18440           emit_insn (gen_sse2_unpcklpd (op, op, op));
18441         }
18442     }
18443   PUT_MODE (operands[1], GET_MODE (operands[0]));
18444   if (!sse_comparison_operator (operands[1], VOIDmode)
18445       || !rtx_equal_p (operands[0], operands[4]))
18446     {
18447       rtx tmp = operands[5];
18448       operands[5] = operands[4];
18449       operands[4] = tmp;
18450       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18451     }
18452   if (!rtx_equal_p (operands[0], operands[4]))
18453     abort ();
18454   operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18455   if (const0_operand (operands[2], GET_MODE (operands[2])))
18456     {
18457       operands[7] = operands[3];
18458       operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18459     }
18460   else
18461     {
18462       operands[7] = operands[2];
18463       operands[6] = operands[8];
18464     }
18465   operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18466 })
18467
18468 (define_expand "allocate_stack_worker"
18469   [(match_operand:SI 0 "register_operand" "")]
18470   "TARGET_STACK_PROBE"
18471 {
18472   if (reload_completed)
18473     {
18474       if (TARGET_64BIT)
18475         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18476       else
18477         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18478     }
18479   else
18480     {
18481       if (TARGET_64BIT)
18482         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18483       else
18484         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18485     }
18486   DONE;
18487 })
18488
18489 (define_insn "allocate_stack_worker_1"
18490   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18491     UNSPECV_STACK_PROBE)
18492    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18493    (clobber (match_scratch:SI 1 "=0"))
18494    (clobber (reg:CC FLAGS_REG))]
18495   "!TARGET_64BIT && TARGET_STACK_PROBE"
18496   "call\t__alloca"
18497   [(set_attr "type" "multi")
18498    (set_attr "length" "5")])
18499
18500 (define_expand "allocate_stack_worker_postreload"
18501   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18502                                     UNSPECV_STACK_PROBE)
18503               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18504               (clobber (match_dup 0))
18505               (clobber (reg:CC FLAGS_REG))])]
18506   ""
18507   "")
18508
18509 (define_insn "allocate_stack_worker_rex64"
18510   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18511     UNSPECV_STACK_PROBE)
18512    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18513    (clobber (match_scratch:DI 1 "=0"))
18514    (clobber (reg:CC FLAGS_REG))]
18515   "TARGET_64BIT && TARGET_STACK_PROBE"
18516   "call\t__alloca"
18517   [(set_attr "type" "multi")
18518    (set_attr "length" "5")])
18519
18520 (define_expand "allocate_stack_worker_rex64_postreload"
18521   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18522                                     UNSPECV_STACK_PROBE)
18523               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18524               (clobber (match_dup 0))
18525               (clobber (reg:CC FLAGS_REG))])]
18526   ""
18527   "")
18528
18529 (define_expand "allocate_stack"
18530   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18531                    (minus:SI (reg:SI SP_REG)
18532                              (match_operand:SI 1 "general_operand" "")))
18533               (clobber (reg:CC FLAGS_REG))])
18534    (parallel [(set (reg:SI SP_REG)
18535                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18536               (clobber (reg:CC FLAGS_REG))])]
18537   "TARGET_STACK_PROBE"
18538 {
18539 #ifdef CHECK_STACK_LIMIT
18540   if (GET_CODE (operands[1]) == CONST_INT
18541       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18542     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18543                            operands[1]));
18544   else 
18545 #endif
18546     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18547                                                             operands[1])));
18548
18549   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18550   DONE;
18551 })
18552
18553 (define_expand "builtin_setjmp_receiver"
18554   [(label_ref (match_operand 0 "" ""))]
18555   "!TARGET_64BIT && flag_pic"
18556 {
18557   emit_insn (gen_set_got (pic_offset_table_rtx));
18558   DONE;
18559 })
18560 \f
18561 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18562
18563 (define_split
18564   [(set (match_operand 0 "register_operand" "")
18565         (match_operator 3 "promotable_binary_operator"
18566            [(match_operand 1 "register_operand" "")
18567             (match_operand 2 "aligned_operand" "")]))
18568    (clobber (reg:CC FLAGS_REG))]
18569   "! TARGET_PARTIAL_REG_STALL && reload_completed
18570    && ((GET_MODE (operands[0]) == HImode 
18571         && ((!optimize_size && !TARGET_FAST_PREFIX)
18572             || GET_CODE (operands[2]) != CONST_INT
18573             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18574        || (GET_MODE (operands[0]) == QImode 
18575            && (TARGET_PROMOTE_QImode || optimize_size)))"
18576   [(parallel [(set (match_dup 0)
18577                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18578               (clobber (reg:CC FLAGS_REG))])]
18579   "operands[0] = gen_lowpart (SImode, operands[0]);
18580    operands[1] = gen_lowpart (SImode, operands[1]);
18581    if (GET_CODE (operands[3]) != ASHIFT)
18582      operands[2] = gen_lowpart (SImode, operands[2]);
18583    PUT_MODE (operands[3], SImode);")
18584
18585 ; Promote the QImode tests, as i386 has encoding of the AND
18586 ; instruction with 32-bit sign-extended immediate and thus the
18587 ; instruction size is unchanged, except in the %eax case for
18588 ; which it is increased by one byte, hence the ! optimize_size.
18589 (define_split
18590   [(set (match_operand 0 "flags_reg_operand" "")
18591         (match_operator 2 "compare_operator"
18592           [(and (match_operand 3 "aligned_operand" "")
18593                 (match_operand 4 "const_int_operand" ""))
18594            (const_int 0)]))
18595    (set (match_operand 1 "register_operand" "")
18596         (and (match_dup 3) (match_dup 4)))]
18597   "! TARGET_PARTIAL_REG_STALL && reload_completed
18598    /* Ensure that the operand will remain sign-extended immediate.  */
18599    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18600    && ! optimize_size
18601    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18602        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18603   [(parallel [(set (match_dup 0)
18604                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18605                                     (const_int 0)]))
18606               (set (match_dup 1)
18607                    (and:SI (match_dup 3) (match_dup 4)))])]
18608 {
18609   operands[4]
18610     = gen_int_mode (INTVAL (operands[4])
18611                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18612   operands[1] = gen_lowpart (SImode, operands[1]);
18613   operands[3] = gen_lowpart (SImode, operands[3]);
18614 })
18615
18616 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18617 ; the TEST instruction with 32-bit sign-extended immediate and thus
18618 ; the instruction size would at least double, which is not what we
18619 ; want even with ! optimize_size.
18620 (define_split
18621   [(set (match_operand 0 "flags_reg_operand" "")
18622         (match_operator 1 "compare_operator"
18623           [(and (match_operand:HI 2 "aligned_operand" "")
18624                 (match_operand:HI 3 "const_int_operand" ""))
18625            (const_int 0)]))]
18626   "! TARGET_PARTIAL_REG_STALL && reload_completed
18627    /* Ensure that the operand will remain sign-extended immediate.  */
18628    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18629    && ! TARGET_FAST_PREFIX
18630    && ! optimize_size"
18631   [(set (match_dup 0)
18632         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18633                          (const_int 0)]))]
18634 {
18635   operands[3]
18636     = gen_int_mode (INTVAL (operands[3])
18637                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18638   operands[2] = gen_lowpart (SImode, operands[2]);
18639 })
18640
18641 (define_split
18642   [(set (match_operand 0 "register_operand" "")
18643         (neg (match_operand 1 "register_operand" "")))
18644    (clobber (reg:CC FLAGS_REG))]
18645   "! TARGET_PARTIAL_REG_STALL && reload_completed
18646    && (GET_MODE (operands[0]) == HImode
18647        || (GET_MODE (operands[0]) == QImode 
18648            && (TARGET_PROMOTE_QImode || optimize_size)))"
18649   [(parallel [(set (match_dup 0)
18650                    (neg:SI (match_dup 1)))
18651               (clobber (reg:CC FLAGS_REG))])]
18652   "operands[0] = gen_lowpart (SImode, operands[0]);
18653    operands[1] = gen_lowpart (SImode, operands[1]);")
18654
18655 (define_split
18656   [(set (match_operand 0 "register_operand" "")
18657         (not (match_operand 1 "register_operand" "")))]
18658   "! TARGET_PARTIAL_REG_STALL && reload_completed
18659    && (GET_MODE (operands[0]) == HImode
18660        || (GET_MODE (operands[0]) == QImode 
18661            && (TARGET_PROMOTE_QImode || optimize_size)))"
18662   [(set (match_dup 0)
18663         (not:SI (match_dup 1)))]
18664   "operands[0] = gen_lowpart (SImode, operands[0]);
18665    operands[1] = gen_lowpart (SImode, operands[1]);")
18666
18667 (define_split 
18668   [(set (match_operand 0 "register_operand" "")
18669         (if_then_else (match_operator 1 "comparison_operator" 
18670                                 [(reg FLAGS_REG) (const_int 0)])
18671                       (match_operand 2 "register_operand" "")
18672                       (match_operand 3 "register_operand" "")))]
18673   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18674    && (GET_MODE (operands[0]) == HImode
18675        || (GET_MODE (operands[0]) == QImode 
18676            && (TARGET_PROMOTE_QImode || optimize_size)))"
18677   [(set (match_dup 0)
18678         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18679   "operands[0] = gen_lowpart (SImode, operands[0]);
18680    operands[2] = gen_lowpart (SImode, operands[2]);
18681    operands[3] = gen_lowpart (SImode, operands[3]);")
18682                         
18683 \f
18684 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18685 ;; transform a complex memory operation into two memory to register operations.
18686
18687 ;; Don't push memory operands
18688 (define_peephole2
18689   [(set (match_operand:SI 0 "push_operand" "")
18690         (match_operand:SI 1 "memory_operand" ""))
18691    (match_scratch:SI 2 "r")]
18692   "! optimize_size && ! TARGET_PUSH_MEMORY"
18693   [(set (match_dup 2) (match_dup 1))
18694    (set (match_dup 0) (match_dup 2))]
18695   "")
18696
18697 (define_peephole2
18698   [(set (match_operand:DI 0 "push_operand" "")
18699         (match_operand:DI 1 "memory_operand" ""))
18700    (match_scratch:DI 2 "r")]
18701   "! optimize_size && ! TARGET_PUSH_MEMORY"
18702   [(set (match_dup 2) (match_dup 1))
18703    (set (match_dup 0) (match_dup 2))]
18704   "")
18705
18706 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18707 ;; SImode pushes.
18708 (define_peephole2
18709   [(set (match_operand:SF 0 "push_operand" "")
18710         (match_operand:SF 1 "memory_operand" ""))
18711    (match_scratch:SF 2 "r")]
18712   "! optimize_size && ! TARGET_PUSH_MEMORY"
18713   [(set (match_dup 2) (match_dup 1))
18714    (set (match_dup 0) (match_dup 2))]
18715   "")
18716
18717 (define_peephole2
18718   [(set (match_operand:HI 0 "push_operand" "")
18719         (match_operand:HI 1 "memory_operand" ""))
18720    (match_scratch:HI 2 "r")]
18721   "! optimize_size && ! TARGET_PUSH_MEMORY"
18722   [(set (match_dup 2) (match_dup 1))
18723    (set (match_dup 0) (match_dup 2))]
18724   "")
18725
18726 (define_peephole2
18727   [(set (match_operand:QI 0 "push_operand" "")
18728         (match_operand:QI 1 "memory_operand" ""))
18729    (match_scratch:QI 2 "q")]
18730   "! optimize_size && ! TARGET_PUSH_MEMORY"
18731   [(set (match_dup 2) (match_dup 1))
18732    (set (match_dup 0) (match_dup 2))]
18733   "")
18734
18735 ;; Don't move an immediate directly to memory when the instruction
18736 ;; gets too big.
18737 (define_peephole2
18738   [(match_scratch:SI 1 "r")
18739    (set (match_operand:SI 0 "memory_operand" "")
18740         (const_int 0))]
18741   "! optimize_size
18742    && ! TARGET_USE_MOV0
18743    && TARGET_SPLIT_LONG_MOVES
18744    && get_attr_length (insn) >= ix86_cost->large_insn
18745    && peep2_regno_dead_p (0, FLAGS_REG)"
18746   [(parallel [(set (match_dup 1) (const_int 0))
18747               (clobber (reg:CC FLAGS_REG))])
18748    (set (match_dup 0) (match_dup 1))]
18749   "")
18750
18751 (define_peephole2
18752   [(match_scratch:HI 1 "r")
18753    (set (match_operand:HI 0 "memory_operand" "")
18754         (const_int 0))]
18755   "! optimize_size
18756    && ! TARGET_USE_MOV0
18757    && TARGET_SPLIT_LONG_MOVES
18758    && get_attr_length (insn) >= ix86_cost->large_insn
18759    && peep2_regno_dead_p (0, FLAGS_REG)"
18760   [(parallel [(set (match_dup 2) (const_int 0))
18761               (clobber (reg:CC FLAGS_REG))])
18762    (set (match_dup 0) (match_dup 1))]
18763   "operands[2] = gen_lowpart (SImode, operands[1]);")
18764
18765 (define_peephole2
18766   [(match_scratch:QI 1 "q")
18767    (set (match_operand:QI 0 "memory_operand" "")
18768         (const_int 0))]
18769   "! optimize_size
18770    && ! TARGET_USE_MOV0
18771    && TARGET_SPLIT_LONG_MOVES
18772    && get_attr_length (insn) >= ix86_cost->large_insn
18773    && peep2_regno_dead_p (0, FLAGS_REG)"
18774   [(parallel [(set (match_dup 2) (const_int 0))
18775               (clobber (reg:CC FLAGS_REG))])
18776    (set (match_dup 0) (match_dup 1))]
18777   "operands[2] = gen_lowpart (SImode, operands[1]);")
18778
18779 (define_peephole2
18780   [(match_scratch:SI 2 "r")
18781    (set (match_operand:SI 0 "memory_operand" "")
18782         (match_operand:SI 1 "immediate_operand" ""))]
18783   "! optimize_size
18784    && get_attr_length (insn) >= ix86_cost->large_insn
18785    && TARGET_SPLIT_LONG_MOVES"
18786   [(set (match_dup 2) (match_dup 1))
18787    (set (match_dup 0) (match_dup 2))]
18788   "")
18789
18790 (define_peephole2
18791   [(match_scratch:HI 2 "r")
18792    (set (match_operand:HI 0 "memory_operand" "")
18793         (match_operand:HI 1 "immediate_operand" ""))]
18794   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18795   && TARGET_SPLIT_LONG_MOVES"
18796   [(set (match_dup 2) (match_dup 1))
18797    (set (match_dup 0) (match_dup 2))]
18798   "")
18799
18800 (define_peephole2
18801   [(match_scratch:QI 2 "q")
18802    (set (match_operand:QI 0 "memory_operand" "")
18803         (match_operand:QI 1 "immediate_operand" ""))]
18804   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18805   && TARGET_SPLIT_LONG_MOVES"
18806   [(set (match_dup 2) (match_dup 1))
18807    (set (match_dup 0) (match_dup 2))]
18808   "")
18809
18810 ;; Don't compare memory with zero, load and use a test instead.
18811 (define_peephole2
18812   [(set (match_operand 0 "flags_reg_operand" "")
18813         (match_operator 1 "compare_operator"
18814           [(match_operand:SI 2 "memory_operand" "")
18815            (const_int 0)]))
18816    (match_scratch:SI 3 "r")]
18817   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18818   [(set (match_dup 3) (match_dup 2))
18819    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18820   "")
18821
18822 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18823 ;; Don't split NOTs with a displacement operand, because resulting XOR
18824 ;; will not be pairable anyway.
18825 ;;
18826 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18827 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18828 ;; so this split helps here as well.
18829 ;;
18830 ;; Note: Can't do this as a regular split because we can't get proper
18831 ;; lifetime information then.
18832
18833 (define_peephole2
18834   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18835         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18836   "!optimize_size
18837    && peep2_regno_dead_p (0, FLAGS_REG)
18838    && ((TARGET_PENTIUM 
18839         && (GET_CODE (operands[0]) != MEM
18840             || !memory_displacement_operand (operands[0], SImode)))
18841        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18842   [(parallel [(set (match_dup 0)
18843                    (xor:SI (match_dup 1) (const_int -1)))
18844               (clobber (reg:CC FLAGS_REG))])]
18845   "")
18846
18847 (define_peephole2
18848   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18849         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18850   "!optimize_size
18851    && peep2_regno_dead_p (0, FLAGS_REG)
18852    && ((TARGET_PENTIUM 
18853         && (GET_CODE (operands[0]) != MEM
18854             || !memory_displacement_operand (operands[0], HImode)))
18855        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18856   [(parallel [(set (match_dup 0)
18857                    (xor:HI (match_dup 1) (const_int -1)))
18858               (clobber (reg:CC FLAGS_REG))])]
18859   "")
18860
18861 (define_peephole2
18862   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18863         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18864   "!optimize_size
18865    && peep2_regno_dead_p (0, FLAGS_REG)
18866    && ((TARGET_PENTIUM 
18867         && (GET_CODE (operands[0]) != MEM
18868             || !memory_displacement_operand (operands[0], QImode)))
18869        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18870   [(parallel [(set (match_dup 0)
18871                    (xor:QI (match_dup 1) (const_int -1)))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   "")
18874
18875 ;; Non pairable "test imm, reg" instructions can be translated to
18876 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18877 ;; byte opcode instead of two, have a short form for byte operands),
18878 ;; so do it for other CPUs as well.  Given that the value was dead,
18879 ;; this should not create any new dependencies.  Pass on the sub-word
18880 ;; versions if we're concerned about partial register stalls.
18881
18882 (define_peephole2
18883   [(set (match_operand 0 "flags_reg_operand" "")
18884         (match_operator 1 "compare_operator"
18885           [(and:SI (match_operand:SI 2 "register_operand" "")
18886                    (match_operand:SI 3 "immediate_operand" ""))
18887            (const_int 0)]))]
18888   "ix86_match_ccmode (insn, CCNOmode)
18889    && (true_regnum (operands[2]) != 0
18890        || (GET_CODE (operands[3]) == CONST_INT
18891            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18892    && peep2_reg_dead_p (1, operands[2])"
18893   [(parallel
18894      [(set (match_dup 0)
18895            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18896                             (const_int 0)]))
18897       (set (match_dup 2)
18898            (and:SI (match_dup 2) (match_dup 3)))])]
18899   "")
18900
18901 ;; We don't need to handle HImode case, because it will be promoted to SImode
18902 ;; on ! TARGET_PARTIAL_REG_STALL
18903
18904 (define_peephole2
18905   [(set (match_operand 0 "flags_reg_operand" "")
18906         (match_operator 1 "compare_operator"
18907           [(and:QI (match_operand:QI 2 "register_operand" "")
18908                    (match_operand:QI 3 "immediate_operand" ""))
18909            (const_int 0)]))]
18910   "! TARGET_PARTIAL_REG_STALL
18911    && ix86_match_ccmode (insn, CCNOmode)
18912    && true_regnum (operands[2]) != 0
18913    && peep2_reg_dead_p (1, operands[2])"
18914   [(parallel
18915      [(set (match_dup 0)
18916            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18917                             (const_int 0)]))
18918       (set (match_dup 2)
18919            (and:QI (match_dup 2) (match_dup 3)))])]
18920   "")
18921
18922 (define_peephole2
18923   [(set (match_operand 0 "flags_reg_operand" "")
18924         (match_operator 1 "compare_operator"
18925           [(and:SI
18926              (zero_extract:SI
18927                (match_operand 2 "ext_register_operand" "")
18928                (const_int 8)
18929                (const_int 8))
18930              (match_operand 3 "const_int_operand" ""))
18931            (const_int 0)]))]
18932   "! TARGET_PARTIAL_REG_STALL
18933    && ix86_match_ccmode (insn, CCNOmode)
18934    && true_regnum (operands[2]) != 0
18935    && peep2_reg_dead_p (1, operands[2])"
18936   [(parallel [(set (match_dup 0)
18937                    (match_op_dup 1
18938                      [(and:SI
18939                         (zero_extract:SI
18940                           (match_dup 2)
18941                           (const_int 8)
18942                           (const_int 8))
18943                         (match_dup 3))
18944                       (const_int 0)]))
18945               (set (zero_extract:SI (match_dup 2)
18946                                     (const_int 8)
18947                                     (const_int 8))
18948                    (and:SI 
18949                      (zero_extract:SI
18950                        (match_dup 2)
18951                        (const_int 8)
18952                        (const_int 8))
18953                      (match_dup 3)))])]
18954   "")
18955
18956 ;; Don't do logical operations with memory inputs.
18957 (define_peephole2
18958   [(match_scratch:SI 2 "r")
18959    (parallel [(set (match_operand:SI 0 "register_operand" "")
18960                    (match_operator:SI 3 "arith_or_logical_operator"
18961                      [(match_dup 0)
18962                       (match_operand:SI 1 "memory_operand" "")]))
18963               (clobber (reg:CC FLAGS_REG))])]
18964   "! optimize_size && ! TARGET_READ_MODIFY"
18965   [(set (match_dup 2) (match_dup 1))
18966    (parallel [(set (match_dup 0)
18967                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18968               (clobber (reg:CC FLAGS_REG))])]
18969   "")
18970
18971 (define_peephole2
18972   [(match_scratch:SI 2 "r")
18973    (parallel [(set (match_operand:SI 0 "register_operand" "")
18974                    (match_operator:SI 3 "arith_or_logical_operator"
18975                      [(match_operand:SI 1 "memory_operand" "")
18976                       (match_dup 0)]))
18977               (clobber (reg:CC FLAGS_REG))])]
18978   "! optimize_size && ! TARGET_READ_MODIFY"
18979   [(set (match_dup 2) (match_dup 1))
18980    (parallel [(set (match_dup 0)
18981                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18982               (clobber (reg:CC FLAGS_REG))])]
18983   "")
18984
18985 ; Don't do logical operations with memory outputs
18986 ;
18987 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18988 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18989 ; the same decoder scheduling characteristics as the original.
18990
18991 (define_peephole2
18992   [(match_scratch:SI 2 "r")
18993    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18994                    (match_operator:SI 3 "arith_or_logical_operator"
18995                      [(match_dup 0)
18996                       (match_operand:SI 1 "nonmemory_operand" "")]))
18997               (clobber (reg:CC FLAGS_REG))])]
18998   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18999   [(set (match_dup 2) (match_dup 0))
19000    (parallel [(set (match_dup 2)
19001                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19002               (clobber (reg:CC FLAGS_REG))])
19003    (set (match_dup 0) (match_dup 2))]
19004   "")
19005
19006 (define_peephole2
19007   [(match_scratch:SI 2 "r")
19008    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19009                    (match_operator:SI 3 "arith_or_logical_operator"
19010                      [(match_operand:SI 1 "nonmemory_operand" "")
19011                       (match_dup 0)]))
19012               (clobber (reg:CC FLAGS_REG))])]
19013   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19014   [(set (match_dup 2) (match_dup 0))
19015    (parallel [(set (match_dup 2)
19016                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19017               (clobber (reg:CC FLAGS_REG))])
19018    (set (match_dup 0) (match_dup 2))]
19019   "")
19020
19021 ;; Attempt to always use XOR for zeroing registers.
19022 (define_peephole2
19023   [(set (match_operand 0 "register_operand" "")
19024         (const_int 0))]
19025   "(GET_MODE (operands[0]) == QImode
19026     || GET_MODE (operands[0]) == HImode
19027     || GET_MODE (operands[0]) == SImode
19028     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19029    && (! TARGET_USE_MOV0 || optimize_size)
19030    && peep2_regno_dead_p (0, FLAGS_REG)"
19031   [(parallel [(set (match_dup 0) (const_int 0))
19032               (clobber (reg:CC FLAGS_REG))])]
19033   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19034                               operands[0]);")
19035
19036 (define_peephole2
19037   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19038         (const_int 0))]
19039   "(GET_MODE (operands[0]) == QImode
19040     || GET_MODE (operands[0]) == HImode)
19041    && (! TARGET_USE_MOV0 || optimize_size)
19042    && peep2_regno_dead_p (0, FLAGS_REG)"
19043   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19044               (clobber (reg:CC FLAGS_REG))])])
19045
19046 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19047 (define_peephole2
19048   [(set (match_operand 0 "register_operand" "")
19049         (const_int -1))]
19050   "(GET_MODE (operands[0]) == HImode
19051     || GET_MODE (operands[0]) == SImode 
19052     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19053    && (optimize_size || TARGET_PENTIUM)
19054    && peep2_regno_dead_p (0, FLAGS_REG)"
19055   [(parallel [(set (match_dup 0) (const_int -1))
19056               (clobber (reg:CC FLAGS_REG))])]
19057   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19058                               operands[0]);")
19059
19060 ;; Attempt to convert simple leas to adds. These can be created by
19061 ;; move expanders.
19062 (define_peephole2
19063   [(set (match_operand:SI 0 "register_operand" "")
19064         (plus:SI (match_dup 0)
19065                  (match_operand:SI 1 "nonmemory_operand" "")))]
19066   "peep2_regno_dead_p (0, FLAGS_REG)"
19067   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19068               (clobber (reg:CC FLAGS_REG))])]
19069   "")
19070
19071 (define_peephole2
19072   [(set (match_operand:SI 0 "register_operand" "")
19073         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19074                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19075   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19076   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19077               (clobber (reg:CC FLAGS_REG))])]
19078   "operands[2] = gen_lowpart (SImode, operands[2]);")
19079
19080 (define_peephole2
19081   [(set (match_operand:DI 0 "register_operand" "")
19082         (plus:DI (match_dup 0)
19083                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19084   "peep2_regno_dead_p (0, FLAGS_REG)"
19085   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19086               (clobber (reg:CC FLAGS_REG))])]
19087   "")
19088
19089 (define_peephole2
19090   [(set (match_operand:SI 0 "register_operand" "")
19091         (mult:SI (match_dup 0)
19092                  (match_operand:SI 1 "const_int_operand" "")))]
19093   "exact_log2 (INTVAL (operands[1])) >= 0
19094    && peep2_regno_dead_p (0, FLAGS_REG)"
19095   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19098
19099 (define_peephole2
19100   [(set (match_operand:DI 0 "register_operand" "")
19101         (mult:DI (match_dup 0)
19102                  (match_operand:DI 1 "const_int_operand" "")))]
19103   "exact_log2 (INTVAL (operands[1])) >= 0
19104    && peep2_regno_dead_p (0, FLAGS_REG)"
19105   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19106               (clobber (reg:CC FLAGS_REG))])]
19107   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19108
19109 (define_peephole2
19110   [(set (match_operand:SI 0 "register_operand" "")
19111         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19112                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19113   "exact_log2 (INTVAL (operands[2])) >= 0
19114    && REGNO (operands[0]) == REGNO (operands[1])
19115    && peep2_regno_dead_p (0, FLAGS_REG)"
19116   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19117               (clobber (reg:CC FLAGS_REG))])]
19118   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19119
19120 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19121 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19122 ;; many CPUs it is also faster, since special hardware to avoid esp
19123 ;; dependencies is present.
19124
19125 ;; While some of these conversions may be done using splitters, we use peepholes
19126 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19127
19128 ;; Convert prologue esp subtractions to push.
19129 ;; We need register to push.  In order to keep verify_flow_info happy we have
19130 ;; two choices
19131 ;; - use scratch and clobber it in order to avoid dependencies
19132 ;; - use already live register
19133 ;; We can't use the second way right now, since there is no reliable way how to
19134 ;; verify that given register is live.  First choice will also most likely in
19135 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19136 ;; call clobbered registers are dead.  We may want to use base pointer as an
19137 ;; alternative when no register is available later.
19138
19139 (define_peephole2
19140   [(match_scratch:SI 0 "r")
19141    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19142               (clobber (reg:CC FLAGS_REG))
19143               (clobber (mem:BLK (scratch)))])]
19144   "optimize_size || !TARGET_SUB_ESP_4"
19145   [(clobber (match_dup 0))
19146    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19147               (clobber (mem:BLK (scratch)))])])
19148
19149 (define_peephole2
19150   [(match_scratch:SI 0 "r")
19151    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19152               (clobber (reg:CC FLAGS_REG))
19153               (clobber (mem:BLK (scratch)))])]
19154   "optimize_size || !TARGET_SUB_ESP_8"
19155   [(clobber (match_dup 0))
19156    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19157    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19158               (clobber (mem:BLK (scratch)))])])
19159
19160 ;; Convert esp subtractions to push.
19161 (define_peephole2
19162   [(match_scratch:SI 0 "r")
19163    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19164               (clobber (reg:CC FLAGS_REG))])]
19165   "optimize_size || !TARGET_SUB_ESP_4"
19166   [(clobber (match_dup 0))
19167    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19168
19169 (define_peephole2
19170   [(match_scratch:SI 0 "r")
19171    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19172               (clobber (reg:CC FLAGS_REG))])]
19173   "optimize_size || !TARGET_SUB_ESP_8"
19174   [(clobber (match_dup 0))
19175    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19176    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19177
19178 ;; Convert epilogue deallocator to pop.
19179 (define_peephole2
19180   [(match_scratch:SI 0 "r")
19181    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19182               (clobber (reg:CC FLAGS_REG))
19183               (clobber (mem:BLK (scratch)))])]
19184   "optimize_size || !TARGET_ADD_ESP_4"
19185   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19186               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19187               (clobber (mem:BLK (scratch)))])]
19188   "")
19189
19190 ;; Two pops case is tricky, since pop causes dependency on destination register.
19191 ;; We use two registers if available.
19192 (define_peephole2
19193   [(match_scratch:SI 0 "r")
19194    (match_scratch:SI 1 "r")
19195    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19196               (clobber (reg:CC FLAGS_REG))
19197               (clobber (mem:BLK (scratch)))])]
19198   "optimize_size || !TARGET_ADD_ESP_8"
19199   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19200               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19201               (clobber (mem:BLK (scratch)))])
19202    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19203               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19204   "")
19205
19206 (define_peephole2
19207   [(match_scratch:SI 0 "r")
19208    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19209               (clobber (reg:CC FLAGS_REG))
19210               (clobber (mem:BLK (scratch)))])]
19211   "optimize_size"
19212   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19213               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19214               (clobber (mem:BLK (scratch)))])
19215    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19216               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19217   "")
19218
19219 ;; Convert esp additions to pop.
19220 (define_peephole2
19221   [(match_scratch:SI 0 "r")
19222    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19223               (clobber (reg:CC FLAGS_REG))])]
19224   ""
19225   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19226               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19227   "")
19228
19229 ;; Two pops case is tricky, since pop causes dependency on destination register.
19230 ;; We use two registers if available.
19231 (define_peephole2
19232   [(match_scratch:SI 0 "r")
19233    (match_scratch:SI 1 "r")
19234    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19235               (clobber (reg:CC FLAGS_REG))])]
19236   ""
19237   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19238               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19239    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19240               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19241   "")
19242
19243 (define_peephole2
19244   [(match_scratch:SI 0 "r")
19245    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "optimize_size"
19248   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19249               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19250    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19251               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19252   "")
19253 \f
19254 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19255 ;; required and register dies.  Similarly for 128 to plus -128.
19256 (define_peephole2
19257   [(set (match_operand 0 "flags_reg_operand" "")
19258         (match_operator 1 "compare_operator"
19259           [(match_operand 2 "register_operand" "")
19260            (match_operand 3 "const_int_operand" "")]))]
19261   "(INTVAL (operands[3]) == -1
19262     || INTVAL (operands[3]) == 1
19263     || INTVAL (operands[3]) == 128)
19264    && ix86_match_ccmode (insn, CCGCmode)
19265    && peep2_reg_dead_p (1, operands[2])"
19266   [(parallel [(set (match_dup 0)
19267                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19268               (clobber (match_dup 2))])]
19269   "")
19270 \f
19271 (define_peephole2
19272   [(match_scratch:DI 0 "r")
19273    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19274               (clobber (reg:CC FLAGS_REG))
19275               (clobber (mem:BLK (scratch)))])]
19276   "optimize_size || !TARGET_SUB_ESP_4"
19277   [(clobber (match_dup 0))
19278    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19279               (clobber (mem:BLK (scratch)))])])
19280
19281 (define_peephole2
19282   [(match_scratch:DI 0 "r")
19283    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19284               (clobber (reg:CC FLAGS_REG))
19285               (clobber (mem:BLK (scratch)))])]
19286   "optimize_size || !TARGET_SUB_ESP_8"
19287   [(clobber (match_dup 0))
19288    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19289    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19290               (clobber (mem:BLK (scratch)))])])
19291
19292 ;; Convert esp subtractions to push.
19293 (define_peephole2
19294   [(match_scratch:DI 0 "r")
19295    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19296               (clobber (reg:CC FLAGS_REG))])]
19297   "optimize_size || !TARGET_SUB_ESP_4"
19298   [(clobber (match_dup 0))
19299    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19300
19301 (define_peephole2
19302   [(match_scratch:DI 0 "r")
19303    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19304               (clobber (reg:CC FLAGS_REG))])]
19305   "optimize_size || !TARGET_SUB_ESP_8"
19306   [(clobber (match_dup 0))
19307    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19308    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19309
19310 ;; Convert epilogue deallocator to pop.
19311 (define_peephole2
19312   [(match_scratch:DI 0 "r")
19313    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19314               (clobber (reg:CC FLAGS_REG))
19315               (clobber (mem:BLK (scratch)))])]
19316   "optimize_size || !TARGET_ADD_ESP_4"
19317   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19318               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19319               (clobber (mem:BLK (scratch)))])]
19320   "")
19321
19322 ;; Two pops case is tricky, since pop causes dependency on destination register.
19323 ;; We use two registers if available.
19324 (define_peephole2
19325   [(match_scratch:DI 0 "r")
19326    (match_scratch:DI 1 "r")
19327    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19328               (clobber (reg:CC FLAGS_REG))
19329               (clobber (mem:BLK (scratch)))])]
19330   "optimize_size || !TARGET_ADD_ESP_8"
19331   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19332               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19333               (clobber (mem:BLK (scratch)))])
19334    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19335               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19336   "")
19337
19338 (define_peephole2
19339   [(match_scratch:DI 0 "r")
19340    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19341               (clobber (reg:CC FLAGS_REG))
19342               (clobber (mem:BLK (scratch)))])]
19343   "optimize_size"
19344   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19345               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19346               (clobber (mem:BLK (scratch)))])
19347    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19348               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19349   "")
19350
19351 ;; Convert esp additions to pop.
19352 (define_peephole2
19353   [(match_scratch:DI 0 "r")
19354    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19355               (clobber (reg:CC FLAGS_REG))])]
19356   ""
19357   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19358               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19359   "")
19360
19361 ;; Two pops case is tricky, since pop causes dependency on destination register.
19362 ;; We use two registers if available.
19363 (define_peephole2
19364   [(match_scratch:DI 0 "r")
19365    (match_scratch:DI 1 "r")
19366    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19367               (clobber (reg:CC FLAGS_REG))])]
19368   ""
19369   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19370               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19371    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19372               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19373   "")
19374
19375 (define_peephole2
19376   [(match_scratch:DI 0 "r")
19377    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19378               (clobber (reg:CC FLAGS_REG))])]
19379   "optimize_size"
19380   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19381               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19382    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19383               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19384   "")
19385 \f
19386 ;; Convert imul by three, five and nine into lea
19387 (define_peephole2
19388   [(parallel
19389     [(set (match_operand:SI 0 "register_operand" "")
19390           (mult:SI (match_operand:SI 1 "register_operand" "")
19391                    (match_operand:SI 2 "const_int_operand" "")))
19392      (clobber (reg:CC FLAGS_REG))])]
19393   "INTVAL (operands[2]) == 3
19394    || INTVAL (operands[2]) == 5
19395    || INTVAL (operands[2]) == 9"
19396   [(set (match_dup 0)
19397         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19398                  (match_dup 1)))]
19399   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19400
19401 (define_peephole2
19402   [(parallel
19403     [(set (match_operand:SI 0 "register_operand" "")
19404           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19405                    (match_operand:SI 2 "const_int_operand" "")))
19406      (clobber (reg:CC FLAGS_REG))])]
19407   "!optimize_size 
19408    && (INTVAL (operands[2]) == 3
19409        || INTVAL (operands[2]) == 5
19410        || INTVAL (operands[2]) == 9)"
19411   [(set (match_dup 0) (match_dup 1))
19412    (set (match_dup 0)
19413         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19414                  (match_dup 0)))]
19415   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19416
19417 (define_peephole2
19418   [(parallel
19419     [(set (match_operand:DI 0 "register_operand" "")
19420           (mult:DI (match_operand:DI 1 "register_operand" "")
19421                    (match_operand:DI 2 "const_int_operand" "")))
19422      (clobber (reg:CC FLAGS_REG))])]
19423   "TARGET_64BIT
19424    && (INTVAL (operands[2]) == 3
19425        || INTVAL (operands[2]) == 5
19426        || INTVAL (operands[2]) == 9)"
19427   [(set (match_dup 0)
19428         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19429                  (match_dup 1)))]
19430   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19431
19432 (define_peephole2
19433   [(parallel
19434     [(set (match_operand:DI 0 "register_operand" "")
19435           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19436                    (match_operand:DI 2 "const_int_operand" "")))
19437      (clobber (reg:CC FLAGS_REG))])]
19438   "TARGET_64BIT
19439    && !optimize_size 
19440    && (INTVAL (operands[2]) == 3
19441        || INTVAL (operands[2]) == 5
19442        || INTVAL (operands[2]) == 9)"
19443   [(set (match_dup 0) (match_dup 1))
19444    (set (match_dup 0)
19445         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19446                  (match_dup 0)))]
19447   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19448
19449 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19450 ;; imul $32bit_imm, reg, reg is direct decoded.
19451 (define_peephole2
19452   [(match_scratch:DI 3 "r")
19453    (parallel [(set (match_operand:DI 0 "register_operand" "")
19454                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19455                             (match_operand:DI 2 "immediate_operand" "")))
19456               (clobber (reg:CC FLAGS_REG))])]
19457   "TARGET_K8 && !optimize_size
19458    && (GET_CODE (operands[2]) != CONST_INT
19459        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19460   [(set (match_dup 3) (match_dup 1))
19461    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19462               (clobber (reg:CC FLAGS_REG))])]
19463 "")
19464
19465 (define_peephole2
19466   [(match_scratch:SI 3 "r")
19467    (parallel [(set (match_operand:SI 0 "register_operand" "")
19468                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19469                             (match_operand:SI 2 "immediate_operand" "")))
19470               (clobber (reg:CC FLAGS_REG))])]
19471   "TARGET_K8 && !optimize_size
19472    && (GET_CODE (operands[2]) != CONST_INT
19473        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19474   [(set (match_dup 3) (match_dup 1))
19475    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19476               (clobber (reg:CC FLAGS_REG))])]
19477 "")
19478
19479 (define_peephole2
19480   [(match_scratch:SI 3 "r")
19481    (parallel [(set (match_operand:DI 0 "register_operand" "")
19482                    (zero_extend:DI
19483                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19484                               (match_operand:SI 2 "immediate_operand" ""))))
19485               (clobber (reg:CC FLAGS_REG))])]
19486   "TARGET_K8 && !optimize_size
19487    && (GET_CODE (operands[2]) != CONST_INT
19488        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19489   [(set (match_dup 3) (match_dup 1))
19490    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19491               (clobber (reg:CC FLAGS_REG))])]
19492 "")
19493
19494 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19495 ;; Convert it into imul reg, reg
19496 ;; It would be better to force assembler to encode instruction using long
19497 ;; immediate, but there is apparently no way to do so.
19498 (define_peephole2
19499   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19500                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19501                             (match_operand:DI 2 "const_int_operand" "")))
19502               (clobber (reg:CC FLAGS_REG))])
19503    (match_scratch:DI 3 "r")]
19504   "TARGET_K8 && !optimize_size
19505    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19506   [(set (match_dup 3) (match_dup 2))
19507    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19508               (clobber (reg:CC FLAGS_REG))])]
19509 {
19510   if (!rtx_equal_p (operands[0], operands[1]))
19511     emit_move_insn (operands[0], operands[1]);
19512 })
19513
19514 (define_peephole2
19515   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19516                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19517                             (match_operand:SI 2 "const_int_operand" "")))
19518               (clobber (reg:CC FLAGS_REG))])
19519    (match_scratch:SI 3 "r")]
19520   "TARGET_K8 && !optimize_size
19521    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19522   [(set (match_dup 3) (match_dup 2))
19523    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19524               (clobber (reg:CC FLAGS_REG))])]
19525 {
19526   if (!rtx_equal_p (operands[0], operands[1]))
19527     emit_move_insn (operands[0], operands[1]);
19528 })
19529
19530 (define_peephole2
19531   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19532                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19533                             (match_operand:HI 2 "immediate_operand" "")))
19534               (clobber (reg:CC FLAGS_REG))])
19535    (match_scratch:HI 3 "r")]
19536   "TARGET_K8 && !optimize_size"
19537   [(set (match_dup 3) (match_dup 2))
19538    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19539               (clobber (reg:CC FLAGS_REG))])]
19540 {
19541   if (!rtx_equal_p (operands[0], operands[1]))
19542     emit_move_insn (operands[0], operands[1]);
19543 })
19544 \f
19545 ;; Call-value patterns last so that the wildcard operand does not
19546 ;; disrupt insn-recog's switch tables.
19547
19548 (define_insn "*call_value_pop_0"
19549   [(set (match_operand 0 "" "")
19550         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19551               (match_operand:SI 2 "" "")))
19552    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19553                             (match_operand:SI 3 "immediate_operand" "")))]
19554   "!TARGET_64BIT"
19555 {
19556   if (SIBLING_CALL_P (insn))
19557     return "jmp\t%P1";
19558   else
19559     return "call\t%P1";
19560 }
19561   [(set_attr "type" "callv")])
19562
19563 (define_insn "*call_value_pop_1"
19564   [(set (match_operand 0 "" "")
19565         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19566               (match_operand:SI 2 "" "")))
19567    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19568                             (match_operand:SI 3 "immediate_operand" "i")))]
19569   "!TARGET_64BIT"
19570 {
19571   if (constant_call_address_operand (operands[1], Pmode))
19572     {
19573       if (SIBLING_CALL_P (insn))
19574         return "jmp\t%P1";
19575       else
19576         return "call\t%P1";
19577     }
19578   if (SIBLING_CALL_P (insn))
19579     return "jmp\t%A1";
19580   else
19581     return "call\t%A1";
19582 }
19583   [(set_attr "type" "callv")])
19584
19585 (define_insn "*call_value_0"
19586   [(set (match_operand 0 "" "")
19587         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19588               (match_operand:SI 2 "" "")))]
19589   "!TARGET_64BIT"
19590 {
19591   if (SIBLING_CALL_P (insn))
19592     return "jmp\t%P1";
19593   else
19594     return "call\t%P1";
19595 }
19596   [(set_attr "type" "callv")])
19597
19598 (define_insn "*call_value_0_rex64"
19599   [(set (match_operand 0 "" "")
19600         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19601               (match_operand:DI 2 "const_int_operand" "")))]
19602   "TARGET_64BIT"
19603 {
19604   if (SIBLING_CALL_P (insn))
19605     return "jmp\t%P1";
19606   else
19607     return "call\t%P1";
19608 }
19609   [(set_attr "type" "callv")])
19610
19611 (define_insn "*call_value_1"
19612   [(set (match_operand 0 "" "")
19613         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19614               (match_operand:SI 2 "" "")))]
19615   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19616 {
19617   if (constant_call_address_operand (operands[1], Pmode))
19618     return "call\t%P1";
19619   return "call\t%A1";
19620 }
19621   [(set_attr "type" "callv")])
19622
19623 (define_insn "*sibcall_value_1"
19624   [(set (match_operand 0 "" "")
19625         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19626               (match_operand:SI 2 "" "")))]
19627   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19628 {
19629   if (constant_call_address_operand (operands[1], Pmode))
19630     return "jmp\t%P1";
19631   return "jmp\t%A1";
19632 }
19633   [(set_attr "type" "callv")])
19634
19635 (define_insn "*call_value_1_rex64"
19636   [(set (match_operand 0 "" "")
19637         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19638               (match_operand:DI 2 "" "")))]
19639   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19640 {
19641   if (constant_call_address_operand (operands[1], Pmode))
19642     return "call\t%P1";
19643   return "call\t%A1";
19644 }
19645   [(set_attr "type" "callv")])
19646
19647 (define_insn "*sibcall_value_1_rex64"
19648   [(set (match_operand 0 "" "")
19649         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19650               (match_operand:DI 2 "" "")))]
19651   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19652   "jmp\t%P1"
19653   [(set_attr "type" "callv")])
19654
19655 (define_insn "*sibcall_value_1_rex64_v"
19656   [(set (match_operand 0 "" "")
19657         (call (mem:QI (reg:DI 40))
19658               (match_operand:DI 1 "" "")))]
19659   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19660   "jmp\t*%%r11"
19661   [(set_attr "type" "callv")])
19662 \f
19663 (define_insn "trap"
19664   [(trap_if (const_int 1) (const_int 5))]
19665   ""
19666   "int\t$5")
19667
19668 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19669 ;;; for the sake of bounds checking.  By emitting bounds checks as
19670 ;;; conditional traps rather than as conditional jumps around
19671 ;;; unconditional traps we avoid introducing spurious basic-block
19672 ;;; boundaries and facilitate elimination of redundant checks.  In
19673 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19674 ;;; interrupt 5.
19675 ;;; 
19676 ;;; FIXME: Static branch prediction rules for ix86 are such that
19677 ;;; forward conditional branches predict as untaken.  As implemented
19678 ;;; below, pseudo conditional traps violate that rule.  We should use
19679 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19680 ;;; section loaded at the end of the text segment and branch forward
19681 ;;; there on bounds-failure, and then jump back immediately (in case
19682 ;;; the system chooses to ignore bounds violations, or to report
19683 ;;; violations and continue execution).
19684
19685 (define_expand "conditional_trap"
19686   [(trap_if (match_operator 0 "comparison_operator"
19687              [(match_dup 2) (const_int 0)])
19688             (match_operand 1 "const_int_operand" ""))]
19689   ""
19690 {
19691   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19692                               ix86_expand_compare (GET_CODE (operands[0]),
19693                                                    NULL, NULL),
19694                               operands[1]));
19695   DONE;
19696 })
19697
19698 (define_insn "*conditional_trap_1"
19699   [(trap_if (match_operator 0 "comparison_operator"
19700              [(reg FLAGS_REG) (const_int 0)])
19701             (match_operand 1 "const_int_operand" ""))]
19702   ""
19703 {
19704   operands[2] = gen_label_rtx ();
19705   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19706   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19707                              CODE_LABEL_NUMBER (operands[2]));
19708   RET;
19709 })
19710
19711 ;; Pentium III SIMD instructions.
19712
19713 ;; Moves for SSE/MMX regs.
19714
19715 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
19716 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
19717
19718 (define_expand "mov<mode>"
19719   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "")
19720         (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))]
19721   "TARGET_MMX"
19722 {
19723   ix86_expand_vector_move (<MODE>mode, operands);
19724   DONE;
19725 })
19726
19727 (define_insn "*mov<mode>_internal_rex64"
19728   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19729                                 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
19730         (match_operand:MMXMODEI 1 "vector_move_operand"
19731                                 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19732   "TARGET_64BIT && TARGET_MMX
19733    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19734   "@
19735     movq\t{%1, %0|%0, %1}
19736     movq\t{%1, %0|%0, %1}
19737     pxor\t%0, %0
19738     movq\t{%1, %0|%0, %1}
19739     movq\t{%1, %0|%0, %1}
19740     movdq2q\t{%1, %0|%0, %1}
19741     movq2dq\t{%1, %0|%0, %1}
19742     pxor\t%0, %0
19743     movq\t{%1, %0|%0, %1}
19744     movq\t{%1, %0|%0, %1}
19745     movd\t{%1, %0|%0, %1}
19746     movd\t{%1, %0|%0, %1}"
19747   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19748    (set_attr "mode" "DI")])
19749
19750 (define_insn "*mov<mode>_internal"
19751   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
19752                                 "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m")
19753         (match_operand:MMXMODEI 1 "vector_move_operand"
19754                                 "C  ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x"))]
19755   "TARGET_MMX
19756    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19757   "@
19758     pxor\t%0, %0
19759     movq\t{%1, %0|%0, %1}
19760     movq\t{%1, %0|%0, %1}
19761     movdq2q\t{%1, %0|%0, %1}
19762     movq2dq\t{%1, %0|%0, %1}
19763     pxor\t%0, %0
19764     movq\t{%1, %0|%0, %1}
19765     movq\t{%1, %0|%0, %1}
19766     xorps\t%0, %0
19767     movaps\t{%1, %0|%0, %1}
19768     movlps\t{%1, %0|%0, %1}
19769     movlps\t{%1, %0|%0, %1}"
19770   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
19771    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF")])
19772
19773 (define_expand "movv2sf"
19774   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19775         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19776   "TARGET_MMX"
19777 {
19778   ix86_expand_vector_move (V2SFmode, operands);
19779   DONE;
19780 })
19781
19782 (define_insn "*movv2sf_internal_rex64"
19783   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19784                                 "=rm,r,*y ,*y ,m ,*y,Y ,x,x ,m,r,x")
19785         (match_operand:V2SF 1 "vector_move_operand"
19786                                 "Cr ,m ,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
19787   "TARGET_64BIT && TARGET_MMX
19788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19789   "@
19790     movq\t{%1, %0|%0, %1}
19791     movq\t{%1, %0|%0, %1}
19792     pxor\t%0, %0
19793     movq\t{%1, %0|%0, %1}
19794     movq\t{%1, %0|%0, %1}
19795     movdq2q\t{%1, %0|%0, %1}
19796     movq2dq\t{%1, %0|%0, %1}
19797     xorps\t%0, %0
19798     movlps\t{%1, %0|%0, %1}
19799     movlps\t{%1, %0|%0, %1}
19800     movd\t{%1, %0|%0, %1}
19801     movd\t{%1, %0|%0, %1}"
19802   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
19803    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
19804
19805 (define_insn "*movv2sf_internal"
19806   [(set (match_operand:V2SF 0 "nonimmediate_operand"
19807                                         "=*y,*y ,m,*y,*Y,*x,*x ,m")
19808         (match_operand:V2SF 1 "vector_move_operand"
19809                                         "C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
19810   "TARGET_MMX
19811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19812   "@
19813     pxor\t%0, %0
19814     movq\t{%1, %0|%0, %1}
19815     movq\t{%1, %0|%0, %1}
19816     movdq2q\t{%1, %0|%0, %1}
19817     movq2dq\t{%1, %0|%0, %1}
19818     xorps\t%0, %0
19819     movlps\t{%1, %0|%0, %1}
19820     movlps\t{%1, %0|%0, %1}"
19821   [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
19822    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
19823
19824 ;; All 8-byte vector modes handled by MMX
19825 (define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF])
19826
19827 (define_expand "movmisalign<mode>"
19828   [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
19829         (match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
19830   "TARGET_MMX"
19831 {
19832   ix86_expand_vector_move (<MODE>mode, operands);
19833   DONE;
19834 })
19835
19836 ;; SSE Strange Moves.
19837
19838 (define_insn "mmx_pmovmskb"
19839   [(set (match_operand:SI 0 "register_operand" "=r")
19840         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19841                    UNSPEC_MOVMSK))]
19842   "TARGET_SSE || TARGET_3DNOW_A"
19843   "pmovmskb\t{%1, %0|%0, %1}"
19844   [(set_attr "type" "ssecvt")
19845    (set_attr "mode" "V4SF")])
19846
19847
19848 (define_insn "mmx_maskmovq"
19849   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19850         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19851                       (match_operand:V8QI 2 "register_operand" "y")]
19852                      UNSPEC_MASKMOV))]
19853   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19854   ;; @@@ check ordering of operands in intel/nonintel syntax
19855   "maskmovq\t{%2, %1|%1, %2}"
19856   [(set_attr "type" "mmxcvt")
19857    (set_attr "mode" "DI")])
19858
19859 (define_insn "mmx_maskmovq_rex"
19860   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19861         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19862                       (match_operand:V8QI 2 "register_operand" "y")]
19863                      UNSPEC_MASKMOV))]
19864   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19865   ;; @@@ check ordering of operands in intel/nonintel syntax
19866   "maskmovq\t{%2, %1|%1, %2}"
19867   [(set_attr "type" "mmxcvt")
19868    (set_attr "mode" "DI")])
19869
19870 (define_insn "sse_movntdi"
19871   [(set (match_operand:DI 0 "memory_operand" "=m")
19872         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19873                    UNSPEC_MOVNT))]
19874   "TARGET_SSE || TARGET_3DNOW_A"
19875   "movntq\t{%1, %0|%0, %1}"
19876   [(set_attr "type" "mmxmov")
19877    (set_attr "mode" "DI")])
19878
19879 ;; MMX insns
19880
19881 ;; MMX arithmetic
19882
19883 (define_insn "addv8qi3"
19884   [(set (match_operand:V8QI 0 "register_operand" "=y")
19885         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
19886                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19887   "TARGET_MMX"
19888   "paddb\t{%2, %0|%0, %2}"
19889   [(set_attr "type" "mmxadd")
19890    (set_attr "mode" "DI")])
19891
19892 (define_insn "addv4hi3"
19893   [(set (match_operand:V4HI 0 "register_operand" "=y")
19894         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
19895                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19896   "TARGET_MMX"
19897   "paddw\t{%2, %0|%0, %2}"
19898   [(set_attr "type" "mmxadd")
19899    (set_attr "mode" "DI")])
19900
19901 (define_insn "addv2si3"
19902   [(set (match_operand:V2SI 0 "register_operand" "=y")
19903         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
19904                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19905   "TARGET_MMX"
19906   "paddd\t{%2, %0|%0, %2}"
19907   [(set_attr "type" "mmxadd")
19908    (set_attr "mode" "DI")])
19909
19910 (define_insn "mmx_adddi3"
19911   [(set (match_operand:DI 0 "register_operand" "=y")
19912         (unspec:DI
19913          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
19914                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19915          UNSPEC_NOP))]
19916   "TARGET_MMX"
19917   "paddq\t{%2, %0|%0, %2}"
19918   [(set_attr "type" "mmxadd")
19919    (set_attr "mode" "DI")])
19920
19921 (define_insn "ssaddv8qi3"
19922   [(set (match_operand:V8QI 0 "register_operand" "=y")
19923         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
19924                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19925   "TARGET_MMX"
19926   "paddsb\t{%2, %0|%0, %2}"
19927   [(set_attr "type" "mmxadd")
19928    (set_attr "mode" "DI")])
19929
19930 (define_insn "ssaddv4hi3"
19931   [(set (match_operand:V4HI 0 "register_operand" "=y")
19932         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
19933                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19934   "TARGET_MMX"
19935   "paddsw\t{%2, %0|%0, %2}"
19936   [(set_attr "type" "mmxadd")
19937    (set_attr "mode" "DI")])
19938
19939 (define_insn "usaddv8qi3"
19940   [(set (match_operand:V8QI 0 "register_operand" "=y")
19941         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
19942                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19943   "TARGET_MMX"
19944   "paddusb\t{%2, %0|%0, %2}"
19945   [(set_attr "type" "mmxadd")
19946    (set_attr "mode" "DI")])
19947
19948 (define_insn "usaddv4hi3"
19949   [(set (match_operand:V4HI 0 "register_operand" "=y")
19950         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
19951                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19952   "TARGET_MMX"
19953   "paddusw\t{%2, %0|%0, %2}"
19954   [(set_attr "type" "mmxadd")
19955    (set_attr "mode" "DI")])
19956
19957 (define_insn "subv8qi3"
19958   [(set (match_operand:V8QI 0 "register_operand" "=y")
19959         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19960                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19961   "TARGET_MMX"
19962   "psubb\t{%2, %0|%0, %2}"
19963   [(set_attr "type" "mmxadd")
19964    (set_attr "mode" "DI")])
19965
19966 (define_insn "subv4hi3"
19967   [(set (match_operand:V4HI 0 "register_operand" "=y")
19968         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
19969                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19970   "TARGET_MMX"
19971   "psubw\t{%2, %0|%0, %2}"
19972   [(set_attr "type" "mmxadd")
19973    (set_attr "mode" "DI")])
19974
19975 (define_insn "subv2si3"
19976   [(set (match_operand:V2SI 0 "register_operand" "=y")
19977         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
19978                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19979   "TARGET_MMX"
19980   "psubd\t{%2, %0|%0, %2}"
19981   [(set_attr "type" "mmxadd")
19982    (set_attr "mode" "DI")])
19983
19984 (define_insn "mmx_subdi3"
19985   [(set (match_operand:DI 0 "register_operand" "=y")
19986         (unspec:DI
19987          [(minus:DI (match_operand:DI 1 "register_operand" "0")
19988                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
19989          UNSPEC_NOP))]
19990   "TARGET_MMX"
19991   "psubq\t{%2, %0|%0, %2}"
19992   [(set_attr "type" "mmxadd")
19993    (set_attr "mode" "DI")])
19994
19995 (define_insn "sssubv8qi3"
19996   [(set (match_operand:V8QI 0 "register_operand" "=y")
19997         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19998                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19999   "TARGET_MMX"
20000   "psubsb\t{%2, %0|%0, %2}"
20001   [(set_attr "type" "mmxadd")
20002    (set_attr "mode" "DI")])
20003
20004 (define_insn "sssubv4hi3"
20005   [(set (match_operand:V4HI 0 "register_operand" "=y")
20006         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20007                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20008   "TARGET_MMX"
20009   "psubsw\t{%2, %0|%0, %2}"
20010   [(set_attr "type" "mmxadd")
20011    (set_attr "mode" "DI")])
20012
20013 (define_insn "ussubv8qi3"
20014   [(set (match_operand:V8QI 0 "register_operand" "=y")
20015         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20016                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20017   "TARGET_MMX"
20018   "psubusb\t{%2, %0|%0, %2}"
20019   [(set_attr "type" "mmxadd")
20020    (set_attr "mode" "DI")])
20021
20022 (define_insn "ussubv4hi3"
20023   [(set (match_operand:V4HI 0 "register_operand" "=y")
20024         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20025                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20026   "TARGET_MMX"
20027   "psubusw\t{%2, %0|%0, %2}"
20028   [(set_attr "type" "mmxadd")
20029    (set_attr "mode" "DI")])
20030
20031 (define_insn "mulv4hi3"
20032   [(set (match_operand:V4HI 0 "register_operand" "=y")
20033         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20034                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20035   "TARGET_MMX"
20036   "pmullw\t{%2, %0|%0, %2}"
20037   [(set_attr "type" "mmxmul")
20038    (set_attr "mode" "DI")])
20039
20040 (define_insn "smulv4hi3_highpart"
20041   [(set (match_operand:V4HI 0 "register_operand" "=y")
20042         (truncate:V4HI
20043          (lshiftrt:V4SI
20044           (mult:V4SI (sign_extend:V4SI
20045                       (match_operand:V4HI 1 "register_operand" "0"))
20046                      (sign_extend:V4SI
20047                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20048           (const_int 16))))]
20049   "TARGET_MMX"
20050   "pmulhw\t{%2, %0|%0, %2}"
20051   [(set_attr "type" "mmxmul")
20052    (set_attr "mode" "DI")])
20053
20054 (define_insn "umulv4hi3_highpart"
20055   [(set (match_operand:V4HI 0 "register_operand" "=y")
20056         (truncate:V4HI
20057          (lshiftrt:V4SI
20058           (mult:V4SI (zero_extend:V4SI
20059                       (match_operand:V4HI 1 "register_operand" "0"))
20060                      (zero_extend:V4SI
20061                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20062           (const_int 16))))]
20063   "TARGET_SSE || TARGET_3DNOW_A"
20064   "pmulhuw\t{%2, %0|%0, %2}"
20065   [(set_attr "type" "mmxmul")
20066    (set_attr "mode" "DI")])
20067
20068 (define_insn "mmx_pmaddwd"
20069   [(set (match_operand:V2SI 0 "register_operand" "=y")
20070         (plus:V2SI
20071          (mult:V2SI
20072           (sign_extend:V2SI
20073            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20074                             (parallel [(const_int 0) (const_int 2)])))
20075           (sign_extend:V2SI
20076            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20077                             (parallel [(const_int 0) (const_int 2)]))))
20078          (mult:V2SI
20079           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20080                                              (parallel [(const_int 1)
20081                                                         (const_int 3)])))
20082           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20083                                              (parallel [(const_int 1)
20084                                                         (const_int 3)]))))))]
20085   "TARGET_MMX"
20086   "pmaddwd\t{%2, %0|%0, %2}"
20087   [(set_attr "type" "mmxmul")
20088    (set_attr "mode" "DI")])
20089
20090 (define_insn "sse2_umulsidi3"
20091   [(set (match_operand:DI 0 "register_operand" "=y")
20092         (mult:DI
20093           (zero_extend:DI
20094             (vec_select:SI
20095               (match_operand:V2SI 1 "register_operand" "0")
20096               (parallel [(const_int 0)])))
20097           (zero_extend:DI
20098             (vec_select:SI
20099               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
20100               (parallel [(const_int 0)])))))]
20101   "TARGET_SSE2"
20102   "pmuludq\t{%2, %0|%0, %2}"
20103   [(set_attr "type" "mmxmul")
20104    (set_attr "mode" "DI")])
20105
20106
20107 ;; MMX logical operations
20108 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20109 ;; normal code that also wants to use the FPU from getting broken.
20110 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20111 (define_insn "mmx_iordi3"
20112   [(set (match_operand:DI 0 "register_operand" "=y")
20113         (unspec:DI
20114          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20115                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20116          UNSPEC_NOP))]
20117   "TARGET_MMX"
20118   "por\t{%2, %0|%0, %2}"
20119   [(set_attr "type" "mmxadd")
20120    (set_attr "mode" "DI")])
20121
20122 (define_insn "mmx_xordi3"
20123   [(set (match_operand:DI 0 "register_operand" "=y")
20124         (unspec:DI
20125          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20126                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20127          UNSPEC_NOP))]
20128   "TARGET_MMX"
20129   "pxor\t{%2, %0|%0, %2}"
20130   [(set_attr "type" "mmxadd")
20131    (set_attr "mode" "DI")
20132    (set_attr "memory" "none")])
20133
20134 ;; Same as pxor, but don't show input operands so that we don't think
20135 ;; they are live.
20136 (define_insn "mmx_clrdi"
20137   [(set (match_operand:DI 0 "register_operand" "=y")
20138         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20139   "TARGET_MMX"
20140   "pxor\t{%0, %0|%0, %0}"
20141   [(set_attr "type" "mmxadd")
20142    (set_attr "mode" "DI")
20143    (set_attr "memory" "none")])
20144
20145 (define_insn "mmx_anddi3"
20146   [(set (match_operand:DI 0 "register_operand" "=y")
20147         (unspec:DI
20148          [(and:DI (match_operand:DI 1 "register_operand" "%0")
20149                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20150          UNSPEC_NOP))]
20151   "TARGET_MMX"
20152   "pand\t{%2, %0|%0, %2}"
20153   [(set_attr "type" "mmxadd")
20154    (set_attr "mode" "DI")])
20155
20156 (define_insn "mmx_nanddi3"
20157   [(set (match_operand:DI 0 "register_operand" "=y")
20158         (unspec:DI
20159          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20160                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20161          UNSPEC_NOP))]
20162   "TARGET_MMX"
20163   "pandn\t{%2, %0|%0, %2}"
20164   [(set_attr "type" "mmxadd")
20165    (set_attr "mode" "DI")])
20166
20167
20168 ;; MMX unsigned averages/sum of absolute differences
20169
20170 (define_insn "mmx_uavgv8qi3"
20171   [(set (match_operand:V8QI 0 "register_operand" "=y")
20172         (ashiftrt:V8QI
20173          (plus:V8QI (plus:V8QI
20174                      (match_operand:V8QI 1 "register_operand" "0")
20175                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20176                     (const_vector:V8QI [(const_int 1)
20177                                         (const_int 1)
20178                                         (const_int 1)
20179                                         (const_int 1)
20180                                         (const_int 1)
20181                                         (const_int 1)
20182                                         (const_int 1)
20183                                         (const_int 1)]))
20184          (const_int 1)))]
20185   "TARGET_SSE || TARGET_3DNOW_A"
20186   "pavgb\t{%2, %0|%0, %2}"
20187   [(set_attr "type" "mmxshft")
20188    (set_attr "mode" "DI")])
20189
20190 (define_insn "mmx_uavgv4hi3"
20191   [(set (match_operand:V4HI 0 "register_operand" "=y")
20192         (ashiftrt:V4HI
20193          (plus:V4HI (plus:V4HI
20194                      (match_operand:V4HI 1 "register_operand" "0")
20195                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20196                     (const_vector:V4HI [(const_int 1)
20197                                         (const_int 1)
20198                                         (const_int 1)
20199                                         (const_int 1)]))
20200          (const_int 1)))]
20201   "TARGET_SSE || TARGET_3DNOW_A"
20202   "pavgw\t{%2, %0|%0, %2}"
20203   [(set_attr "type" "mmxshft")
20204    (set_attr "mode" "DI")])
20205
20206 (define_insn "mmx_psadbw"
20207   [(set (match_operand:DI 0 "register_operand" "=y")
20208         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20209                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20210                    UNSPEC_PSADBW))]
20211   "TARGET_SSE || TARGET_3DNOW_A"
20212   "psadbw\t{%2, %0|%0, %2}"
20213   [(set_attr "type" "mmxshft")
20214    (set_attr "mode" "DI")])
20215
20216
20217 ;; MMX insert/extract/shuffle
20218
20219 (define_expand "mmx_pinsrw"
20220   [(set (match_operand:V4HI 0 "register_operand" "")
20221         (vec_merge:V4HI
20222           (match_operand:V4HI 1 "register_operand" "")
20223           (vec_duplicate:V4HI
20224             (match_operand:SI 2 "nonimmediate_operand" ""))
20225           (match_operand:SI 3 "const_0_to_3_operand" "")))]
20226   "TARGET_SSE || TARGET_3DNOW_A"
20227 {
20228   operands[2] = gen_lowpart (HImode, operands[2]);
20229   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
20230 })
20231
20232 (define_insn "*mmx_pinsrw"
20233   [(set (match_operand:V4HI 0 "register_operand" "=y")
20234         (vec_merge:V4HI
20235           (match_operand:V4HI 1 "register_operand" "0")
20236           (vec_duplicate:V4HI
20237             (match_operand:HI 2 "nonimmediate_operand" "rm"))
20238           (match_operand:SI 3 "const_pow2_1_to_8_operand" "N")))]
20239   "TARGET_SSE || TARGET_3DNOW_A"
20240 {
20241   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
20242   return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
20243 }
20244   [(set_attr "type" "mmxcvt")
20245    (set_attr "mode" "DI")])
20246
20247 (define_insn "mmx_pextrw"
20248   [(set (match_operand:SI 0 "register_operand" "=r")
20249         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20250                                        (parallel
20251                                         [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20252   "TARGET_SSE || TARGET_3DNOW_A"
20253   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20254   [(set_attr "type" "mmxcvt")
20255    (set_attr "mode" "DI")])
20256
20257 (define_insn "mmx_pshufw"
20258   [(set (match_operand:V4HI 0 "register_operand" "=y")
20259         (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
20260                       (match_operand:SI 2 "immediate_operand" "i")]
20261                      UNSPEC_SHUFFLE))]
20262   "TARGET_SSE || TARGET_3DNOW_A"
20263   "pshufw\t{%2, %1, %0|%0, %1, %2}"
20264   [(set_attr "type" "mmxcvt")
20265    (set_attr "mode" "DI")])
20266
20267
20268 ;; MMX mask-generating comparisons
20269
20270 (define_insn "eqv8qi3"
20271   [(set (match_operand:V8QI 0 "register_operand" "=y")
20272         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20273                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20274   "TARGET_MMX"
20275   "pcmpeqb\t{%2, %0|%0, %2}"
20276   [(set_attr "type" "mmxcmp")
20277    (set_attr "mode" "DI")])
20278
20279 (define_insn "eqv4hi3"
20280   [(set (match_operand:V4HI 0 "register_operand" "=y")
20281         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20282                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20283   "TARGET_MMX"
20284   "pcmpeqw\t{%2, %0|%0, %2}"
20285   [(set_attr "type" "mmxcmp")
20286    (set_attr "mode" "DI")])
20287
20288 (define_insn "eqv2si3"
20289   [(set (match_operand:V2SI 0 "register_operand" "=y")
20290         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20291                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20292   "TARGET_MMX"
20293   "pcmpeqd\t{%2, %0|%0, %2}"
20294   [(set_attr "type" "mmxcmp")
20295    (set_attr "mode" "DI")])
20296
20297 (define_insn "gtv8qi3"
20298   [(set (match_operand:V8QI 0 "register_operand" "=y")
20299         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20300                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20301   "TARGET_MMX"
20302   "pcmpgtb\t{%2, %0|%0, %2}"
20303   [(set_attr "type" "mmxcmp")
20304    (set_attr "mode" "DI")])
20305
20306 (define_insn "gtv4hi3"
20307   [(set (match_operand:V4HI 0 "register_operand" "=y")
20308         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20309                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20310   "TARGET_MMX"
20311   "pcmpgtw\t{%2, %0|%0, %2}"
20312   [(set_attr "type" "mmxcmp")
20313    (set_attr "mode" "DI")])
20314
20315 (define_insn "gtv2si3"
20316   [(set (match_operand:V2SI 0 "register_operand" "=y")
20317         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20318                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20319   "TARGET_MMX"
20320   "pcmpgtd\t{%2, %0|%0, %2}"
20321   [(set_attr "type" "mmxcmp")
20322    (set_attr "mode" "DI")])
20323
20324
20325 ;; MMX max/min insns
20326
20327 (define_insn "umaxv8qi3"
20328   [(set (match_operand:V8QI 0 "register_operand" "=y")
20329         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20330                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20331   "TARGET_SSE || TARGET_3DNOW_A"
20332   "pmaxub\t{%2, %0|%0, %2}"
20333   [(set_attr "type" "mmxadd")
20334    (set_attr "mode" "DI")])
20335
20336 (define_insn "smaxv4hi3"
20337   [(set (match_operand:V4HI 0 "register_operand" "=y")
20338         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20339                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20340   "TARGET_SSE || TARGET_3DNOW_A"
20341   "pmaxsw\t{%2, %0|%0, %2}"
20342   [(set_attr "type" "mmxadd")
20343    (set_attr "mode" "DI")])
20344
20345 (define_insn "uminv8qi3"
20346   [(set (match_operand:V8QI 0 "register_operand" "=y")
20347         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20348                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20349   "TARGET_SSE || TARGET_3DNOW_A"
20350   "pminub\t{%2, %0|%0, %2}"
20351   [(set_attr "type" "mmxadd")
20352    (set_attr "mode" "DI")])
20353
20354 (define_insn "sminv4hi3"
20355   [(set (match_operand:V4HI 0 "register_operand" "=y")
20356         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20357                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20358   "TARGET_SSE || TARGET_3DNOW_A"
20359   "pminsw\t{%2, %0|%0, %2}"
20360   [(set_attr "type" "mmxadd")
20361    (set_attr "mode" "DI")])
20362
20363
20364 ;; MMX shifts
20365
20366 (define_insn "ashrv4hi3"
20367   [(set (match_operand:V4HI 0 "register_operand" "=y")
20368         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20369                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20370   "TARGET_MMX"
20371   "psraw\t{%2, %0|%0, %2}"
20372   [(set_attr "type" "mmxshft")
20373    (set_attr "mode" "DI")])
20374
20375 (define_insn "ashrv2si3"
20376   [(set (match_operand:V2SI 0 "register_operand" "=y")
20377         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20378                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20379   "TARGET_MMX"
20380   "psrad\t{%2, %0|%0, %2}"
20381   [(set_attr "type" "mmxshft")
20382    (set_attr "mode" "DI")])
20383
20384 (define_insn "lshrv4hi3"
20385   [(set (match_operand:V4HI 0 "register_operand" "=y")
20386         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20387                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20388   "TARGET_MMX"
20389   "psrlw\t{%2, %0|%0, %2}"
20390   [(set_attr "type" "mmxshft")
20391    (set_attr "mode" "DI")])
20392
20393 (define_insn "lshrv2si3"
20394   [(set (match_operand:V2SI 0 "register_operand" "=y")
20395         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20396                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20397   "TARGET_MMX"
20398   "psrld\t{%2, %0|%0, %2}"
20399   [(set_attr "type" "mmxshft")
20400    (set_attr "mode" "DI")])
20401
20402 ;; See logical MMX insns.
20403 (define_insn "mmx_lshrdi3"
20404   [(set (match_operand:DI 0 "register_operand" "=y")
20405         (unspec:DI
20406           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20407                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
20408           UNSPEC_NOP))]
20409   "TARGET_MMX"
20410   "psrlq\t{%2, %0|%0, %2}"
20411   [(set_attr "type" "mmxshft")
20412    (set_attr "mode" "DI")])
20413
20414 (define_insn "ashlv4hi3"
20415   [(set (match_operand:V4HI 0 "register_operand" "=y")
20416         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20417                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20418   "TARGET_MMX"
20419   "psllw\t{%2, %0|%0, %2}"
20420   [(set_attr "type" "mmxshft")
20421    (set_attr "mode" "DI")])
20422
20423 (define_insn "ashlv2si3"
20424   [(set (match_operand:V2SI 0 "register_operand" "=y")
20425         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20426                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
20427   "TARGET_MMX"
20428   "pslld\t{%2, %0|%0, %2}"
20429   [(set_attr "type" "mmxshft")
20430    (set_attr "mode" "DI")])
20431
20432 ;; See logical MMX insns.
20433 (define_insn "mmx_ashldi3"
20434   [(set (match_operand:DI 0 "register_operand" "=y")
20435         (unspec:DI
20436          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20437                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
20438          UNSPEC_NOP))]
20439   "TARGET_MMX"
20440   "psllq\t{%2, %0|%0, %2}"
20441   [(set_attr "type" "mmxshft")
20442    (set_attr "mode" "DI")])
20443
20444
20445 ;; MMX pack/unpack insns.
20446
20447 (define_insn "mmx_packsswb"
20448   [(set (match_operand:V8QI 0 "register_operand" "=y")
20449         (vec_concat:V8QI
20450          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20451          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20452   "TARGET_MMX"
20453   "packsswb\t{%2, %0|%0, %2}"
20454   [(set_attr "type" "mmxshft")
20455    (set_attr "mode" "DI")])
20456
20457 (define_insn "mmx_packssdw"
20458   [(set (match_operand:V4HI 0 "register_operand" "=y")
20459         (vec_concat:V4HI
20460          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20461          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20462   "TARGET_MMX"
20463   "packssdw\t{%2, %0|%0, %2}"
20464   [(set_attr "type" "mmxshft")
20465    (set_attr "mode" "DI")])
20466
20467 (define_insn "mmx_packuswb"
20468   [(set (match_operand:V8QI 0 "register_operand" "=y")
20469         (vec_concat:V8QI
20470          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20471          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20472   "TARGET_MMX"
20473   "packuswb\t{%2, %0|%0, %2}"
20474   [(set_attr "type" "mmxshft")
20475    (set_attr "mode" "DI")])
20476
20477 (define_insn "mmx_punpckhbw"
20478   [(set (match_operand:V8QI 0 "register_operand" "=y")
20479         (vec_merge:V8QI
20480          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20481                           (parallel [(const_int 4)
20482                                      (const_int 0)
20483                                      (const_int 5)
20484                                      (const_int 1)
20485                                      (const_int 6)
20486                                      (const_int 2)
20487                                      (const_int 7)
20488                                      (const_int 3)]))
20489          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20490                           (parallel [(const_int 0)
20491                                      (const_int 4)
20492                                      (const_int 1)
20493                                      (const_int 5)
20494                                      (const_int 2)
20495                                      (const_int 6)
20496                                      (const_int 3)
20497                                      (const_int 7)]))
20498          (const_int 85)))]
20499   "TARGET_MMX"
20500   "punpckhbw\t{%2, %0|%0, %2}"
20501   [(set_attr "type" "mmxcvt")
20502    (set_attr "mode" "DI")])
20503
20504 (define_insn "mmx_punpckhwd"
20505   [(set (match_operand:V4HI 0 "register_operand" "=y")
20506         (vec_merge:V4HI
20507          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20508                           (parallel [(const_int 0)
20509                                      (const_int 2)
20510                                      (const_int 1)
20511                                      (const_int 3)]))
20512          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20513                           (parallel [(const_int 2)
20514                                      (const_int 0)
20515                                      (const_int 3)
20516                                      (const_int 1)]))
20517          (const_int 5)))]
20518   "TARGET_MMX"
20519   "punpckhwd\t{%2, %0|%0, %2}"
20520   [(set_attr "type" "mmxcvt")
20521    (set_attr "mode" "DI")])
20522
20523 (define_insn "mmx_punpckhdq"
20524   [(set (match_operand:V2SI 0 "register_operand" "=y")
20525         (vec_merge:V2SI
20526          (match_operand:V2SI 1 "register_operand" "0")
20527          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20528                           (parallel [(const_int 1)
20529                                      (const_int 0)]))
20530          (const_int 1)))]
20531   "TARGET_MMX"
20532   "punpckhdq\t{%2, %0|%0, %2}"
20533   [(set_attr "type" "mmxcvt")
20534    (set_attr "mode" "DI")])
20535
20536 (define_insn "mmx_punpcklbw"
20537   [(set (match_operand:V8QI 0 "register_operand" "=y")
20538         (vec_merge:V8QI
20539          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20540                           (parallel [(const_int 0)
20541                                      (const_int 4)
20542                                      (const_int 1)
20543                                      (const_int 5)
20544                                      (const_int 2)
20545                                      (const_int 6)
20546                                      (const_int 3)
20547                                      (const_int 7)]))
20548          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20549                           (parallel [(const_int 4)
20550                                      (const_int 0)
20551                                      (const_int 5)
20552                                      (const_int 1)
20553                                      (const_int 6)
20554                                      (const_int 2)
20555                                      (const_int 7)
20556                                      (const_int 3)]))
20557          (const_int 85)))]
20558   "TARGET_MMX"
20559   "punpcklbw\t{%2, %0|%0, %2}"
20560   [(set_attr "type" "mmxcvt")
20561    (set_attr "mode" "DI")])
20562
20563 (define_insn "mmx_punpcklwd"
20564   [(set (match_operand:V4HI 0 "register_operand" "=y")
20565         (vec_merge:V4HI
20566          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20567                           (parallel [(const_int 2)
20568                                      (const_int 0)
20569                                      (const_int 3)
20570                                      (const_int 1)]))
20571          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20572                           (parallel [(const_int 0)
20573                                      (const_int 2)
20574                                      (const_int 1)
20575                                      (const_int 3)]))
20576          (const_int 5)))]
20577   "TARGET_MMX"
20578   "punpcklwd\t{%2, %0|%0, %2}"
20579   [(set_attr "type" "mmxcvt")
20580    (set_attr "mode" "DI")])
20581
20582 (define_insn "mmx_punpckldq"
20583   [(set (match_operand:V2SI 0 "register_operand" "=y")
20584         (vec_merge:V2SI
20585          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20586                            (parallel [(const_int 1)
20587                                       (const_int 0)]))
20588          (match_operand:V2SI 2 "register_operand" "y")
20589          (const_int 1)))]
20590   "TARGET_MMX"
20591   "punpckldq\t{%2, %0|%0, %2}"
20592   [(set_attr "type" "mmxcvt")
20593    (set_attr "mode" "DI")])
20594
20595
20596 ;; Miscellaneous stuff
20597
20598 (define_insn "emms"
20599   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20600    (clobber (reg:XF 8))
20601    (clobber (reg:XF 9))
20602    (clobber (reg:XF 10))
20603    (clobber (reg:XF 11))
20604    (clobber (reg:XF 12))
20605    (clobber (reg:XF 13))
20606    (clobber (reg:XF 14))
20607    (clobber (reg:XF 15))
20608    (clobber (reg:DI 29))
20609    (clobber (reg:DI 30))
20610    (clobber (reg:DI 31))
20611    (clobber (reg:DI 32))
20612    (clobber (reg:DI 33))
20613    (clobber (reg:DI 34))
20614    (clobber (reg:DI 35))
20615    (clobber (reg:DI 36))]
20616   "TARGET_MMX"
20617   "emms"
20618   [(set_attr "type" "mmx")
20619    (set_attr "memory" "unknown")])
20620
20621 (define_insn "ldmxcsr"
20622   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20623                     UNSPECV_LDMXCSR)]
20624   "TARGET_SSE"
20625   "ldmxcsr\t%0"
20626   [(set_attr "type" "sse")
20627    (set_attr "memory" "load")])
20628
20629 (define_insn "stmxcsr"
20630   [(set (match_operand:SI 0 "memory_operand" "=m")
20631         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20632   "TARGET_SSE"
20633   "stmxcsr\t%0"
20634   [(set_attr "type" "sse")
20635    (set_attr "memory" "store")])
20636
20637 (define_expand "sfence"
20638   [(set (match_dup 0)
20639         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20640   "TARGET_SSE || TARGET_3DNOW_A"
20641 {
20642   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20643   MEM_VOLATILE_P (operands[0]) = 1;
20644 })
20645
20646 (define_insn "*sfence_insn"
20647   [(set (match_operand:BLK 0 "" "")
20648         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20649   "TARGET_SSE || TARGET_3DNOW_A"
20650   "sfence"
20651   [(set_attr "type" "sse")
20652    (set_attr "memory" "unknown")])
20653
20654 (define_expand "sse_prologue_save"
20655   [(parallel [(set (match_operand:BLK 0 "" "")
20656                    (unspec:BLK [(reg:DI 21)
20657                                 (reg:DI 22)
20658                                 (reg:DI 23)
20659                                 (reg:DI 24)
20660                                 (reg:DI 25)
20661                                 (reg:DI 26)
20662                                 (reg:DI 27)
20663                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20664               (use (match_operand:DI 1 "register_operand" ""))
20665               (use (match_operand:DI 2 "immediate_operand" ""))
20666               (use (label_ref:DI (match_operand 3 "" "")))])]
20667   "TARGET_64BIT"
20668   "")
20669
20670 (define_insn "*sse_prologue_save_insn"
20671   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20672                           (match_operand:DI 4 "const_int_operand" "n")))
20673         (unspec:BLK [(reg:DI 21)
20674                      (reg:DI 22)
20675                      (reg:DI 23)
20676                      (reg:DI 24)
20677                      (reg:DI 25)
20678                      (reg:DI 26)
20679                      (reg:DI 27)
20680                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20681    (use (match_operand:DI 1 "register_operand" "r"))
20682    (use (match_operand:DI 2 "const_int_operand" "i"))
20683    (use (label_ref:DI (match_operand 3 "" "X")))]
20684   "TARGET_64BIT
20685    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20686    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20687   "*
20688 {
20689   int i;
20690   operands[0] = gen_rtx_MEM (Pmode,
20691                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20692   output_asm_insn (\"jmp\\t%A1\", operands);
20693   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20694     {
20695       operands[4] = adjust_address (operands[0], DImode, i*16);
20696       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20697       PUT_MODE (operands[4], TImode);
20698       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20699         output_asm_insn (\"rex\", operands);
20700       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20701     }
20702   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20703                              CODE_LABEL_NUMBER (operands[3]));
20704   RET;
20705 }
20706   "
20707   [(set_attr "type" "other")
20708    (set_attr "length_immediate" "0")
20709    (set_attr "length_address" "0")
20710    (set_attr "length" "135")
20711    (set_attr "memory" "store")
20712    (set_attr "modrm" "0")
20713    (set_attr "mode" "DI")])
20714
20715 ;; 3Dnow! instructions
20716
20717 (define_insn "addv2sf3"
20718   [(set (match_operand:V2SF 0 "register_operand" "=y")
20719         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20720                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20721   "TARGET_3DNOW"
20722   "pfadd\\t{%2, %0|%0, %2}"
20723   [(set_attr "type" "mmxadd")
20724    (set_attr "mode" "V2SF")])
20725
20726 (define_insn "subv2sf3"
20727   [(set (match_operand:V2SF 0 "register_operand" "=y")
20728         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20729                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20730   "TARGET_3DNOW"
20731   "pfsub\\t{%2, %0|%0, %2}"
20732   [(set_attr "type" "mmxadd")
20733    (set_attr "mode" "V2SF")])
20734
20735 (define_insn "subrv2sf3"
20736   [(set (match_operand:V2SF 0 "register_operand" "=y")
20737         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20738                     (match_operand:V2SF 1 "register_operand" "0")))]
20739   "TARGET_3DNOW"
20740   "pfsubr\\t{%2, %0|%0, %2}"
20741   [(set_attr "type" "mmxadd")
20742    (set_attr "mode" "V2SF")])
20743
20744 (define_insn "gtv2sf3"
20745   [(set (match_operand:V2SI 0 "register_operand" "=y")
20746         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20747                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20748   "TARGET_3DNOW"
20749   "pfcmpgt\\t{%2, %0|%0, %2}"
20750   [(set_attr "type" "mmxcmp")
20751    (set_attr "mode" "V2SF")])
20752
20753 (define_insn "gev2sf3"
20754   [(set (match_operand:V2SI 0 "register_operand" "=y")
20755         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20756                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20757   "TARGET_3DNOW"
20758   "pfcmpge\\t{%2, %0|%0, %2}"
20759   [(set_attr "type" "mmxcmp")
20760    (set_attr "mode" "V2SF")])
20761
20762 (define_insn "eqv2sf3"
20763   [(set (match_operand:V2SI 0 "register_operand" "=y")
20764         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20765                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20766   "TARGET_3DNOW"
20767   "pfcmpeq\\t{%2, %0|%0, %2}"
20768   [(set_attr "type" "mmxcmp")
20769    (set_attr "mode" "V2SF")])
20770
20771 (define_insn "pfmaxv2sf3"
20772   [(set (match_operand:V2SF 0 "register_operand" "=y")
20773         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20774                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20775   "TARGET_3DNOW"
20776   "pfmax\\t{%2, %0|%0, %2}"
20777   [(set_attr "type" "mmxadd")
20778    (set_attr "mode" "V2SF")])
20779
20780 (define_insn "pfminv2sf3"
20781   [(set (match_operand:V2SF 0 "register_operand" "=y")
20782         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20783                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20784   "TARGET_3DNOW"
20785   "pfmin\\t{%2, %0|%0, %2}"
20786   [(set_attr "type" "mmxadd")
20787    (set_attr "mode" "V2SF")])
20788
20789 (define_insn "mulv2sf3"
20790   [(set (match_operand:V2SF 0 "register_operand" "=y")
20791         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20792                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20793   "TARGET_3DNOW"
20794   "pfmul\\t{%2, %0|%0, %2}"
20795   [(set_attr "type" "mmxmul")
20796    (set_attr "mode" "V2SF")])
20797
20798 (define_insn "femms"
20799   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20800    (clobber (reg:XF 8))
20801    (clobber (reg:XF 9))
20802    (clobber (reg:XF 10))
20803    (clobber (reg:XF 11))
20804    (clobber (reg:XF 12))
20805    (clobber (reg:XF 13))
20806    (clobber (reg:XF 14))
20807    (clobber (reg:XF 15))
20808    (clobber (reg:DI 29))
20809    (clobber (reg:DI 30))
20810    (clobber (reg:DI 31))
20811    (clobber (reg:DI 32))
20812    (clobber (reg:DI 33))
20813    (clobber (reg:DI 34))
20814    (clobber (reg:DI 35))
20815    (clobber (reg:DI 36))]
20816   "TARGET_3DNOW"
20817   "femms"
20818   [(set_attr "type" "mmx")
20819    (set_attr "memory" "none")]) 
20820
20821 (define_insn "pf2id"
20822   [(set (match_operand:V2SI 0 "register_operand" "=y")
20823         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20824   "TARGET_3DNOW"
20825   "pf2id\\t{%1, %0|%0, %1}"
20826   [(set_attr "type" "mmxcvt")
20827    (set_attr "mode" "V2SF")])
20828
20829 (define_insn "pf2iw"
20830   [(set (match_operand:V2SI 0 "register_operand" "=y")
20831         (sign_extend:V2SI
20832            (ss_truncate:V2HI
20833               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20834   "TARGET_3DNOW_A"
20835   "pf2iw\\t{%1, %0|%0, %1}"
20836   [(set_attr "type" "mmxcvt")
20837    (set_attr "mode" "V2SF")])
20838
20839 (define_insn "pfacc"
20840   [(set (match_operand:V2SF 0 "register_operand" "=y")
20841         (vec_concat:V2SF
20842            (plus:SF
20843               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20844                              (parallel [(const_int  0)]))
20845               (vec_select:SF (match_dup 1)
20846                              (parallel [(const_int 1)])))
20847            (plus:SF
20848               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20849                              (parallel [(const_int  0)]))
20850               (vec_select:SF (match_dup 2)
20851                              (parallel [(const_int 1)])))))]
20852   "TARGET_3DNOW"
20853   "pfacc\\t{%2, %0|%0, %2}"
20854   [(set_attr "type" "mmxadd")
20855    (set_attr "mode" "V2SF")])
20856
20857 (define_insn "pfnacc"
20858   [(set (match_operand:V2SF 0 "register_operand" "=y")
20859         (vec_concat:V2SF
20860            (minus:SF
20861               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20862                              (parallel [(const_int 0)]))
20863               (vec_select:SF (match_dup 1)
20864                              (parallel [(const_int 1)])))
20865            (minus:SF
20866               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20867                              (parallel [(const_int  0)]))
20868               (vec_select:SF (match_dup 2)
20869                              (parallel [(const_int 1)])))))]
20870   "TARGET_3DNOW_A"
20871   "pfnacc\\t{%2, %0|%0, %2}"
20872   [(set_attr "type" "mmxadd")
20873    (set_attr "mode" "V2SF")])
20874
20875 (define_insn "pfpnacc"
20876   [(set (match_operand:V2SF 0 "register_operand" "=y")
20877         (vec_concat:V2SF
20878            (minus:SF
20879               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20880                              (parallel [(const_int 0)]))
20881               (vec_select:SF (match_dup 1)
20882                              (parallel [(const_int 1)])))
20883            (plus:SF
20884               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20885                              (parallel [(const_int 0)]))
20886               (vec_select:SF (match_dup 2)
20887                              (parallel [(const_int 1)])))))]
20888   "TARGET_3DNOW_A"
20889   "pfpnacc\\t{%2, %0|%0, %2}"
20890   [(set_attr "type" "mmxadd")
20891    (set_attr "mode" "V2SF")])
20892
20893 (define_insn "pi2fw"
20894   [(set (match_operand:V2SF 0 "register_operand" "=y")
20895         (float:V2SF
20896            (vec_concat:V2SI
20897               (sign_extend:SI
20898                  (truncate:HI
20899                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
20900                                    (parallel [(const_int 0)]))))
20901               (sign_extend:SI
20902                  (truncate:HI
20903                     (vec_select:SI (match_dup 1)
20904                                    (parallel [(const_int  1)])))))))]
20905   "TARGET_3DNOW_A"
20906   "pi2fw\\t{%1, %0|%0, %1}"
20907   [(set_attr "type" "mmxcvt")
20908    (set_attr "mode" "V2SF")])
20909
20910 (define_insn "floatv2si2"
20911   [(set (match_operand:V2SF 0 "register_operand" "=y")
20912         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
20913   "TARGET_3DNOW"
20914   "pi2fd\\t{%1, %0|%0, %1}"
20915   [(set_attr "type" "mmxcvt")
20916    (set_attr "mode" "V2SF")])
20917
20918 ;; This insn is identical to pavgb in operation, but the opcode is
20919 ;; different.  To avoid accidentally matching pavgb, use an unspec.
20920
20921 (define_insn "pavgusb"
20922  [(set (match_operand:V8QI 0 "register_operand" "=y")
20923        (unspec:V8QI
20924           [(match_operand:V8QI 1 "register_operand" "0")
20925            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20926           UNSPEC_PAVGUSB))]
20927   "TARGET_3DNOW"
20928   "pavgusb\\t{%2, %0|%0, %2}"
20929   [(set_attr "type" "mmxshft")
20930    (set_attr "mode" "TI")])
20931
20932 ;; 3DNow reciprocal and sqrt
20933  
20934 (define_insn "pfrcpv2sf2"
20935   [(set (match_operand:V2SF 0 "register_operand" "=y")
20936         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
20937         UNSPEC_PFRCP))]
20938   "TARGET_3DNOW"
20939   "pfrcp\\t{%1, %0|%0, %1}"
20940   [(set_attr "type" "mmx")
20941    (set_attr "mode" "TI")])
20942
20943 (define_insn "pfrcpit1v2sf3"
20944   [(set (match_operand:V2SF 0 "register_operand" "=y")
20945         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20946                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20947                      UNSPEC_PFRCPIT1))]
20948   "TARGET_3DNOW"
20949   "pfrcpit1\\t{%2, %0|%0, %2}"
20950   [(set_attr "type" "mmx")
20951    (set_attr "mode" "TI")])
20952
20953 (define_insn "pfrcpit2v2sf3"
20954   [(set (match_operand:V2SF 0 "register_operand" "=y")
20955         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20956                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20957                      UNSPEC_PFRCPIT2))]
20958   "TARGET_3DNOW"
20959   "pfrcpit2\\t{%2, %0|%0, %2}"
20960   [(set_attr "type" "mmx")
20961    (set_attr "mode" "TI")])
20962
20963 (define_insn "pfrsqrtv2sf2"
20964   [(set (match_operand:V2SF 0 "register_operand" "=y")
20965         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
20966                      UNSPEC_PFRSQRT))]
20967   "TARGET_3DNOW"
20968   "pfrsqrt\\t{%1, %0|%0, %1}"
20969   [(set_attr "type" "mmx")
20970    (set_attr "mode" "TI")])
20971                 
20972 (define_insn "pfrsqit1v2sf3"
20973   [(set (match_operand:V2SF 0 "register_operand" "=y")
20974         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
20975                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
20976                      UNSPEC_PFRSQIT1))]
20977   "TARGET_3DNOW"
20978   "pfrsqit1\\t{%2, %0|%0, %2}"
20979   [(set_attr "type" "mmx")
20980    (set_attr "mode" "TI")])
20981
20982 (define_insn "pmulhrwv4hi3"
20983   [(set (match_operand:V4HI 0 "register_operand" "=y")
20984         (truncate:V4HI
20985            (lshiftrt:V4SI
20986               (plus:V4SI
20987                  (mult:V4SI
20988                     (sign_extend:V4SI
20989                        (match_operand:V4HI 1 "register_operand" "0"))
20990                     (sign_extend:V4SI
20991                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20992                  (const_vector:V4SI [(const_int 32768)
20993                                      (const_int 32768)
20994                                      (const_int 32768)
20995                                      (const_int 32768)]))
20996               (const_int 16))))]
20997   "TARGET_3DNOW"
20998   "pmulhrw\\t{%2, %0|%0, %2}"
20999   [(set_attr "type" "mmxmul")
21000    (set_attr "mode" "TI")])
21001
21002 (define_insn "pswapdv2si2"
21003   [(set (match_operand:V2SI 0 "register_operand" "=y")
21004         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21005                          (parallel [(const_int 1) (const_int 0)])))]
21006   "TARGET_3DNOW_A"
21007   "pswapd\\t{%1, %0|%0, %1}"
21008   [(set_attr "type" "mmxcvt")
21009    (set_attr "mode" "TI")])
21010
21011 (define_insn "pswapdv2sf2"
21012   [(set (match_operand:V2SF 0 "register_operand" "=y")
21013         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21014                          (parallel [(const_int 1) (const_int 0)])))]
21015   "TARGET_3DNOW_A"
21016   "pswapd\\t{%1, %0|%0, %1}"
21017   [(set_attr "type" "mmxcvt")
21018    (set_attr "mode" "TI")])
21019
21020 (define_expand "prefetch"
21021   [(prefetch (match_operand 0 "address_operand" "")
21022              (match_operand:SI 1 "const_int_operand" "")
21023              (match_operand:SI 2 "const_int_operand" ""))]
21024   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21025 {
21026   int rw = INTVAL (operands[1]);
21027   int locality = INTVAL (operands[2]);
21028
21029   if (rw != 0 && rw != 1)
21030     abort ();
21031   if (locality < 0 || locality > 3)
21032     abort ();
21033   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21034     abort ();
21035
21036   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21037      suported by SSE counterpart or the SSE prefetch is not available
21038      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21039      of locality.  */
21040   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21041     operands[2] = GEN_INT (3);
21042   else
21043     operands[1] = const0_rtx;
21044 })
21045
21046 (define_insn "*prefetch_sse"
21047   [(prefetch (match_operand:SI 0 "address_operand" "p")
21048              (const_int 0)
21049              (match_operand:SI 1 "const_int_operand" ""))]
21050   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21051 {
21052   static const char * const patterns[4] = {
21053    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21054   };
21055
21056   int locality = INTVAL (operands[1]);
21057   if (locality < 0 || locality > 3)
21058     abort ();
21059
21060   return patterns[locality];  
21061 }
21062   [(set_attr "type" "sse")
21063    (set_attr "memory" "none")])
21064
21065 (define_insn "*prefetch_sse_rex"
21066   [(prefetch (match_operand:DI 0 "address_operand" "p")
21067              (const_int 0)
21068              (match_operand:SI 1 "const_int_operand" ""))]
21069   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21070 {
21071   static const char * const patterns[4] = {
21072    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21073   };
21074
21075   int locality = INTVAL (operands[1]);
21076   if (locality < 0 || locality > 3)
21077     abort ();
21078
21079   return patterns[locality];  
21080 }
21081   [(set_attr "type" "sse")
21082    (set_attr "memory" "none")])
21083
21084 (define_insn "*prefetch_3dnow"
21085   [(prefetch (match_operand:SI 0 "address_operand" "p")
21086              (match_operand:SI 1 "const_int_operand" "n")
21087              (const_int 3))]
21088   "TARGET_3DNOW && !TARGET_64BIT"
21089 {
21090   if (INTVAL (operands[1]) == 0)
21091     return "prefetch\t%a0";
21092   else
21093     return "prefetchw\t%a0";
21094 }
21095   [(set_attr "type" "mmx")
21096    (set_attr "memory" "none")])
21097
21098 (define_insn "*prefetch_3dnow_rex"
21099   [(prefetch (match_operand:DI 0 "address_operand" "p")
21100              (match_operand:SI 1 "const_int_operand" "n")
21101              (const_int 3))]
21102   "TARGET_3DNOW && TARGET_64BIT"
21103 {
21104   if (INTVAL (operands[1]) == 0)
21105     return "prefetch\t%a0";
21106   else
21107     return "prefetchw\t%a0";
21108 }
21109   [(set_attr "type" "mmx")
21110    (set_attr "memory" "none")])
21111
21112 (include "sse.md")