OSDN Git Service

* reg-stack.c (subst_stack_regs_pat): Handle <UNSPEC_FIST_FLOOR> and
[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_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
84
85    ; For SSE/MMX support:
86    (UNSPEC_FIX_NOTRUNC          30)
87    (UNSPEC_MASKMOV              31)
88    (UNSPEC_MOVMSK               32)
89    (UNSPEC_MOVNT                33)
90    (UNSPEC_MOVU                 34)
91    (UNSPEC_RCP                  35)
92    (UNSPEC_RSQRT                36)
93    (UNSPEC_SFENCE               37)
94    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
95    (UNSPEC_PFRCP                39)
96    (UNSPEC_PFRCPIT1             40)
97    (UNSPEC_PFRCPIT2             41)
98    (UNSPEC_PFRSQRT              42)
99    (UNSPEC_PFRSQIT1             43)
100    (UNSPEC_MFENCE               44)
101    (UNSPEC_LFENCE               45)
102    (UNSPEC_PSADBW               46)
103    (UNSPEC_LDQQU                47)
104
105    ; Generic math support
106    (UNSPEC_COPYSIGN             50)
107    (UNSPEC_IEEE_MIN             51)     ; not commutative
108    (UNSPEC_IEEE_MAX             52)     ; not commutative
109
110    ; x87 Floating point
111    (UNSPEC_SIN                  60)
112    (UNSPEC_COS                  61)
113    (UNSPEC_FPATAN               62)
114    (UNSPEC_FYL2X                63)
115    (UNSPEC_FYL2XP1              64)
116    (UNSPEC_FRNDINT              65)
117    (UNSPEC_FIST                 66)
118    (UNSPEC_F2XM1                67)
119
120    ; x87 Rounding
121    (UNSPEC_FRNDINT_FLOOR        70)
122    (UNSPEC_FRNDINT_CEIL         71)
123    (UNSPEC_FRNDINT_TRUNC        72)
124    (UNSPEC_FRNDINT_MASK_PM      73)
125    (UNSPEC_FIST_FLOOR           74)
126    (UNSPEC_FIST_CEIL            75)
127
128    ; x87 Double output FP
129    (UNSPEC_SINCOS_COS           80)
130    (UNSPEC_SINCOS_SIN           81)
131    (UNSPEC_TAN_ONE              82)
132    (UNSPEC_TAN_TAN              83)
133    (UNSPEC_XTRACT_FRACT         84)
134    (UNSPEC_XTRACT_EXP           85)
135    (UNSPEC_FSCALE_FRACT         86)
136    (UNSPEC_FSCALE_EXP           87)
137    (UNSPEC_FPREM_F              88)
138    (UNSPEC_FPREM_U              89)
139    (UNSPEC_FPREM1_F             90)
140    (UNSPEC_FPREM1_U             91)
141   ])
142
143 (define_constants
144   [(UNSPECV_BLOCKAGE            0)
145    (UNSPECV_STACK_PROBE         1)
146    (UNSPECV_EMMS                2)
147    (UNSPECV_LDMXCSR             3)
148    (UNSPECV_STMXCSR             4)
149    (UNSPECV_FEMMS               5)
150    (UNSPECV_CLFLUSH             6)
151    (UNSPECV_ALIGN               7)
152    (UNSPECV_MONITOR             8)
153    (UNSPECV_MWAIT               9)
154   ])
155
156 ;; Registers by name.
157 (define_constants
158   [(BP_REG                       6)
159    (SP_REG                       7)
160    (FLAGS_REG                   17)
161    (FPSR_REG                    18)
162    (DIRFLAG_REG                 19)
163   ])
164
165 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
166 ;; from i386.c.
167
168 ;; In C guard expressions, put expressions which may be compile-time
169 ;; constants first.  This allows for better optimization.  For
170 ;; example, write "TARGET_64BIT && reload_completed", not
171 ;; "reload_completed && TARGET_64BIT".
172
173 \f
174 ;; Processor type.  This attribute must exactly match the processor_type
175 ;; enumeration in i386.h.
176 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
177   (const (symbol_ref "ix86_tune")))
178
179 ;; A basic instruction type.  Refinements due to arguments to be
180 ;; provided in other attributes.
181 (define_attr "type"
182   "other,multi,
183    alu,alu1,negnot,imov,imovx,lea,
184    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
185    icmp,test,ibr,setcc,icmov,
186    push,pop,call,callv,leave,
187    str,cld,
188    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
189    sselog,sselog1,sseiadd,sseishft,sseimul,
190    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
191    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
192   (const_string "other"))
193
194 ;; Main data type used by the insn
195 (define_attr "mode"
196   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
197   (const_string "unknown"))
198
199 ;; The CPU unit operations uses.
200 (define_attr "unit" "integer,i387,sse,mmx,unknown"
201   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
202            (const_string "i387")
203          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
204                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
205            (const_string "sse")
206          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
207            (const_string "mmx")
208          (eq_attr "type" "other")
209            (const_string "unknown")]
210          (const_string "integer")))
211
212 ;; The (bounding maximum) length of an instruction immediate.
213 (define_attr "length_immediate" ""
214   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
215            (const_int 0)
216          (eq_attr "unit" "i387,sse,mmx")
217            (const_int 0)
218          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
219                           imul,icmp,push,pop")
220            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
221          (eq_attr "type" "imov,test")
222            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
223          (eq_attr "type" "call")
224            (if_then_else (match_operand 0 "constant_call_address_operand" "")
225              (const_int 4)
226              (const_int 0))
227          (eq_attr "type" "callv")
228            (if_then_else (match_operand 1 "constant_call_address_operand" "")
229              (const_int 4)
230              (const_int 0))
231          ;; We don't know the size before shorten_branches.  Expect
232          ;; the instruction to fit for better scheduling.
233          (eq_attr "type" "ibr")
234            (const_int 1)
235          ]
236          (symbol_ref "/* Update immediate_length and other attributes! */
237                       abort(),1")))
238
239 ;; The (bounding maximum) length of an instruction address.
240 (define_attr "length_address" ""
241   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
242            (const_int 0)
243          (and (eq_attr "type" "call")
244               (match_operand 0 "constant_call_address_operand" ""))
245              (const_int 0)
246          (and (eq_attr "type" "callv")
247               (match_operand 1 "constant_call_address_operand" ""))
248              (const_int 0)
249          ]
250          (symbol_ref "ix86_attr_length_address_default (insn)")))
251
252 ;; Set when length prefix is used.
253 (define_attr "prefix_data16" ""
254   (if_then_else (ior (eq_attr "mode" "HI")
255                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
256     (const_int 1)
257     (const_int 0)))
258
259 ;; Set when string REP prefix is used.
260 (define_attr "prefix_rep" "" 
261   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
262     (const_int 1)
263     (const_int 0)))
264
265 ;; Set when 0f opcode prefix is used.
266 (define_attr "prefix_0f" ""
267   (if_then_else 
268     (ior (eq_attr "type" "imovx,setcc,icmov")
269          (eq_attr "unit" "sse,mmx"))
270     (const_int 1)
271     (const_int 0)))
272
273 ;; Set when REX opcode prefix is used.
274 (define_attr "prefix_rex" ""
275   (cond [(and (eq_attr "mode" "DI")
276               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
277            (const_int 1)
278          (and (eq_attr "mode" "QI")
279               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
280                   (const_int 0)))
281            (const_int 1)
282          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
283              (const_int 0))
284            (const_int 1)
285         ]
286         (const_int 0)))
287
288 ;; Set when modrm byte is used.
289 (define_attr "modrm" ""
290   (cond [(eq_attr "type" "str,cld,leave")
291            (const_int 0)
292          (eq_attr "unit" "i387")
293            (const_int 0)
294          (and (eq_attr "type" "incdec")
295               (ior (match_operand:SI 1 "register_operand" "")
296                    (match_operand:HI 1 "register_operand" "")))
297            (const_int 0)
298          (and (eq_attr "type" "push")
299               (not (match_operand 1 "memory_operand" "")))
300            (const_int 0)
301          (and (eq_attr "type" "pop")
302               (not (match_operand 0 "memory_operand" "")))
303            (const_int 0)
304          (and (eq_attr "type" "imov")
305               (and (match_operand 0 "register_operand" "")
306                    (match_operand 1 "immediate_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "call")
309               (match_operand 0 "constant_call_address_operand" ""))
310              (const_int 0)
311          (and (eq_attr "type" "callv")
312               (match_operand 1 "constant_call_address_operand" ""))
313              (const_int 0)
314          ]
315          (const_int 1)))
316
317 ;; The (bounding maximum) length of an instruction in bytes.
318 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
319 ;; Later we may want to split them and compute proper length as for
320 ;; other insns.
321 (define_attr "length" ""
322   (cond [(eq_attr "type" "other,multi,fistp,frndint")
323            (const_int 16)
324          (eq_attr "type" "fcmp")
325            (const_int 4)
326          (eq_attr "unit" "i387")
327            (plus (const_int 2)
328                  (plus (attr "prefix_data16")
329                        (attr "length_address")))]
330          (plus (plus (attr "modrm")
331                      (plus (attr "prefix_0f")
332                            (plus (attr "prefix_rex")
333                                  (const_int 1))))
334                (plus (attr "prefix_rep")
335                      (plus (attr "prefix_data16")
336                            (plus (attr "length_immediate")
337                                  (attr "length_address")))))))
338
339 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
340 ;; `store' if there is a simple memory reference therein, or `unknown'
341 ;; if the instruction is complex.
342
343 (define_attr "memory" "none,load,store,both,unknown"
344   (cond [(eq_attr "type" "other,multi,str")
345            (const_string "unknown")
346          (eq_attr "type" "lea,fcmov,fpspc,cld")
347            (const_string "none")
348          (eq_attr "type" "fistp,leave")
349            (const_string "both")
350          (eq_attr "type" "frndint")
351            (const_string "load")
352          (eq_attr "type" "push")
353            (if_then_else (match_operand 1 "memory_operand" "")
354              (const_string "both")
355              (const_string "store"))
356          (eq_attr "type" "pop")
357            (if_then_else (match_operand 0 "memory_operand" "")
358              (const_string "both")
359              (const_string "load"))
360          (eq_attr "type" "setcc")
361            (if_then_else (match_operand 0 "memory_operand" "")
362              (const_string "store")
363              (const_string "none"))
364          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
365            (if_then_else (ior (match_operand 0 "memory_operand" "")
366                               (match_operand 1 "memory_operand" ""))
367              (const_string "load")
368              (const_string "none"))
369          (eq_attr "type" "ibr")
370            (if_then_else (match_operand 0 "memory_operand" "")
371              (const_string "load")
372              (const_string "none"))
373          (eq_attr "type" "call")
374            (if_then_else (match_operand 0 "constant_call_address_operand" "")
375              (const_string "none")
376              (const_string "load"))
377          (eq_attr "type" "callv")
378            (if_then_else (match_operand 1 "constant_call_address_operand" "")
379              (const_string "none")
380              (const_string "load"))
381          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
382               (match_operand 1 "memory_operand" ""))
383            (const_string "both")
384          (and (match_operand 0 "memory_operand" "")
385               (match_operand 1 "memory_operand" ""))
386            (const_string "both")
387          (match_operand 0 "memory_operand" "")
388            (const_string "store")
389          (match_operand 1 "memory_operand" "")
390            (const_string "load")
391          (and (eq_attr "type"
392                  "!alu1,negnot,ishift1,
393                    imov,imovx,icmp,test,
394                    fmov,fcmp,fsgn,
395                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
396                    mmx,mmxmov,mmxcmp,mmxcvt")
397               (match_operand 2 "memory_operand" ""))
398            (const_string "load")
399          (and (eq_attr "type" "icmov")
400               (match_operand 3 "memory_operand" ""))
401            (const_string "load")
402         ]
403         (const_string "none")))
404
405 ;; Indicates if an instruction has both an immediate and a displacement.
406
407 (define_attr "imm_disp" "false,true,unknown"
408   (cond [(eq_attr "type" "other,multi")
409            (const_string "unknown")
410          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
411               (and (match_operand 0 "memory_displacement_operand" "")
412                    (match_operand 1 "immediate_operand" "")))
413            (const_string "true")
414          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
415               (and (match_operand 0 "memory_displacement_operand" "")
416                    (match_operand 2 "immediate_operand" "")))
417            (const_string "true")
418         ]
419         (const_string "false")))
420
421 ;; Indicates if an FP operation has an integer source.
422
423 (define_attr "fp_int_src" "false,true"
424   (const_string "false"))
425
426 ;; Defines rounding mode of an FP operation.
427
428 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
429   (const_string "any"))
430
431 ;; Describe a user's asm statement.
432 (define_asm_attributes
433   [(set_attr "length" "128")
434    (set_attr "type" "multi")])
435
436 ;; All x87 floating point modes
437 (define_mode_macro X87MODEF [SF DF XF])
438  
439 ;; All integer modes handled by x87 fisttp operator.
440 (define_mode_macro X87MODEI [HI SI DI])
441
442 ;; All integer modes handled by integer x87 operators.
443 (define_mode_macro X87MODEI12 [HI SI])
444
445 ;; All SSE floating point modes
446 (define_mode_macro SSEMODEF [SF DF])
447  
448 ;; All integer modes handled by SSE cvtts?2si* operators.
449 (define_mode_macro SSEMODEI24 [SI DI])
450
451 \f
452 ;; Scheduling descriptions
453
454 (include "pentium.md")
455 (include "ppro.md")
456 (include "k6.md")
457 (include "athlon.md")
458
459 \f
460 ;; Operand and operator predicates
461
462 (include "predicates.md")
463
464 \f
465 ;; Compare instructions.
466
467 ;; All compare insns have expanders that save the operands away without
468 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
469 ;; after the cmp) will actually emit the cmpM.
470
471 (define_expand "cmpdi"
472   [(set (reg:CC FLAGS_REG)
473         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
474                     (match_operand:DI 1 "x86_64_general_operand" "")))]
475   ""
476 {
477   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
478     operands[0] = force_reg (DImode, operands[0]);
479   ix86_compare_op0 = operands[0];
480   ix86_compare_op1 = operands[1];
481   DONE;
482 })
483
484 (define_expand "cmpsi"
485   [(set (reg:CC FLAGS_REG)
486         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
487                     (match_operand:SI 1 "general_operand" "")))]
488   ""
489 {
490   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
491     operands[0] = force_reg (SImode, operands[0]);
492   ix86_compare_op0 = operands[0];
493   ix86_compare_op1 = operands[1];
494   DONE;
495 })
496
497 (define_expand "cmphi"
498   [(set (reg:CC FLAGS_REG)
499         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
500                     (match_operand:HI 1 "general_operand" "")))]
501   ""
502 {
503   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
504     operands[0] = force_reg (HImode, operands[0]);
505   ix86_compare_op0 = operands[0];
506   ix86_compare_op1 = operands[1];
507   DONE;
508 })
509
510 (define_expand "cmpqi"
511   [(set (reg:CC FLAGS_REG)
512         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
513                     (match_operand:QI 1 "general_operand" "")))]
514   "TARGET_QIMODE_MATH"
515 {
516   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
517     operands[0] = force_reg (QImode, operands[0]);
518   ix86_compare_op0 = operands[0];
519   ix86_compare_op1 = operands[1];
520   DONE;
521 })
522
523 (define_insn "cmpdi_ccno_1_rex64"
524   [(set (reg FLAGS_REG)
525         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
526                  (match_operand:DI 1 "const0_operand" "n,n")))]
527   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
528   "@
529    test{q}\t{%0, %0|%0, %0}
530    cmp{q}\t{%1, %0|%0, %1}"
531   [(set_attr "type" "test,icmp")
532    (set_attr "length_immediate" "0,1")
533    (set_attr "mode" "DI")])
534
535 (define_insn "*cmpdi_minus_1_rex64"
536   [(set (reg FLAGS_REG)
537         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
538                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
539                  (const_int 0)))]
540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
541   "cmp{q}\t{%1, %0|%0, %1}"
542   [(set_attr "type" "icmp")
543    (set_attr "mode" "DI")])
544
545 (define_expand "cmpdi_1_rex64"
546   [(set (reg:CC FLAGS_REG)
547         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
548                     (match_operand:DI 1 "general_operand" "")))]
549   "TARGET_64BIT"
550   "")
551
552 (define_insn "cmpdi_1_insn_rex64"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
555                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
556   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
557   "cmp{q}\t{%1, %0|%0, %1}"
558   [(set_attr "type" "icmp")
559    (set_attr "mode" "DI")])
560
561
562 (define_insn "*cmpsi_ccno_1"
563   [(set (reg FLAGS_REG)
564         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
565                  (match_operand:SI 1 "const0_operand" "n,n")))]
566   "ix86_match_ccmode (insn, CCNOmode)"
567   "@
568    test{l}\t{%0, %0|%0, %0}
569    cmp{l}\t{%1, %0|%0, %1}"
570   [(set_attr "type" "test,icmp")
571    (set_attr "length_immediate" "0,1")
572    (set_attr "mode" "SI")])
573
574 (define_insn "*cmpsi_minus_1"
575   [(set (reg FLAGS_REG)
576         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577                            (match_operand:SI 1 "general_operand" "ri,mr"))
578                  (const_int 0)))]
579   "ix86_match_ccmode (insn, CCGOCmode)"
580   "cmp{l}\t{%1, %0|%0, %1}"
581   [(set_attr "type" "icmp")
582    (set_attr "mode" "SI")])
583
584 (define_expand "cmpsi_1"
585   [(set (reg:CC FLAGS_REG)
586         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                     (match_operand:SI 1 "general_operand" "ri,mr")))]
588   ""
589   "")
590
591 (define_insn "*cmpsi_1_insn"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
594                  (match_operand:SI 1 "general_operand" "ri,mr")))]
595   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
596     && ix86_match_ccmode (insn, CCmode)"
597   "cmp{l}\t{%1, %0|%0, %1}"
598   [(set_attr "type" "icmp")
599    (set_attr "mode" "SI")])
600
601 (define_insn "*cmphi_ccno_1"
602   [(set (reg FLAGS_REG)
603         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
604                  (match_operand:HI 1 "const0_operand" "n,n")))]
605   "ix86_match_ccmode (insn, CCNOmode)"
606   "@
607    test{w}\t{%0, %0|%0, %0}
608    cmp{w}\t{%1, %0|%0, %1}"
609   [(set_attr "type" "test,icmp")
610    (set_attr "length_immediate" "0,1")
611    (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_minus_1"
614   [(set (reg FLAGS_REG)
615         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616                            (match_operand:HI 1 "general_operand" "ri,mr"))
617                  (const_int 0)))]
618   "ix86_match_ccmode (insn, CCGOCmode)"
619   "cmp{w}\t{%1, %0|%0, %1}"
620   [(set_attr "type" "icmp")
621    (set_attr "mode" "HI")])
622
623 (define_insn "*cmphi_1"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626                  (match_operand:HI 1 "general_operand" "ri,mr")))]
627   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628    && ix86_match_ccmode (insn, CCmode)"
629   "cmp{w}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "HI")])
632
633 (define_insn "*cmpqi_ccno_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
636                  (match_operand:QI 1 "const0_operand" "n,n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "@
639    test{b}\t{%0, %0|%0, %0}
640    cmp{b}\t{$0, %0|%0, 0}"
641   [(set_attr "type" "test,icmp")
642    (set_attr "length_immediate" "0,1")
643    (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_1"
646   [(set (reg FLAGS_REG)
647         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648                  (match_operand:QI 1 "general_operand" "qi,mq")))]
649   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
650     && ix86_match_ccmode (insn, CCmode)"
651   "cmp{b}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_minus_1"
656   [(set (reg FLAGS_REG)
657         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658                            (match_operand:QI 1 "general_operand" "qi,mq"))
659                  (const_int 0)))]
660   "ix86_match_ccmode (insn, CCGOCmode)"
661   "cmp{b}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "QI")])
664
665 (define_insn "*cmpqi_ext_1"
666   [(set (reg FLAGS_REG)
667         (compare
668           (match_operand:QI 0 "general_operand" "Qm")
669           (subreg:QI
670             (zero_extract:SI
671               (match_operand 1 "ext_register_operand" "Q")
672               (const_int 8)
673               (const_int 8)) 0)))]
674   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
675   "cmp{b}\t{%h1, %0|%0, %h1}"
676   [(set_attr "type" "icmp")
677    (set_attr "mode" "QI")])
678
679 (define_insn "*cmpqi_ext_1_rex64"
680   [(set (reg FLAGS_REG)
681         (compare
682           (match_operand:QI 0 "register_operand" "Q")
683           (subreg:QI
684             (zero_extract:SI
685               (match_operand 1 "ext_register_operand" "Q")
686               (const_int 8)
687               (const_int 8)) 0)))]
688   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
689   "cmp{b}\t{%h1, %0|%0, %h1}"
690   [(set_attr "type" "icmp")
691    (set_attr "mode" "QI")])
692
693 (define_insn "*cmpqi_ext_2"
694   [(set (reg FLAGS_REG)
695         (compare
696           (subreg:QI
697             (zero_extract:SI
698               (match_operand 0 "ext_register_operand" "Q")
699               (const_int 8)
700               (const_int 8)) 0)
701           (match_operand:QI 1 "const0_operand" "n")))]
702   "ix86_match_ccmode (insn, CCNOmode)"
703   "test{b}\t%h0, %h0"
704   [(set_attr "type" "test")
705    (set_attr "length_immediate" "0")
706    (set_attr "mode" "QI")])
707
708 (define_expand "cmpqi_ext_3"
709   [(set (reg:CC FLAGS_REG)
710         (compare:CC
711           (subreg:QI
712             (zero_extract:SI
713               (match_operand 0 "ext_register_operand" "")
714               (const_int 8)
715               (const_int 8)) 0)
716           (match_operand:QI 1 "general_operand" "")))]
717   ""
718   "")
719
720 (define_insn "cmpqi_ext_3_insn"
721   [(set (reg FLAGS_REG)
722         (compare
723           (subreg:QI
724             (zero_extract:SI
725               (match_operand 0 "ext_register_operand" "Q")
726               (const_int 8)
727               (const_int 8)) 0)
728           (match_operand:QI 1 "general_operand" "Qmn")))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%1, %h0|%h0, %1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "cmpqi_ext_3_insn_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (subreg:QI
738             (zero_extract:SI
739               (match_operand 0 "ext_register_operand" "Q")
740               (const_int 8)
741               (const_int 8)) 0)
742           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%1, %h0|%h0, %1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_4"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (subreg:QI
757             (zero_extract:SI
758               (match_operand 1 "ext_register_operand" "Q")
759               (const_int 8)
760               (const_int 8)) 0)))]
761   "ix86_match_ccmode (insn, CCmode)"
762   "cmp{b}\t{%h1, %h0|%h0, %h1}"
763   [(set_attr "type" "icmp")
764    (set_attr "mode" "QI")])
765
766 ;; These implement float point compares.
767 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
768 ;; which would allow mix and match FP modes on the compares.  Which is what
769 ;; the old patterns did, but with many more of them.
770
771 (define_expand "cmpxf"
772   [(set (reg:CC FLAGS_REG)
773         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
774                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
775   "TARGET_80387"
776 {
777   ix86_compare_op0 = operands[0];
778   ix86_compare_op1 = operands[1];
779   DONE;
780 })
781
782 (define_expand "cmpdf"
783   [(set (reg:CC FLAGS_REG)
784         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
785                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
786   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
787 {
788   ix86_compare_op0 = operands[0];
789   ix86_compare_op1 = operands[1];
790   DONE;
791 })
792
793 (define_expand "cmpsf"
794   [(set (reg:CC FLAGS_REG)
795         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
796                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
797   "TARGET_80387 || TARGET_SSE_MATH"
798 {
799   ix86_compare_op0 = operands[0];
800   ix86_compare_op1 = operands[1];
801   DONE;
802 })
803
804 ;; FP compares, step 1:
805 ;; Set the FP condition codes.
806 ;;
807 ;; CCFPmode     compare with exceptions
808 ;; CCFPUmode    compare with no exceptions
809
810 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
811 ;; used to manage the reg stack popping would not be preserved.
812
813 (define_insn "*cmpfp_0_sf"
814   [(set (match_operand:HI 0 "register_operand" "=a")
815         (unspec:HI
816           [(compare:CCFP
817              (match_operand:SF 1 "register_operand" "f")
818              (match_operand:SF 2 "const0_operand" "X"))]
819         UNSPEC_FNSTSW))]
820   "TARGET_80387"
821   "* return output_fp_compare (insn, operands, 0, 0);"
822   [(set_attr "type" "multi")
823    (set_attr "mode" "SF")])
824
825 (define_insn "*cmpfp_0_df"
826   [(set (match_operand:HI 0 "register_operand" "=a")
827         (unspec:HI
828           [(compare:CCFP
829              (match_operand:DF 1 "register_operand" "f")
830              (match_operand:DF 2 "const0_operand" "X"))]
831         UNSPEC_FNSTSW))]
832   "TARGET_80387"
833   "* return output_fp_compare (insn, operands, 0, 0);"
834   [(set_attr "type" "multi")
835    (set_attr "mode" "DF")])
836
837 (define_insn "*cmpfp_0_xf"
838   [(set (match_operand:HI 0 "register_operand" "=a")
839         (unspec:HI
840           [(compare:CCFP
841              (match_operand:XF 1 "register_operand" "f")
842              (match_operand:XF 2 "const0_operand" "X"))]
843         UNSPEC_FNSTSW))]
844   "TARGET_80387"
845   "* return output_fp_compare (insn, operands, 0, 0);"
846   [(set_attr "type" "multi")
847    (set_attr "mode" "XF")])
848
849 (define_insn "*cmpfp_sf"
850   [(set (match_operand:HI 0 "register_operand" "=a")
851         (unspec:HI
852           [(compare:CCFP
853              (match_operand:SF 1 "register_operand" "f")
854              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
855           UNSPEC_FNSTSW))]
856   "TARGET_80387"
857   "* return output_fp_compare (insn, operands, 0, 0);"
858   [(set_attr "type" "multi")
859    (set_attr "mode" "SF")])
860
861 (define_insn "*cmpfp_df"
862   [(set (match_operand:HI 0 "register_operand" "=a")
863         (unspec:HI
864           [(compare:CCFP
865              (match_operand:DF 1 "register_operand" "f")
866              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
867           UNSPEC_FNSTSW))]
868   "TARGET_80387"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "multi")
871    (set_attr "mode" "DF")])
872
873 (define_insn "*cmpfp_xf"
874   [(set (match_operand:HI 0 "register_operand" "=a")
875         (unspec:HI
876           [(compare:CCFP
877              (match_operand:XF 1 "register_operand" "f")
878              (match_operand:XF 2 "register_operand" "f"))]
879           UNSPEC_FNSTSW))]
880   "TARGET_80387"
881   "* return output_fp_compare (insn, operands, 0, 0);"
882   [(set_attr "type" "multi")
883    (set_attr "mode" "XF")])
884
885 (define_insn "*cmpfp_u"
886   [(set (match_operand:HI 0 "register_operand" "=a")
887         (unspec:HI
888           [(compare:CCFPU
889              (match_operand 1 "register_operand" "f")
890              (match_operand 2 "register_operand" "f"))]
891           UNSPEC_FNSTSW))]
892   "TARGET_80387
893    && FLOAT_MODE_P (GET_MODE (operands[1]))
894    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
895   "* return output_fp_compare (insn, operands, 0, 1);"
896   [(set_attr "type" "multi")
897    (set (attr "mode")
898      (cond [(match_operand:SF 1 "" "")
899               (const_string "SF")
900             (match_operand:DF 1 "" "")
901               (const_string "DF")
902            ]
903            (const_string "XF")))])
904
905 (define_insn "*cmpfp_<mode>"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFP
909              (match_operand 1 "register_operand" "f")
910              (match_operator 3 "float_operator"
911                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
912           UNSPEC_FNSTSW))]
913   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
914    && FLOAT_MODE_P (GET_MODE (operands[1]))
915    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
916   "* return output_fp_compare (insn, operands, 0, 0);"
917   [(set_attr "type" "multi")
918    (set_attr "fp_int_src" "true")
919    (set_attr "mode" "<MODE>")])
920
921 ;; FP compares, step 2
922 ;; Move the fpsw to ax.
923
924 (define_insn "x86_fnstsw_1"
925   [(set (match_operand:HI 0 "register_operand" "=a")
926         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
927   "TARGET_80387"
928   "fnstsw\t%0"
929   [(set_attr "length" "2")
930    (set_attr "mode" "SI")
931    (set_attr "unit" "i387")])
932
933 ;; FP compares, step 3
934 ;; Get ax into flags, general case.
935
936 (define_insn "x86_sahf_1"
937   [(set (reg:CC FLAGS_REG)
938         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
939   "!TARGET_64BIT"
940   "sahf"
941   [(set_attr "length" "1")
942    (set_attr "athlon_decode" "vector")
943    (set_attr "mode" "SI")])
944
945 ;; Pentium Pro can do steps 1 through 3 in one go.
946
947 (define_insn "*cmpfp_i_mixed"
948   [(set (reg:CCFP FLAGS_REG)
949         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
950                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
951   "TARGET_MIX_SSE_I387
952    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
953    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
954   "* return output_fp_compare (insn, operands, 1, 0);"
955   [(set_attr "type" "fcmp,ssecomi")
956    (set (attr "mode")
957      (if_then_else (match_operand:SF 1 "" "")
958         (const_string "SF")
959         (const_string "DF")))
960    (set_attr "athlon_decode" "vector")])
961
962 (define_insn "*cmpfp_i_sse"
963   [(set (reg:CCFP FLAGS_REG)
964         (compare:CCFP (match_operand 0 "register_operand" "x")
965                       (match_operand 1 "nonimmediate_operand" "xm")))]
966   "TARGET_SSE_MATH
967    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969   "* return output_fp_compare (insn, operands, 1, 0);"
970   [(set_attr "type" "ssecomi")
971    (set (attr "mode")
972      (if_then_else (match_operand:SF 1 "" "")
973         (const_string "SF")
974         (const_string "DF")))
975    (set_attr "athlon_decode" "vector")])
976
977 (define_insn "*cmpfp_i_i387"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "f")
980                       (match_operand 1 "register_operand" "f")))]
981   "TARGET_80387 && TARGET_CMOVE
982    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
983    && FLOAT_MODE_P (GET_MODE (operands[0]))
984    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
985   "* return output_fp_compare (insn, operands, 1, 0);"
986   [(set_attr "type" "fcmp")
987    (set (attr "mode")
988      (cond [(match_operand:SF 1 "" "")
989               (const_string "SF")
990             (match_operand:DF 1 "" "")
991               (const_string "DF")
992            ]
993            (const_string "XF")))
994    (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_iu_mixed"
997   [(set (reg:CCFPU FLAGS_REG)
998         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
999                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000   "TARGET_MIX_SSE_I387
1001    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003   "* return output_fp_compare (insn, operands, 1, 1);"
1004   [(set_attr "type" "fcmp,ssecomi")
1005    (set (attr "mode")
1006      (if_then_else (match_operand:SF 1 "" "")
1007         (const_string "SF")
1008         (const_string "DF")))
1009    (set_attr "athlon_decode" "vector")])
1010
1011 (define_insn "*cmpfp_iu_sse"
1012   [(set (reg:CCFPU FLAGS_REG)
1013         (compare:CCFPU (match_operand 0 "register_operand" "x")
1014                        (match_operand 1 "nonimmediate_operand" "xm")))]
1015   "TARGET_SSE_MATH
1016    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018   "* return output_fp_compare (insn, operands, 1, 1);"
1019   [(set_attr "type" "ssecomi")
1020    (set (attr "mode")
1021      (if_then_else (match_operand:SF 1 "" "")
1022         (const_string "SF")
1023         (const_string "DF")))
1024    (set_attr "athlon_decode" "vector")])
1025
1026 (define_insn "*cmpfp_iu_387"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "f")
1029                        (match_operand 1 "register_operand" "f")))]
1030   "TARGET_80387 && TARGET_CMOVE
1031    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1032    && FLOAT_MODE_P (GET_MODE (operands[0]))
1033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034   "* return output_fp_compare (insn, operands, 1, 1);"
1035   [(set_attr "type" "fcmp")
1036    (set (attr "mode")
1037      (cond [(match_operand:SF 1 "" "")
1038               (const_string "SF")
1039             (match_operand:DF 1 "" "")
1040               (const_string "DF")
1041            ]
1042            (const_string "XF")))
1043    (set_attr "athlon_decode" "vector")])
1044 \f
1045 ;; Move instructions.
1046
1047 ;; General case of fullword move.
1048
1049 (define_expand "movsi"
1050   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1051         (match_operand:SI 1 "general_operand" ""))]
1052   ""
1053   "ix86_expand_move (SImode, operands); DONE;")
1054
1055 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1056 ;; general_operand.
1057 ;;
1058 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1059 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1060 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1061 ;; targets without our curiosities, and it is just as easy to represent
1062 ;; this differently.
1063
1064 (define_insn "*pushsi2"
1065   [(set (match_operand:SI 0 "push_operand" "=<")
1066         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1067   "!TARGET_64BIT"
1068   "push{l}\t%1"
1069   [(set_attr "type" "push")
1070    (set_attr "mode" "SI")])
1071
1072 ;; For 64BIT abi we always round up to 8 bytes.
1073 (define_insn "*pushsi2_rex64"
1074   [(set (match_operand:SI 0 "push_operand" "=X")
1075         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1076   "TARGET_64BIT"
1077   "push{q}\t%q1"
1078   [(set_attr "type" "push")
1079    (set_attr "mode" "SI")])
1080
1081 (define_insn "*pushsi2_prologue"
1082   [(set (match_operand:SI 0 "push_operand" "=<")
1083         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1084    (clobber (mem:BLK (scratch)))]
1085   "!TARGET_64BIT"
1086   "push{l}\t%1"
1087   [(set_attr "type" "push")
1088    (set_attr "mode" "SI")])
1089
1090 (define_insn "*popsi1_epilogue"
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    (clobber (mem:BLK (scratch)))]
1096   "!TARGET_64BIT"
1097   "pop{l}\t%0"
1098   [(set_attr "type" "pop")
1099    (set_attr "mode" "SI")])
1100
1101 (define_insn "popsi1"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103         (mem:SI (reg:SI SP_REG)))
1104    (set (reg:SI SP_REG)
1105         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1106   "!TARGET_64BIT"
1107   "pop{l}\t%0"
1108   [(set_attr "type" "pop")
1109    (set_attr "mode" "SI")])
1110
1111 (define_insn "*movsi_xor"
1112   [(set (match_operand:SI 0 "register_operand" "=r")
1113         (match_operand:SI 1 "const0_operand" "i"))
1114    (clobber (reg:CC FLAGS_REG))]
1115   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1116   "xor{l}\t{%0, %0|%0, %0}"
1117   [(set_attr "type" "alu1")
1118    (set_attr "mode" "SI")
1119    (set_attr "length_immediate" "0")])
1120  
1121 (define_insn "*movsi_or"
1122   [(set (match_operand:SI 0 "register_operand" "=r")
1123         (match_operand:SI 1 "immediate_operand" "i"))
1124    (clobber (reg:CC FLAGS_REG))]
1125   "reload_completed
1126    && operands[1] == constm1_rtx
1127    && (TARGET_PENTIUM || optimize_size)"
1128 {
1129   operands[1] = constm1_rtx;
1130   return "or{l}\t{%1, %0|%0, %1}";
1131 }
1132   [(set_attr "type" "alu1")
1133    (set_attr "mode" "SI")
1134    (set_attr "length_immediate" "1")])
1135
1136 (define_insn "*movsi_1"
1137   [(set (match_operand:SI 0 "nonimmediate_operand"
1138                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1139         (match_operand:SI 1 "general_operand"
1140                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1141   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1142 {
1143   switch (get_attr_type (insn))
1144     {
1145     case TYPE_SSELOG1:
1146       if (get_attr_mode (insn) == MODE_TI)
1147         return "pxor\t%0, %0";
1148       return "xorps\t%0, %0";
1149
1150     case TYPE_SSEMOV:
1151       switch (get_attr_mode (insn))
1152         {
1153         case MODE_TI:
1154           return "movdqa\t{%1, %0|%0, %1}";
1155         case MODE_V4SF:
1156           return "movaps\t{%1, %0|%0, %1}";
1157         case MODE_SI:
1158           return "movd\t{%1, %0|%0, %1}";
1159         case MODE_SF:
1160           return "movss\t{%1, %0|%0, %1}";
1161         default:
1162           gcc_unreachable ();
1163         }
1164
1165     case TYPE_MMXADD:
1166       return "pxor\t%0, %0";
1167
1168     case TYPE_MMXMOV:
1169       if (get_attr_mode (insn) == MODE_DI)
1170         return "movq\t{%1, %0|%0, %1}";
1171       return "movd\t{%1, %0|%0, %1}";
1172
1173     case TYPE_LEA:
1174       return "lea{l}\t{%1, %0|%0, %1}";
1175
1176     default:
1177       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1178         abort();
1179       return "mov{l}\t{%1, %0|%0, %1}";
1180     }
1181 }
1182   [(set (attr "type")
1183      (cond [(eq_attr "alternative" "2")
1184               (const_string "mmx")
1185             (eq_attr "alternative" "3,4,5")
1186               (const_string "mmxmov")
1187             (eq_attr "alternative" "6")
1188               (const_string "sselog1")
1189             (eq_attr "alternative" "7,8,9,10,11")
1190               (const_string "ssemov")
1191             (and (ne (symbol_ref "flag_pic") (const_int 0))
1192                  (match_operand:SI 1 "symbolic_operand" ""))
1193               (const_string "lea")
1194            ]
1195            (const_string "imov")))
1196    (set (attr "mode")
1197      (cond [(eq_attr "alternative" "2,3")
1198               (const_string "DI")
1199             (eq_attr "alternative" "6,7")
1200               (if_then_else
1201                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1202                 (const_string "V4SF")
1203                 (const_string "TI"))
1204             (and (eq_attr "alternative" "8,9,10,11")
1205                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1206               (const_string "SF")
1207            ]
1208            (const_string "SI")))])
1209
1210 ;; Stores and loads of ax to arbitrary constant address.
1211 ;; We fake an second form of instruction to force reload to load address
1212 ;; into register when rax is not available
1213 (define_insn "*movabssi_1_rex64"
1214   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1215         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1216   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1217   "@
1218    movabs{l}\t{%1, %P0|%P0, %1}
1219    mov{l}\t{%1, %a0|%a0, %1}"
1220   [(set_attr "type" "imov")
1221    (set_attr "modrm" "0,*")
1222    (set_attr "length_address" "8,0")
1223    (set_attr "length_immediate" "0,*")
1224    (set_attr "memory" "store")
1225    (set_attr "mode" "SI")])
1226
1227 (define_insn "*movabssi_2_rex64"
1228   [(set (match_operand:SI 0 "register_operand" "=a,r")
1229         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1230   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1231   "@
1232    movabs{l}\t{%P1, %0|%0, %P1}
1233    mov{l}\t{%a1, %0|%0, %a1}"
1234   [(set_attr "type" "imov")
1235    (set_attr "modrm" "0,*")
1236    (set_attr "length_address" "8,0")
1237    (set_attr "length_immediate" "0")
1238    (set_attr "memory" "load")
1239    (set_attr "mode" "SI")])
1240
1241 (define_insn "*swapsi"
1242   [(set (match_operand:SI 0 "register_operand" "+r")
1243         (match_operand:SI 1 "register_operand" "+r"))
1244    (set (match_dup 1)
1245         (match_dup 0))]
1246   ""
1247   "xchg{l}\t%1, %0"
1248   [(set_attr "type" "imov")
1249    (set_attr "mode" "SI")
1250    (set_attr "pent_pair" "np")
1251    (set_attr "athlon_decode" "vector")])
1252
1253 (define_expand "movhi"
1254   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1255         (match_operand:HI 1 "general_operand" ""))]
1256   ""
1257   "ix86_expand_move (HImode, operands); DONE;")
1258
1259 (define_insn "*pushhi2"
1260   [(set (match_operand:HI 0 "push_operand" "=<,<")
1261         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1262   "!TARGET_64BIT"
1263   "@
1264    push{w}\t{|WORD PTR }%1
1265    push{w}\t%1"
1266   [(set_attr "type" "push")
1267    (set_attr "mode" "HI")])
1268
1269 ;; For 64BIT abi we always round up to 8 bytes.
1270 (define_insn "*pushhi2_rex64"
1271   [(set (match_operand:HI 0 "push_operand" "=X")
1272         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1273   "TARGET_64BIT"
1274   "push{q}\t%q1"
1275   [(set_attr "type" "push")
1276    (set_attr "mode" "QI")])
1277
1278 (define_insn "*movhi_1"
1279   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1280         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1281   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1282 {
1283   switch (get_attr_type (insn))
1284     {
1285     case TYPE_IMOVX:
1286       /* movzwl is faster than movw on p2 due to partial word stalls,
1287          though not as fast as an aligned movl.  */
1288       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1289     default:
1290       if (get_attr_mode (insn) == MODE_SI)
1291         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1292       else
1293         return "mov{w}\t{%1, %0|%0, %1}";
1294     }
1295 }
1296   [(set (attr "type")
1297      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1298               (const_string "imov")
1299             (and (eq_attr "alternative" "0")
1300                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1301                           (const_int 0))
1302                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1303                           (const_int 0))))
1304               (const_string "imov")
1305             (and (eq_attr "alternative" "1,2")
1306                  (match_operand:HI 1 "aligned_operand" ""))
1307               (const_string "imov")
1308             (and (ne (symbol_ref "TARGET_MOVX")
1309                      (const_int 0))
1310                  (eq_attr "alternative" "0,2"))
1311               (const_string "imovx")
1312            ]
1313            (const_string "imov")))
1314     (set (attr "mode")
1315       (cond [(eq_attr "type" "imovx")
1316                (const_string "SI")
1317              (and (eq_attr "alternative" "1,2")
1318                   (match_operand:HI 1 "aligned_operand" ""))
1319                (const_string "SI")
1320              (and (eq_attr "alternative" "0")
1321                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1322                            (const_int 0))
1323                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1324                            (const_int 0))))
1325                (const_string "SI")
1326             ]
1327             (const_string "HI")))])
1328
1329 ;; Stores and loads of ax to arbitrary constant address.
1330 ;; We fake an second form of instruction to force reload to load address
1331 ;; into register when rax is not available
1332 (define_insn "*movabshi_1_rex64"
1333   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1334         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1335   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1336   "@
1337    movabs{w}\t{%1, %P0|%P0, %1}
1338    mov{w}\t{%1, %a0|%a0, %1}"
1339   [(set_attr "type" "imov")
1340    (set_attr "modrm" "0,*")
1341    (set_attr "length_address" "8,0")
1342    (set_attr "length_immediate" "0,*")
1343    (set_attr "memory" "store")
1344    (set_attr "mode" "HI")])
1345
1346 (define_insn "*movabshi_2_rex64"
1347   [(set (match_operand:HI 0 "register_operand" "=a,r")
1348         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1349   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1350   "@
1351    movabs{w}\t{%P1, %0|%0, %P1}
1352    mov{w}\t{%a1, %0|%0, %a1}"
1353   [(set_attr "type" "imov")
1354    (set_attr "modrm" "0,*")
1355    (set_attr "length_address" "8,0")
1356    (set_attr "length_immediate" "0")
1357    (set_attr "memory" "load")
1358    (set_attr "mode" "HI")])
1359
1360 (define_insn "*swaphi_1"
1361   [(set (match_operand:HI 0 "register_operand" "+r")
1362         (match_operand:HI 1 "register_operand" "+r"))
1363    (set (match_dup 1)
1364         (match_dup 0))]
1365   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1366   "xchg{l}\t%k1, %k0"
1367   [(set_attr "type" "imov")
1368    (set_attr "mode" "SI")
1369    (set_attr "pent_pair" "np")
1370    (set_attr "athlon_decode" "vector")])
1371
1372 (define_insn "*swaphi_2"
1373   [(set (match_operand:HI 0 "register_operand" "+r")
1374         (match_operand:HI 1 "register_operand" "+r"))
1375    (set (match_dup 1)
1376         (match_dup 0))]
1377   "TARGET_PARTIAL_REG_STALL"
1378   "xchg{w}\t%1, %0"
1379   [(set_attr "type" "imov")
1380    (set_attr "mode" "HI")
1381    (set_attr "pent_pair" "np")
1382    (set_attr "athlon_decode" "vector")])
1383
1384 (define_expand "movstricthi"
1385   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1386         (match_operand:HI 1 "general_operand" ""))]
1387   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1388 {
1389   /* Don't generate memory->memory moves, go through a register */
1390   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1391     operands[1] = force_reg (HImode, operands[1]);
1392 })
1393
1394 (define_insn "*movstricthi_1"
1395   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1396         (match_operand:HI 1 "general_operand" "rn,m"))]
1397   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1398    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1399   "mov{w}\t{%1, %0|%0, %1}"
1400   [(set_attr "type" "imov")
1401    (set_attr "mode" "HI")])
1402
1403 (define_insn "*movstricthi_xor"
1404   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1405         (match_operand:HI 1 "const0_operand" "i"))
1406    (clobber (reg:CC FLAGS_REG))]
1407   "reload_completed
1408    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1409   "xor{w}\t{%0, %0|%0, %0}"
1410   [(set_attr "type" "alu1")
1411    (set_attr "mode" "HI")
1412    (set_attr "length_immediate" "0")])
1413
1414 (define_expand "movqi"
1415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1416         (match_operand:QI 1 "general_operand" ""))]
1417   ""
1418   "ix86_expand_move (QImode, operands); DONE;")
1419
1420 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1421 ;; "push a byte".  But actually we use pushw, which has the effect
1422 ;; of rounding the amount pushed up to a halfword.
1423
1424 (define_insn "*pushqi2"
1425   [(set (match_operand:QI 0 "push_operand" "=X,X")
1426         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1427   "!TARGET_64BIT"
1428   "@
1429    push{w}\t{|word ptr }%1
1430    push{w}\t%w1"
1431   [(set_attr "type" "push")
1432    (set_attr "mode" "HI")])
1433
1434 ;; For 64BIT abi we always round up to 8 bytes.
1435 (define_insn "*pushqi2_rex64"
1436   [(set (match_operand:QI 0 "push_operand" "=X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1438   "TARGET_64BIT"
1439   "push{q}\t%q1"
1440   [(set_attr "type" "push")
1441    (set_attr "mode" "QI")])
1442
1443 ;; Situation is quite tricky about when to choose full sized (SImode) move
1444 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1445 ;; partial register dependency machines (such as AMD Athlon), where QImode
1446 ;; moves issue extra dependency and for partial register stalls machines
1447 ;; that don't use QImode patterns (and QImode move cause stall on the next
1448 ;; instruction).
1449 ;;
1450 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1451 ;; register stall machines with, where we use QImode instructions, since
1452 ;; partial register stall can be caused there.  Then we use movzx.
1453 (define_insn "*movqi_1"
1454   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1455         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1456   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1457 {
1458   switch (get_attr_type (insn))
1459     {
1460     case TYPE_IMOVX:
1461       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1462         abort ();
1463       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1464     default:
1465       if (get_attr_mode (insn) == MODE_SI)
1466         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1467       else
1468         return "mov{b}\t{%1, %0|%0, %1}";
1469     }
1470 }
1471   [(set (attr "type")
1472      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1473               (const_string "imov")
1474             (and (eq_attr "alternative" "3")
1475                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1476                           (const_int 0))
1477                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1478                           (const_int 0))))
1479               (const_string "imov")
1480             (eq_attr "alternative" "3,5")
1481               (const_string "imovx")
1482             (and (ne (symbol_ref "TARGET_MOVX")
1483                      (const_int 0))
1484                  (eq_attr "alternative" "2"))
1485               (const_string "imovx")
1486            ]
1487            (const_string "imov")))
1488    (set (attr "mode")
1489       (cond [(eq_attr "alternative" "3,4,5")
1490                (const_string "SI")
1491              (eq_attr "alternative" "6")
1492                (const_string "QI")
1493              (eq_attr "type" "imovx")
1494                (const_string "SI")
1495              (and (eq_attr "type" "imov")
1496                   (and (eq_attr "alternative" "0,1")
1497                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1498                            (const_int 0))))
1499                (const_string "SI")
1500              ;; Avoid partial register stalls when not using QImode arithmetic
1501              (and (eq_attr "type" "imov")
1502                   (and (eq_attr "alternative" "0,1")
1503                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1504                                 (const_int 0))
1505                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1506                                 (const_int 0)))))
1507                (const_string "SI")
1508            ]
1509            (const_string "QI")))])
1510
1511 (define_expand "reload_outqi"
1512   [(parallel [(match_operand:QI 0 "" "=m")
1513               (match_operand:QI 1 "register_operand" "r")
1514               (match_operand:QI 2 "register_operand" "=&q")])]
1515   ""
1516 {
1517   rtx op0, op1, op2;
1518   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1519
1520   if (reg_overlap_mentioned_p (op2, op0))
1521     abort ();
1522   if (! q_regs_operand (op1, QImode))
1523     {
1524       emit_insn (gen_movqi (op2, op1));
1525       op1 = op2;
1526     }
1527   emit_insn (gen_movqi (op0, op1));
1528   DONE;
1529 })
1530
1531 (define_insn "*swapqi_1"
1532   [(set (match_operand:QI 0 "register_operand" "+r")
1533         (match_operand:QI 1 "register_operand" "+r"))
1534    (set (match_dup 1)
1535         (match_dup 0))]
1536   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1537   "xchg{l}\t%k1, %k0"
1538   [(set_attr "type" "imov")
1539    (set_attr "mode" "SI")
1540    (set_attr "pent_pair" "np")
1541    (set_attr "athlon_decode" "vector")])
1542
1543 (define_insn "*swapqi_2"
1544   [(set (match_operand:QI 0 "register_operand" "+q")
1545         (match_operand:QI 1 "register_operand" "+q"))
1546    (set (match_dup 1)
1547         (match_dup 0))]
1548   "TARGET_PARTIAL_REG_STALL"
1549   "xchg{b}\t%1, %0"
1550   [(set_attr "type" "imov")
1551    (set_attr "mode" "QI")
1552    (set_attr "pent_pair" "np")
1553    (set_attr "athlon_decode" "vector")])
1554
1555 (define_expand "movstrictqi"
1556   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1557         (match_operand:QI 1 "general_operand" ""))]
1558   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1559 {
1560   /* Don't generate memory->memory moves, go through a register.  */
1561   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1562     operands[1] = force_reg (QImode, operands[1]);
1563 })
1564
1565 (define_insn "*movstrictqi_1"
1566   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1567         (match_operand:QI 1 "general_operand" "*qn,m"))]
1568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1569    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1570   "mov{b}\t{%1, %0|%0, %1}"
1571   [(set_attr "type" "imov")
1572    (set_attr "mode" "QI")])
1573
1574 (define_insn "*movstrictqi_xor"
1575   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1576         (match_operand:QI 1 "const0_operand" "i"))
1577    (clobber (reg:CC FLAGS_REG))]
1578   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1579   "xor{b}\t{%0, %0|%0, %0}"
1580   [(set_attr "type" "alu1")
1581    (set_attr "mode" "QI")
1582    (set_attr "length_immediate" "0")])
1583
1584 (define_insn "*movsi_extv_1"
1585   [(set (match_operand:SI 0 "register_operand" "=R")
1586         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1587                          (const_int 8)
1588                          (const_int 8)))]
1589   ""
1590   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1591   [(set_attr "type" "imovx")
1592    (set_attr "mode" "SI")])
1593
1594 (define_insn "*movhi_extv_1"
1595   [(set (match_operand:HI 0 "register_operand" "=R")
1596         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1597                          (const_int 8)
1598                          (const_int 8)))]
1599   ""
1600   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1601   [(set_attr "type" "imovx")
1602    (set_attr "mode" "SI")])
1603
1604 (define_insn "*movqi_extv_1"
1605   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1606         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   "!TARGET_64BIT"
1610 {
1611   switch (get_attr_type (insn))
1612     {
1613     case TYPE_IMOVX:
1614       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1615     default:
1616       return "mov{b}\t{%h1, %0|%0, %h1}";
1617     }
1618 }
1619   [(set (attr "type")
1620      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1621                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1622                              (ne (symbol_ref "TARGET_MOVX")
1623                                  (const_int 0))))
1624         (const_string "imovx")
1625         (const_string "imov")))
1626    (set (attr "mode")
1627      (if_then_else (eq_attr "type" "imovx")
1628         (const_string "SI")
1629         (const_string "QI")))])
1630
1631 (define_insn "*movqi_extv_1_rex64"
1632   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1633         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   "TARGET_64BIT"
1637 {
1638   switch (get_attr_type (insn))
1639     {
1640     case TYPE_IMOVX:
1641       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642     default:
1643       return "mov{b}\t{%h1, %0|%0, %h1}";
1644     }
1645 }
1646   [(set (attr "type")
1647      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649                              (ne (symbol_ref "TARGET_MOVX")
1650                                  (const_int 0))))
1651         (const_string "imovx")
1652         (const_string "imov")))
1653    (set (attr "mode")
1654      (if_then_else (eq_attr "type" "imovx")
1655         (const_string "SI")
1656         (const_string "QI")))])
1657
1658 ;; Stores and loads of ax to arbitrary constant address.
1659 ;; We fake an second form of instruction to force reload to load address
1660 ;; into register when rax is not available
1661 (define_insn "*movabsqi_1_rex64"
1662   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1663         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1664   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1665   "@
1666    movabs{b}\t{%1, %P0|%P0, %1}
1667    mov{b}\t{%1, %a0|%a0, %1}"
1668   [(set_attr "type" "imov")
1669    (set_attr "modrm" "0,*")
1670    (set_attr "length_address" "8,0")
1671    (set_attr "length_immediate" "0,*")
1672    (set_attr "memory" "store")
1673    (set_attr "mode" "QI")])
1674
1675 (define_insn "*movabsqi_2_rex64"
1676   [(set (match_operand:QI 0 "register_operand" "=a,r")
1677         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1678   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1679   "@
1680    movabs{b}\t{%P1, %0|%0, %P1}
1681    mov{b}\t{%a1, %0|%0, %a1}"
1682   [(set_attr "type" "imov")
1683    (set_attr "modrm" "0,*")
1684    (set_attr "length_address" "8,0")
1685    (set_attr "length_immediate" "0")
1686    (set_attr "memory" "load")
1687    (set_attr "mode" "QI")])
1688
1689 (define_insn "*movsi_extzv_1"
1690   [(set (match_operand:SI 0 "register_operand" "=R")
1691         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1692                          (const_int 8)
1693                          (const_int 8)))]
1694   ""
1695   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1696   [(set_attr "type" "imovx")
1697    (set_attr "mode" "SI")])
1698
1699 (define_insn "*movqi_extzv_2"
1700   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1701         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1702                                     (const_int 8)
1703                                     (const_int 8)) 0))]
1704   "!TARGET_64BIT"
1705 {
1706   switch (get_attr_type (insn))
1707     {
1708     case TYPE_IMOVX:
1709       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1710     default:
1711       return "mov{b}\t{%h1, %0|%0, %h1}";
1712     }
1713 }
1714   [(set (attr "type")
1715      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1716                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1717                              (ne (symbol_ref "TARGET_MOVX")
1718                                  (const_int 0))))
1719         (const_string "imovx")
1720         (const_string "imov")))
1721    (set (attr "mode")
1722      (if_then_else (eq_attr "type" "imovx")
1723         (const_string "SI")
1724         (const_string "QI")))])
1725
1726 (define_insn "*movqi_extzv_2_rex64"
1727   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1728         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729                                     (const_int 8)
1730                                     (const_int 8)) 0))]
1731   "TARGET_64BIT"
1732 {
1733   switch (get_attr_type (insn))
1734     {
1735     case TYPE_IMOVX:
1736       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737     default:
1738       return "mov{b}\t{%h1, %0|%0, %h1}";
1739     }
1740 }
1741   [(set (attr "type")
1742      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1743                         (ne (symbol_ref "TARGET_MOVX")
1744                             (const_int 0)))
1745         (const_string "imovx")
1746         (const_string "imov")))
1747    (set (attr "mode")
1748      (if_then_else (eq_attr "type" "imovx")
1749         (const_string "SI")
1750         (const_string "QI")))])
1751
1752 (define_insn "movsi_insv_1"
1753   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1754                          (const_int 8)
1755                          (const_int 8))
1756         (match_operand:SI 1 "general_operand" "Qmn"))]
1757   "!TARGET_64BIT"
1758   "mov{b}\t{%b1, %h0|%h0, %b1}"
1759   [(set_attr "type" "imov")
1760    (set_attr "mode" "QI")])
1761
1762 (define_insn "movdi_insv_1_rex64"
1763   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1764                          (const_int 8)
1765                          (const_int 8))
1766         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1767   "TARGET_64BIT"
1768   "mov{b}\t{%b1, %h0|%h0, %b1}"
1769   [(set_attr "type" "imov")
1770    (set_attr "mode" "QI")])
1771
1772 (define_insn "*movqi_insv_2"
1773   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1774                          (const_int 8)
1775                          (const_int 8))
1776         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1777                      (const_int 8)))]
1778   ""
1779   "mov{b}\t{%h1, %h0|%h0, %h1}"
1780   [(set_attr "type" "imov")
1781    (set_attr "mode" "QI")])
1782
1783 (define_expand "movdi"
1784   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1785         (match_operand:DI 1 "general_operand" ""))]
1786   ""
1787   "ix86_expand_move (DImode, operands); DONE;")
1788
1789 (define_insn "*pushdi"
1790   [(set (match_operand:DI 0 "push_operand" "=<")
1791         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1792   "!TARGET_64BIT"
1793   "#")
1794
1795 (define_insn "*pushdi2_rex64"
1796   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1797         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1798   "TARGET_64BIT"
1799   "@
1800    push{q}\t%1
1801    #"
1802   [(set_attr "type" "push,multi")
1803    (set_attr "mode" "DI")])
1804
1805 ;; Convert impossible pushes of immediate to existing instructions.
1806 ;; First try to get scratch register and go through it.  In case this
1807 ;; fails, push sign extended lower part first and then overwrite
1808 ;; upper part by 32bit move.
1809 (define_peephole2
1810   [(match_scratch:DI 2 "r")
1811    (set (match_operand:DI 0 "push_operand" "")
1812         (match_operand:DI 1 "immediate_operand" ""))]
1813   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1814    && !x86_64_immediate_operand (operands[1], DImode)"
1815   [(set (match_dup 2) (match_dup 1))
1816    (set (match_dup 0) (match_dup 2))]
1817   "")
1818
1819 ;; We need to define this as both peepholer and splitter for case
1820 ;; peephole2 pass is not run.
1821 ;; "&& 1" is needed to keep it from matching the previous pattern.
1822 (define_peephole2
1823   [(set (match_operand:DI 0 "push_operand" "")
1824         (match_operand:DI 1 "immediate_operand" ""))]
1825   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1826    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1827   [(set (match_dup 0) (match_dup 1))
1828    (set (match_dup 2) (match_dup 3))]
1829   "split_di (operands + 1, 1, operands + 2, operands + 3);
1830    operands[1] = gen_lowpart (DImode, operands[2]);
1831    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1832                                                     GEN_INT (4)));
1833   ")
1834
1835 (define_split
1836   [(set (match_operand:DI 0 "push_operand" "")
1837         (match_operand:DI 1 "immediate_operand" ""))]
1838   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1839    && !symbolic_operand (operands[1], DImode)
1840    && !x86_64_immediate_operand (operands[1], DImode)"
1841   [(set (match_dup 0) (match_dup 1))
1842    (set (match_dup 2) (match_dup 3))]
1843   "split_di (operands + 1, 1, operands + 2, operands + 3);
1844    operands[1] = gen_lowpart (DImode, operands[2]);
1845    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1846                                                     GEN_INT (4)));
1847   ")
1848
1849 (define_insn "*pushdi2_prologue_rex64"
1850   [(set (match_operand:DI 0 "push_operand" "=<")
1851         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1852    (clobber (mem:BLK (scratch)))]
1853   "TARGET_64BIT"
1854   "push{q}\t%1"
1855   [(set_attr "type" "push")
1856    (set_attr "mode" "DI")])
1857
1858 (define_insn "*popdi1_epilogue_rex64"
1859   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1860         (mem:DI (reg:DI SP_REG)))
1861    (set (reg:DI SP_REG)
1862         (plus:DI (reg:DI SP_REG) (const_int 8)))
1863    (clobber (mem:BLK (scratch)))]
1864   "TARGET_64BIT"
1865   "pop{q}\t%0"
1866   [(set_attr "type" "pop")
1867    (set_attr "mode" "DI")])
1868
1869 (define_insn "popdi1"
1870   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1871         (mem:DI (reg:DI SP_REG)))
1872    (set (reg:DI SP_REG)
1873         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1874   "TARGET_64BIT"
1875   "pop{q}\t%0"
1876   [(set_attr "type" "pop")
1877    (set_attr "mode" "DI")])
1878
1879 (define_insn "*movdi_xor_rex64"
1880   [(set (match_operand:DI 0 "register_operand" "=r")
1881         (match_operand:DI 1 "const0_operand" "i"))
1882    (clobber (reg:CC FLAGS_REG))]
1883   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1884    && reload_completed"
1885   "xor{l}\t{%k0, %k0|%k0, %k0}"
1886   [(set_attr "type" "alu1")
1887    (set_attr "mode" "SI")
1888    (set_attr "length_immediate" "0")])
1889
1890 (define_insn "*movdi_or_rex64"
1891   [(set (match_operand:DI 0 "register_operand" "=r")
1892         (match_operand:DI 1 "const_int_operand" "i"))
1893    (clobber (reg:CC FLAGS_REG))]
1894   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1895    && reload_completed
1896    && operands[1] == constm1_rtx"
1897 {
1898   operands[1] = constm1_rtx;
1899   return "or{q}\t{%1, %0|%0, %1}";
1900 }
1901   [(set_attr "type" "alu1")
1902    (set_attr "mode" "DI")
1903    (set_attr "length_immediate" "1")])
1904
1905 (define_insn "*movdi_2"
1906   [(set (match_operand:DI 0 "nonimmediate_operand"
1907                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1908         (match_operand:DI 1 "general_operand"
1909                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1910   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1911   "@
1912    #
1913    #
1914    pxor\t%0, %0
1915    movq\t{%1, %0|%0, %1}
1916    movq\t{%1, %0|%0, %1}
1917    pxor\t%0, %0
1918    movq\t{%1, %0|%0, %1}
1919    movdqa\t{%1, %0|%0, %1}
1920    movq\t{%1, %0|%0, %1}
1921    xorps\t%0, %0
1922    movlps\t{%1, %0|%0, %1}
1923    movaps\t{%1, %0|%0, %1}
1924    movlps\t{%1, %0|%0, %1}"
1925   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1926    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1927
1928 (define_split
1929   [(set (match_operand:DI 0 "push_operand" "")
1930         (match_operand:DI 1 "general_operand" ""))]
1931   "!TARGET_64BIT && reload_completed
1932    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1933   [(const_int 0)]
1934   "ix86_split_long_move (operands); DONE;")
1935
1936 ;; %%% This multiword shite has got to go.
1937 (define_split
1938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1939         (match_operand:DI 1 "general_operand" ""))]
1940   "!TARGET_64BIT && reload_completed
1941    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1942    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1943   [(const_int 0)]
1944   "ix86_split_long_move (operands); DONE;")
1945
1946 (define_insn "*movdi_1_rex64"
1947   [(set (match_operand:DI 0 "nonimmediate_operand"
1948                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1949         (match_operand:DI 1 "general_operand"
1950                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1951   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1952 {
1953   switch (get_attr_type (insn))
1954     {
1955     case TYPE_SSECVT:
1956       if (which_alternative == 13)
1957         return "movq2dq\t{%1, %0|%0, %1}";
1958       else
1959         return "movdq2q\t{%1, %0|%0, %1}";
1960     case TYPE_SSEMOV:
1961       if (get_attr_mode (insn) == MODE_TI)
1962           return "movdqa\t{%1, %0|%0, %1}";
1963       /* FALLTHRU */
1964     case TYPE_MMXMOV:
1965       /* Moves from and into integer register is done using movd opcode with
1966          REX prefix.  */
1967       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1968           return "movd\t{%1, %0|%0, %1}";
1969       return "movq\t{%1, %0|%0, %1}";
1970     case TYPE_SSELOG1:
1971     case TYPE_MMXADD:
1972       return "pxor\t%0, %0";
1973     case TYPE_MULTI:
1974       return "#";
1975     case TYPE_LEA:
1976       return "lea{q}\t{%a1, %0|%0, %a1}";
1977     default:
1978       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1979         abort ();
1980       if (get_attr_mode (insn) == MODE_SI)
1981         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1982       else if (which_alternative == 2)
1983         return "movabs{q}\t{%1, %0|%0, %1}";
1984       else
1985         return "mov{q}\t{%1, %0|%0, %1}";
1986     }
1987 }
1988   [(set (attr "type")
1989      (cond [(eq_attr "alternative" "5")
1990               (const_string "mmx")
1991             (eq_attr "alternative" "6,7,8")
1992               (const_string "mmxmov")
1993             (eq_attr "alternative" "9")
1994               (const_string "sselog1")
1995             (eq_attr "alternative" "10,11,12")
1996               (const_string "ssemov")
1997             (eq_attr "alternative" "13,14")
1998               (const_string "ssecvt")
1999             (eq_attr "alternative" "4")
2000               (const_string "multi")
2001             (and (ne (symbol_ref "flag_pic") (const_int 0))
2002                  (match_operand:DI 1 "symbolic_operand" ""))
2003               (const_string "lea")
2004            ]
2005            (const_string "imov")))
2006    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2007    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2008    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2009
2010 ;; Stores and loads of ax to arbitrary constant address.
2011 ;; We fake an second form of instruction to force reload to load address
2012 ;; into register when rax is not available
2013 (define_insn "*movabsdi_1_rex64"
2014   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2015         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2016   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2017   "@
2018    movabs{q}\t{%1, %P0|%P0, %1}
2019    mov{q}\t{%1, %a0|%a0, %1}"
2020   [(set_attr "type" "imov")
2021    (set_attr "modrm" "0,*")
2022    (set_attr "length_address" "8,0")
2023    (set_attr "length_immediate" "0,*")
2024    (set_attr "memory" "store")
2025    (set_attr "mode" "DI")])
2026
2027 (define_insn "*movabsdi_2_rex64"
2028   [(set (match_operand:DI 0 "register_operand" "=a,r")
2029         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2030   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2031   "@
2032    movabs{q}\t{%P1, %0|%0, %P1}
2033    mov{q}\t{%a1, %0|%0, %a1}"
2034   [(set_attr "type" "imov")
2035    (set_attr "modrm" "0,*")
2036    (set_attr "length_address" "8,0")
2037    (set_attr "length_immediate" "0")
2038    (set_attr "memory" "load")
2039    (set_attr "mode" "DI")])
2040
2041 ;; Convert impossible stores of immediate to existing instructions.
2042 ;; First try to get scratch register and go through it.  In case this
2043 ;; fails, move by 32bit parts.
2044 (define_peephole2
2045   [(match_scratch:DI 2 "r")
2046    (set (match_operand:DI 0 "memory_operand" "")
2047         (match_operand:DI 1 "immediate_operand" ""))]
2048   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2049    && !x86_64_immediate_operand (operands[1], DImode)"
2050   [(set (match_dup 2) (match_dup 1))
2051    (set (match_dup 0) (match_dup 2))]
2052   "")
2053
2054 ;; We need to define this as both peepholer and splitter for case
2055 ;; peephole2 pass is not run.
2056 ;; "&& 1" is needed to keep it from matching the previous pattern.
2057 (define_peephole2
2058   [(set (match_operand:DI 0 "memory_operand" "")
2059         (match_operand:DI 1 "immediate_operand" ""))]
2060   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2061    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2062   [(set (match_dup 2) (match_dup 3))
2063    (set (match_dup 4) (match_dup 5))]
2064   "split_di (operands, 2, operands + 2, operands + 4);")
2065
2066 (define_split
2067   [(set (match_operand:DI 0 "memory_operand" "")
2068         (match_operand:DI 1 "immediate_operand" ""))]
2069   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2070    && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode)"
2072   [(set (match_dup 2) (match_dup 3))
2073    (set (match_dup 4) (match_dup 5))]
2074   "split_di (operands, 2, operands + 2, operands + 4);")
2075
2076 (define_insn "*swapdi_rex64"
2077   [(set (match_operand:DI 0 "register_operand" "+r")
2078         (match_operand:DI 1 "register_operand" "+r"))
2079    (set (match_dup 1)
2080         (match_dup 0))]
2081   "TARGET_64BIT"
2082   "xchg{q}\t%1, %0"
2083   [(set_attr "type" "imov")
2084    (set_attr "mode" "DI")
2085    (set_attr "pent_pair" "np")
2086    (set_attr "athlon_decode" "vector")])
2087
2088 (define_expand "movti"
2089   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2090         (match_operand:TI 1 "nonimmediate_operand" ""))]
2091   "TARGET_SSE || TARGET_64BIT"
2092 {
2093   if (TARGET_64BIT)
2094     ix86_expand_move (TImode, operands);
2095   else
2096     ix86_expand_vector_move (TImode, operands);
2097   DONE;
2098 })
2099
2100 (define_insn "*movti_internal"
2101   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2102         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2103   "TARGET_SSE && !TARGET_64BIT
2104    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2105 {
2106   switch (which_alternative)
2107     {
2108     case 0:
2109       if (get_attr_mode (insn) == MODE_V4SF)
2110         return "xorps\t%0, %0";
2111       else
2112         return "pxor\t%0, %0";
2113     case 1:
2114     case 2:
2115       if (get_attr_mode (insn) == MODE_V4SF)
2116         return "movaps\t{%1, %0|%0, %1}";
2117       else
2118         return "movdqa\t{%1, %0|%0, %1}";
2119     default:
2120       abort ();
2121     }
2122 }
2123   [(set_attr "type" "ssemov,ssemov,ssemov")
2124    (set (attr "mode")
2125         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2126                  (const_string "V4SF")
2127
2128                (eq_attr "alternative" "0,1")
2129                  (if_then_else
2130                    (ne (symbol_ref "optimize_size")
2131                        (const_int 0))
2132                    (const_string "V4SF")
2133                    (const_string "TI"))
2134                (eq_attr "alternative" "2")
2135                  (if_then_else
2136                    (ne (symbol_ref "optimize_size")
2137                        (const_int 0))
2138                    (const_string "V4SF")
2139                    (const_string "TI"))]
2140                (const_string "TI")))])
2141
2142 (define_insn "*movti_rex64"
2143   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2144         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2145   "TARGET_64BIT
2146    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2147 {
2148   switch (which_alternative)
2149     {
2150     case 0:
2151     case 1:
2152       return "#";
2153     case 2:
2154       if (get_attr_mode (insn) == MODE_V4SF)
2155         return "xorps\t%0, %0";
2156       else
2157         return "pxor\t%0, %0";
2158     case 3:
2159     case 4:
2160       if (get_attr_mode (insn) == MODE_V4SF)
2161         return "movaps\t{%1, %0|%0, %1}";
2162       else
2163         return "movdqa\t{%1, %0|%0, %1}";
2164     default:
2165       abort ();
2166     }
2167 }
2168   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2169    (set (attr "mode")
2170         (cond [(eq_attr "alternative" "2,3")
2171                  (if_then_else
2172                    (ne (symbol_ref "optimize_size")
2173                        (const_int 0))
2174                    (const_string "V4SF")
2175                    (const_string "TI"))
2176                (eq_attr "alternative" "4")
2177                  (if_then_else
2178                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2179                             (const_int 0))
2180                         (ne (symbol_ref "optimize_size")
2181                             (const_int 0)))
2182                    (const_string "V4SF")
2183                    (const_string "TI"))]
2184                (const_string "DI")))])
2185
2186 (define_split
2187   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2188         (match_operand:TI 1 "general_operand" ""))]
2189   "reload_completed && !SSE_REG_P (operands[0])
2190    && !SSE_REG_P (operands[1])"
2191   [(const_int 0)]
2192   "ix86_split_long_move (operands); DONE;")
2193
2194 (define_expand "movsf"
2195   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2196         (match_operand:SF 1 "general_operand" ""))]
2197   ""
2198   "ix86_expand_move (SFmode, operands); DONE;")
2199
2200 (define_insn "*pushsf"
2201   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2202         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2203   "!TARGET_64BIT"
2204 {
2205   switch (which_alternative)
2206     {
2207     case 1:
2208       return "push{l}\t%1";
2209
2210     default:
2211       /* This insn should be already split before reg-stack.  */
2212       abort ();
2213     }
2214 }
2215   [(set_attr "type" "multi,push,multi")
2216    (set_attr "mode" "SF,SI,SF")])
2217
2218 (define_insn "*pushsf_rex64"
2219   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2220         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2221   "TARGET_64BIT"
2222 {
2223   switch (which_alternative)
2224     {
2225     case 1:
2226       return "push{q}\t%q1";
2227
2228     default:
2229       /* This insn should be already split before reg-stack.  */
2230       abort ();
2231     }
2232 }
2233   [(set_attr "type" "multi,push,multi")
2234    (set_attr "mode" "SF,DI,SF")])
2235
2236 (define_split
2237   [(set (match_operand:SF 0 "push_operand" "")
2238         (match_operand:SF 1 "memory_operand" ""))]
2239   "reload_completed
2240    && GET_CODE (operands[1]) == MEM
2241    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2242    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2243   [(set (match_dup 0)
2244         (match_dup 1))]
2245   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2246
2247
2248 ;; %%% Kill this when call knows how to work this out.
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "any_fp_register_operand" ""))]
2252   "!TARGET_64BIT"
2253   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2254    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2255
2256 (define_split
2257   [(set (match_operand:SF 0 "push_operand" "")
2258         (match_operand:SF 1 "any_fp_register_operand" ""))]
2259   "TARGET_64BIT"
2260   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2261    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2262
2263 (define_insn "*movsf_1"
2264   [(set (match_operand:SF 0 "nonimmediate_operand"
2265           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2266         (match_operand:SF 1 "general_operand"
2267           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2268   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2269    && (reload_in_progress || reload_completed
2270        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2271        || GET_CODE (operands[1]) != CONST_DOUBLE
2272        || memory_operand (operands[0], SFmode))" 
2273 {
2274   switch (which_alternative)
2275     {
2276     case 0:
2277       return output_387_reg_move (insn, operands);
2278
2279     case 1:
2280       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2281         return "fstp%z0\t%y0";
2282       else
2283         return "fst%z0\t%y0";
2284
2285     case 2:
2286       return standard_80387_constant_opcode (operands[1]);
2287
2288     case 3:
2289     case 4:
2290       return "mov{l}\t{%1, %0|%0, %1}";
2291     case 5:
2292       if (get_attr_mode (insn) == MODE_TI)
2293         return "pxor\t%0, %0";
2294       else
2295         return "xorps\t%0, %0";
2296     case 6:
2297       if (get_attr_mode (insn) == MODE_V4SF)
2298         return "movaps\t{%1, %0|%0, %1}";
2299       else
2300         return "movss\t{%1, %0|%0, %1}";
2301     case 7:
2302     case 8:
2303       return "movss\t{%1, %0|%0, %1}";
2304
2305     case 9:
2306     case 10:
2307       return "movd\t{%1, %0|%0, %1}";
2308
2309     case 11:
2310       return "movq\t{%1, %0|%0, %1}";
2311
2312     default:
2313       abort();
2314     }
2315 }
2316   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2317    (set (attr "mode")
2318         (cond [(eq_attr "alternative" "3,4,9,10")
2319                  (const_string "SI")
2320                (eq_attr "alternative" "5")
2321                  (if_then_else
2322                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2323                                  (const_int 0))
2324                              (ne (symbol_ref "TARGET_SSE2")
2325                                  (const_int 0)))
2326                         (eq (symbol_ref "optimize_size")
2327                             (const_int 0)))
2328                    (const_string "TI")
2329                    (const_string "V4SF"))
2330                /* For architectures resolving dependencies on
2331                   whole SSE registers use APS move to break dependency
2332                   chains, otherwise use short move to avoid extra work. 
2333
2334                   Do the same for architectures resolving dependencies on
2335                   the parts.  While in DF mode it is better to always handle
2336                   just register parts, the SF mode is different due to lack
2337                   of instructions to load just part of the register.  It is
2338                   better to maintain the whole registers in single format
2339                   to avoid problems on using packed logical operations.  */
2340                (eq_attr "alternative" "6")
2341                  (if_then_else
2342                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2343                             (const_int 0))
2344                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2345                             (const_int 0)))
2346                    (const_string "V4SF")
2347                    (const_string "SF"))
2348                (eq_attr "alternative" "11")
2349                  (const_string "DI")]
2350                (const_string "SF")))])
2351
2352 (define_insn "*swapsf"
2353   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2354         (match_operand:SF 1 "fp_register_operand" "+f"))
2355    (set (match_dup 1)
2356         (match_dup 0))]
2357   "reload_completed || TARGET_80387"
2358 {
2359   if (STACK_TOP_P (operands[0]))
2360     return "fxch\t%1";
2361   else
2362     return "fxch\t%0";
2363 }
2364   [(set_attr "type" "fxch")
2365    (set_attr "mode" "SF")])
2366
2367 (define_expand "movdf"
2368   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2369         (match_operand:DF 1 "general_operand" ""))]
2370   ""
2371   "ix86_expand_move (DFmode, operands); DONE;")
2372
2373 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2374 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2375 ;; On the average, pushdf using integers can be still shorter.  Allow this
2376 ;; pattern for optimize_size too.
2377
2378 (define_insn "*pushdf_nointeger"
2379   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2380         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2381   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2382 {
2383   /* This insn should be already split before reg-stack.  */
2384   abort ();
2385 }
2386   [(set_attr "type" "multi")
2387    (set_attr "mode" "DF,SI,SI,DF")])
2388
2389 (define_insn "*pushdf_integer"
2390   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2391         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2392   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2393 {
2394   /* This insn should be already split before reg-stack.  */
2395   abort ();
2396 }
2397   [(set_attr "type" "multi")
2398    (set_attr "mode" "DF,SI,DF")])
2399
2400 ;; %%% Kill this when call knows how to work this out.
2401 (define_split
2402   [(set (match_operand:DF 0 "push_operand" "")
2403         (match_operand:DF 1 "any_fp_register_operand" ""))]
2404   "!TARGET_64BIT && reload_completed"
2405   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2406    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2407   "")
2408
2409 (define_split
2410   [(set (match_operand:DF 0 "push_operand" "")
2411         (match_operand:DF 1 "any_fp_register_operand" ""))]
2412   "TARGET_64BIT && reload_completed"
2413   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2414    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2415   "")
2416
2417 (define_split
2418   [(set (match_operand:DF 0 "push_operand" "")
2419         (match_operand:DF 1 "general_operand" ""))]
2420   "reload_completed"
2421   [(const_int 0)]
2422   "ix86_split_long_move (operands); DONE;")
2423
2424 ;; Moving is usually shorter when only FP registers are used. This separate
2425 ;; movdf pattern avoids the use of integer registers for FP operations
2426 ;; when optimizing for size.
2427
2428 (define_insn "*movdf_nointeger"
2429   [(set (match_operand:DF 0 "nonimmediate_operand"
2430                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2431         (match_operand:DF 1 "general_operand"
2432                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2433   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2434    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2435    && (reload_in_progress || reload_completed
2436        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2437        || GET_CODE (operands[1]) != CONST_DOUBLE
2438        || memory_operand (operands[0], DFmode))" 
2439 {
2440   switch (which_alternative)
2441     {
2442     case 0:
2443       return output_387_reg_move (insn, operands);
2444
2445     case 1:
2446       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2447         return "fstp%z0\t%y0";
2448       else
2449         return "fst%z0\t%y0";
2450
2451     case 2:
2452       return standard_80387_constant_opcode (operands[1]);
2453
2454     case 3:
2455     case 4:
2456       return "#";
2457     case 5:
2458       switch (get_attr_mode (insn))
2459         {
2460         case MODE_V4SF:
2461           return "xorps\t%0, %0";
2462         case MODE_V2DF:
2463           return "xorpd\t%0, %0";
2464         case MODE_TI:
2465           return "pxor\t%0, %0";
2466         default:
2467           abort ();
2468         }
2469     case 6:
2470     case 7:
2471     case 8:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "movaps\t{%1, %0|%0, %1}";
2476         case MODE_V2DF:
2477           return "movapd\t{%1, %0|%0, %1}";
2478         case MODE_TI:
2479           return "movdqa\t{%1, %0|%0, %1}";
2480         case MODE_DI:
2481           return "movq\t{%1, %0|%0, %1}";
2482         case MODE_DF:
2483           return "movsd\t{%1, %0|%0, %1}";
2484         case MODE_V1DF:
2485           return "movlpd\t{%1, %0|%0, %1}";
2486         case MODE_V2SF:
2487           return "movlps\t{%1, %0|%0, %1}";
2488         default:
2489           abort ();
2490         }
2491
2492     default:
2493       abort();
2494     }
2495 }
2496   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2497    (set (attr "mode")
2498         (cond [(eq_attr "alternative" "0,1,2")
2499                  (const_string "DF")
2500                (eq_attr "alternative" "3,4")
2501                  (const_string "SI")
2502
2503                /* For SSE1, we have many fewer alternatives.  */
2504                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2505                  (cond [(eq_attr "alternative" "5,6")
2506                           (const_string "V4SF")
2507                        ]
2508                    (const_string "V2SF"))
2509
2510                /* xorps is one byte shorter.  */
2511                (eq_attr "alternative" "5")
2512                  (cond [(ne (symbol_ref "optimize_size")
2513                             (const_int 0))
2514                           (const_string "V4SF")
2515                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2516                             (const_int 0))
2517                           (const_string "TI")
2518                        ]
2519                        (const_string "V2DF"))
2520
2521                /* For architectures resolving dependencies on
2522                   whole SSE registers use APD move to break dependency
2523                   chains, otherwise use short move to avoid extra work.
2524
2525                   movaps encodes one byte shorter.  */
2526                (eq_attr "alternative" "6")
2527                  (cond
2528                    [(ne (symbol_ref "optimize_size")
2529                         (const_int 0))
2530                       (const_string "V4SF")
2531                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2532                         (const_int 0))
2533                       (const_string "V2DF")
2534                    ]
2535                    (const_string "DF"))
2536                /* For architectures resolving dependencies on register
2537                   parts we may avoid extra work to zero out upper part
2538                   of register.  */
2539                (eq_attr "alternative" "7")
2540                  (if_then_else
2541                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2542                        (const_int 0))
2543                    (const_string "V1DF")
2544                    (const_string "DF"))
2545               ]
2546               (const_string "DF")))])
2547
2548 (define_insn "*movdf_integer"
2549   [(set (match_operand:DF 0 "nonimmediate_operand"
2550                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2551         (match_operand:DF 1 "general_operand"
2552                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2553   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2554    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2555    && (reload_in_progress || reload_completed
2556        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2557        || GET_CODE (operands[1]) != CONST_DOUBLE
2558        || memory_operand (operands[0], DFmode))" 
2559 {
2560   switch (which_alternative)
2561     {
2562     case 0:
2563       return output_387_reg_move (insn, operands);
2564
2565     case 1:
2566       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2567         return "fstp%z0\t%y0";
2568       else
2569         return "fst%z0\t%y0";
2570
2571     case 2:
2572       return standard_80387_constant_opcode (operands[1]);
2573
2574     case 3:
2575     case 4:
2576       return "#";
2577
2578     case 5:
2579       switch (get_attr_mode (insn))
2580         {
2581         case MODE_V4SF:
2582           return "xorps\t%0, %0";
2583         case MODE_V2DF:
2584           return "xorpd\t%0, %0";
2585         case MODE_TI:
2586           return "pxor\t%0, %0";
2587         default:
2588           abort ();
2589         }
2590     case 6:
2591     case 7:
2592     case 8:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "movaps\t{%1, %0|%0, %1}";
2597         case MODE_V2DF:
2598           return "movapd\t{%1, %0|%0, %1}";
2599         case MODE_TI:
2600           return "movdqa\t{%1, %0|%0, %1}";
2601         case MODE_DI:
2602           return "movq\t{%1, %0|%0, %1}";
2603         case MODE_DF:
2604           return "movsd\t{%1, %0|%0, %1}";
2605         case MODE_V1DF:
2606           return "movlpd\t{%1, %0|%0, %1}";
2607         case MODE_V2SF:
2608           return "movlps\t{%1, %0|%0, %1}";
2609         default:
2610           abort ();
2611         }
2612
2613     default:
2614       abort();
2615     }
2616 }
2617   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2618    (set (attr "mode")
2619         (cond [(eq_attr "alternative" "0,1,2")
2620                  (const_string "DF")
2621                (eq_attr "alternative" "3,4")
2622                  (const_string "SI")
2623
2624                /* For SSE1, we have many fewer alternatives.  */
2625                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2626                  (cond [(eq_attr "alternative" "5,6")
2627                           (const_string "V4SF")
2628                        ]
2629                    (const_string "V2SF"))
2630
2631                /* xorps is one byte shorter.  */
2632                (eq_attr "alternative" "5")
2633                  (cond [(ne (symbol_ref "optimize_size")
2634                             (const_int 0))
2635                           (const_string "V4SF")
2636                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2637                             (const_int 0))
2638                           (const_string "TI")
2639                        ]
2640                        (const_string "V2DF"))
2641
2642                /* For architectures resolving dependencies on
2643                   whole SSE registers use APD move to break dependency
2644                   chains, otherwise use short move to avoid extra work.
2645
2646                   movaps encodes one byte shorter.  */
2647                (eq_attr "alternative" "6")
2648                  (cond
2649                    [(ne (symbol_ref "optimize_size")
2650                         (const_int 0))
2651                       (const_string "V4SF")
2652                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2653                         (const_int 0))
2654                       (const_string "V2DF")
2655                    ]
2656                    (const_string "DF"))
2657                /* For architectures resolving dependencies on register
2658                   parts we may avoid extra work to zero out upper part
2659                   of register.  */
2660                (eq_attr "alternative" "7")
2661                  (if_then_else
2662                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2663                        (const_int 0))
2664                    (const_string "V1DF")
2665                    (const_string "DF"))
2666               ]
2667               (const_string "DF")))])
2668
2669 (define_split
2670   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2671         (match_operand:DF 1 "general_operand" ""))]
2672   "reload_completed
2673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2674    && ! (ANY_FP_REG_P (operands[0]) || 
2675          (GET_CODE (operands[0]) == SUBREG
2676           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2677    && ! (ANY_FP_REG_P (operands[1]) || 
2678          (GET_CODE (operands[1]) == SUBREG
2679           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2680   [(const_int 0)]
2681   "ix86_split_long_move (operands); DONE;")
2682
2683 (define_insn "*swapdf"
2684   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2685         (match_operand:DF 1 "fp_register_operand" "+f"))
2686    (set (match_dup 1)
2687         (match_dup 0))]
2688   "reload_completed || TARGET_80387"
2689 {
2690   if (STACK_TOP_P (operands[0]))
2691     return "fxch\t%1";
2692   else
2693     return "fxch\t%0";
2694 }
2695   [(set_attr "type" "fxch")
2696    (set_attr "mode" "DF")])
2697
2698 (define_expand "movxf"
2699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2700         (match_operand:XF 1 "general_operand" ""))]
2701   ""
2702   "ix86_expand_move (XFmode, operands); DONE;")
2703
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2706 ;; Pushing using integer instructions is longer except for constants
2707 ;; and direct memory references.
2708 ;; (assuming that any given constant is pushed only once, but this ought to be
2709 ;;  handled elsewhere).
2710
2711 (define_insn "*pushxf_nointeger"
2712   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2713         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2714   "optimize_size"
2715 {
2716   /* This insn should be already split before reg-stack.  */
2717   abort ();
2718 }
2719   [(set_attr "type" "multi")
2720    (set_attr "mode" "XF,SI,SI")])
2721
2722 (define_insn "*pushxf_integer"
2723   [(set (match_operand:XF 0 "push_operand" "=<,<")
2724         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2725   "!optimize_size"
2726 {
2727   /* This insn should be already split before reg-stack.  */
2728   abort ();
2729 }
2730   [(set_attr "type" "multi")
2731    (set_attr "mode" "XF,SI")])
2732
2733 (define_split
2734   [(set (match_operand 0 "push_operand" "")
2735         (match_operand 1 "general_operand" ""))]
2736   "reload_completed
2737    && (GET_MODE (operands[0]) == XFmode
2738        || GET_MODE (operands[0]) == DFmode)
2739    && !ANY_FP_REG_P (operands[1])"
2740   [(const_int 0)]
2741   "ix86_split_long_move (operands); DONE;")
2742
2743 (define_split
2744   [(set (match_operand:XF 0 "push_operand" "")
2745         (match_operand:XF 1 "any_fp_register_operand" ""))]
2746   "!TARGET_64BIT"
2747   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2748    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2749   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2750
2751 (define_split
2752   [(set (match_operand:XF 0 "push_operand" "")
2753         (match_operand:XF 1 "any_fp_register_operand" ""))]
2754   "TARGET_64BIT"
2755   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2756    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2757   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2758
2759 ;; Do not use integer registers when optimizing for size
2760 (define_insn "*movxf_nointeger"
2761   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2762         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2763   "optimize_size
2764    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2765    && (reload_in_progress || reload_completed
2766        || GET_CODE (operands[1]) != CONST_DOUBLE
2767        || memory_operand (operands[0], XFmode))" 
2768 {
2769   switch (which_alternative)
2770     {
2771     case 0:
2772       return output_387_reg_move (insn, operands);
2773
2774     case 1:
2775       /* There is no non-popping store to memory for XFmode.  So if
2776          we need one, follow the store with a load.  */
2777       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2778         return "fstp%z0\t%y0\;fld%z0\t%y0";
2779       else
2780         return "fstp%z0\t%y0";
2781
2782     case 2:
2783       return standard_80387_constant_opcode (operands[1]);
2784
2785     case 3: case 4:
2786       return "#";
2787     }
2788   abort();
2789 }
2790   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2791    (set_attr "mode" "XF,XF,XF,SI,SI")])
2792
2793 (define_insn "*movxf_integer"
2794   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2795         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2796   "!optimize_size
2797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2798    && (reload_in_progress || reload_completed
2799        || GET_CODE (operands[1]) != CONST_DOUBLE
2800        || memory_operand (operands[0], XFmode))" 
2801 {
2802   switch (which_alternative)
2803     {
2804     case 0:
2805       return output_387_reg_move (insn, operands);
2806
2807     case 1:
2808       /* There is no non-popping store to memory for XFmode.  So if
2809          we need one, follow the store with a load.  */
2810       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2811         return "fstp%z0\t%y0\;fld%z0\t%y0";
2812       else
2813         return "fstp%z0\t%y0";
2814
2815     case 2:
2816       return standard_80387_constant_opcode (operands[1]);
2817
2818     case 3: case 4:
2819       return "#";
2820     }
2821   abort();
2822 }
2823   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824    (set_attr "mode" "XF,XF,XF,SI,SI")])
2825
2826 (define_split
2827   [(set (match_operand 0 "nonimmediate_operand" "")
2828         (match_operand 1 "general_operand" ""))]
2829   "reload_completed
2830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831    && GET_MODE (operands[0]) == XFmode
2832    && ! (ANY_FP_REG_P (operands[0]) || 
2833          (GET_CODE (operands[0]) == SUBREG
2834           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2835    && ! (ANY_FP_REG_P (operands[1]) || 
2836          (GET_CODE (operands[1]) == SUBREG
2837           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2838   [(const_int 0)]
2839   "ix86_split_long_move (operands); DONE;")
2840
2841 (define_split
2842   [(set (match_operand 0 "register_operand" "")
2843         (match_operand 1 "memory_operand" ""))]
2844   "reload_completed
2845    && GET_CODE (operands[1]) == MEM
2846    && (GET_MODE (operands[0]) == XFmode
2847        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2848    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2849    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2850   [(set (match_dup 0) (match_dup 1))]
2851 {
2852   rtx c = get_pool_constant (XEXP (operands[1], 0));
2853   rtx r = operands[0];
2854
2855   if (GET_CODE (r) == SUBREG)
2856     r = SUBREG_REG (r);
2857
2858   if (SSE_REG_P (r))
2859     {
2860       if (!standard_sse_constant_p (c))
2861         FAIL;
2862     }
2863   else if (FP_REG_P (r))
2864     {
2865       if (!standard_80387_constant_p (c))
2866         FAIL;
2867     }
2868   else if (MMX_REG_P (r))
2869     FAIL;
2870
2871   operands[1] = c;
2872 })
2873
2874 (define_insn "swapxf"
2875   [(set (match_operand:XF 0 "register_operand" "+f")
2876         (match_operand:XF 1 "register_operand" "+f"))
2877    (set (match_dup 1)
2878         (match_dup 0))]
2879   "TARGET_80387"
2880 {
2881   if (STACK_TOP_P (operands[0]))
2882     return "fxch\t%1";
2883   else
2884     return "fxch\t%0";
2885 }
2886   [(set_attr "type" "fxch")
2887    (set_attr "mode" "XF")])
2888
2889 (define_expand "movtf"
2890   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2891         (match_operand:TF 1 "nonimmediate_operand" ""))]
2892   "TARGET_64BIT"
2893 {
2894   ix86_expand_move (TFmode, operands);
2895   DONE;
2896 })
2897
2898 (define_insn "*movtf_internal"
2899   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2900         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2901   "TARGET_64BIT
2902    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2903 {
2904   switch (which_alternative)
2905     {
2906     case 0:
2907     case 1:
2908       return "#";
2909     case 2:
2910       if (get_attr_mode (insn) == MODE_V4SF)
2911         return "xorps\t%0, %0";
2912       else
2913         return "pxor\t%0, %0";
2914     case 3:
2915     case 4:
2916       if (get_attr_mode (insn) == MODE_V4SF)
2917         return "movaps\t{%1, %0|%0, %1}";
2918       else
2919         return "movdqa\t{%1, %0|%0, %1}";
2920     default:
2921       abort ();
2922     }
2923 }
2924   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2925    (set (attr "mode")
2926         (cond [(eq_attr "alternative" "2,3")
2927                  (if_then_else
2928                    (ne (symbol_ref "optimize_size")
2929                        (const_int 0))
2930                    (const_string "V4SF")
2931                    (const_string "TI"))
2932                (eq_attr "alternative" "4")
2933                  (if_then_else
2934                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2935                             (const_int 0))
2936                         (ne (symbol_ref "optimize_size")
2937                             (const_int 0)))
2938                    (const_string "V4SF")
2939                    (const_string "TI"))]
2940                (const_string "DI")))])
2941
2942 (define_split
2943   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2944         (match_operand:TF 1 "general_operand" ""))]
2945   "reload_completed && !SSE_REG_P (operands[0])
2946    && !SSE_REG_P (operands[1])"
2947   [(const_int 0)]
2948   "ix86_split_long_move (operands); DONE;")
2949 \f
2950 ;; Zero extension instructions
2951
2952 (define_expand "zero_extendhisi2"
2953   [(set (match_operand:SI 0 "register_operand" "")
2954      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2955   ""
2956 {
2957   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2958     {
2959       operands[1] = force_reg (HImode, operands[1]);
2960       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2961       DONE;
2962     }
2963 })
2964
2965 (define_insn "zero_extendhisi2_and"
2966   [(set (match_operand:SI 0 "register_operand" "=r")
2967      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2968    (clobber (reg:CC FLAGS_REG))]
2969   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2970   "#"
2971   [(set_attr "type" "alu1")
2972    (set_attr "mode" "SI")])
2973
2974 (define_split
2975   [(set (match_operand:SI 0 "register_operand" "")
2976         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2977    (clobber (reg:CC FLAGS_REG))]
2978   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2979   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2980               (clobber (reg:CC FLAGS_REG))])]
2981   "")
2982
2983 (define_insn "*zero_extendhisi2_movzwl"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2986   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2987   "movz{wl|x}\t{%1, %0|%0, %1}"
2988   [(set_attr "type" "imovx")
2989    (set_attr "mode" "SI")])
2990
2991 (define_expand "zero_extendqihi2"
2992   [(parallel
2993     [(set (match_operand:HI 0 "register_operand" "")
2994        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995      (clobber (reg:CC FLAGS_REG))])]
2996   ""
2997   "")
2998
2999 (define_insn "*zero_extendqihi2_and"
3000   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3001      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3002    (clobber (reg:CC FLAGS_REG))]
3003   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3004   "#"
3005   [(set_attr "type" "alu1")
3006    (set_attr "mode" "HI")])
3007
3008 (define_insn "*zero_extendqihi2_movzbw_and"
3009   [(set (match_operand:HI 0 "register_operand" "=r,r")
3010      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3011    (clobber (reg:CC FLAGS_REG))]
3012   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3013   "#"
3014   [(set_attr "type" "imovx,alu1")
3015    (set_attr "mode" "HI")])
3016
3017 (define_insn "*zero_extendqihi2_movzbw"
3018   [(set (match_operand:HI 0 "register_operand" "=r")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3020   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3021   "movz{bw|x}\t{%1, %0|%0, %1}"
3022   [(set_attr "type" "imovx")
3023    (set_attr "mode" "HI")])
3024
3025 ;; For the movzbw case strip only the clobber
3026 (define_split
3027   [(set (match_operand:HI 0 "register_operand" "")
3028         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "reload_completed 
3031    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3032    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3033   [(set (match_operand:HI 0 "register_operand" "")
3034         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3035
3036 ;; When source and destination does not overlap, clear destination
3037 ;; first and then do the movb
3038 (define_split
3039   [(set (match_operand:HI 0 "register_operand" "")
3040         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3041    (clobber (reg:CC FLAGS_REG))]
3042   "reload_completed
3043    && ANY_QI_REG_P (operands[0])
3044    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3045    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3046   [(set (match_dup 0) (const_int 0))
3047    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3048   "operands[2] = gen_lowpart (QImode, operands[0]);")
3049
3050 ;; Rest is handled by single and.
3051 (define_split
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3054    (clobber (reg:CC FLAGS_REG))]
3055   "reload_completed
3056    && true_regnum (operands[0]) == true_regnum (operands[1])"
3057   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3058               (clobber (reg:CC FLAGS_REG))])]
3059   "")
3060
3061 (define_expand "zero_extendqisi2"
3062   [(parallel
3063     [(set (match_operand:SI 0 "register_operand" "")
3064        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065      (clobber (reg:CC FLAGS_REG))])]
3066   ""
3067   "")
3068
3069 (define_insn "*zero_extendqisi2_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3071      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074   "#"
3075   [(set_attr "type" "alu1")
3076    (set_attr "mode" "SI")])
3077
3078 (define_insn "*zero_extendqisi2_movzbw_and"
3079   [(set (match_operand:SI 0 "register_operand" "=r,r")
3080      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3083   "#"
3084   [(set_attr "type" "imovx,alu1")
3085    (set_attr "mode" "SI")])
3086
3087 (define_insn "*zero_extendqisi2_movzbw"
3088   [(set (match_operand:SI 0 "register_operand" "=r")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3090   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3091   "movz{bl|x}\t{%1, %0|%0, %1}"
3092   [(set_attr "type" "imovx")
3093    (set_attr "mode" "SI")])
3094
3095 ;; For the movzbl case strip only the clobber
3096 (define_split
3097   [(set (match_operand:SI 0 "register_operand" "")
3098         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "reload_completed 
3101    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3102    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3103   [(set (match_dup 0)
3104         (zero_extend:SI (match_dup 1)))])
3105
3106 ;; When source and destination does not overlap, clear destination
3107 ;; first and then do the movb
3108 (define_split
3109   [(set (match_operand:SI 0 "register_operand" "")
3110         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "reload_completed
3113    && ANY_QI_REG_P (operands[0])
3114    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3115    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3116    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3117   [(set (match_dup 0) (const_int 0))
3118    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3119   "operands[2] = gen_lowpart (QImode, operands[0]);")
3120
3121 ;; Rest is handled by single and.
3122 (define_split
3123   [(set (match_operand:SI 0 "register_operand" "")
3124         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "reload_completed
3127    && true_regnum (operands[0]) == true_regnum (operands[1])"
3128   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3129               (clobber (reg:CC FLAGS_REG))])]
3130   "")
3131
3132 ;; %%% Kill me once multi-word ops are sane.
3133 (define_expand "zero_extendsidi2"
3134   [(set (match_operand:DI 0 "register_operand" "=r")
3135      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3136   ""
3137   "if (!TARGET_64BIT)
3138      {
3139        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3140        DONE;
3141      }
3142   ")
3143
3144 (define_insn "zero_extendsidi2_32"
3145   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3146         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3147    (clobber (reg:CC FLAGS_REG))]
3148   "!TARGET_64BIT"
3149   "@
3150    #
3151    #
3152    #
3153    movd\t{%1, %0|%0, %1}
3154    movd\t{%1, %0|%0, %1}"
3155   [(set_attr "mode" "SI,SI,SI,DI,TI")
3156    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3157
3158 (define_insn "zero_extendsidi2_rex64"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3160      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3161   "TARGET_64BIT"
3162   "@
3163    mov\t{%k1, %k0|%k0, %k1}
3164    #
3165    movd\t{%1, %0|%0, %1}
3166    movd\t{%1, %0|%0, %1}"
3167   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3168    (set_attr "mode" "SI,DI,SI,SI")])
3169
3170 (define_split
3171   [(set (match_operand:DI 0 "memory_operand" "")
3172      (zero_extend:DI (match_dup 0)))]
3173   "TARGET_64BIT"
3174   [(set (match_dup 4) (const_int 0))]
3175   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3176
3177 (define_split 
3178   [(set (match_operand:DI 0 "register_operand" "")
3179         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3180    (clobber (reg:CC FLAGS_REG))]
3181   "!TARGET_64BIT && reload_completed
3182    && true_regnum (operands[0]) == true_regnum (operands[1])"
3183   [(set (match_dup 4) (const_int 0))]
3184   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3185
3186 (define_split 
3187   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3188         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3189    (clobber (reg:CC FLAGS_REG))]
3190   "!TARGET_64BIT && reload_completed
3191    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3192   [(set (match_dup 3) (match_dup 1))
3193    (set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195
3196 (define_insn "zero_extendhidi2"
3197   [(set (match_operand:DI 0 "register_operand" "=r,r")
3198      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3199   "TARGET_64BIT"
3200   "@
3201    movz{wl|x}\t{%1, %k0|%k0, %1}
3202    movz{wq|x}\t{%1, %0|%0, %1}"
3203   [(set_attr "type" "imovx")
3204    (set_attr "mode" "SI,DI")])
3205
3206 (define_insn "zero_extendqidi2"
3207   [(set (match_operand:DI 0 "register_operand" "=r,r")
3208      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3209   "TARGET_64BIT"
3210   "@
3211    movz{bl|x}\t{%1, %k0|%k0, %1}
3212    movz{bq|x}\t{%1, %0|%0, %1}"
3213   [(set_attr "type" "imovx")
3214    (set_attr "mode" "SI,DI")])
3215 \f
3216 ;; Sign extension instructions
3217
3218 (define_expand "extendsidi2"
3219   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3220                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3221               (clobber (reg:CC FLAGS_REG))
3222               (clobber (match_scratch:SI 2 ""))])]
3223   ""
3224 {
3225   if (TARGET_64BIT)
3226     {
3227       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3228       DONE;
3229     }
3230 })
3231
3232 (define_insn "*extendsidi2_1"
3233   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3234         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3235    (clobber (reg:CC FLAGS_REG))
3236    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3237   "!TARGET_64BIT"
3238   "#")
3239
3240 (define_insn "extendsidi2_rex64"
3241   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3242         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3243   "TARGET_64BIT"
3244   "@
3245    {cltq|cdqe}
3246    movs{lq|x}\t{%1,%0|%0, %1}"
3247   [(set_attr "type" "imovx")
3248    (set_attr "mode" "DI")
3249    (set_attr "prefix_0f" "0")
3250    (set_attr "modrm" "0,1")])
3251
3252 (define_insn "extendhidi2"
3253   [(set (match_operand:DI 0 "register_operand" "=r")
3254         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3255   "TARGET_64BIT"
3256   "movs{wq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")])
3259
3260 (define_insn "extendqidi2"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3263   "TARGET_64BIT"
3264   "movs{bq|x}\t{%1,%0|%0, %1}"
3265    [(set_attr "type" "imovx")
3266     (set_attr "mode" "DI")])
3267
3268 ;; Extend to memory case when source register does die.
3269 (define_split 
3270   [(set (match_operand:DI 0 "memory_operand" "")
3271         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3272    (clobber (reg:CC FLAGS_REG))
3273    (clobber (match_operand:SI 2 "register_operand" ""))]
3274   "(reload_completed
3275     && dead_or_set_p (insn, operands[1])
3276     && !reg_mentioned_p (operands[1], operands[0]))"
3277   [(set (match_dup 3) (match_dup 1))
3278    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3279               (clobber (reg:CC FLAGS_REG))])
3280    (set (match_dup 4) (match_dup 1))]
3281   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3282
3283 ;; Extend to memory case when source register does not die.
3284 (define_split 
3285   [(set (match_operand:DI 0 "memory_operand" "")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_operand:SI 2 "register_operand" ""))]
3289   "reload_completed"
3290   [(const_int 0)]
3291 {
3292   split_di (&operands[0], 1, &operands[3], &operands[4]);
3293
3294   emit_move_insn (operands[3], operands[1]);
3295
3296   /* Generate a cltd if possible and doing so it profitable.  */
3297   if (true_regnum (operands[1]) == 0
3298       && true_regnum (operands[2]) == 1
3299       && (optimize_size || TARGET_USE_CLTD))
3300     {
3301       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3302     }
3303   else
3304     {
3305       emit_move_insn (operands[2], operands[1]);
3306       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3307     }
3308   emit_move_insn (operands[4], operands[2]);
3309   DONE;
3310 })
3311
3312 ;; Extend to register case.  Optimize case where source and destination
3313 ;; registers match and cases where we can use cltd.
3314 (define_split 
3315   [(set (match_operand:DI 0 "register_operand" "")
3316         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3317    (clobber (reg:CC FLAGS_REG))
3318    (clobber (match_scratch:SI 2 ""))]
3319   "reload_completed"
3320   [(const_int 0)]
3321 {
3322   split_di (&operands[0], 1, &operands[3], &operands[4]);
3323
3324   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3325     emit_move_insn (operands[3], operands[1]);
3326
3327   /* Generate a cltd if possible and doing so it profitable.  */
3328   if (true_regnum (operands[3]) == 0
3329       && (optimize_size || TARGET_USE_CLTD))
3330     {
3331       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3332       DONE;
3333     }
3334
3335   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3336     emit_move_insn (operands[4], operands[1]);
3337
3338   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3339   DONE;
3340 })
3341
3342 (define_insn "extendhisi2"
3343   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3344         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3345   ""
3346 {
3347   switch (get_attr_prefix_0f (insn))
3348     {
3349     case 0:
3350       return "{cwtl|cwde}";
3351     default:
3352       return "movs{wl|x}\t{%1,%0|%0, %1}";
3353     }
3354 }
3355   [(set_attr "type" "imovx")
3356    (set_attr "mode" "SI")
3357    (set (attr "prefix_0f")
3358      ;; movsx is short decodable while cwtl is vector decoded.
3359      (if_then_else (and (eq_attr "cpu" "!k6")
3360                         (eq_attr "alternative" "0"))
3361         (const_string "0")
3362         (const_string "1")))
3363    (set (attr "modrm")
3364      (if_then_else (eq_attr "prefix_0f" "0")
3365         (const_string "0")
3366         (const_string "1")))])
3367
3368 (define_insn "*extendhisi2_zext"
3369   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3370         (zero_extend:DI
3371           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3372   "TARGET_64BIT"
3373 {
3374   switch (get_attr_prefix_0f (insn))
3375     {
3376     case 0:
3377       return "{cwtl|cwde}";
3378     default:
3379       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3380     }
3381 }
3382   [(set_attr "type" "imovx")
3383    (set_attr "mode" "SI")
3384    (set (attr "prefix_0f")
3385      ;; movsx is short decodable while cwtl is vector decoded.
3386      (if_then_else (and (eq_attr "cpu" "!k6")
3387                         (eq_attr "alternative" "0"))
3388         (const_string "0")
3389         (const_string "1")))
3390    (set (attr "modrm")
3391      (if_then_else (eq_attr "prefix_0f" "0")
3392         (const_string "0")
3393         (const_string "1")))])
3394
3395 (define_insn "extendqihi2"
3396   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3397         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3398   ""
3399 {
3400   switch (get_attr_prefix_0f (insn))
3401     {
3402     case 0:
3403       return "{cbtw|cbw}";
3404     default:
3405       return "movs{bw|x}\t{%1,%0|%0, %1}";
3406     }
3407 }
3408   [(set_attr "type" "imovx")
3409    (set_attr "mode" "HI")
3410    (set (attr "prefix_0f")
3411      ;; movsx is short decodable while cwtl is vector decoded.
3412      (if_then_else (and (eq_attr "cpu" "!k6")
3413                         (eq_attr "alternative" "0"))
3414         (const_string "0")
3415         (const_string "1")))
3416    (set (attr "modrm")
3417      (if_then_else (eq_attr "prefix_0f" "0")
3418         (const_string "0")
3419         (const_string "1")))])
3420
3421 (define_insn "extendqisi2"
3422   [(set (match_operand:SI 0 "register_operand" "=r")
3423         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3424   ""
3425   "movs{bl|x}\t{%1,%0|%0, %1}"
3426    [(set_attr "type" "imovx")
3427     (set_attr "mode" "SI")])
3428
3429 (define_insn "*extendqisi2_zext"
3430   [(set (match_operand:DI 0 "register_operand" "=r")
3431         (zero_extend:DI
3432           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3433   "TARGET_64BIT"
3434   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3435    [(set_attr "type" "imovx")
3436     (set_attr "mode" "SI")])
3437 \f
3438 ;; Conversions between float and double.
3439
3440 ;; These are all no-ops in the model used for the 80387.  So just
3441 ;; emit moves.
3442
3443 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3444 (define_insn "*dummy_extendsfdf2"
3445   [(set (match_operand:DF 0 "push_operand" "=<")
3446         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3447   "0"
3448   "#")
3449
3450 (define_split
3451   [(set (match_operand:DF 0 "push_operand" "")
3452         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3453   "!TARGET_64BIT"
3454   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3455    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3456
3457 (define_split
3458   [(set (match_operand:DF 0 "push_operand" "")
3459         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3460   "TARGET_64BIT"
3461   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3462    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3463
3464 (define_insn "*dummy_extendsfxf2"
3465   [(set (match_operand:XF 0 "push_operand" "=<")
3466         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3467   "0"
3468   "#")
3469
3470 (define_split
3471   [(set (match_operand:XF 0 "push_operand" "")
3472         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3473   ""
3474   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3475    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3476   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3477
3478 (define_split
3479   [(set (match_operand:XF 0 "push_operand" "")
3480         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3481   "TARGET_64BIT"
3482   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3483    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3484   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3485
3486 (define_split
3487   [(set (match_operand:XF 0 "push_operand" "")
3488         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3489   ""
3490   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3491    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3492   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493
3494 (define_split
3495   [(set (match_operand:XF 0 "push_operand" "")
3496         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3497   "TARGET_64BIT"
3498   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3499    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3500   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501
3502 (define_expand "extendsfdf2"
3503   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3504         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3505   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3506 {
3507   /* ??? Needed for compress_float_constant since all fp constants
3508      are LEGITIMATE_CONSTANT_P.  */
3509   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3510     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3511   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3512     operands[1] = force_reg (SFmode, operands[1]);
3513 })
3514
3515 (define_insn "*extendsfdf2_mixed"
3516   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3517         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3518   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3519    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3520 {
3521   switch (which_alternative)
3522     {
3523     case 0:
3524       return output_387_reg_move (insn, operands);
3525
3526     case 1:
3527       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3528         return "fstp%z0\t%y0";
3529       else
3530         return "fst%z0\t%y0";
3531
3532     case 2:
3533       return "cvtss2sd\t{%1, %0|%0, %1}";
3534
3535     default:
3536       abort ();
3537     }
3538 }
3539   [(set_attr "type" "fmov,fmov,ssecvt")
3540    (set_attr "mode" "SF,XF,DF")])
3541
3542 (define_insn "*extendsfdf2_sse"
3543   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3544         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3545   "TARGET_SSE2 && TARGET_SSE_MATH
3546    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3547   "cvtss2sd\t{%1, %0|%0, %1}"
3548   [(set_attr "type" "ssecvt")
3549    (set_attr "mode" "DF")])
3550
3551 (define_insn "*extendsfdf2_i387"
3552   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3553         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3554   "TARGET_80387
3555    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3556 {
3557   switch (which_alternative)
3558     {
3559     case 0:
3560       return output_387_reg_move (insn, operands);
3561
3562     case 1:
3563       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3564         return "fstp%z0\t%y0";
3565       else
3566         return "fst%z0\t%y0";
3567
3568     default:
3569       abort ();
3570     }
3571 }
3572   [(set_attr "type" "fmov")
3573    (set_attr "mode" "SF,XF")])
3574
3575 (define_expand "extendsfxf2"
3576   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3577         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3578   "TARGET_80387"
3579 {
3580   /* ??? Needed for compress_float_constant since all fp constants
3581      are LEGITIMATE_CONSTANT_P.  */
3582   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3583     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3584   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3585     operands[1] = force_reg (SFmode, operands[1]);
3586 })
3587
3588 (define_insn "*extendsfxf2_i387"
3589   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3590         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3591   "TARGET_80387
3592    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3593 {
3594   switch (which_alternative)
3595     {
3596     case 0:
3597       return output_387_reg_move (insn, operands);
3598
3599     case 1:
3600       /* There is no non-popping store to memory for XFmode.  So if
3601          we need one, follow the store with a load.  */
3602       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603         return "fstp%z0\t%y0";
3604       else
3605         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3606
3607     default:
3608       abort ();
3609     }
3610 }
3611   [(set_attr "type" "fmov")
3612    (set_attr "mode" "SF,XF")])
3613
3614 (define_expand "extenddfxf2"
3615   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3616         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3617   "TARGET_80387"
3618 {
3619   /* ??? Needed for compress_float_constant since all fp constants
3620      are LEGITIMATE_CONSTANT_P.  */
3621   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3622     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3623   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3624     operands[1] = force_reg (DFmode, operands[1]);
3625 })
3626
3627 (define_insn "*extenddfxf2_i387"
3628   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3629         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3630   "TARGET_80387
3631    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3632 {
3633   switch (which_alternative)
3634     {
3635     case 0:
3636       return output_387_reg_move (insn, operands);
3637
3638     case 1:
3639       /* There is no non-popping store to memory for XFmode.  So if
3640          we need one, follow the store with a load.  */
3641       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3642         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3643       else
3644         return "fstp%z0\t%y0";
3645
3646     default:
3647       abort ();
3648     }
3649 }
3650   [(set_attr "type" "fmov")
3651    (set_attr "mode" "DF,XF")])
3652
3653 ;; %%% This seems bad bad news.
3654 ;; This cannot output into an f-reg because there is no way to be sure
3655 ;; of truncating in that case.  Otherwise this is just like a simple move
3656 ;; insn.  So we pretend we can output to a reg in order to get better
3657 ;; register preferencing, but we really use a stack slot.
3658
3659 ;; Conversion from DFmode to SFmode.
3660
3661 (define_expand "truncdfsf2"
3662   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3663         (float_truncate:SF
3664           (match_operand:DF 1 "nonimmediate_operand" "")))]
3665   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3666 {
3667   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3668     operands[1] = force_reg (DFmode, operands[1]);
3669
3670   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3671     ;
3672   else if (flag_unsafe_math_optimizations)
3673     ;
3674   else
3675     {
3676       rtx temp = assign_386_stack_local (SFmode, 0);
3677       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3678       DONE;
3679     }
3680 })
3681
3682 (define_expand "truncdfsf2_with_temp"
3683   [(parallel [(set (match_operand:SF 0 "" "")
3684                    (float_truncate:SF (match_operand:DF 1 "" "")))
3685               (clobber (match_operand:SF 2 "" ""))])]
3686   "")
3687
3688 (define_insn "*truncdfsf_fast_mixed"
3689   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3690         (float_truncate:SF
3691           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3692   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3693 {
3694   switch (which_alternative)
3695     {
3696     case 0:
3697       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3698         return "fstp%z0\t%y0";
3699       else
3700         return "fst%z0\t%y0";
3701     case 1:
3702       return output_387_reg_move (insn, operands);
3703     case 2:
3704       return "cvtsd2ss\t{%1, %0|%0, %1}";
3705     default:
3706       abort ();
3707     }
3708 }
3709   [(set_attr "type" "fmov,fmov,ssecvt")
3710    (set_attr "mode" "SF")])
3711
3712 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3713 ;; because nothing we do here is unsafe.
3714 (define_insn "*truncdfsf_fast_sse"
3715   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3716         (float_truncate:SF
3717           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3718   "TARGET_SSE2 && TARGET_SSE_MATH"
3719   "cvtsd2ss\t{%1, %0|%0, %1}"
3720   [(set_attr "type" "ssecvt")
3721    (set_attr "mode" "SF")])
3722
3723 (define_insn "*truncdfsf_fast_i387"
3724   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3727   "TARGET_80387 && flag_unsafe_math_optimizations"
3728   "* return output_387_reg_move (insn, operands);"
3729   [(set_attr "type" "fmov")
3730    (set_attr "mode" "SF")])
3731
3732 (define_insn "*truncdfsf_mixed"
3733   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3734         (float_truncate:SF
3735           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3736    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3737   "TARGET_MIX_SSE_I387"
3738 {
3739   switch (which_alternative)
3740     {
3741     case 0:
3742       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3743         return "fstp%z0\t%y0";
3744       else
3745         return "fst%z0\t%y0";
3746     case 1:
3747       return "#";
3748     case 2:
3749       return "cvtsd2ss\t{%1, %0|%0, %1}";
3750     default:
3751       abort ();
3752     }
3753 }
3754   [(set_attr "type" "fmov,multi,ssecvt")
3755    (set_attr "mode" "SF")])
3756
3757 (define_insn "*truncdfsf_i387"
3758   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3759         (float_truncate:SF
3760           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3761    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3762   "TARGET_80387"
3763 {
3764   switch (which_alternative)
3765     {
3766     case 0:
3767       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768         return "fstp%z0\t%y0";
3769       else
3770         return "fst%z0\t%y0";
3771     case 1:
3772       return "#";
3773     default:
3774       abort ();
3775     }
3776 }
3777   [(set_attr "type" "fmov,multi")
3778    (set_attr "mode" "SF")])
3779
3780 (define_insn "*truncdfsf2_i387_1"
3781   [(set (match_operand:SF 0 "memory_operand" "=m")
3782         (float_truncate:SF
3783           (match_operand:DF 1 "register_operand" "f")))]
3784   "TARGET_80387
3785    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3786    && !TARGET_MIX_SSE_I387"
3787 {
3788   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789     return "fstp%z0\t%y0";
3790   else
3791     return "fst%z0\t%y0";
3792 }
3793   [(set_attr "type" "fmov")
3794    (set_attr "mode" "SF")])
3795
3796 (define_split
3797   [(set (match_operand:SF 0 "register_operand" "")
3798         (float_truncate:SF
3799          (match_operand:DF 1 "fp_register_operand" "")))
3800    (clobber (match_operand 2 "" ""))]
3801   "reload_completed"
3802   [(set (match_dup 2) (match_dup 1))
3803    (set (match_dup 0) (match_dup 2))]
3804 {
3805   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3806 })
3807
3808 ;; Conversion from XFmode to SFmode.
3809
3810 (define_expand "truncxfsf2"
3811   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812                    (float_truncate:SF
3813                     (match_operand:XF 1 "register_operand" "")))
3814               (clobber (match_dup 2))])]
3815   "TARGET_80387"
3816 {
3817   if (flag_unsafe_math_optimizations)
3818     {
3819       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3821       if (reg != operands[0])
3822         emit_move_insn (operands[0], reg);
3823       DONE;
3824     }
3825   else
3826     operands[2] = assign_386_stack_local (SFmode, 0);
3827 })
3828
3829 (define_insn "*truncxfsf2_mixed"
3830   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3831         (float_truncate:SF
3832          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3833    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3834   "TARGET_MIX_SSE_I387"
3835 {
3836   switch (which_alternative)
3837     {
3838     case 0:
3839       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840         return "fstp%z0\t%y0";
3841       else
3842         return "fst%z0\t%y0";
3843     default:
3844       abort();
3845     }
3846 }
3847   [(set_attr "type" "fmov,multi,multi,multi")
3848    (set_attr "mode" "SF")])
3849
3850 (define_insn "truncxfsf2_i387_noop"
3851   [(set (match_operand:SF 0 "register_operand" "=f")
3852         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3853   "TARGET_80387 && flag_unsafe_math_optimizations"
3854 {
3855   return output_387_reg_move (insn, operands);
3856 }
3857   [(set_attr "type" "fmov")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_i387"
3861   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f,f,f")))
3864    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3865   "TARGET_80387"
3866 {
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871         return "fstp%z0\t%y0";
3872       else
3873         return "fst%z0\t%y0";
3874     default:
3875       abort ();
3876     }
3877 }
3878   [(set_attr "type" "fmov,multi,multi")
3879    (set_attr "mode" "SF")])
3880
3881 (define_insn "*truncxfsf2_i387_1"
3882   [(set (match_operand:SF 0 "memory_operand" "=m")
3883         (float_truncate:SF
3884          (match_operand:XF 1 "register_operand" "f")))]
3885   "TARGET_80387"
3886 {
3887   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3888     return "fstp%z0\t%y0";
3889   else
3890     return "fst%z0\t%y0";
3891 }
3892   [(set_attr "type" "fmov")
3893    (set_attr "mode" "SF")])
3894
3895 (define_split
3896   [(set (match_operand:SF 0 "register_operand" "")
3897         (float_truncate:SF
3898          (match_operand:XF 1 "register_operand" "")))
3899    (clobber (match_operand:SF 2 "memory_operand" ""))]
3900   "TARGET_80387 && reload_completed"
3901   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3902    (set (match_dup 0) (match_dup 2))]
3903   "")
3904
3905 (define_split
3906   [(set (match_operand:SF 0 "memory_operand" "")
3907         (float_truncate:SF
3908          (match_operand:XF 1 "register_operand" "")))
3909    (clobber (match_operand:SF 2 "memory_operand" ""))]
3910   "TARGET_80387"
3911   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3912   "")
3913
3914 ;; Conversion from XFmode to DFmode.
3915
3916 (define_expand "truncxfdf2"
3917   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3918                    (float_truncate:DF
3919                     (match_operand:XF 1 "register_operand" "")))
3920               (clobber (match_dup 2))])]
3921   "TARGET_80387"
3922 {
3923   if (flag_unsafe_math_optimizations)
3924     {
3925       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3926       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3927       if (reg != operands[0])
3928         emit_move_insn (operands[0], reg);
3929       DONE;
3930     }
3931   else
3932     operands[2] = assign_386_stack_local (DFmode, 0);
3933 })
3934
3935 (define_insn "*truncxfdf2_mixed"
3936   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3937         (float_truncate:DF
3938          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3939    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3940   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3941 {
3942   switch (which_alternative)
3943     {
3944     case 0:
3945       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946         return "fstp%z0\t%y0";
3947       else
3948         return "fst%z0\t%y0";
3949     default:
3950       abort();
3951     }
3952   abort ();
3953 }
3954   [(set_attr "type" "fmov,multi,multi,multi")
3955    (set_attr "mode" "DF")])
3956
3957 (define_insn "truncxfdf2_i387_noop"
3958   [(set (match_operand:DF 0 "register_operand" "=f")
3959         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3960   "TARGET_80387 && flag_unsafe_math_optimizations"
3961 {
3962   return output_387_reg_move (insn, operands);
3963 }
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "DF")])
3966
3967 (define_insn "*truncxfdf2_i387"
3968   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "f,f,f")))
3971    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3972   "TARGET_80387"
3973 {
3974   switch (which_alternative)
3975     {
3976     case 0:
3977       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978         return "fstp%z0\t%y0";
3979       else
3980         return "fst%z0\t%y0";
3981     default:
3982       abort ();
3983     }
3984 }
3985   [(set_attr "type" "fmov,multi,multi")
3986    (set_attr "mode" "DF")])
3987
3988 (define_insn "*truncxfdf2_i387_1"
3989   [(set (match_operand:DF 0 "memory_operand" "=m")
3990         (float_truncate:DF
3991           (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387"
3993 {
3994   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995     return "fstp%z0\t%y0";
3996   else
3997     return "fst%z0\t%y0";
3998 }
3999   [(set_attr "type" "fmov")
4000    (set_attr "mode" "DF")])
4001
4002 (define_split
4003   [(set (match_operand:DF 0 "register_operand" "")
4004         (float_truncate:DF
4005          (match_operand:XF 1 "register_operand" "")))
4006    (clobber (match_operand:DF 2 "memory_operand" ""))]
4007   "TARGET_80387 && reload_completed"
4008   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4009    (set (match_dup 0) (match_dup 2))]
4010   "")
4011
4012 (define_split
4013   [(set (match_operand:DF 0 "memory_operand" "")
4014         (float_truncate:DF
4015          (match_operand:XF 1 "register_operand" "")))
4016    (clobber (match_operand:DF 2 "memory_operand" ""))]
4017   "TARGET_80387"
4018   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4019   "")
4020 \f
4021 ;; Signed conversion to DImode.
4022
4023 (define_expand "fix_truncxfdi2"
4024   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4025                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4026               (clobber (reg:CC FLAGS_REG))])]
4027   "TARGET_80387"
4028 {
4029   if (TARGET_FISTTP)
4030    {
4031      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4032      DONE;
4033    }
4034 })
4035
4036 (define_expand "fix_trunc<mode>di2"
4037   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4038                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4039               (clobber (reg:CC FLAGS_REG))])]
4040   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4041 {
4042   if (TARGET_FISTTP
4043       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4044    {
4045      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4046      DONE;
4047    }
4048   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4049    {
4050      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4051      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4052      if (out != operands[0])
4053         emit_move_insn (operands[0], out);
4054      DONE;
4055    }
4056 })
4057
4058 ;; Signed conversion to SImode.
4059
4060 (define_expand "fix_truncxfsi2"
4061   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4062                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4063               (clobber (reg:CC FLAGS_REG))])]
4064   "TARGET_80387"
4065 {
4066   if (TARGET_FISTTP)
4067    {
4068      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4069      DONE;
4070    }
4071 })
4072
4073 (define_expand "fix_trunc<mode>si2"
4074   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4075                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4076               (clobber (reg:CC FLAGS_REG))])]
4077   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4078 {
4079   if (TARGET_FISTTP
4080       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4081    {
4082      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4083      DONE;
4084    }
4085   if (SSE_FLOAT_MODE_P (<MODE>mode))
4086    {
4087      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4088      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4089      if (out != operands[0])
4090         emit_move_insn (operands[0], out);
4091      DONE;
4092    }
4093 })
4094
4095 ;; Signed conversion to HImode.
4096
4097 (define_expand "fix_trunc<mode>hi2"
4098   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4099                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4100               (clobber (reg:CC FLAGS_REG))])]
4101   "TARGET_80387
4102    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4103 {
4104   if (TARGET_FISTTP)
4105    {
4106      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4107      DONE;
4108    }
4109 })
4110
4111 ;; When SSE is available, it is always faster to use it!
4112 (define_insn "fix_truncsfdi_sse"
4113   [(set (match_operand:DI 0 "register_operand" "=r,r")
4114         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4115   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4116   "cvttss2si{q}\t{%1, %0|%0, %1}"
4117   [(set_attr "type" "sseicvt")
4118    (set_attr "mode" "SF")
4119    (set_attr "athlon_decode" "double,vector")])
4120
4121 (define_insn "fix_truncdfdi_sse"
4122   [(set (match_operand:DI 0 "register_operand" "=r,r")
4123         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4124   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4125   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4126   [(set_attr "type" "sseicvt")
4127    (set_attr "mode" "DF")
4128    (set_attr "athlon_decode" "double,vector")])
4129
4130 (define_insn "fix_truncsfsi_sse"
4131   [(set (match_operand:SI 0 "register_operand" "=r,r")
4132         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4133   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4134   "cvttss2si\t{%1, %0|%0, %1}"
4135   [(set_attr "type" "sseicvt")
4136    (set_attr "mode" "DF")
4137    (set_attr "athlon_decode" "double,vector")])
4138
4139 (define_insn "fix_truncdfsi_sse"
4140   [(set (match_operand:SI 0 "register_operand" "=r,r")
4141         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4142   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4143   "cvttsd2si\t{%1, %0|%0, %1}"
4144   [(set_attr "type" "sseicvt")
4145    (set_attr "mode" "DF")
4146    (set_attr "athlon_decode" "double,vector")])
4147
4148 ;; Avoid vector decoded forms of the instruction.
4149 (define_peephole2
4150   [(match_scratch:DF 2 "Y")
4151    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4152         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4153   "TARGET_K8 && !optimize_size"
4154   [(set (match_dup 2) (match_dup 1))
4155    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4156   "")
4157
4158 (define_peephole2
4159   [(match_scratch:SF 2 "x")
4160    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4161         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4162   "TARGET_K8 && !optimize_size"
4163   [(set (match_dup 2) (match_dup 1))
4164    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4165   "")
4166
4167 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4168   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4169         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4170   "TARGET_80387 && TARGET_FISTTP
4171    && FLOAT_MODE_P (GET_MODE (operands[1]))
4172    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4173          && (TARGET_64BIT || <MODE>mode != DImode))
4174         && TARGET_SSE_MATH)
4175    && !(reload_completed || reload_in_progress)"
4176   "#"
4177   "&& 1"
4178   [(const_int 0)]
4179 {
4180   if (memory_operand (operands[0], VOIDmode))
4181     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4182   else
4183     {
4184       operands[2] = assign_386_stack_local (<MODE>mode, 0);
4185       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4186                                                             operands[1],
4187                                                             operands[2]));
4188     }
4189   DONE;
4190 }
4191   [(set_attr "type" "fisttp")
4192    (set_attr "mode" "<MODE>")])
4193
4194 (define_insn "fix_trunc<mode>_i387_fisttp"
4195   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4196         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4197    (clobber (match_scratch:XF 2 "=&1f"))]
4198   "TARGET_80387 && TARGET_FISTTP
4199    && FLOAT_MODE_P (GET_MODE (operands[1]))
4200    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201          && (TARGET_64BIT || <MODE>mode != DImode))
4202         && TARGET_SSE_MATH)"
4203   "* return output_fix_trunc (insn, operands, 1);"
4204   [(set_attr "type" "fisttp")
4205    (set_attr "mode" "<MODE>")])
4206
4207 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4208   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4209         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4210    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4211    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4212   "TARGET_80387 && TARGET_FISTTP
4213    && FLOAT_MODE_P (GET_MODE (operands[1]))
4214    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4215         && (TARGET_64BIT || <MODE>mode != DImode))
4216         && TARGET_SSE_MATH)"
4217   "#"
4218   [(set_attr "type" "fisttp")
4219    (set_attr "mode" "<MODE>")])
4220
4221 (define_split
4222   [(set (match_operand:X87MODEI 0 "register_operand" "")
4223         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4224    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4225    (clobber (match_scratch 3 ""))]
4226   "reload_completed"
4227   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4228               (clobber (match_dup 3))])
4229    (set (match_dup 0) (match_dup 2))]
4230   "")
4231
4232 (define_split
4233   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4234         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4235    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4236    (clobber (match_scratch 3 ""))]
4237   "reload_completed"
4238   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4239               (clobber (match_dup 3))])]
4240   "")
4241
4242 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4243 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4244 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4245 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4246 ;; function in i386.c.
4247 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4248   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4249         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4250    (clobber (reg:CC FLAGS_REG))]
4251   "TARGET_80387 && !TARGET_FISTTP
4252    && FLOAT_MODE_P (GET_MODE (operands[1]))
4253    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4254          && (TARGET_64BIT || <MODE>mode != DImode))
4255    && !(reload_completed || reload_in_progress)"
4256   "#"
4257   "&& 1"
4258   [(const_int 0)]
4259 {
4260   ix86_optimize_mode_switching = 1;
4261   operands[2] = assign_386_stack_local (HImode, 1);
4262   operands[3] = assign_386_stack_local (HImode, 2);
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265                                          operands[2], operands[3]));
4266   else
4267     {
4268       operands[4] = assign_386_stack_local (<MODE>mode, 0);
4269       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270                                                      operands[2], operands[3],
4271                                                      operands[4]));
4272     }
4273   DONE;
4274 }
4275   [(set_attr "type" "fistp")
4276    (set_attr "i387_cw" "trunc")
4277    (set_attr "mode" "<MODE>")])
4278
4279 (define_insn "fix_truncdi_i387"
4280   [(set (match_operand:DI 0 "memory_operand" "=m")
4281         (fix:DI (match_operand 1 "register_operand" "f")))
4282    (use (match_operand:HI 2 "memory_operand" "m"))
4283    (use (match_operand:HI 3 "memory_operand" "m"))
4284    (clobber (match_scratch:XF 4 "=&1f"))]
4285   "TARGET_80387 && !TARGET_FISTTP
4286    && FLOAT_MODE_P (GET_MODE (operands[1]))
4287    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288   "* return output_fix_trunc (insn, operands, 0);"
4289   [(set_attr "type" "fistp")
4290    (set_attr "i387_cw" "trunc")
4291    (set_attr "mode" "DI")])
4292
4293 (define_insn "fix_truncdi_i387_with_temp"
4294   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295         (fix:DI (match_operand 1 "register_operand" "f,f")))
4296    (use (match_operand:HI 2 "memory_operand" "m,m"))
4297    (use (match_operand:HI 3 "memory_operand" "m,m"))
4298    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300   "TARGET_80387 && !TARGET_FISTTP
4301    && FLOAT_MODE_P (GET_MODE (operands[1]))
4302    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4303   "#"
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "DI")])
4307
4308 (define_split 
4309   [(set (match_operand:DI 0 "register_operand" "")
4310         (fix:DI (match_operand 1 "register_operand" "")))
4311    (use (match_operand:HI 2 "memory_operand" ""))
4312    (use (match_operand:HI 3 "memory_operand" ""))
4313    (clobber (match_operand:DI 4 "memory_operand" ""))
4314    (clobber (match_scratch 5 ""))]
4315   "reload_completed"
4316   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317               (use (match_dup 2))
4318               (use (match_dup 3))
4319               (clobber (match_dup 5))])
4320    (set (match_dup 0) (match_dup 4))]
4321   "")
4322
4323 (define_split 
4324   [(set (match_operand:DI 0 "memory_operand" "")
4325         (fix:DI (match_operand 1 "register_operand" "")))
4326    (use (match_operand:HI 2 "memory_operand" ""))
4327    (use (match_operand:HI 3 "memory_operand" ""))
4328    (clobber (match_operand:DI 4 "memory_operand" ""))
4329    (clobber (match_scratch 5 ""))]
4330   "reload_completed"
4331   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4332               (use (match_dup 2))
4333               (use (match_dup 3))
4334               (clobber (match_dup 5))])]
4335   "")
4336
4337 (define_insn "fix_trunc<mode>_i387"
4338   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340    (use (match_operand:HI 2 "memory_operand" "m"))
4341    (use (match_operand:HI 3 "memory_operand" "m"))]
4342   "TARGET_80387 && !TARGET_FISTTP
4343    && FLOAT_MODE_P (GET_MODE (operands[1]))
4344    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345   "* return output_fix_trunc (insn, operands, 0);"
4346   [(set_attr "type" "fistp")
4347    (set_attr "i387_cw" "trunc")
4348    (set_attr "mode" "<MODE>")])
4349
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353    (use (match_operand:HI 2 "memory_operand" "m,m"))
4354    (use (match_operand:HI 3 "memory_operand" "m,m"))
4355    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356   "TARGET_80387 && !TARGET_FISTTP
4357    && FLOAT_MODE_P (GET_MODE (operands[1]))
4358    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4359   "#"
4360   [(set_attr "type" "fistp")
4361    (set_attr "i387_cw" "trunc")
4362    (set_attr "mode" "<MODE>")])
4363
4364 (define_split 
4365   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367    (use (match_operand:HI 2 "memory_operand" ""))
4368    (use (match_operand:HI 3 "memory_operand" ""))
4369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4370   "reload_completed"
4371   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4372               (use (match_dup 2))
4373               (use (match_dup 3))])
4374    (set (match_dup 0) (match_dup 4))]
4375   "")
4376
4377 (define_split 
4378   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380    (use (match_operand:HI 2 "memory_operand" ""))
4381    (use (match_operand:HI 3 "memory_operand" ""))
4382    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4383   "reload_completed"
4384   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4385               (use (match_dup 2))
4386               (use (match_dup 3))])]
4387   "")
4388
4389 (define_insn "x86_fnstcw_1"
4390   [(set (match_operand:HI 0 "memory_operand" "=m")
4391         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4392   "TARGET_80387"
4393   "fnstcw\t%0"
4394   [(set_attr "length" "2")
4395    (set_attr "mode" "HI")
4396    (set_attr "unit" "i387")])
4397
4398 (define_insn "x86_fldcw_1"
4399   [(set (reg:HI FPSR_REG)
4400         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4401   "TARGET_80387"
4402   "fldcw\t%0"
4403   [(set_attr "length" "2")
4404    (set_attr "mode" "HI")
4405    (set_attr "unit" "i387")
4406    (set_attr "athlon_decode" "vector")])
4407 \f
4408 ;; Conversion between fixed point and floating point.
4409
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4412
4413 (define_expand "floathisf2"
4414   [(set (match_operand:SF 0 "register_operand" "")
4415         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416   "TARGET_80387 || TARGET_SSE_MATH"
4417 {
4418   if (TARGET_SSE_MATH)
4419     {
4420       emit_insn (gen_floatsisf2 (operands[0],
4421                                  convert_to_mode (SImode, operands[1], 0)));
4422       DONE;
4423     }
4424 })
4425
4426 (define_insn "*floathisf2_i387"
4427   [(set (match_operand:SF 0 "register_operand" "=f,f")
4428         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4430   "@
4431    fild%z1\t%1
4432    #"
4433   [(set_attr "type" "fmov,multi")
4434    (set_attr "mode" "SF")
4435    (set_attr "fp_int_src" "true")])
4436
4437 (define_expand "floatsisf2"
4438   [(set (match_operand:SF 0 "register_operand" "")
4439         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4440   "TARGET_80387 || TARGET_SSE_MATH"
4441   "")
4442
4443 (define_insn "*floatsisf2_mixed"
4444   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4445         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4446   "TARGET_MIX_SSE_I387"
4447   "@
4448    fild%z1\t%1
4449    #
4450    cvtsi2ss\t{%1, %0|%0, %1}
4451    cvtsi2ss\t{%1, %0|%0, %1}"
4452   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4453    (set_attr "mode" "SF")
4454    (set_attr "athlon_decode" "*,*,vector,double")
4455    (set_attr "fp_int_src" "true")])
4456
4457 (define_insn "*floatsisf2_sse"
4458   [(set (match_operand:SF 0 "register_operand" "=x,x")
4459         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4460   "TARGET_SSE_MATH"
4461   "cvtsi2ss\t{%1, %0|%0, %1}"
4462   [(set_attr "type" "sseicvt")
4463    (set_attr "mode" "SF")
4464    (set_attr "athlon_decode" "vector,double")
4465    (set_attr "fp_int_src" "true")])
4466
4467 (define_insn "*floatsisf2_i387"
4468   [(set (match_operand:SF 0 "register_operand" "=f,f")
4469         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4470   "TARGET_80387"
4471   "@
4472    fild%z1\t%1
4473    #"
4474   [(set_attr "type" "fmov,multi")
4475    (set_attr "mode" "SF")
4476    (set_attr "fp_int_src" "true")])
4477
4478 (define_expand "floatdisf2"
4479   [(set (match_operand:SF 0 "register_operand" "")
4480         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4481   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4482   "")
4483
4484 (define_insn "*floatdisf2_mixed"
4485   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4488   "@
4489    fild%z1\t%1
4490    #
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}
4492    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "athlon_decode" "*,*,vector,double")
4496    (set_attr "fp_int_src" "true")])
4497
4498 (define_insn "*floatdisf2_sse"
4499   [(set (match_operand:SF 0 "register_operand" "=x,x")
4500         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501   "TARGET_64BIT && TARGET_SSE_MATH"
4502   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "vector,double")
4506    (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "fp_int_src" "true")])
4518
4519 (define_expand "floathidf2"
4520   [(set (match_operand:DF 0 "register_operand" "")
4521         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4522   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4523 {
4524   if (TARGET_SSE2 && TARGET_SSE_MATH)
4525     {
4526       emit_insn (gen_floatsidf2 (operands[0],
4527                                  convert_to_mode (SImode, operands[1], 0)));
4528       DONE;
4529     }
4530 })
4531
4532 (define_insn "*floathidf2_i387"
4533   [(set (match_operand:DF 0 "register_operand" "=f,f")
4534         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4535   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4536   "@
4537    fild%z1\t%1
4538    #"
4539   [(set_attr "type" "fmov,multi")
4540    (set_attr "mode" "DF")
4541    (set_attr "fp_int_src" "true")])
4542
4543 (define_expand "floatsidf2"
4544   [(set (match_operand:DF 0 "register_operand" "")
4545         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4546   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4547   "")
4548
4549 (define_insn "*floatsidf2_mixed"
4550   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4551         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4552   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4553   "@
4554    fild%z1\t%1
4555    #
4556    cvtsi2sd\t{%1, %0|%0, %1}
4557    cvtsi2sd\t{%1, %0|%0, %1}"
4558   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4559    (set_attr "mode" "DF")
4560    (set_attr "athlon_decode" "*,*,double,direct")
4561    (set_attr "fp_int_src" "true")])
4562
4563 (define_insn "*floatsidf2_sse"
4564   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4565         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4566   "TARGET_SSE2 && TARGET_SSE_MATH"
4567   "cvtsi2sd\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "sseicvt")
4569    (set_attr "mode" "DF")
4570    (set_attr "athlon_decode" "double,direct")
4571    (set_attr "fp_int_src" "true")])
4572
4573 (define_insn "*floatsidf2_i387"
4574   [(set (match_operand:DF 0 "register_operand" "=f,f")
4575         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4576   "TARGET_80387"
4577   "@
4578    fild%z1\t%1
4579    #"
4580   [(set_attr "type" "fmov,multi")
4581    (set_attr "mode" "DF")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_expand "floatdidf2"
4585   [(set (match_operand:DF 0 "register_operand" "")
4586         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4587   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4588   "")
4589
4590 (define_insn "*floatdidf2_mixed"
4591   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4592         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594   "@
4595    fild%z1\t%1
4596    #
4597    cvtsi2sd{q}\t{%1, %0|%0, %1}
4598    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4599   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600    (set_attr "mode" "DF")
4601    (set_attr "athlon_decode" "*,*,double,direct")
4602    (set_attr "fp_int_src" "true")])
4603
4604 (define_insn "*floatdidf2_sse"
4605   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4606         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4607   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4608   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4609   [(set_attr "type" "sseicvt")
4610    (set_attr "mode" "DF")
4611    (set_attr "athlon_decode" "double,direct")
4612    (set_attr "fp_int_src" "true")])
4613
4614 (define_insn "*floatdidf2_i387"
4615   [(set (match_operand:DF 0 "register_operand" "=f,f")
4616         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4617   "TARGET_80387"
4618   "@
4619    fild%z1\t%1
4620    #"
4621   [(set_attr "type" "fmov,multi")
4622    (set_attr "mode" "DF")
4623    (set_attr "fp_int_src" "true")])
4624
4625 (define_insn "floathixf2"
4626   [(set (match_operand:XF 0 "register_operand" "=f,f")
4627         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4628   "TARGET_80387"
4629   "@
4630    fild%z1\t%1
4631    #"
4632   [(set_attr "type" "fmov,multi")
4633    (set_attr "mode" "XF")
4634    (set_attr "fp_int_src" "true")])
4635
4636 (define_insn "floatsixf2"
4637   [(set (match_operand:XF 0 "register_operand" "=f,f")
4638         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4639   "TARGET_80387"
4640   "@
4641    fild%z1\t%1
4642    #"
4643   [(set_attr "type" "fmov,multi")
4644    (set_attr "mode" "XF")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "floatdixf2"
4648   [(set (match_operand:XF 0 "register_operand" "=f,f")
4649         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4650   "TARGET_80387"
4651   "@
4652    fild%z1\t%1
4653    #"
4654   [(set_attr "type" "fmov,multi")
4655    (set_attr "mode" "XF")
4656    (set_attr "fp_int_src" "true")])
4657
4658 ;; %%% Kill these when reload knows how to do it.
4659 (define_split
4660   [(set (match_operand 0 "fp_register_operand" "")
4661         (float (match_operand 1 "register_operand" "")))]
4662   "reload_completed
4663    && TARGET_80387
4664    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4665   [(const_int 0)]
4666 {
4667   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670   ix86_free_from_memory (GET_MODE (operands[1]));
4671   DONE;
4672 })
4673
4674 (define_expand "floatunssisf2"
4675   [(use (match_operand:SF 0 "register_operand" ""))
4676    (use (match_operand:SI 1 "register_operand" ""))]
4677   "!TARGET_64BIT && TARGET_SSE_MATH"
4678   "x86_emit_floatuns (operands); DONE;")
4679
4680 (define_expand "floatunsdisf2"
4681   [(use (match_operand:SF 0 "register_operand" ""))
4682    (use (match_operand:DI 1 "register_operand" ""))]
4683   "TARGET_64BIT && TARGET_SSE_MATH"
4684   "x86_emit_floatuns (operands); DONE;")
4685
4686 (define_expand "floatunsdidf2"
4687   [(use (match_operand:DF 0 "register_operand" ""))
4688    (use (match_operand:DI 1 "register_operand" ""))]
4689   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4690   "x86_emit_floatuns (operands); DONE;")
4691 \f
4692 ;; SSE extract/set expanders
4693
4694 \f
4695 ;; Add instructions
4696
4697 ;; %%% splits for addsidi3
4698 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4700 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4701
4702 (define_expand "adddi3"
4703   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4704         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4705                  (match_operand:DI 2 "x86_64_general_operand" "")))
4706    (clobber (reg:CC FLAGS_REG))]
4707   ""
4708   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4709
4710 (define_insn "*adddi3_1"
4711   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4712         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4713                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4714    (clobber (reg:CC FLAGS_REG))]
4715   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4716   "#")
4717
4718 (define_split
4719   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4720         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4721                  (match_operand:DI 2 "general_operand" "")))
4722    (clobber (reg:CC FLAGS_REG))]
4723   "!TARGET_64BIT && reload_completed"
4724   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4725                                           UNSPEC_ADD_CARRY))
4726               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4727    (parallel [(set (match_dup 3)
4728                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4729                                      (match_dup 4))
4730                             (match_dup 5)))
4731               (clobber (reg:CC FLAGS_REG))])]
4732   "split_di (operands+0, 1, operands+0, operands+3);
4733    split_di (operands+1, 1, operands+1, operands+4);
4734    split_di (operands+2, 1, operands+2, operands+5);")
4735
4736 (define_insn "adddi3_carry_rex64"
4737   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4738           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4739                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4740                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4741    (clobber (reg:CC FLAGS_REG))]
4742   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4743   "adc{q}\t{%2, %0|%0, %2}"
4744   [(set_attr "type" "alu")
4745    (set_attr "pent_pair" "pu")
4746    (set_attr "mode" "DI")])
4747
4748 (define_insn "*adddi3_cc_rex64"
4749   [(set (reg:CC FLAGS_REG)
4750         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4751                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4752                    UNSPEC_ADD_CARRY))
4753    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4754         (plus:DI (match_dup 1) (match_dup 2)))]
4755   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4756   "add{q}\t{%2, %0|%0, %2}"
4757   [(set_attr "type" "alu")
4758    (set_attr "mode" "DI")])
4759
4760 (define_insn "addqi3_carry"
4761   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4762           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4763                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4764                    (match_operand:QI 2 "general_operand" "qi,qm")))
4765    (clobber (reg:CC FLAGS_REG))]
4766   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4767   "adc{b}\t{%2, %0|%0, %2}"
4768   [(set_attr "type" "alu")
4769    (set_attr "pent_pair" "pu")
4770    (set_attr "mode" "QI")])
4771
4772 (define_insn "addhi3_carry"
4773   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4774           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4775                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4776                    (match_operand:HI 2 "general_operand" "ri,rm")))
4777    (clobber (reg:CC FLAGS_REG))]
4778   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4779   "adc{w}\t{%2, %0|%0, %2}"
4780   [(set_attr "type" "alu")
4781    (set_attr "pent_pair" "pu")
4782    (set_attr "mode" "HI")])
4783
4784 (define_insn "addsi3_carry"
4785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4786           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4787                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4788                    (match_operand:SI 2 "general_operand" "ri,rm")))
4789    (clobber (reg:CC FLAGS_REG))]
4790   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4791   "adc{l}\t{%2, %0|%0, %2}"
4792   [(set_attr "type" "alu")
4793    (set_attr "pent_pair" "pu")
4794    (set_attr "mode" "SI")])
4795
4796 (define_insn "*addsi3_carry_zext"
4797   [(set (match_operand:DI 0 "register_operand" "=r")
4798           (zero_extend:DI 
4799             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4800                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4801                      (match_operand:SI 2 "general_operand" "rim"))))
4802    (clobber (reg:CC FLAGS_REG))]
4803   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4804   "adc{l}\t{%2, %k0|%k0, %2}"
4805   [(set_attr "type" "alu")
4806    (set_attr "pent_pair" "pu")
4807    (set_attr "mode" "SI")])
4808
4809 (define_insn "*addsi3_cc"
4810   [(set (reg:CC FLAGS_REG)
4811         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4812                     (match_operand:SI 2 "general_operand" "ri,rm")]
4813                    UNSPEC_ADD_CARRY))
4814    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4815         (plus:SI (match_dup 1) (match_dup 2)))]
4816   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4817   "add{l}\t{%2, %0|%0, %2}"
4818   [(set_attr "type" "alu")
4819    (set_attr "mode" "SI")])
4820
4821 (define_insn "addqi3_cc"
4822   [(set (reg:CC FLAGS_REG)
4823         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4824                     (match_operand:QI 2 "general_operand" "qi,qm")]
4825                    UNSPEC_ADD_CARRY))
4826    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4827         (plus:QI (match_dup 1) (match_dup 2)))]
4828   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4829   "add{b}\t{%2, %0|%0, %2}"
4830   [(set_attr "type" "alu")
4831    (set_attr "mode" "QI")])
4832
4833 (define_expand "addsi3"
4834   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4836                             (match_operand:SI 2 "general_operand" "")))
4837               (clobber (reg:CC FLAGS_REG))])]
4838   ""
4839   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4840
4841 (define_insn "*lea_1"
4842   [(set (match_operand:SI 0 "register_operand" "=r")
4843         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4844   "!TARGET_64BIT"
4845   "lea{l}\t{%a1, %0|%0, %a1}"
4846   [(set_attr "type" "lea")
4847    (set_attr "mode" "SI")])
4848
4849 (define_insn "*lea_1_rex64"
4850   [(set (match_operand:SI 0 "register_operand" "=r")
4851         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4852   "TARGET_64BIT"
4853   "lea{l}\t{%a1, %0|%0, %a1}"
4854   [(set_attr "type" "lea")
4855    (set_attr "mode" "SI")])
4856
4857 (define_insn "*lea_1_zext"
4858   [(set (match_operand:DI 0 "register_operand" "=r")
4859         (zero_extend:DI
4860          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4861   "TARGET_64BIT"
4862   "lea{l}\t{%a1, %k0|%k0, %a1}"
4863   [(set_attr "type" "lea")
4864    (set_attr "mode" "SI")])
4865
4866 (define_insn "*lea_2_rex64"
4867   [(set (match_operand:DI 0 "register_operand" "=r")
4868         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4869   "TARGET_64BIT"
4870   "lea{q}\t{%a1, %0|%0, %a1}"
4871   [(set_attr "type" "lea")
4872    (set_attr "mode" "DI")])
4873
4874 ;; The lea patterns for non-Pmodes needs to be matched by several
4875 ;; insns converted to real lea by splitters.
4876
4877 (define_insn_and_split "*lea_general_1"
4878   [(set (match_operand 0 "register_operand" "=r")
4879         (plus (plus (match_operand 1 "index_register_operand" "l")
4880                     (match_operand 2 "register_operand" "r"))
4881               (match_operand 3 "immediate_operand" "i")))]
4882   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4883     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4884    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4885    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4886    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4887    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4888        || GET_MODE (operands[3]) == VOIDmode)"
4889   "#"
4890   "&& reload_completed"
4891   [(const_int 0)]
4892 {
4893   rtx pat;
4894   operands[0] = gen_lowpart (SImode, operands[0]);
4895   operands[1] = gen_lowpart (Pmode, operands[1]);
4896   operands[2] = gen_lowpart (Pmode, operands[2]);
4897   operands[3] = gen_lowpart (Pmode, operands[3]);
4898   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4899                       operands[3]);
4900   if (Pmode != SImode)
4901     pat = gen_rtx_SUBREG (SImode, pat, 0);
4902   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4903   DONE;
4904 }
4905   [(set_attr "type" "lea")
4906    (set_attr "mode" "SI")])
4907
4908 (define_insn_and_split "*lea_general_1_zext"
4909   [(set (match_operand:DI 0 "register_operand" "=r")
4910         (zero_extend:DI
4911           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4912                             (match_operand:SI 2 "register_operand" "r"))
4913                    (match_operand:SI 3 "immediate_operand" "i"))))]
4914   "TARGET_64BIT"
4915   "#"
4916   "&& reload_completed"
4917   [(set (match_dup 0)
4918         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4919                                                      (match_dup 2))
4920                                             (match_dup 3)) 0)))]
4921 {
4922   operands[1] = gen_lowpart (Pmode, operands[1]);
4923   operands[2] = gen_lowpart (Pmode, operands[2]);
4924   operands[3] = gen_lowpart (Pmode, operands[3]);
4925 }
4926   [(set_attr "type" "lea")
4927    (set_attr "mode" "SI")])
4928
4929 (define_insn_and_split "*lea_general_2"
4930   [(set (match_operand 0 "register_operand" "=r")
4931         (plus (mult (match_operand 1 "index_register_operand" "l")
4932                     (match_operand 2 "const248_operand" "i"))
4933               (match_operand 3 "nonmemory_operand" "ri")))]
4934   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4935     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4936    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4937    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4938    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4939        || GET_MODE (operands[3]) == VOIDmode)"
4940   "#"
4941   "&& reload_completed"
4942   [(const_int 0)]
4943 {
4944   rtx pat;
4945   operands[0] = gen_lowpart (SImode, operands[0]);
4946   operands[1] = gen_lowpart (Pmode, operands[1]);
4947   operands[3] = gen_lowpart (Pmode, operands[3]);
4948   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4949                       operands[3]);
4950   if (Pmode != SImode)
4951     pat = gen_rtx_SUBREG (SImode, pat, 0);
4952   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4953   DONE;
4954 }
4955   [(set_attr "type" "lea")
4956    (set_attr "mode" "SI")])
4957
4958 (define_insn_and_split "*lea_general_2_zext"
4959   [(set (match_operand:DI 0 "register_operand" "=r")
4960         (zero_extend:DI
4961           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4962                             (match_operand:SI 2 "const248_operand" "n"))
4963                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4964   "TARGET_64BIT"
4965   "#"
4966   "&& reload_completed"
4967   [(set (match_dup 0)
4968         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4969                                                      (match_dup 2))
4970                                             (match_dup 3)) 0)))]
4971 {
4972   operands[1] = gen_lowpart (Pmode, operands[1]);
4973   operands[3] = gen_lowpart (Pmode, operands[3]);
4974 }
4975   [(set_attr "type" "lea")
4976    (set_attr "mode" "SI")])
4977
4978 (define_insn_and_split "*lea_general_3"
4979   [(set (match_operand 0 "register_operand" "=r")
4980         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4981                           (match_operand 2 "const248_operand" "i"))
4982                     (match_operand 3 "register_operand" "r"))
4983               (match_operand 4 "immediate_operand" "i")))]
4984   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4985     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4986    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4987    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4988    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4989   "#"
4990   "&& reload_completed"
4991   [(const_int 0)]
4992 {
4993   rtx pat;
4994   operands[0] = gen_lowpart (SImode, operands[0]);
4995   operands[1] = gen_lowpart (Pmode, operands[1]);
4996   operands[3] = gen_lowpart (Pmode, operands[3]);
4997   operands[4] = gen_lowpart (Pmode, operands[4]);
4998   pat = gen_rtx_PLUS (Pmode,
4999                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5000                                                          operands[2]),
5001                                     operands[3]),
5002                       operands[4]);
5003   if (Pmode != SImode)
5004     pat = gen_rtx_SUBREG (SImode, pat, 0);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5006   DONE;
5007 }
5008   [(set_attr "type" "lea")
5009    (set_attr "mode" "SI")])
5010
5011 (define_insn_and_split "*lea_general_3_zext"
5012   [(set (match_operand:DI 0 "register_operand" "=r")
5013         (zero_extend:DI
5014           (plus:SI (plus:SI (mult:SI
5015                               (match_operand:SI 1 "index_register_operand" "l")
5016                               (match_operand:SI 2 "const248_operand" "n"))
5017                             (match_operand:SI 3 "register_operand" "r"))
5018                    (match_operand:SI 4 "immediate_operand" "i"))))]
5019   "TARGET_64BIT"
5020   "#"
5021   "&& reload_completed"
5022   [(set (match_dup 0)
5023         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5024                                                               (match_dup 2))
5025                                                      (match_dup 3))
5026                                             (match_dup 4)) 0)))]
5027 {
5028   operands[1] = gen_lowpart (Pmode, operands[1]);
5029   operands[3] = gen_lowpart (Pmode, operands[3]);
5030   operands[4] = gen_lowpart (Pmode, operands[4]);
5031 }
5032   [(set_attr "type" "lea")
5033    (set_attr "mode" "SI")])
5034
5035 (define_insn "*adddi_1_rex64"
5036   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5037         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5038                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5041 {
5042   switch (get_attr_type (insn))
5043     {
5044     case TYPE_LEA:
5045       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5046       return "lea{q}\t{%a2, %0|%0, %a2}";
5047
5048     case TYPE_INCDEC:
5049       if (! rtx_equal_p (operands[0], operands[1]))
5050         abort ();
5051       if (operands[2] == const1_rtx)
5052         return "inc{q}\t%0";
5053       else if (operands[2] == constm1_rtx)
5054         return "dec{q}\t%0";
5055       else
5056         abort ();
5057
5058     default:
5059       if (! rtx_equal_p (operands[0], operands[1]))
5060         abort ();
5061
5062       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5063          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5064       if (GET_CODE (operands[2]) == CONST_INT
5065           /* Avoid overflows.  */
5066           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5067           && (INTVAL (operands[2]) == 128
5068               || (INTVAL (operands[2]) < 0
5069                   && INTVAL (operands[2]) != -128)))
5070         {
5071           operands[2] = GEN_INT (-INTVAL (operands[2]));
5072           return "sub{q}\t{%2, %0|%0, %2}";
5073         }
5074       return "add{q}\t{%2, %0|%0, %2}";
5075     }
5076 }
5077   [(set (attr "type")
5078      (cond [(eq_attr "alternative" "2")
5079               (const_string "lea")
5080             ; Current assemblers are broken and do not allow @GOTOFF in
5081             ; ought but a memory context.
5082             (match_operand:DI 2 "pic_symbolic_operand" "")
5083               (const_string "lea")
5084             (match_operand:DI 2 "incdec_operand" "")
5085               (const_string "incdec")
5086            ]
5087            (const_string "alu")))
5088    (set_attr "mode" "DI")])
5089
5090 ;; Convert lea to the lea pattern to avoid flags dependency.
5091 (define_split
5092   [(set (match_operand:DI 0 "register_operand" "")
5093         (plus:DI (match_operand:DI 1 "register_operand" "")
5094                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5095    (clobber (reg:CC FLAGS_REG))]
5096   "TARGET_64BIT && reload_completed
5097    && true_regnum (operands[0]) != true_regnum (operands[1])"
5098   [(set (match_dup 0)
5099         (plus:DI (match_dup 1)
5100                  (match_dup 2)))]
5101   "")
5102
5103 (define_insn "*adddi_2_rex64"
5104   [(set (reg FLAGS_REG)
5105         (compare
5106           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5107                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5108           (const_int 0)))                       
5109    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5110         (plus:DI (match_dup 1) (match_dup 2)))]
5111   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5112    && ix86_binary_operator_ok (PLUS, DImode, operands)
5113    /* Current assemblers are broken and do not allow @GOTOFF in
5114       ought but a memory context.  */
5115    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5116 {
5117   switch (get_attr_type (insn))
5118     {
5119     case TYPE_INCDEC:
5120       if (! rtx_equal_p (operands[0], operands[1]))
5121         abort ();
5122       if (operands[2] == const1_rtx)
5123         return "inc{q}\t%0";
5124       else if (operands[2] == constm1_rtx)
5125         return "dec{q}\t%0";
5126       else
5127         abort ();
5128
5129     default:
5130       if (! rtx_equal_p (operands[0], operands[1]))
5131         abort ();
5132       /* ???? We ought to handle there the 32bit case too
5133          - do we need new constraint?  */
5134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5135          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5136       if (GET_CODE (operands[2]) == CONST_INT
5137           /* Avoid overflows.  */
5138           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5139           && (INTVAL (operands[2]) == 128
5140               || (INTVAL (operands[2]) < 0
5141                   && INTVAL (operands[2]) != -128)))
5142         {
5143           operands[2] = GEN_INT (-INTVAL (operands[2]));
5144           return "sub{q}\t{%2, %0|%0, %2}";
5145         }
5146       return "add{q}\t{%2, %0|%0, %2}";
5147     }
5148 }
5149   [(set (attr "type")
5150      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5151         (const_string "incdec")
5152         (const_string "alu")))
5153    (set_attr "mode" "DI")])
5154
5155 (define_insn "*adddi_3_rex64"
5156   [(set (reg FLAGS_REG)
5157         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5158                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5159    (clobber (match_scratch:DI 0 "=r"))]
5160   "TARGET_64BIT
5161    && ix86_match_ccmode (insn, CCZmode)
5162    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5163    /* Current assemblers are broken and do not allow @GOTOFF in
5164       ought but a memory context.  */
5165    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5166 {
5167   switch (get_attr_type (insn))
5168     {
5169     case TYPE_INCDEC:
5170       if (! rtx_equal_p (operands[0], operands[1]))
5171         abort ();
5172       if (operands[2] == const1_rtx)
5173         return "inc{q}\t%0";
5174       else if (operands[2] == constm1_rtx)
5175         return "dec{q}\t%0";
5176       else
5177         abort ();
5178
5179     default:
5180       if (! rtx_equal_p (operands[0], operands[1]))
5181         abort ();
5182       /* ???? We ought to handle there the 32bit case too
5183          - do we need new constraint?  */
5184       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5185          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5186       if (GET_CODE (operands[2]) == CONST_INT
5187           /* Avoid overflows.  */
5188           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5189           && (INTVAL (operands[2]) == 128
5190               || (INTVAL (operands[2]) < 0
5191                   && INTVAL (operands[2]) != -128)))
5192         {
5193           operands[2] = GEN_INT (-INTVAL (operands[2]));
5194           return "sub{q}\t{%2, %0|%0, %2}";
5195         }
5196       return "add{q}\t{%2, %0|%0, %2}";
5197     }
5198 }
5199   [(set (attr "type")
5200      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5201         (const_string "incdec")
5202         (const_string "alu")))
5203    (set_attr "mode" "DI")])
5204
5205 ; For comparisons against 1, -1 and 128, we may generate better code
5206 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5207 ; is matched then.  We can't accept general immediate, because for
5208 ; case of overflows,  the result is messed up.
5209 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5210 ; when negated.
5211 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5212 ; only for comparisons not depending on it.
5213 (define_insn "*adddi_4_rex64"
5214   [(set (reg FLAGS_REG)
5215         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5216                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5217    (clobber (match_scratch:DI 0 "=rm"))]
5218   "TARGET_64BIT
5219    &&  ix86_match_ccmode (insn, CCGCmode)"
5220 {
5221   switch (get_attr_type (insn))
5222     {
5223     case TYPE_INCDEC:
5224       if (operands[2] == constm1_rtx)
5225         return "inc{q}\t%0";
5226       else if (operands[2] == const1_rtx)
5227         return "dec{q}\t%0";
5228       else
5229         abort();
5230
5231     default:
5232       if (! rtx_equal_p (operands[0], operands[1]))
5233         abort ();
5234       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5235          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5236       if ((INTVAL (operands[2]) == -128
5237            || (INTVAL (operands[2]) > 0
5238                && INTVAL (operands[2]) != 128))
5239           /* Avoid overflows.  */
5240           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5241         return "sub{q}\t{%2, %0|%0, %2}";
5242       operands[2] = GEN_INT (-INTVAL (operands[2]));
5243       return "add{q}\t{%2, %0|%0, %2}";
5244     }
5245 }
5246   [(set (attr "type")
5247      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5248         (const_string "incdec")
5249         (const_string "alu")))
5250    (set_attr "mode" "DI")])
5251
5252 (define_insn "*adddi_5_rex64"
5253   [(set (reg FLAGS_REG)
5254         (compare
5255           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5256                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5257           (const_int 0)))                       
5258    (clobber (match_scratch:DI 0 "=r"))]
5259   "TARGET_64BIT
5260    && ix86_match_ccmode (insn, CCGOCmode)
5261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5262    /* Current assemblers are broken and do not allow @GOTOFF in
5263       ought but a memory context.  */
5264    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5265 {
5266   switch (get_attr_type (insn))
5267     {
5268     case TYPE_INCDEC:
5269       if (! rtx_equal_p (operands[0], operands[1]))
5270         abort ();
5271       if (operands[2] == const1_rtx)
5272         return "inc{q}\t%0";
5273       else if (operands[2] == constm1_rtx)
5274         return "dec{q}\t%0";
5275       else
5276         abort();
5277
5278     default:
5279       if (! rtx_equal_p (operands[0], operands[1]))
5280         abort ();
5281       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5282          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5283       if (GET_CODE (operands[2]) == CONST_INT
5284           /* Avoid overflows.  */
5285           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5286           && (INTVAL (operands[2]) == 128
5287               || (INTVAL (operands[2]) < 0
5288                   && INTVAL (operands[2]) != -128)))
5289         {
5290           operands[2] = GEN_INT (-INTVAL (operands[2]));
5291           return "sub{q}\t{%2, %0|%0, %2}";
5292         }
5293       return "add{q}\t{%2, %0|%0, %2}";
5294     }
5295 }
5296   [(set (attr "type")
5297      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5298         (const_string "incdec")
5299         (const_string "alu")))
5300    (set_attr "mode" "DI")])
5301
5302
5303 (define_insn "*addsi_1"
5304   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5305         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5306                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5307    (clobber (reg:CC FLAGS_REG))]
5308   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5309 {
5310   switch (get_attr_type (insn))
5311     {
5312     case TYPE_LEA:
5313       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5314       return "lea{l}\t{%a2, %0|%0, %a2}";
5315
5316     case TYPE_INCDEC:
5317       if (! rtx_equal_p (operands[0], operands[1]))
5318         abort ();
5319       if (operands[2] == const1_rtx)
5320         return "inc{l}\t%0";
5321       else if (operands[2] == constm1_rtx)
5322         return "dec{l}\t%0";
5323       else
5324         abort();
5325
5326     default:
5327       if (! rtx_equal_p (operands[0], operands[1]))
5328         abort ();
5329
5330       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5331          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5332       if (GET_CODE (operands[2]) == CONST_INT
5333           && (INTVAL (operands[2]) == 128
5334               || (INTVAL (operands[2]) < 0
5335                   && INTVAL (operands[2]) != -128)))
5336         {
5337           operands[2] = GEN_INT (-INTVAL (operands[2]));
5338           return "sub{l}\t{%2, %0|%0, %2}";
5339         }
5340       return "add{l}\t{%2, %0|%0, %2}";
5341     }
5342 }
5343   [(set (attr "type")
5344      (cond [(eq_attr "alternative" "2")
5345               (const_string "lea")
5346             ; Current assemblers are broken and do not allow @GOTOFF in
5347             ; ought but a memory context.
5348             (match_operand:SI 2 "pic_symbolic_operand" "")
5349               (const_string "lea")
5350             (match_operand:SI 2 "incdec_operand" "")
5351               (const_string "incdec")
5352            ]
5353            (const_string "alu")))
5354    (set_attr "mode" "SI")])
5355
5356 ;; Convert lea to the lea pattern to avoid flags dependency.
5357 (define_split
5358   [(set (match_operand 0 "register_operand" "")
5359         (plus (match_operand 1 "register_operand" "")
5360               (match_operand 2 "nonmemory_operand" "")))
5361    (clobber (reg:CC FLAGS_REG))]
5362   "reload_completed
5363    && true_regnum (operands[0]) != true_regnum (operands[1])"
5364   [(const_int 0)]
5365 {
5366   rtx pat;
5367   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5368      may confuse gen_lowpart.  */
5369   if (GET_MODE (operands[0]) != Pmode)
5370     {
5371       operands[1] = gen_lowpart (Pmode, operands[1]);
5372       operands[2] = gen_lowpart (Pmode, operands[2]);
5373     }
5374   operands[0] = gen_lowpart (SImode, operands[0]);
5375   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5376   if (Pmode != SImode)
5377     pat = gen_rtx_SUBREG (SImode, pat, 0);
5378   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5379   DONE;
5380 })
5381
5382 ;; It may seem that nonimmediate operand is proper one for operand 1.
5383 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5384 ;; we take care in ix86_binary_operator_ok to not allow two memory
5385 ;; operands so proper swapping will be done in reload.  This allow
5386 ;; patterns constructed from addsi_1 to match.
5387 (define_insn "addsi_1_zext"
5388   [(set (match_operand:DI 0 "register_operand" "=r,r")
5389         (zero_extend:DI
5390           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5391                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5392    (clobber (reg:CC FLAGS_REG))]
5393   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5394 {
5395   switch (get_attr_type (insn))
5396     {
5397     case TYPE_LEA:
5398       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5399       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5400
5401     case TYPE_INCDEC:
5402       if (operands[2] == const1_rtx)
5403         return "inc{l}\t%k0";
5404       else if (operands[2] == constm1_rtx)
5405         return "dec{l}\t%k0";
5406       else
5407         abort();
5408
5409     default:
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (GET_CODE (operands[2]) == CONST_INT
5413           && (INTVAL (operands[2]) == 128
5414               || (INTVAL (operands[2]) < 0
5415                   && INTVAL (operands[2]) != -128)))
5416         {
5417           operands[2] = GEN_INT (-INTVAL (operands[2]));
5418           return "sub{l}\t{%2, %k0|%k0, %2}";
5419         }
5420       return "add{l}\t{%2, %k0|%k0, %2}";
5421     }
5422 }
5423   [(set (attr "type")
5424      (cond [(eq_attr "alternative" "1")
5425               (const_string "lea")
5426             ; Current assemblers are broken and do not allow @GOTOFF in
5427             ; ought but a memory context.
5428             (match_operand:SI 2 "pic_symbolic_operand" "")
5429               (const_string "lea")
5430             (match_operand:SI 2 "incdec_operand" "")
5431               (const_string "incdec")
5432            ]
5433            (const_string "alu")))
5434    (set_attr "mode" "SI")])
5435
5436 ;; Convert lea to the lea pattern to avoid flags dependency.
5437 (define_split
5438   [(set (match_operand:DI 0 "register_operand" "")
5439         (zero_extend:DI
5440           (plus:SI (match_operand:SI 1 "register_operand" "")
5441                    (match_operand:SI 2 "nonmemory_operand" ""))))
5442    (clobber (reg:CC FLAGS_REG))]
5443   "TARGET_64BIT && reload_completed
5444    && true_regnum (operands[0]) != true_regnum (operands[1])"
5445   [(set (match_dup 0)
5446         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5447 {
5448   operands[1] = gen_lowpart (Pmode, operands[1]);
5449   operands[2] = gen_lowpart (Pmode, operands[2]);
5450 })
5451
5452 (define_insn "*addsi_2"
5453   [(set (reg FLAGS_REG)
5454         (compare
5455           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5456                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5457           (const_int 0)))                       
5458    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5459         (plus:SI (match_dup 1) (match_dup 2)))]
5460   "ix86_match_ccmode (insn, CCGOCmode)
5461    && ix86_binary_operator_ok (PLUS, SImode, operands)
5462    /* Current assemblers are broken and do not allow @GOTOFF in
5463       ought but a memory context.  */
5464    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5465 {
5466   switch (get_attr_type (insn))
5467     {
5468     case TYPE_INCDEC:
5469       if (! rtx_equal_p (operands[0], operands[1]))
5470         abort ();
5471       if (operands[2] == const1_rtx)
5472         return "inc{l}\t%0";
5473       else if (operands[2] == constm1_rtx)
5474         return "dec{l}\t%0";
5475       else
5476         abort();
5477
5478     default:
5479       if (! rtx_equal_p (operands[0], operands[1]))
5480         abort ();
5481       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5483       if (GET_CODE (operands[2]) == CONST_INT
5484           && (INTVAL (operands[2]) == 128
5485               || (INTVAL (operands[2]) < 0
5486                   && INTVAL (operands[2]) != -128)))
5487         {
5488           operands[2] = GEN_INT (-INTVAL (operands[2]));
5489           return "sub{l}\t{%2, %0|%0, %2}";
5490         }
5491       return "add{l}\t{%2, %0|%0, %2}";
5492     }
5493 }
5494   [(set (attr "type")
5495      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5496         (const_string "incdec")
5497         (const_string "alu")))
5498    (set_attr "mode" "SI")])
5499
5500 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5501 (define_insn "*addsi_2_zext"
5502   [(set (reg FLAGS_REG)
5503         (compare
5504           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5505                    (match_operand:SI 2 "general_operand" "rmni"))
5506           (const_int 0)))                       
5507    (set (match_operand:DI 0 "register_operand" "=r")
5508         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5509   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5510    && ix86_binary_operator_ok (PLUS, SImode, operands)
5511    /* Current assemblers are broken and do not allow @GOTOFF in
5512       ought but a memory context.  */
5513    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5514 {
5515   switch (get_attr_type (insn))
5516     {
5517     case TYPE_INCDEC:
5518       if (operands[2] == const1_rtx)
5519         return "inc{l}\t%k0";
5520       else if (operands[2] == constm1_rtx)
5521         return "dec{l}\t%k0";
5522       else
5523         abort();
5524
5525     default:
5526       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5528       if (GET_CODE (operands[2]) == CONST_INT
5529           && (INTVAL (operands[2]) == 128
5530               || (INTVAL (operands[2]) < 0
5531                   && INTVAL (operands[2]) != -128)))
5532         {
5533           operands[2] = GEN_INT (-INTVAL (operands[2]));
5534           return "sub{l}\t{%2, %k0|%k0, %2}";
5535         }
5536       return "add{l}\t{%2, %k0|%k0, %2}";
5537     }
5538 }
5539   [(set (attr "type")
5540      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5541         (const_string "incdec")
5542         (const_string "alu")))
5543    (set_attr "mode" "SI")])
5544
5545 (define_insn "*addsi_3"
5546   [(set (reg FLAGS_REG)
5547         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5548                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5549    (clobber (match_scratch:SI 0 "=r"))]
5550   "ix86_match_ccmode (insn, CCZmode)
5551    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       if (! rtx_equal_p (operands[0], operands[1]))
5560         abort ();
5561       if (operands[2] == const1_rtx)
5562         return "inc{l}\t%0";
5563       else if (operands[2] == constm1_rtx)
5564         return "dec{l}\t%0";
5565       else
5566         abort();
5567
5568     default:
5569       if (! rtx_equal_p (operands[0], operands[1]))
5570         abort ();
5571       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5573       if (GET_CODE (operands[2]) == CONST_INT
5574           && (INTVAL (operands[2]) == 128
5575               || (INTVAL (operands[2]) < 0
5576                   && INTVAL (operands[2]) != -128)))
5577         {
5578           operands[2] = GEN_INT (-INTVAL (operands[2]));
5579           return "sub{l}\t{%2, %0|%0, %2}";
5580         }
5581       return "add{l}\t{%2, %0|%0, %2}";
5582     }
5583 }
5584   [(set (attr "type")
5585      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586         (const_string "incdec")
5587         (const_string "alu")))
5588    (set_attr "mode" "SI")])
5589
5590 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5591 (define_insn "*addsi_3_zext"
5592   [(set (reg FLAGS_REG)
5593         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5594                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5595    (set (match_operand:DI 0 "register_operand" "=r")
5596         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5598    && ix86_binary_operator_ok (PLUS, SImode, operands)
5599    /* Current assemblers are broken and do not allow @GOTOFF in
5600       ought but a memory context.  */
5601    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5602 {
5603   switch (get_attr_type (insn))
5604     {
5605     case TYPE_INCDEC:
5606       if (operands[2] == const1_rtx)
5607         return "inc{l}\t%k0";
5608       else if (operands[2] == constm1_rtx)
5609         return "dec{l}\t%k0";
5610       else
5611         abort();
5612
5613     default:
5614       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5615          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5616       if (GET_CODE (operands[2]) == CONST_INT
5617           && (INTVAL (operands[2]) == 128
5618               || (INTVAL (operands[2]) < 0
5619                   && INTVAL (operands[2]) != -128)))
5620         {
5621           operands[2] = GEN_INT (-INTVAL (operands[2]));
5622           return "sub{l}\t{%2, %k0|%k0, %2}";
5623         }
5624       return "add{l}\t{%2, %k0|%k0, %2}";
5625     }
5626 }
5627   [(set (attr "type")
5628      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5629         (const_string "incdec")
5630         (const_string "alu")))
5631    (set_attr "mode" "SI")])
5632
5633 ; For comparisons against 1, -1 and 128, we may generate better code
5634 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5635 ; is matched then.  We can't accept general immediate, because for
5636 ; case of overflows,  the result is messed up.
5637 ; This pattern also don't hold of 0x80000000, since the value overflows
5638 ; when negated.
5639 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5640 ; only for comparisons not depending on it.
5641 (define_insn "*addsi_4"
5642   [(set (reg FLAGS_REG)
5643         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5644                  (match_operand:SI 2 "const_int_operand" "n")))
5645    (clobber (match_scratch:SI 0 "=rm"))]
5646   "ix86_match_ccmode (insn, CCGCmode)
5647    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5648 {
5649   switch (get_attr_type (insn))
5650     {
5651     case TYPE_INCDEC:
5652       if (operands[2] == constm1_rtx)
5653         return "inc{l}\t%0";
5654       else if (operands[2] == const1_rtx)
5655         return "dec{l}\t%0";
5656       else
5657         abort();
5658
5659     default:
5660       if (! rtx_equal_p (operands[0], operands[1]))
5661         abort ();
5662       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5663          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5664       if ((INTVAL (operands[2]) == -128
5665            || (INTVAL (operands[2]) > 0
5666                && INTVAL (operands[2]) != 128)))
5667         return "sub{l}\t{%2, %0|%0, %2}";
5668       operands[2] = GEN_INT (-INTVAL (operands[2]));
5669       return "add{l}\t{%2, %0|%0, %2}";
5670     }
5671 }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5677
5678 (define_insn "*addsi_5"
5679   [(set (reg FLAGS_REG)
5680         (compare
5681           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5682                    (match_operand:SI 2 "general_operand" "rmni"))
5683           (const_int 0)))                       
5684    (clobber (match_scratch:SI 0 "=r"))]
5685   "ix86_match_ccmode (insn, CCGOCmode)
5686    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5687    /* Current assemblers are broken and do not allow @GOTOFF in
5688       ought but a memory context.  */
5689    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5690 {
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (! rtx_equal_p (operands[0], operands[1]))
5695         abort ();
5696       if (operands[2] == const1_rtx)
5697         return "inc{l}\t%0";
5698       else if (operands[2] == constm1_rtx)
5699         return "dec{l}\t%0";
5700       else
5701         abort();
5702
5703     default:
5704       if (! rtx_equal_p (operands[0], operands[1]))
5705         abort ();
5706       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5708       if (GET_CODE (operands[2]) == CONST_INT
5709           && (INTVAL (operands[2]) == 128
5710               || (INTVAL (operands[2]) < 0
5711                   && INTVAL (operands[2]) != -128)))
5712         {
5713           operands[2] = GEN_INT (-INTVAL (operands[2]));
5714           return "sub{l}\t{%2, %0|%0, %2}";
5715         }
5716       return "add{l}\t{%2, %0|%0, %2}";
5717     }
5718 }
5719   [(set (attr "type")
5720      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5721         (const_string "incdec")
5722         (const_string "alu")))
5723    (set_attr "mode" "SI")])
5724
5725 (define_expand "addhi3"
5726   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5727                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5728                             (match_operand:HI 2 "general_operand" "")))
5729               (clobber (reg:CC FLAGS_REG))])]
5730   "TARGET_HIMODE_MATH"
5731   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5732
5733 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5734 ;; type optimizations enabled by define-splits.  This is not important
5735 ;; for PII, and in fact harmful because of partial register stalls.
5736
5737 (define_insn "*addhi_1_lea"
5738   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5739         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5740                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5741    (clobber (reg:CC FLAGS_REG))]
5742   "!TARGET_PARTIAL_REG_STALL
5743    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5744 {
5745   switch (get_attr_type (insn))
5746     {
5747     case TYPE_LEA:
5748       return "#";
5749     case TYPE_INCDEC:
5750       if (operands[2] == const1_rtx)
5751         return "inc{w}\t%0";
5752       else if (operands[2] == constm1_rtx)
5753         return "dec{w}\t%0";
5754       abort();
5755
5756     default:
5757       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5758          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5759       if (GET_CODE (operands[2]) == CONST_INT
5760           && (INTVAL (operands[2]) == 128
5761               || (INTVAL (operands[2]) < 0
5762                   && INTVAL (operands[2]) != -128)))
5763         {
5764           operands[2] = GEN_INT (-INTVAL (operands[2]));
5765           return "sub{w}\t{%2, %0|%0, %2}";
5766         }
5767       return "add{w}\t{%2, %0|%0, %2}";
5768     }
5769 }
5770   [(set (attr "type")
5771      (if_then_else (eq_attr "alternative" "2")
5772         (const_string "lea")
5773         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5774            (const_string "incdec")
5775            (const_string "alu"))))
5776    (set_attr "mode" "HI,HI,SI")])
5777
5778 (define_insn "*addhi_1"
5779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5780         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5781                  (match_operand:HI 2 "general_operand" "ri,rm")))
5782    (clobber (reg:CC FLAGS_REG))]
5783   "TARGET_PARTIAL_REG_STALL
5784    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 {
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_INCDEC:
5789       if (operands[2] == const1_rtx)
5790         return "inc{w}\t%0";
5791       else if (operands[2] == constm1_rtx)
5792         return "dec{w}\t%0";
5793       abort();
5794
5795     default:
5796       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5797          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5798       if (GET_CODE (operands[2]) == CONST_INT
5799           && (INTVAL (operands[2]) == 128
5800               || (INTVAL (operands[2]) < 0
5801                   && INTVAL (operands[2]) != -128)))
5802         {
5803           operands[2] = GEN_INT (-INTVAL (operands[2]));
5804           return "sub{w}\t{%2, %0|%0, %2}";
5805         }
5806       return "add{w}\t{%2, %0|%0, %2}";
5807     }
5808 }
5809   [(set (attr "type")
5810      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5811         (const_string "incdec")
5812         (const_string "alu")))
5813    (set_attr "mode" "HI")])
5814
5815 (define_insn "*addhi_2"
5816   [(set (reg FLAGS_REG)
5817         (compare
5818           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5819                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5820           (const_int 0)))                       
5821    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5822         (plus:HI (match_dup 1) (match_dup 2)))]
5823   "ix86_match_ccmode (insn, CCGOCmode)
5824    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5825 {
5826   switch (get_attr_type (insn))
5827     {
5828     case TYPE_INCDEC:
5829       if (operands[2] == const1_rtx)
5830         return "inc{w}\t%0";
5831       else if (operands[2] == constm1_rtx)
5832         return "dec{w}\t%0";
5833       abort();
5834
5835     default:
5836       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5837          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5838       if (GET_CODE (operands[2]) == CONST_INT
5839           && (INTVAL (operands[2]) == 128
5840               || (INTVAL (operands[2]) < 0
5841                   && INTVAL (operands[2]) != -128)))
5842         {
5843           operands[2] = GEN_INT (-INTVAL (operands[2]));
5844           return "sub{w}\t{%2, %0|%0, %2}";
5845         }
5846       return "add{w}\t{%2, %0|%0, %2}";
5847     }
5848 }
5849   [(set (attr "type")
5850      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5851         (const_string "incdec")
5852         (const_string "alu")))
5853    (set_attr "mode" "HI")])
5854
5855 (define_insn "*addhi_3"
5856   [(set (reg FLAGS_REG)
5857         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5858                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5859    (clobber (match_scratch:HI 0 "=r"))]
5860   "ix86_match_ccmode (insn, CCZmode)
5861    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5862 {
5863   switch (get_attr_type (insn))
5864     {
5865     case TYPE_INCDEC:
5866       if (operands[2] == const1_rtx)
5867         return "inc{w}\t%0";
5868       else if (operands[2] == constm1_rtx)
5869         return "dec{w}\t%0";
5870       abort();
5871
5872     default:
5873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875       if (GET_CODE (operands[2]) == CONST_INT
5876           && (INTVAL (operands[2]) == 128
5877               || (INTVAL (operands[2]) < 0
5878                   && INTVAL (operands[2]) != -128)))
5879         {
5880           operands[2] = GEN_INT (-INTVAL (operands[2]));
5881           return "sub{w}\t{%2, %0|%0, %2}";
5882         }
5883       return "add{w}\t{%2, %0|%0, %2}";
5884     }
5885 }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set_attr "mode" "HI")])
5891
5892 ; See comments above addsi_4 for details.
5893 (define_insn "*addhi_4"
5894   [(set (reg FLAGS_REG)
5895         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5896                  (match_operand:HI 2 "const_int_operand" "n")))
5897    (clobber (match_scratch:HI 0 "=rm"))]
5898   "ix86_match_ccmode (insn, CCGCmode)
5899    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == constm1_rtx)
5905         return "inc{w}\t%0";
5906       else if (operands[2] == const1_rtx)
5907         return "dec{w}\t%0";
5908       else
5909         abort();
5910
5911     default:
5912       if (! rtx_equal_p (operands[0], operands[1]))
5913         abort ();
5914       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5916       if ((INTVAL (operands[2]) == -128
5917            || (INTVAL (operands[2]) > 0
5918                && INTVAL (operands[2]) != 128)))
5919         return "sub{w}\t{%2, %0|%0, %2}";
5920       operands[2] = GEN_INT (-INTVAL (operands[2]));
5921       return "add{w}\t{%2, %0|%0, %2}";
5922     }
5923 }
5924   [(set (attr "type")
5925      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5926         (const_string "incdec")
5927         (const_string "alu")))
5928    (set_attr "mode" "SI")])
5929
5930
5931 (define_insn "*addhi_5"
5932   [(set (reg FLAGS_REG)
5933         (compare
5934           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5935                    (match_operand:HI 2 "general_operand" "rmni"))
5936           (const_int 0)))                       
5937    (clobber (match_scratch:HI 0 "=r"))]
5938   "ix86_match_ccmode (insn, CCGOCmode)
5939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5940 {
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{w}\t%0";
5946       else if (operands[2] == constm1_rtx)
5947         return "dec{w}\t%0";
5948       abort();
5949
5950     default:
5951       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5953       if (GET_CODE (operands[2]) == CONST_INT
5954           && (INTVAL (operands[2]) == 128
5955               || (INTVAL (operands[2]) < 0
5956                   && INTVAL (operands[2]) != -128)))
5957         {
5958           operands[2] = GEN_INT (-INTVAL (operands[2]));
5959           return "sub{w}\t{%2, %0|%0, %2}";
5960         }
5961       return "add{w}\t{%2, %0|%0, %2}";
5962     }
5963 }
5964   [(set (attr "type")
5965      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5966         (const_string "incdec")
5967         (const_string "alu")))
5968    (set_attr "mode" "HI")])
5969
5970 (define_expand "addqi3"
5971   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5972                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5973                             (match_operand:QI 2 "general_operand" "")))
5974               (clobber (reg:CC FLAGS_REG))])]
5975   "TARGET_QIMODE_MATH"
5976   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5977
5978 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5979 (define_insn "*addqi_1_lea"
5980   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5981         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5982                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5983    (clobber (reg:CC FLAGS_REG))]
5984   "!TARGET_PARTIAL_REG_STALL
5985    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5986 {
5987   int widen = (which_alternative == 2);
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_LEA:
5991       return "#";
5992     case TYPE_INCDEC:
5993       if (operands[2] == const1_rtx)
5994         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5995       else if (operands[2] == constm1_rtx)
5996         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5997       abort();
5998
5999     default:
6000       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6001          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6002       if (GET_CODE (operands[2]) == CONST_INT
6003           && (INTVAL (operands[2]) == 128
6004               || (INTVAL (operands[2]) < 0
6005                   && INTVAL (operands[2]) != -128)))
6006         {
6007           operands[2] = GEN_INT (-INTVAL (operands[2]));
6008           if (widen)
6009             return "sub{l}\t{%2, %k0|%k0, %2}";
6010           else
6011             return "sub{b}\t{%2, %0|%0, %2}";
6012         }
6013       if (widen)
6014         return "add{l}\t{%k2, %k0|%k0, %k2}";
6015       else
6016         return "add{b}\t{%2, %0|%0, %2}";
6017     }
6018 }
6019   [(set (attr "type")
6020      (if_then_else (eq_attr "alternative" "3")
6021         (const_string "lea")
6022         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6023            (const_string "incdec")
6024            (const_string "alu"))))
6025    (set_attr "mode" "QI,QI,SI,SI")])
6026
6027 (define_insn "*addqi_1"
6028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6029         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6030                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "TARGET_PARTIAL_REG_STALL
6033    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6034 {
6035   int widen = (which_alternative == 2);
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == const1_rtx)
6040         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6041       else if (operands[2] == constm1_rtx)
6042         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6043       abort();
6044
6045     default:
6046       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6048       if (GET_CODE (operands[2]) == CONST_INT
6049           && (INTVAL (operands[2]) == 128
6050               || (INTVAL (operands[2]) < 0
6051                   && INTVAL (operands[2]) != -128)))
6052         {
6053           operands[2] = GEN_INT (-INTVAL (operands[2]));
6054           if (widen)
6055             return "sub{l}\t{%2, %k0|%k0, %2}";
6056           else
6057             return "sub{b}\t{%2, %0|%0, %2}";
6058         }
6059       if (widen)
6060         return "add{l}\t{%k2, %k0|%k0, %k2}";
6061       else
6062         return "add{b}\t{%2, %0|%0, %2}";
6063     }
6064 }
6065   [(set (attr "type")
6066      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6067         (const_string "incdec")
6068         (const_string "alu")))
6069    (set_attr "mode" "QI,QI,SI")])
6070
6071 (define_insn "*addqi_1_slp"
6072   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6073         (plus:QI (match_dup 0)
6074                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6075    (clobber (reg:CC FLAGS_REG))]
6076   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6077    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6078 {
6079   switch (get_attr_type (insn))
6080     {
6081     case TYPE_INCDEC:
6082       if (operands[1] == const1_rtx)
6083         return "inc{b}\t%0";
6084       else if (operands[1] == constm1_rtx)
6085         return "dec{b}\t%0";
6086       abort();
6087
6088     default:
6089       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6090       if (GET_CODE (operands[1]) == CONST_INT
6091           && INTVAL (operands[1]) < 0)
6092         {
6093           operands[1] = GEN_INT (-INTVAL (operands[1]));
6094           return "sub{b}\t{%1, %0|%0, %1}";
6095         }
6096       return "add{b}\t{%1, %0|%0, %1}";
6097     }
6098 }
6099   [(set (attr "type")
6100      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6101         (const_string "incdec")
6102         (const_string "alu1")))
6103    (set (attr "memory")
6104      (if_then_else (match_operand 1 "memory_operand" "")
6105         (const_string "load")
6106         (const_string "none")))
6107    (set_attr "mode" "QI")])
6108
6109 (define_insn "*addqi_2"
6110   [(set (reg FLAGS_REG)
6111         (compare
6112           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6113                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6114           (const_int 0)))
6115    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6116         (plus:QI (match_dup 1) (match_dup 2)))]
6117   "ix86_match_ccmode (insn, CCGOCmode)
6118    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119 {
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == const1_rtx)
6124         return "inc{b}\t%0";
6125       else if (operands[2] == constm1_rtx
6126                || (GET_CODE (operands[2]) == CONST_INT
6127                    && INTVAL (operands[2]) == 255))
6128         return "dec{b}\t%0";
6129       abort();
6130
6131     default:
6132       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6133       if (GET_CODE (operands[2]) == CONST_INT
6134           && INTVAL (operands[2]) < 0)
6135         {
6136           operands[2] = GEN_INT (-INTVAL (operands[2]));
6137           return "sub{b}\t{%2, %0|%0, %2}";
6138         }
6139       return "add{b}\t{%2, %0|%0, %2}";
6140     }
6141 }
6142   [(set (attr "type")
6143      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6144         (const_string "incdec")
6145         (const_string "alu")))
6146    (set_attr "mode" "QI")])
6147
6148 (define_insn "*addqi_3"
6149   [(set (reg FLAGS_REG)
6150         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6151                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6152    (clobber (match_scratch:QI 0 "=q"))]
6153   "ix86_match_ccmode (insn, CCZmode)
6154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6155 {
6156   switch (get_attr_type (insn))
6157     {
6158     case TYPE_INCDEC:
6159       if (operands[2] == const1_rtx)
6160         return "inc{b}\t%0";
6161       else if (operands[2] == constm1_rtx
6162                || (GET_CODE (operands[2]) == CONST_INT
6163                    && INTVAL (operands[2]) == 255))
6164         return "dec{b}\t%0";
6165       abort();
6166
6167     default:
6168       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6169       if (GET_CODE (operands[2]) == CONST_INT
6170           && INTVAL (operands[2]) < 0)
6171         {
6172           operands[2] = GEN_INT (-INTVAL (operands[2]));
6173           return "sub{b}\t{%2, %0|%0, %2}";
6174         }
6175       return "add{b}\t{%2, %0|%0, %2}";
6176     }
6177 }
6178   [(set (attr "type")
6179      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6180         (const_string "incdec")
6181         (const_string "alu")))
6182    (set_attr "mode" "QI")])
6183
6184 ; See comments above addsi_4 for details.
6185 (define_insn "*addqi_4"
6186   [(set (reg FLAGS_REG)
6187         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6188                  (match_operand:QI 2 "const_int_operand" "n")))
6189    (clobber (match_scratch:QI 0 "=qm"))]
6190   "ix86_match_ccmode (insn, CCGCmode)
6191    && (INTVAL (operands[2]) & 0xff) != 0x80"
6192 {
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == constm1_rtx
6197           || (GET_CODE (operands[2]) == CONST_INT
6198               && INTVAL (operands[2]) == 255))
6199         return "inc{b}\t%0";
6200       else if (operands[2] == const1_rtx)
6201         return "dec{b}\t%0";
6202       else
6203         abort();
6204
6205     default:
6206       if (! rtx_equal_p (operands[0], operands[1]))
6207         abort ();
6208       if (INTVAL (operands[2]) < 0)
6209         {
6210           operands[2] = GEN_INT (-INTVAL (operands[2]));
6211           return "add{b}\t{%2, %0|%0, %2}";
6212         }
6213       return "sub{b}\t{%2, %0|%0, %2}";
6214     }
6215 }
6216   [(set (attr "type")
6217      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6218         (const_string "incdec")
6219         (const_string "alu")))
6220    (set_attr "mode" "QI")])
6221
6222
6223 (define_insn "*addqi_5"
6224   [(set (reg FLAGS_REG)
6225         (compare
6226           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6227                    (match_operand:QI 2 "general_operand" "qmni"))
6228           (const_int 0)))
6229    (clobber (match_scratch:QI 0 "=q"))]
6230   "ix86_match_ccmode (insn, CCGOCmode)
6231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6232 {
6233   switch (get_attr_type (insn))
6234     {
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return "inc{b}\t%0";
6238       else if (operands[2] == constm1_rtx
6239                || (GET_CODE (operands[2]) == CONST_INT
6240                    && INTVAL (operands[2]) == 255))
6241         return "dec{b}\t%0";
6242       abort();
6243
6244     default:
6245       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6246       if (GET_CODE (operands[2]) == CONST_INT
6247           && INTVAL (operands[2]) < 0)
6248         {
6249           operands[2] = GEN_INT (-INTVAL (operands[2]));
6250           return "sub{b}\t{%2, %0|%0, %2}";
6251         }
6252       return "add{b}\t{%2, %0|%0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6257         (const_string "incdec")
6258         (const_string "alu")))
6259    (set_attr "mode" "QI")])
6260
6261
6262 (define_insn "addqi_ext_1"
6263   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6264                          (const_int 8)
6265                          (const_int 8))
6266         (plus:SI
6267           (zero_extract:SI
6268             (match_operand 1 "ext_register_operand" "0")
6269             (const_int 8)
6270             (const_int 8))
6271           (match_operand:QI 2 "general_operand" "Qmn")))
6272    (clobber (reg:CC FLAGS_REG))]
6273   "!TARGET_64BIT"
6274 {
6275   switch (get_attr_type (insn))
6276     {
6277     case TYPE_INCDEC:
6278       if (operands[2] == const1_rtx)
6279         return "inc{b}\t%h0";
6280       else if (operands[2] == constm1_rtx
6281                || (GET_CODE (operands[2]) == CONST_INT
6282                    && INTVAL (operands[2]) == 255))
6283         return "dec{b}\t%h0";
6284       abort();
6285
6286     default:
6287       return "add{b}\t{%2, %h0|%h0, %2}";
6288     }
6289 }
6290   [(set (attr "type")
6291      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292         (const_string "incdec")
6293         (const_string "alu")))
6294    (set_attr "mode" "QI")])
6295
6296 (define_insn "*addqi_ext_1_rex64"
6297   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6298                          (const_int 8)
6299                          (const_int 8))
6300         (plus:SI
6301           (zero_extract:SI
6302             (match_operand 1 "ext_register_operand" "0")
6303             (const_int 8)
6304             (const_int 8))
6305           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6306    (clobber (reg:CC FLAGS_REG))]
6307   "TARGET_64BIT"
6308 {
6309   switch (get_attr_type (insn))
6310     {
6311     case TYPE_INCDEC:
6312       if (operands[2] == const1_rtx)
6313         return "inc{b}\t%h0";
6314       else if (operands[2] == constm1_rtx
6315                || (GET_CODE (operands[2]) == CONST_INT
6316                    && INTVAL (operands[2]) == 255))
6317         return "dec{b}\t%h0";
6318       abort();
6319
6320     default:
6321       return "add{b}\t{%2, %h0|%h0, %2}";
6322     }
6323 }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "QI")])
6329
6330 (define_insn "*addqi_ext_2"
6331   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6332                          (const_int 8)
6333                          (const_int 8))
6334         (plus:SI
6335           (zero_extract:SI
6336             (match_operand 1 "ext_register_operand" "%0")
6337             (const_int 8)
6338             (const_int 8))
6339           (zero_extract:SI
6340             (match_operand 2 "ext_register_operand" "Q")
6341             (const_int 8)
6342             (const_int 8))))
6343    (clobber (reg:CC FLAGS_REG))]
6344   ""
6345   "add{b}\t{%h2, %h0|%h0, %h2}"
6346   [(set_attr "type" "alu")
6347    (set_attr "mode" "QI")])
6348
6349 ;; The patterns that match these are at the end of this file.
6350
6351 (define_expand "addxf3"
6352   [(set (match_operand:XF 0 "register_operand" "")
6353         (plus:XF (match_operand:XF 1 "register_operand" "")
6354                  (match_operand:XF 2 "register_operand" "")))]
6355   "TARGET_80387"
6356   "")
6357
6358 (define_expand "adddf3"
6359   [(set (match_operand:DF 0 "register_operand" "")
6360         (plus:DF (match_operand:DF 1 "register_operand" "")
6361                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6362   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6363   "")
6364
6365 (define_expand "addsf3"
6366   [(set (match_operand:SF 0 "register_operand" "")
6367         (plus:SF (match_operand:SF 1 "register_operand" "")
6368                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6369   "TARGET_80387 || TARGET_SSE_MATH"
6370   "")
6371 \f
6372 ;; Subtract instructions
6373
6374 ;; %%% splits for subsidi3
6375
6376 (define_expand "subdi3"
6377   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6378                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6379                              (match_operand:DI 2 "x86_64_general_operand" "")))
6380               (clobber (reg:CC FLAGS_REG))])]
6381   ""
6382   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6383
6384 (define_insn "*subdi3_1"
6385   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6386         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6387                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6388    (clobber (reg:CC FLAGS_REG))]
6389   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6390   "#")
6391
6392 (define_split
6393   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6394         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6395                   (match_operand:DI 2 "general_operand" "")))
6396    (clobber (reg:CC FLAGS_REG))]
6397   "!TARGET_64BIT && reload_completed"
6398   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6399               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6400    (parallel [(set (match_dup 3)
6401                    (minus:SI (match_dup 4)
6402                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6403                                       (match_dup 5))))
6404               (clobber (reg:CC FLAGS_REG))])]
6405   "split_di (operands+0, 1, operands+0, operands+3);
6406    split_di (operands+1, 1, operands+1, operands+4);
6407    split_di (operands+2, 1, operands+2, operands+5);")
6408
6409 (define_insn "subdi3_carry_rex64"
6410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6411           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6412             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6413                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6414    (clobber (reg:CC FLAGS_REG))]
6415   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6416   "sbb{q}\t{%2, %0|%0, %2}"
6417   [(set_attr "type" "alu")
6418    (set_attr "pent_pair" "pu")
6419    (set_attr "mode" "DI")])
6420
6421 (define_insn "*subdi_1_rex64"
6422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6423         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6424                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6425    (clobber (reg:CC FLAGS_REG))]
6426   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6427   "sub{q}\t{%2, %0|%0, %2}"
6428   [(set_attr "type" "alu")
6429    (set_attr "mode" "DI")])
6430
6431 (define_insn "*subdi_2_rex64"
6432   [(set (reg FLAGS_REG)
6433         (compare
6434           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6435                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6436           (const_int 0)))
6437    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6438         (minus:DI (match_dup 1) (match_dup 2)))]
6439   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6440    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6441   "sub{q}\t{%2, %0|%0, %2}"
6442   [(set_attr "type" "alu")
6443    (set_attr "mode" "DI")])
6444
6445 (define_insn "*subdi_3_rex63"
6446   [(set (reg FLAGS_REG)
6447         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6448                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6449    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6450         (minus:DI (match_dup 1) (match_dup 2)))]
6451   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6452    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6453   "sub{q}\t{%2, %0|%0, %2}"
6454   [(set_attr "type" "alu")
6455    (set_attr "mode" "DI")])
6456
6457 (define_insn "subqi3_carry"
6458   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6459           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6460             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6461                (match_operand:QI 2 "general_operand" "qi,qm"))))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6464   "sbb{b}\t{%2, %0|%0, %2}"
6465   [(set_attr "type" "alu")
6466    (set_attr "pent_pair" "pu")
6467    (set_attr "mode" "QI")])
6468
6469 (define_insn "subhi3_carry"
6470   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6471           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6472             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6473                (match_operand:HI 2 "general_operand" "ri,rm"))))
6474    (clobber (reg:CC FLAGS_REG))]
6475   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6476   "sbb{w}\t{%2, %0|%0, %2}"
6477   [(set_attr "type" "alu")
6478    (set_attr "pent_pair" "pu")
6479    (set_attr "mode" "HI")])
6480
6481 (define_insn "subsi3_carry"
6482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6483           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6484             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6485                (match_operand:SI 2 "general_operand" "ri,rm"))))
6486    (clobber (reg:CC FLAGS_REG))]
6487   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6488   "sbb{l}\t{%2, %0|%0, %2}"
6489   [(set_attr "type" "alu")
6490    (set_attr "pent_pair" "pu")
6491    (set_attr "mode" "SI")])
6492
6493 (define_insn "subsi3_carry_zext"
6494   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6495           (zero_extend:DI
6496             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6497               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6498                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6499    (clobber (reg:CC FLAGS_REG))]
6500   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6501   "sbb{l}\t{%2, %k0|%k0, %2}"
6502   [(set_attr "type" "alu")
6503    (set_attr "pent_pair" "pu")
6504    (set_attr "mode" "SI")])
6505
6506 (define_expand "subsi3"
6507   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6508                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6509                              (match_operand:SI 2 "general_operand" "")))
6510               (clobber (reg:CC FLAGS_REG))])]
6511   ""
6512   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6513
6514 (define_insn "*subsi_1"
6515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6516         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6517                   (match_operand:SI 2 "general_operand" "ri,rm")))
6518    (clobber (reg:CC FLAGS_REG))]
6519   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6520   "sub{l}\t{%2, %0|%0, %2}"
6521   [(set_attr "type" "alu")
6522    (set_attr "mode" "SI")])
6523
6524 (define_insn "*subsi_1_zext"
6525   [(set (match_operand:DI 0 "register_operand" "=r")
6526         (zero_extend:DI
6527           (minus:SI (match_operand:SI 1 "register_operand" "0")
6528                     (match_operand:SI 2 "general_operand" "rim"))))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6531   "sub{l}\t{%2, %k0|%k0, %2}"
6532   [(set_attr "type" "alu")
6533    (set_attr "mode" "SI")])
6534
6535 (define_insn "*subsi_2"
6536   [(set (reg FLAGS_REG)
6537         (compare
6538           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6539                     (match_operand:SI 2 "general_operand" "ri,rm"))
6540           (const_int 0)))
6541    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6542         (minus:SI (match_dup 1) (match_dup 2)))]
6543   "ix86_match_ccmode (insn, CCGOCmode)
6544    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6545   "sub{l}\t{%2, %0|%0, %2}"
6546   [(set_attr "type" "alu")
6547    (set_attr "mode" "SI")])
6548
6549 (define_insn "*subsi_2_zext"
6550   [(set (reg FLAGS_REG)
6551         (compare
6552           (minus:SI (match_operand:SI 1 "register_operand" "0")
6553                     (match_operand:SI 2 "general_operand" "rim"))
6554           (const_int 0)))
6555    (set (match_operand:DI 0 "register_operand" "=r")
6556         (zero_extend:DI
6557           (minus:SI (match_dup 1)
6558                     (match_dup 2))))]
6559   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6560    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6561   "sub{l}\t{%2, %k0|%k0, %2}"
6562   [(set_attr "type" "alu")
6563    (set_attr "mode" "SI")])
6564
6565 (define_insn "*subsi_3"
6566   [(set (reg FLAGS_REG)
6567         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6568                  (match_operand:SI 2 "general_operand" "ri,rm")))
6569    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6570         (minus:SI (match_dup 1) (match_dup 2)))]
6571   "ix86_match_ccmode (insn, CCmode)
6572    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573   "sub{l}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "mode" "SI")])
6576
6577 (define_insn "*subsi_3_zext"
6578   [(set (reg FLAGS_REG)
6579         (compare (match_operand:SI 1 "register_operand" "0")
6580                  (match_operand:SI 2 "general_operand" "rim")))
6581    (set (match_operand:DI 0 "register_operand" "=r")
6582         (zero_extend:DI
6583           (minus:SI (match_dup 1)
6584                     (match_dup 2))))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sub{q}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "mode" "DI")])
6590
6591 (define_expand "subhi3"
6592   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6593                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6594                              (match_operand:HI 2 "general_operand" "")))
6595               (clobber (reg:CC FLAGS_REG))])]
6596   "TARGET_HIMODE_MATH"
6597   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6598
6599 (define_insn "*subhi_1"
6600   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6601         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6602                   (match_operand:HI 2 "general_operand" "ri,rm")))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6605   "sub{w}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "mode" "HI")])
6608
6609 (define_insn "*subhi_2"
6610   [(set (reg FLAGS_REG)
6611         (compare
6612           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6613                     (match_operand:HI 2 "general_operand" "ri,rm"))
6614           (const_int 0)))
6615    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6616         (minus:HI (match_dup 1) (match_dup 2)))]
6617   "ix86_match_ccmode (insn, CCGOCmode)
6618    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6619   "sub{w}\t{%2, %0|%0, %2}"
6620   [(set_attr "type" "alu")
6621    (set_attr "mode" "HI")])
6622
6623 (define_insn "*subhi_3"
6624   [(set (reg FLAGS_REG)
6625         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6626                  (match_operand:HI 2 "general_operand" "ri,rm")))
6627    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6628         (minus:HI (match_dup 1) (match_dup 2)))]
6629   "ix86_match_ccmode (insn, CCmode)
6630    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6631   "sub{w}\t{%2, %0|%0, %2}"
6632   [(set_attr "type" "alu")
6633    (set_attr "mode" "HI")])
6634
6635 (define_expand "subqi3"
6636   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6637                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6638                              (match_operand:QI 2 "general_operand" "")))
6639               (clobber (reg:CC FLAGS_REG))])]
6640   "TARGET_QIMODE_MATH"
6641   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6642
6643 (define_insn "*subqi_1"
6644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6645         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6646                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6647    (clobber (reg:CC FLAGS_REG))]
6648   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6649   "sub{b}\t{%2, %0|%0, %2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "mode" "QI")])
6652
6653 (define_insn "*subqi_1_slp"
6654   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6655         (minus:QI (match_dup 0)
6656                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6659    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6660   "sub{b}\t{%1, %0|%0, %1}"
6661   [(set_attr "type" "alu1")
6662    (set_attr "mode" "QI")])
6663
6664 (define_insn "*subqi_2"
6665   [(set (reg FLAGS_REG)
6666         (compare
6667           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6668                     (match_operand:QI 2 "general_operand" "qi,qm"))
6669           (const_int 0)))
6670    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6671         (minus:HI (match_dup 1) (match_dup 2)))]
6672   "ix86_match_ccmode (insn, CCGOCmode)
6673    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6674   "sub{b}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "QI")])
6677
6678 (define_insn "*subqi_3"
6679   [(set (reg FLAGS_REG)
6680         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6681                  (match_operand:QI 2 "general_operand" "qi,qm")))
6682    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6683         (minus:HI (match_dup 1) (match_dup 2)))]
6684   "ix86_match_ccmode (insn, CCmode)
6685    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6686   "sub{b}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "QI")])
6689
6690 ;; The patterns that match these are at the end of this file.
6691
6692 (define_expand "subxf3"
6693   [(set (match_operand:XF 0 "register_operand" "")
6694         (minus:XF (match_operand:XF 1 "register_operand" "")
6695                   (match_operand:XF 2 "register_operand" "")))]
6696   "TARGET_80387"
6697   "")
6698
6699 (define_expand "subdf3"
6700   [(set (match_operand:DF 0 "register_operand" "")
6701         (minus:DF (match_operand:DF 1 "register_operand" "")
6702                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6703   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6704   "")
6705
6706 (define_expand "subsf3"
6707   [(set (match_operand:SF 0 "register_operand" "")
6708         (minus:SF (match_operand:SF 1 "register_operand" "")
6709                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6710   "TARGET_80387 || TARGET_SSE_MATH"
6711   "")
6712 \f
6713 ;; Multiply instructions
6714
6715 (define_expand "muldi3"
6716   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6717                    (mult:DI (match_operand:DI 1 "register_operand" "")
6718                             (match_operand:DI 2 "x86_64_general_operand" "")))
6719               (clobber (reg:CC FLAGS_REG))])]
6720   "TARGET_64BIT"
6721   "")
6722
6723 (define_insn "*muldi3_1_rex64"
6724   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6725         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6726                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6727    (clobber (reg:CC FLAGS_REG))]
6728   "TARGET_64BIT
6729    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6730   "@
6731    imul{q}\t{%2, %1, %0|%0, %1, %2}
6732    imul{q}\t{%2, %1, %0|%0, %1, %2}
6733    imul{q}\t{%2, %0|%0, %2}"
6734   [(set_attr "type" "imul")
6735    (set_attr "prefix_0f" "0,0,1")
6736    (set (attr "athlon_decode")
6737         (cond [(eq_attr "cpu" "athlon")
6738                   (const_string "vector")
6739                (eq_attr "alternative" "1")
6740                   (const_string "vector")
6741                (and (eq_attr "alternative" "2")
6742                     (match_operand 1 "memory_operand" ""))
6743                   (const_string "vector")]
6744               (const_string "direct")))
6745    (set_attr "mode" "DI")])
6746
6747 (define_expand "mulsi3"
6748   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6749                    (mult:SI (match_operand:SI 1 "register_operand" "")
6750                             (match_operand:SI 2 "general_operand" "")))
6751               (clobber (reg:CC FLAGS_REG))])]
6752   ""
6753   "")
6754
6755 (define_insn "*mulsi3_1"
6756   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6757         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6758                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6761   "@
6762    imul{l}\t{%2, %1, %0|%0, %1, %2}
6763    imul{l}\t{%2, %1, %0|%0, %1, %2}
6764    imul{l}\t{%2, %0|%0, %2}"
6765   [(set_attr "type" "imul")
6766    (set_attr "prefix_0f" "0,0,1")
6767    (set (attr "athlon_decode")
6768         (cond [(eq_attr "cpu" "athlon")
6769                   (const_string "vector")
6770                (eq_attr "alternative" "1")
6771                   (const_string "vector")
6772                (and (eq_attr "alternative" "2")
6773                     (match_operand 1 "memory_operand" ""))
6774                   (const_string "vector")]
6775               (const_string "direct")))
6776    (set_attr "mode" "SI")])
6777
6778 (define_insn "*mulsi3_1_zext"
6779   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6780         (zero_extend:DI
6781           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6782                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6783    (clobber (reg:CC FLAGS_REG))]
6784   "TARGET_64BIT
6785    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6786   "@
6787    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6788    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6789    imul{l}\t{%2, %k0|%k0, %2}"
6790   [(set_attr "type" "imul")
6791    (set_attr "prefix_0f" "0,0,1")
6792    (set (attr "athlon_decode")
6793         (cond [(eq_attr "cpu" "athlon")
6794                   (const_string "vector")
6795                (eq_attr "alternative" "1")
6796                   (const_string "vector")
6797                (and (eq_attr "alternative" "2")
6798                     (match_operand 1 "memory_operand" ""))
6799                   (const_string "vector")]
6800               (const_string "direct")))
6801    (set_attr "mode" "SI")])
6802
6803 (define_expand "mulhi3"
6804   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6805                    (mult:HI (match_operand:HI 1 "register_operand" "")
6806                             (match_operand:HI 2 "general_operand" "")))
6807               (clobber (reg:CC FLAGS_REG))])]
6808   "TARGET_HIMODE_MATH"
6809   "")
6810
6811 (define_insn "*mulhi3_1"
6812   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6813         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6814                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6815    (clobber (reg:CC FLAGS_REG))]
6816   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6817   "@
6818    imul{w}\t{%2, %1, %0|%0, %1, %2}
6819    imul{w}\t{%2, %1, %0|%0, %1, %2}
6820    imul{w}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "imul")
6822    (set_attr "prefix_0f" "0,0,1")
6823    (set (attr "athlon_decode")
6824         (cond [(eq_attr "cpu" "athlon")
6825                   (const_string "vector")
6826                (eq_attr "alternative" "1,2")
6827                   (const_string "vector")]
6828               (const_string "direct")))
6829    (set_attr "mode" "HI")])
6830
6831 (define_expand "mulqi3"
6832   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6833                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6834                             (match_operand:QI 2 "register_operand" "")))
6835               (clobber (reg:CC FLAGS_REG))])]
6836   "TARGET_QIMODE_MATH"
6837   "")
6838
6839 (define_insn "*mulqi3_1"
6840   [(set (match_operand:QI 0 "register_operand" "=a")
6841         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6842                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "TARGET_QIMODE_MATH
6845    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6846   "mul{b}\t%2"
6847   [(set_attr "type" "imul")
6848    (set_attr "length_immediate" "0")
6849    (set (attr "athlon_decode")
6850      (if_then_else (eq_attr "cpu" "athlon")
6851         (const_string "vector")
6852         (const_string "direct")))
6853    (set_attr "mode" "QI")])
6854
6855 (define_expand "umulqihi3"
6856   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6857                    (mult:HI (zero_extend:HI
6858                               (match_operand:QI 1 "nonimmediate_operand" ""))
6859                             (zero_extend:HI
6860                               (match_operand:QI 2 "register_operand" ""))))
6861               (clobber (reg:CC FLAGS_REG))])]
6862   "TARGET_QIMODE_MATH"
6863   "")
6864
6865 (define_insn "*umulqihi3_1"
6866   [(set (match_operand:HI 0 "register_operand" "=a")
6867         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6868                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6869    (clobber (reg:CC FLAGS_REG))]
6870   "TARGET_QIMODE_MATH
6871    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6872   "mul{b}\t%2"
6873   [(set_attr "type" "imul")
6874    (set_attr "length_immediate" "0")
6875    (set (attr "athlon_decode")
6876      (if_then_else (eq_attr "cpu" "athlon")
6877         (const_string "vector")
6878         (const_string "direct")))
6879    (set_attr "mode" "QI")])
6880
6881 (define_expand "mulqihi3"
6882   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6883                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6884                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6885               (clobber (reg:CC FLAGS_REG))])]
6886   "TARGET_QIMODE_MATH"
6887   "")
6888
6889 (define_insn "*mulqihi3_insn"
6890   [(set (match_operand:HI 0 "register_operand" "=a")
6891         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6892                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6893    (clobber (reg:CC FLAGS_REG))]
6894   "TARGET_QIMODE_MATH
6895    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6896   "imul{b}\t%2"
6897   [(set_attr "type" "imul")
6898    (set_attr "length_immediate" "0")
6899    (set (attr "athlon_decode")
6900      (if_then_else (eq_attr "cpu" "athlon")
6901         (const_string "vector")
6902         (const_string "direct")))
6903    (set_attr "mode" "QI")])
6904
6905 (define_expand "umulditi3"
6906   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6907                    (mult:TI (zero_extend:TI
6908                               (match_operand:DI 1 "nonimmediate_operand" ""))
6909                             (zero_extend:TI
6910                               (match_operand:DI 2 "register_operand" ""))))
6911               (clobber (reg:CC FLAGS_REG))])]
6912   "TARGET_64BIT"
6913   "")
6914
6915 (define_insn "*umulditi3_insn"
6916   [(set (match_operand:TI 0 "register_operand" "=A")
6917         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6918                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6919    (clobber (reg:CC FLAGS_REG))]
6920   "TARGET_64BIT
6921    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6922   "mul{q}\t%2"
6923   [(set_attr "type" "imul")
6924    (set_attr "length_immediate" "0")
6925    (set (attr "athlon_decode")
6926      (if_then_else (eq_attr "cpu" "athlon")
6927         (const_string "vector")
6928         (const_string "double")))
6929    (set_attr "mode" "DI")])
6930
6931 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6932 (define_expand "umulsidi3"
6933   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6934                    (mult:DI (zero_extend:DI
6935                               (match_operand:SI 1 "nonimmediate_operand" ""))
6936                             (zero_extend:DI
6937                               (match_operand:SI 2 "register_operand" ""))))
6938               (clobber (reg:CC FLAGS_REG))])]
6939   "!TARGET_64BIT"
6940   "")
6941
6942 (define_insn "*umulsidi3_insn"
6943   [(set (match_operand:DI 0 "register_operand" "=A")
6944         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6945                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "!TARGET_64BIT
6948    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6949   "mul{l}\t%2"
6950   [(set_attr "type" "imul")
6951    (set_attr "length_immediate" "0")
6952    (set (attr "athlon_decode")
6953      (if_then_else (eq_attr "cpu" "athlon")
6954         (const_string "vector")
6955         (const_string "double")))
6956    (set_attr "mode" "SI")])
6957
6958 (define_expand "mulditi3"
6959   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6960                    (mult:TI (sign_extend:TI
6961                               (match_operand:DI 1 "nonimmediate_operand" ""))
6962                             (sign_extend:TI
6963                               (match_operand:DI 2 "register_operand" ""))))
6964               (clobber (reg:CC FLAGS_REG))])]
6965   "TARGET_64BIT"
6966   "")
6967
6968 (define_insn "*mulditi3_insn"
6969   [(set (match_operand:TI 0 "register_operand" "=A")
6970         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6971                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "TARGET_64BIT
6974    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6975   "imul{q}\t%2"
6976   [(set_attr "type" "imul")
6977    (set_attr "length_immediate" "0")
6978    (set (attr "athlon_decode")
6979      (if_then_else (eq_attr "cpu" "athlon")
6980         (const_string "vector")
6981         (const_string "double")))
6982    (set_attr "mode" "DI")])
6983
6984 (define_expand "mulsidi3"
6985   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6986                    (mult:DI (sign_extend:DI
6987                               (match_operand:SI 1 "nonimmediate_operand" ""))
6988                             (sign_extend:DI
6989                               (match_operand:SI 2 "register_operand" ""))))
6990               (clobber (reg:CC FLAGS_REG))])]
6991   "!TARGET_64BIT"
6992   "")
6993
6994 (define_insn "*mulsidi3_insn"
6995   [(set (match_operand:DI 0 "register_operand" "=A")
6996         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6997                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6998    (clobber (reg:CC FLAGS_REG))]
6999   "!TARGET_64BIT
7000    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001   "imul{l}\t%2"
7002   [(set_attr "type" "imul")
7003    (set_attr "length_immediate" "0")
7004    (set (attr "athlon_decode")
7005      (if_then_else (eq_attr "cpu" "athlon")
7006         (const_string "vector")
7007         (const_string "double")))
7008    (set_attr "mode" "SI")])
7009
7010 (define_expand "umuldi3_highpart"
7011   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7012                    (truncate:DI
7013                      (lshiftrt:TI
7014                        (mult:TI (zero_extend:TI
7015                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7016                                 (zero_extend:TI
7017                                   (match_operand:DI 2 "register_operand" "")))
7018                        (const_int 64))))
7019               (clobber (match_scratch:DI 3 ""))
7020               (clobber (reg:CC FLAGS_REG))])]
7021   "TARGET_64BIT"
7022   "")
7023
7024 (define_insn "*umuldi3_highpart_rex64"
7025   [(set (match_operand:DI 0 "register_operand" "=d")
7026         (truncate:DI
7027           (lshiftrt:TI
7028             (mult:TI (zero_extend:TI
7029                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7030                      (zero_extend:TI
7031                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7032             (const_int 64))))
7033    (clobber (match_scratch:DI 3 "=1"))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "TARGET_64BIT
7036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7037   "mul{q}\t%2"
7038   [(set_attr "type" "imul")
7039    (set_attr "length_immediate" "0")
7040    (set (attr "athlon_decode")
7041      (if_then_else (eq_attr "cpu" "athlon")
7042         (const_string "vector")
7043         (const_string "double")))
7044    (set_attr "mode" "DI")])
7045
7046 (define_expand "umulsi3_highpart"
7047   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7048                    (truncate:SI
7049                      (lshiftrt:DI
7050                        (mult:DI (zero_extend:DI
7051                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7052                                 (zero_extend:DI
7053                                   (match_operand:SI 2 "register_operand" "")))
7054                        (const_int 32))))
7055               (clobber (match_scratch:SI 3 ""))
7056               (clobber (reg:CC FLAGS_REG))])]
7057   ""
7058   "")
7059
7060 (define_insn "*umulsi3_highpart_insn"
7061   [(set (match_operand:SI 0 "register_operand" "=d")
7062         (truncate:SI
7063           (lshiftrt:DI
7064             (mult:DI (zero_extend:DI
7065                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7066                      (zero_extend:DI
7067                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7068             (const_int 32))))
7069    (clobber (match_scratch:SI 3 "=1"))
7070    (clobber (reg:CC FLAGS_REG))]
7071   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7072   "mul{l}\t%2"
7073   [(set_attr "type" "imul")
7074    (set_attr "length_immediate" "0")
7075    (set (attr "athlon_decode")
7076      (if_then_else (eq_attr "cpu" "athlon")
7077         (const_string "vector")
7078         (const_string "double")))
7079    (set_attr "mode" "SI")])
7080
7081 (define_insn "*umulsi3_highpart_zext"
7082   [(set (match_operand:DI 0 "register_operand" "=d")
7083         (zero_extend:DI (truncate:SI
7084           (lshiftrt:DI
7085             (mult:DI (zero_extend:DI
7086                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7087                      (zero_extend:DI
7088                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7089             (const_int 32)))))
7090    (clobber (match_scratch:SI 3 "=1"))
7091    (clobber (reg:CC FLAGS_REG))]
7092   "TARGET_64BIT
7093    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7094   "mul{l}\t%2"
7095   [(set_attr "type" "imul")
7096    (set_attr "length_immediate" "0")
7097    (set (attr "athlon_decode")
7098      (if_then_else (eq_attr "cpu" "athlon")
7099         (const_string "vector")
7100         (const_string "double")))
7101    (set_attr "mode" "SI")])
7102
7103 (define_expand "smuldi3_highpart"
7104   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7105                    (truncate:DI
7106                      (lshiftrt:TI
7107                        (mult:TI (sign_extend:TI
7108                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7109                                 (sign_extend:TI
7110                                   (match_operand:DI 2 "register_operand" "")))
7111                        (const_int 64))))
7112               (clobber (match_scratch:DI 3 ""))
7113               (clobber (reg:CC FLAGS_REG))])]
7114   "TARGET_64BIT"
7115   "")
7116
7117 (define_insn "*smuldi3_highpart_rex64"
7118   [(set (match_operand:DI 0 "register_operand" "=d")
7119         (truncate:DI
7120           (lshiftrt:TI
7121             (mult:TI (sign_extend:TI
7122                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7123                      (sign_extend:TI
7124                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7125             (const_int 64))))
7126    (clobber (match_scratch:DI 3 "=1"))
7127    (clobber (reg:CC FLAGS_REG))]
7128   "TARGET_64BIT
7129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7130   "imul{q}\t%2"
7131   [(set_attr "type" "imul")
7132    (set (attr "athlon_decode")
7133      (if_then_else (eq_attr "cpu" "athlon")
7134         (const_string "vector")
7135         (const_string "double")))
7136    (set_attr "mode" "DI")])
7137
7138 (define_expand "smulsi3_highpart"
7139   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7140                    (truncate:SI
7141                      (lshiftrt:DI
7142                        (mult:DI (sign_extend:DI
7143                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7144                                 (sign_extend:DI
7145                                   (match_operand:SI 2 "register_operand" "")))
7146                        (const_int 32))))
7147               (clobber (match_scratch:SI 3 ""))
7148               (clobber (reg:CC FLAGS_REG))])]
7149   ""
7150   "")
7151
7152 (define_insn "*smulsi3_highpart_insn"
7153   [(set (match_operand:SI 0 "register_operand" "=d")
7154         (truncate:SI
7155           (lshiftrt:DI
7156             (mult:DI (sign_extend:DI
7157                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7158                      (sign_extend:DI
7159                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7160             (const_int 32))))
7161    (clobber (match_scratch:SI 3 "=1"))
7162    (clobber (reg:CC FLAGS_REG))]
7163   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7164   "imul{l}\t%2"
7165   [(set_attr "type" "imul")
7166    (set (attr "athlon_decode")
7167      (if_then_else (eq_attr "cpu" "athlon")
7168         (const_string "vector")
7169         (const_string "double")))
7170    (set_attr "mode" "SI")])
7171
7172 (define_insn "*smulsi3_highpart_zext"
7173   [(set (match_operand:DI 0 "register_operand" "=d")
7174         (zero_extend:DI (truncate:SI
7175           (lshiftrt:DI
7176             (mult:DI (sign_extend:DI
7177                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7178                      (sign_extend:DI
7179                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7180             (const_int 32)))))
7181    (clobber (match_scratch:SI 3 "=1"))
7182    (clobber (reg:CC FLAGS_REG))]
7183   "TARGET_64BIT
7184    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7185   "imul{l}\t%2"
7186   [(set_attr "type" "imul")
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" "SI")])
7192
7193 ;; The patterns that match these are at the end of this file.
7194
7195 (define_expand "mulxf3"
7196   [(set (match_operand:XF 0 "register_operand" "")
7197         (mult:XF (match_operand:XF 1 "register_operand" "")
7198                  (match_operand:XF 2 "register_operand" "")))]
7199   "TARGET_80387"
7200   "")
7201
7202 (define_expand "muldf3"
7203   [(set (match_operand:DF 0 "register_operand" "")
7204         (mult:DF (match_operand:DF 1 "register_operand" "")
7205                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7206   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7207   "")
7208
7209 (define_expand "mulsf3"
7210   [(set (match_operand:SF 0 "register_operand" "")
7211         (mult:SF (match_operand:SF 1 "register_operand" "")
7212                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7213   "TARGET_80387 || TARGET_SSE_MATH"
7214   "")
7215 \f
7216 ;; Divide instructions
7217
7218 (define_insn "divqi3"
7219   [(set (match_operand:QI 0 "register_operand" "=a")
7220         (div:QI (match_operand:HI 1 "register_operand" "0")
7221                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7222    (clobber (reg:CC FLAGS_REG))]
7223   "TARGET_QIMODE_MATH"
7224   "idiv{b}\t%2"
7225   [(set_attr "type" "idiv")
7226    (set_attr "mode" "QI")])
7227
7228 (define_insn "udivqi3"
7229   [(set (match_operand:QI 0 "register_operand" "=a")
7230         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7231                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_QIMODE_MATH"
7234   "div{b}\t%2"
7235   [(set_attr "type" "idiv")
7236    (set_attr "mode" "QI")])
7237
7238 ;; The patterns that match these are at the end of this file.
7239
7240 (define_expand "divxf3"
7241   [(set (match_operand:XF 0 "register_operand" "")
7242         (div:XF (match_operand:XF 1 "register_operand" "")
7243                 (match_operand:XF 2 "register_operand" "")))]
7244   "TARGET_80387"
7245   "")
7246
7247 (define_expand "divdf3"
7248   [(set (match_operand:DF 0 "register_operand" "")
7249         (div:DF (match_operand:DF 1 "register_operand" "")
7250                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7251    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7252    "")
7253  
7254 (define_expand "divsf3"
7255   [(set (match_operand:SF 0 "register_operand" "")
7256         (div:SF (match_operand:SF 1 "register_operand" "")
7257                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7258   "TARGET_80387 || TARGET_SSE_MATH"
7259   "")
7260 \f
7261 ;; Remainder instructions.
7262
7263 (define_expand "divmoddi4"
7264   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7265                    (div:DI (match_operand:DI 1 "register_operand" "")
7266                            (match_operand:DI 2 "nonimmediate_operand" "")))
7267               (set (match_operand:DI 3 "register_operand" "")
7268                    (mod:DI (match_dup 1) (match_dup 2)))
7269               (clobber (reg:CC FLAGS_REG))])]
7270   "TARGET_64BIT"
7271   "")
7272
7273 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7274 ;; Penalize eax case slightly because it results in worse scheduling
7275 ;; of code.
7276 (define_insn "*divmoddi4_nocltd_rex64"
7277   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7278         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7279                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7280    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7281         (mod:DI (match_dup 2) (match_dup 3)))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7284   "#"
7285   [(set_attr "type" "multi")])
7286
7287 (define_insn "*divmoddi4_cltd_rex64"
7288   [(set (match_operand:DI 0 "register_operand" "=a")
7289         (div:DI (match_operand:DI 2 "register_operand" "a")
7290                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7291    (set (match_operand:DI 1 "register_operand" "=&d")
7292         (mod:DI (match_dup 2) (match_dup 3)))
7293    (clobber (reg:CC FLAGS_REG))]
7294   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7295   "#"
7296   [(set_attr "type" "multi")])
7297
7298 (define_insn "*divmoddi_noext_rex64"
7299   [(set (match_operand:DI 0 "register_operand" "=a")
7300         (div:DI (match_operand:DI 1 "register_operand" "0")
7301                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7302    (set (match_operand:DI 3 "register_operand" "=d")
7303         (mod:DI (match_dup 1) (match_dup 2)))
7304    (use (match_operand:DI 4 "register_operand" "3"))
7305    (clobber (reg:CC FLAGS_REG))]
7306   "TARGET_64BIT"
7307   "idiv{q}\t%2"
7308   [(set_attr "type" "idiv")
7309    (set_attr "mode" "DI")])
7310
7311 (define_split
7312   [(set (match_operand:DI 0 "register_operand" "")
7313         (div:DI (match_operand:DI 1 "register_operand" "")
7314                 (match_operand:DI 2 "nonimmediate_operand" "")))
7315    (set (match_operand:DI 3 "register_operand" "")
7316         (mod:DI (match_dup 1) (match_dup 2)))
7317    (clobber (reg:CC FLAGS_REG))]
7318   "TARGET_64BIT && reload_completed"
7319   [(parallel [(set (match_dup 3)
7320                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7321               (clobber (reg:CC FLAGS_REG))])
7322    (parallel [(set (match_dup 0)
7323                    (div:DI (reg:DI 0) (match_dup 2)))
7324               (set (match_dup 3)
7325                    (mod:DI (reg:DI 0) (match_dup 2)))
7326               (use (match_dup 3))
7327               (clobber (reg:CC FLAGS_REG))])]
7328 {
7329   /* Avoid use of cltd in favor of a mov+shift.  */
7330   if (!TARGET_USE_CLTD && !optimize_size)
7331     {
7332       if (true_regnum (operands[1]))
7333         emit_move_insn (operands[0], operands[1]);
7334       else
7335         emit_move_insn (operands[3], operands[1]);
7336       operands[4] = operands[3];
7337     }
7338   else
7339     {
7340       if (true_regnum (operands[1]))
7341         abort();
7342       operands[4] = operands[1];
7343     }
7344 })
7345
7346
7347 (define_expand "divmodsi4"
7348   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7349                    (div:SI (match_operand:SI 1 "register_operand" "")
7350                            (match_operand:SI 2 "nonimmediate_operand" "")))
7351               (set (match_operand:SI 3 "register_operand" "")
7352                    (mod:SI (match_dup 1) (match_dup 2)))
7353               (clobber (reg:CC FLAGS_REG))])]
7354   ""
7355   "")
7356
7357 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7358 ;; Penalize eax case slightly because it results in worse scheduling
7359 ;; of code.
7360 (define_insn "*divmodsi4_nocltd"
7361   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7362         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7363                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7364    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7365         (mod:SI (match_dup 2) (match_dup 3)))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "!optimize_size && !TARGET_USE_CLTD"
7368   "#"
7369   [(set_attr "type" "multi")])
7370
7371 (define_insn "*divmodsi4_cltd"
7372   [(set (match_operand:SI 0 "register_operand" "=a")
7373         (div:SI (match_operand:SI 2 "register_operand" "a")
7374                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7375    (set (match_operand:SI 1 "register_operand" "=&d")
7376         (mod:SI (match_dup 2) (match_dup 3)))
7377    (clobber (reg:CC FLAGS_REG))]
7378   "optimize_size || TARGET_USE_CLTD"
7379   "#"
7380   [(set_attr "type" "multi")])
7381
7382 (define_insn "*divmodsi_noext"
7383   [(set (match_operand:SI 0 "register_operand" "=a")
7384         (div:SI (match_operand:SI 1 "register_operand" "0")
7385                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7386    (set (match_operand:SI 3 "register_operand" "=d")
7387         (mod:SI (match_dup 1) (match_dup 2)))
7388    (use (match_operand:SI 4 "register_operand" "3"))
7389    (clobber (reg:CC FLAGS_REG))]
7390   ""
7391   "idiv{l}\t%2"
7392   [(set_attr "type" "idiv")
7393    (set_attr "mode" "SI")])
7394
7395 (define_split
7396   [(set (match_operand:SI 0 "register_operand" "")
7397         (div:SI (match_operand:SI 1 "register_operand" "")
7398                 (match_operand:SI 2 "nonimmediate_operand" "")))
7399    (set (match_operand:SI 3 "register_operand" "")
7400         (mod:SI (match_dup 1) (match_dup 2)))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "reload_completed"
7403   [(parallel [(set (match_dup 3)
7404                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7405               (clobber (reg:CC FLAGS_REG))])
7406    (parallel [(set (match_dup 0)
7407                    (div:SI (reg:SI 0) (match_dup 2)))
7408               (set (match_dup 3)
7409                    (mod:SI (reg:SI 0) (match_dup 2)))
7410               (use (match_dup 3))
7411               (clobber (reg:CC FLAGS_REG))])]
7412 {
7413   /* Avoid use of cltd in favor of a mov+shift.  */
7414   if (!TARGET_USE_CLTD && !optimize_size)
7415     {
7416       if (true_regnum (operands[1]))
7417         emit_move_insn (operands[0], operands[1]);
7418       else
7419         emit_move_insn (operands[3], operands[1]);
7420       operands[4] = operands[3];
7421     }
7422   else
7423     {
7424       if (true_regnum (operands[1]))
7425         abort();
7426       operands[4] = operands[1];
7427     }
7428 })
7429 ;; %%% Split me.
7430 (define_insn "divmodhi4"
7431   [(set (match_operand:HI 0 "register_operand" "=a")
7432         (div:HI (match_operand:HI 1 "register_operand" "0")
7433                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7434    (set (match_operand:HI 3 "register_operand" "=&d")
7435         (mod:HI (match_dup 1) (match_dup 2)))
7436    (clobber (reg:CC FLAGS_REG))]
7437   "TARGET_HIMODE_MATH"
7438   "cwtd\;idiv{w}\t%2"
7439   [(set_attr "type" "multi")
7440    (set_attr "length_immediate" "0")
7441    (set_attr "mode" "SI")])
7442
7443 (define_insn "udivmoddi4"
7444   [(set (match_operand:DI 0 "register_operand" "=a")
7445         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7446                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7447    (set (match_operand:DI 3 "register_operand" "=&d")
7448         (umod:DI (match_dup 1) (match_dup 2)))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT"
7451   "xor{q}\t%3, %3\;div{q}\t%2"
7452   [(set_attr "type" "multi")
7453    (set_attr "length_immediate" "0")
7454    (set_attr "mode" "DI")])
7455
7456 (define_insn "*udivmoddi4_noext"
7457   [(set (match_operand:DI 0 "register_operand" "=a")
7458         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7459                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7460    (set (match_operand:DI 3 "register_operand" "=d")
7461         (umod:DI (match_dup 1) (match_dup 2)))
7462    (use (match_dup 3))
7463    (clobber (reg:CC FLAGS_REG))]
7464   "TARGET_64BIT"
7465   "div{q}\t%2"
7466   [(set_attr "type" "idiv")
7467    (set_attr "mode" "DI")])
7468
7469 (define_split
7470   [(set (match_operand:DI 0 "register_operand" "")
7471         (udiv:DI (match_operand:DI 1 "register_operand" "")
7472                  (match_operand:DI 2 "nonimmediate_operand" "")))
7473    (set (match_operand:DI 3 "register_operand" "")
7474         (umod:DI (match_dup 1) (match_dup 2)))
7475    (clobber (reg:CC FLAGS_REG))]
7476   "TARGET_64BIT && reload_completed"
7477   [(set (match_dup 3) (const_int 0))
7478    (parallel [(set (match_dup 0)
7479                    (udiv:DI (match_dup 1) (match_dup 2)))
7480               (set (match_dup 3)
7481                    (umod:DI (match_dup 1) (match_dup 2)))
7482               (use (match_dup 3))
7483               (clobber (reg:CC FLAGS_REG))])]
7484   "")
7485
7486 (define_insn "udivmodsi4"
7487   [(set (match_operand:SI 0 "register_operand" "=a")
7488         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7489                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490    (set (match_operand:SI 3 "register_operand" "=&d")
7491         (umod:SI (match_dup 1) (match_dup 2)))
7492    (clobber (reg:CC FLAGS_REG))]
7493   ""
7494   "xor{l}\t%3, %3\;div{l}\t%2"
7495   [(set_attr "type" "multi")
7496    (set_attr "length_immediate" "0")
7497    (set_attr "mode" "SI")])
7498
7499 (define_insn "*udivmodsi4_noext"
7500   [(set (match_operand:SI 0 "register_operand" "=a")
7501         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7502                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7503    (set (match_operand:SI 3 "register_operand" "=d")
7504         (umod:SI (match_dup 1) (match_dup 2)))
7505    (use (match_dup 3))
7506    (clobber (reg:CC FLAGS_REG))]
7507   ""
7508   "div{l}\t%2"
7509   [(set_attr "type" "idiv")
7510    (set_attr "mode" "SI")])
7511
7512 (define_split
7513   [(set (match_operand:SI 0 "register_operand" "")
7514         (udiv:SI (match_operand:SI 1 "register_operand" "")
7515                  (match_operand:SI 2 "nonimmediate_operand" "")))
7516    (set (match_operand:SI 3 "register_operand" "")
7517         (umod:SI (match_dup 1) (match_dup 2)))
7518    (clobber (reg:CC FLAGS_REG))]
7519   "reload_completed"
7520   [(set (match_dup 3) (const_int 0))
7521    (parallel [(set (match_dup 0)
7522                    (udiv:SI (match_dup 1) (match_dup 2)))
7523               (set (match_dup 3)
7524                    (umod:SI (match_dup 1) (match_dup 2)))
7525               (use (match_dup 3))
7526               (clobber (reg:CC FLAGS_REG))])]
7527   "")
7528
7529 (define_expand "udivmodhi4"
7530   [(set (match_dup 4) (const_int 0))
7531    (parallel [(set (match_operand:HI 0 "register_operand" "")
7532                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7533                             (match_operand:HI 2 "nonimmediate_operand" "")))
7534               (set (match_operand:HI 3 "register_operand" "")
7535                    (umod:HI (match_dup 1) (match_dup 2)))
7536               (use (match_dup 4))
7537               (clobber (reg:CC FLAGS_REG))])]
7538   "TARGET_HIMODE_MATH"
7539   "operands[4] = gen_reg_rtx (HImode);")
7540
7541 (define_insn "*udivmodhi_noext"
7542   [(set (match_operand:HI 0 "register_operand" "=a")
7543         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7544                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7545    (set (match_operand:HI 3 "register_operand" "=d")
7546         (umod:HI (match_dup 1) (match_dup 2)))
7547    (use (match_operand:HI 4 "register_operand" "3"))
7548    (clobber (reg:CC FLAGS_REG))]
7549   ""
7550   "div{w}\t%2"
7551   [(set_attr "type" "idiv")
7552    (set_attr "mode" "HI")])
7553
7554 ;; We cannot use div/idiv for double division, because it causes
7555 ;; "division by zero" on the overflow and that's not what we expect
7556 ;; from truncate.  Because true (non truncating) double division is
7557 ;; never generated, we can't create this insn anyway.
7558 ;
7559 ;(define_insn ""
7560 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7561 ;       (truncate:SI
7562 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7563 ;                  (zero_extend:DI
7564 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7565 ;   (set (match_operand:SI 3 "register_operand" "=d")
7566 ;       (truncate:SI
7567 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7568 ;   (clobber (reg:CC FLAGS_REG))]
7569 ;  ""
7570 ;  "div{l}\t{%2, %0|%0, %2}"
7571 ;  [(set_attr "type" "idiv")])
7572 \f
7573 ;;- Logical AND instructions
7574
7575 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7576 ;; Note that this excludes ah.
7577
7578 (define_insn "*testdi_1_rex64"
7579   [(set (reg FLAGS_REG)
7580         (compare
7581           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7582                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7583           (const_int 0)))]
7584   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7585    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7586   "@
7587    test{l}\t{%k1, %k0|%k0, %k1}
7588    test{l}\t{%k1, %k0|%k0, %k1}
7589    test{q}\t{%1, %0|%0, %1}
7590    test{q}\t{%1, %0|%0, %1}
7591    test{q}\t{%1, %0|%0, %1}"
7592   [(set_attr "type" "test")
7593    (set_attr "modrm" "0,1,0,1,1")
7594    (set_attr "mode" "SI,SI,DI,DI,DI")
7595    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7596
7597 (define_insn "testsi_1"
7598   [(set (reg FLAGS_REG)
7599         (compare
7600           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7601                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7602           (const_int 0)))]
7603   "ix86_match_ccmode (insn, CCNOmode)
7604    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7605   "test{l}\t{%1, %0|%0, %1}"
7606   [(set_attr "type" "test")
7607    (set_attr "modrm" "0,1,1")
7608    (set_attr "mode" "SI")
7609    (set_attr "pent_pair" "uv,np,uv")])
7610
7611 (define_expand "testsi_ccno_1"
7612   [(set (reg:CCNO FLAGS_REG)
7613         (compare:CCNO
7614           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7615                   (match_operand:SI 1 "nonmemory_operand" ""))
7616           (const_int 0)))]
7617   ""
7618   "")
7619
7620 (define_insn "*testhi_1"
7621   [(set (reg FLAGS_REG)
7622         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7623                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7624                  (const_int 0)))]
7625   "ix86_match_ccmode (insn, CCNOmode)
7626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7627   "test{w}\t{%1, %0|%0, %1}"
7628   [(set_attr "type" "test")
7629    (set_attr "modrm" "0,1,1")
7630    (set_attr "mode" "HI")
7631    (set_attr "pent_pair" "uv,np,uv")])
7632
7633 (define_expand "testqi_ccz_1"
7634   [(set (reg:CCZ FLAGS_REG)
7635         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7636                              (match_operand:QI 1 "nonmemory_operand" ""))
7637                  (const_int 0)))]
7638   ""
7639   "")
7640
7641 (define_insn "*testqi_1_maybe_si"
7642   [(set (reg FLAGS_REG)
7643         (compare
7644           (and:QI
7645             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7646             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7647           (const_int 0)))]
7648    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7649     && ix86_match_ccmode (insn,
7650                          GET_CODE (operands[1]) == CONST_INT
7651                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7652 {
7653   if (which_alternative == 3)
7654     {
7655       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7656         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7657       return "test{l}\t{%1, %k0|%k0, %1}";
7658     }
7659   return "test{b}\t{%1, %0|%0, %1}";
7660 }
7661   [(set_attr "type" "test")
7662    (set_attr "modrm" "0,1,1,1")
7663    (set_attr "mode" "QI,QI,QI,SI")
7664    (set_attr "pent_pair" "uv,np,uv,np")])
7665
7666 (define_insn "*testqi_1"
7667   [(set (reg FLAGS_REG)
7668         (compare
7669           (and:QI
7670             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7671             (match_operand:QI 1 "general_operand" "n,n,qn"))
7672           (const_int 0)))]
7673   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7674    && ix86_match_ccmode (insn, CCNOmode)"
7675   "test{b}\t{%1, %0|%0, %1}"
7676   [(set_attr "type" "test")
7677    (set_attr "modrm" "0,1,1")
7678    (set_attr "mode" "QI")
7679    (set_attr "pent_pair" "uv,np,uv")])
7680
7681 (define_expand "testqi_ext_ccno_0"
7682   [(set (reg:CCNO FLAGS_REG)
7683         (compare:CCNO
7684           (and:SI
7685             (zero_extract:SI
7686               (match_operand 0 "ext_register_operand" "")
7687               (const_int 8)
7688               (const_int 8))
7689             (match_operand 1 "const_int_operand" ""))
7690           (const_int 0)))]
7691   ""
7692   "")
7693
7694 (define_insn "*testqi_ext_0"
7695   [(set (reg FLAGS_REG)
7696         (compare
7697           (and:SI
7698             (zero_extract:SI
7699               (match_operand 0 "ext_register_operand" "Q")
7700               (const_int 8)
7701               (const_int 8))
7702             (match_operand 1 "const_int_operand" "n"))
7703           (const_int 0)))]
7704   "ix86_match_ccmode (insn, CCNOmode)"
7705   "test{b}\t{%1, %h0|%h0, %1}"
7706   [(set_attr "type" "test")
7707    (set_attr "mode" "QI")
7708    (set_attr "length_immediate" "1")
7709    (set_attr "pent_pair" "np")])
7710
7711 (define_insn "*testqi_ext_1"
7712   [(set (reg FLAGS_REG)
7713         (compare
7714           (and:SI
7715             (zero_extract:SI
7716               (match_operand 0 "ext_register_operand" "Q")
7717               (const_int 8)
7718               (const_int 8))
7719             (zero_extend:SI
7720               (match_operand:QI 1 "general_operand" "Qm")))
7721           (const_int 0)))]
7722   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724   "test{b}\t{%1, %h0|%h0, %1}"
7725   [(set_attr "type" "test")
7726    (set_attr "mode" "QI")])
7727
7728 (define_insn "*testqi_ext_1_rex64"
7729   [(set (reg FLAGS_REG)
7730         (compare
7731           (and:SI
7732             (zero_extract:SI
7733               (match_operand 0 "ext_register_operand" "Q")
7734               (const_int 8)
7735               (const_int 8))
7736             (zero_extend:SI
7737               (match_operand:QI 1 "register_operand" "Q")))
7738           (const_int 0)))]
7739   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7740   "test{b}\t{%1, %h0|%h0, %1}"
7741   [(set_attr "type" "test")
7742    (set_attr "mode" "QI")])
7743
7744 (define_insn "*testqi_ext_2"
7745   [(set (reg FLAGS_REG)
7746         (compare
7747           (and:SI
7748             (zero_extract:SI
7749               (match_operand 0 "ext_register_operand" "Q")
7750               (const_int 8)
7751               (const_int 8))
7752             (zero_extract:SI
7753               (match_operand 1 "ext_register_operand" "Q")
7754               (const_int 8)
7755               (const_int 8)))
7756           (const_int 0)))]
7757   "ix86_match_ccmode (insn, CCNOmode)"
7758   "test{b}\t{%h1, %h0|%h0, %h1}"
7759   [(set_attr "type" "test")
7760    (set_attr "mode" "QI")])
7761
7762 ;; Combine likes to form bit extractions for some tests.  Humor it.
7763 (define_insn "*testqi_ext_3"
7764   [(set (reg FLAGS_REG)
7765         (compare (zero_extract:SI
7766                    (match_operand 0 "nonimmediate_operand" "rm")
7767                    (match_operand:SI 1 "const_int_operand" "")
7768                    (match_operand:SI 2 "const_int_operand" ""))
7769                  (const_int 0)))]
7770   "ix86_match_ccmode (insn, CCNOmode)
7771    && (GET_MODE (operands[0]) == SImode
7772        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7773        || GET_MODE (operands[0]) == HImode
7774        || GET_MODE (operands[0]) == QImode)"
7775   "#")
7776
7777 (define_insn "*testqi_ext_3_rex64"
7778   [(set (reg FLAGS_REG)
7779         (compare (zero_extract:DI
7780                    (match_operand 0 "nonimmediate_operand" "rm")
7781                    (match_operand:DI 1 "const_int_operand" "")
7782                    (match_operand:DI 2 "const_int_operand" ""))
7783                  (const_int 0)))]
7784   "TARGET_64BIT
7785    && ix86_match_ccmode (insn, CCNOmode)
7786    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7787    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7788    /* Ensure that resulting mask is zero or sign extended operand.  */
7789    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7790        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7791            && INTVAL (operands[1]) > 32))
7792    && (GET_MODE (operands[0]) == SImode
7793        || GET_MODE (operands[0]) == DImode
7794        || GET_MODE (operands[0]) == HImode
7795        || GET_MODE (operands[0]) == QImode)"
7796   "#")
7797
7798 (define_split
7799   [(set (match_operand 0 "flags_reg_operand" "")
7800         (match_operator 1 "compare_operator"
7801           [(zero_extract
7802              (match_operand 2 "nonimmediate_operand" "")
7803              (match_operand 3 "const_int_operand" "")
7804              (match_operand 4 "const_int_operand" ""))
7805            (const_int 0)]))]
7806   "ix86_match_ccmode (insn, CCNOmode)"
7807   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7808 {
7809   rtx val = operands[2];
7810   HOST_WIDE_INT len = INTVAL (operands[3]);
7811   HOST_WIDE_INT pos = INTVAL (operands[4]);
7812   HOST_WIDE_INT mask;
7813   enum machine_mode mode, submode;
7814
7815   mode = GET_MODE (val);
7816   if (GET_CODE (val) == MEM)
7817     {
7818       /* ??? Combine likes to put non-volatile mem extractions in QImode
7819          no matter the size of the test.  So find a mode that works.  */
7820       if (! MEM_VOLATILE_P (val))
7821         {
7822           mode = smallest_mode_for_size (pos + len, MODE_INT);
7823           val = adjust_address (val, mode, 0);
7824         }
7825     }
7826   else if (GET_CODE (val) == SUBREG
7827            && (submode = GET_MODE (SUBREG_REG (val)),
7828                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7829            && pos + len <= GET_MODE_BITSIZE (submode))
7830     {
7831       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7832       mode = submode;
7833       val = SUBREG_REG (val);
7834     }
7835   else if (mode == HImode && pos + len <= 8)
7836     {
7837       /* Small HImode tests can be converted to QImode.  */
7838       mode = QImode;
7839       val = gen_lowpart (QImode, val);
7840     }
7841
7842   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7843   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7844
7845   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7846 })
7847
7848 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7849 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7850 ;; this is relatively important trick.
7851 ;; Do the conversion only post-reload to avoid limiting of the register class
7852 ;; to QI regs.
7853 (define_split
7854   [(set (match_operand 0 "flags_reg_operand" "")
7855         (match_operator 1 "compare_operator"
7856           [(and (match_operand 2 "register_operand" "")
7857                 (match_operand 3 "const_int_operand" ""))
7858            (const_int 0)]))]
7859    "reload_completed
7860     && QI_REG_P (operands[2])
7861     && GET_MODE (operands[2]) != QImode
7862     && ((ix86_match_ccmode (insn, CCZmode)
7863          && !(INTVAL (operands[3]) & ~(255 << 8)))
7864         || (ix86_match_ccmode (insn, CCNOmode)
7865             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7866   [(set (match_dup 0)
7867         (match_op_dup 1
7868           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7869                    (match_dup 3))
7870            (const_int 0)]))]
7871   "operands[2] = gen_lowpart (SImode, operands[2]);
7872    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7873
7874 (define_split
7875   [(set (match_operand 0 "flags_reg_operand" "")
7876         (match_operator 1 "compare_operator"
7877           [(and (match_operand 2 "nonimmediate_operand" "")
7878                 (match_operand 3 "const_int_operand" ""))
7879            (const_int 0)]))]
7880    "reload_completed
7881     && GET_MODE (operands[2]) != QImode
7882     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7883     && ((ix86_match_ccmode (insn, CCZmode)
7884          && !(INTVAL (operands[3]) & ~255))
7885         || (ix86_match_ccmode (insn, CCNOmode)
7886             && !(INTVAL (operands[3]) & ~127)))"
7887   [(set (match_dup 0)
7888         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7889                          (const_int 0)]))]
7890   "operands[2] = gen_lowpart (QImode, operands[2]);
7891    operands[3] = gen_lowpart (QImode, operands[3]);")
7892
7893
7894 ;; %%% This used to optimize known byte-wide and operations to memory,
7895 ;; and sometimes to QImode registers.  If this is considered useful,
7896 ;; it should be done with splitters.
7897
7898 (define_expand "anddi3"
7899   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7900         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7901                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7902    (clobber (reg:CC FLAGS_REG))]
7903   "TARGET_64BIT"
7904   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7905
7906 (define_insn "*anddi_1_rex64"
7907   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7908         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7909                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7910    (clobber (reg:CC FLAGS_REG))]
7911   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7912 {
7913   switch (get_attr_type (insn))
7914     {
7915     case TYPE_IMOVX:
7916       {
7917         enum machine_mode mode;
7918
7919         if (GET_CODE (operands[2]) != CONST_INT)
7920           abort ();
7921         if (INTVAL (operands[2]) == 0xff)
7922           mode = QImode;
7923         else if (INTVAL (operands[2]) == 0xffff)
7924           mode = HImode;
7925         else
7926           abort ();
7927         
7928         operands[1] = gen_lowpart (mode, operands[1]);
7929         if (mode == QImode)
7930           return "movz{bq|x}\t{%1,%0|%0, %1}";
7931         else
7932           return "movz{wq|x}\t{%1,%0|%0, %1}";
7933       }
7934
7935     default:
7936       if (! rtx_equal_p (operands[0], operands[1]))
7937         abort ();
7938       if (get_attr_mode (insn) == MODE_SI)
7939         return "and{l}\t{%k2, %k0|%k0, %k2}";
7940       else
7941         return "and{q}\t{%2, %0|%0, %2}";
7942     }
7943 }
7944   [(set_attr "type" "alu,alu,alu,imovx")
7945    (set_attr "length_immediate" "*,*,*,0")
7946    (set_attr "mode" "SI,DI,DI,DI")])
7947
7948 (define_insn "*anddi_2"
7949   [(set (reg FLAGS_REG)
7950         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7951                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7952                  (const_int 0)))
7953    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7954         (and:DI (match_dup 1) (match_dup 2)))]
7955   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7956    && ix86_binary_operator_ok (AND, DImode, operands)"
7957   "@
7958    and{l}\t{%k2, %k0|%k0, %k2}
7959    and{q}\t{%2, %0|%0, %2}
7960    and{q}\t{%2, %0|%0, %2}"
7961   [(set_attr "type" "alu")
7962    (set_attr "mode" "SI,DI,DI")])
7963
7964 (define_expand "andsi3"
7965   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7966         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7967                 (match_operand:SI 2 "general_operand" "")))
7968    (clobber (reg:CC FLAGS_REG))]
7969   ""
7970   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7971
7972 (define_insn "*andsi_1"
7973   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7974         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7975                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7976    (clobber (reg:CC FLAGS_REG))]
7977   "ix86_binary_operator_ok (AND, SImode, operands)"
7978 {
7979   switch (get_attr_type (insn))
7980     {
7981     case TYPE_IMOVX:
7982       {
7983         enum machine_mode mode;
7984
7985         if (GET_CODE (operands[2]) != CONST_INT)
7986           abort ();
7987         if (INTVAL (operands[2]) == 0xff)
7988           mode = QImode;
7989         else if (INTVAL (operands[2]) == 0xffff)
7990           mode = HImode;
7991         else
7992           abort ();
7993         
7994         operands[1] = gen_lowpart (mode, operands[1]);
7995         if (mode == QImode)
7996           return "movz{bl|x}\t{%1,%0|%0, %1}";
7997         else
7998           return "movz{wl|x}\t{%1,%0|%0, %1}";
7999       }
8000
8001     default:
8002       if (! rtx_equal_p (operands[0], operands[1]))
8003         abort ();
8004       return "and{l}\t{%2, %0|%0, %2}";
8005     }
8006 }
8007   [(set_attr "type" "alu,alu,imovx")
8008    (set_attr "length_immediate" "*,*,0")
8009    (set_attr "mode" "SI")])
8010
8011 (define_split
8012   [(set (match_operand 0 "register_operand" "")
8013         (and (match_dup 0)
8014              (const_int -65536)))
8015    (clobber (reg:CC FLAGS_REG))]
8016   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8017   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8018   "operands[1] = gen_lowpart (HImode, operands[0]);")
8019
8020 (define_split
8021   [(set (match_operand 0 "ext_register_operand" "")
8022         (and (match_dup 0)
8023              (const_int -256)))
8024    (clobber (reg:CC FLAGS_REG))]
8025   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8026   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8027   "operands[1] = gen_lowpart (QImode, operands[0]);")
8028
8029 (define_split
8030   [(set (match_operand 0 "ext_register_operand" "")
8031         (and (match_dup 0)
8032              (const_int -65281)))
8033    (clobber (reg:CC FLAGS_REG))]
8034   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8035   [(parallel [(set (zero_extract:SI (match_dup 0)
8036                                     (const_int 8)
8037                                     (const_int 8))
8038                    (xor:SI 
8039                      (zero_extract:SI (match_dup 0)
8040                                       (const_int 8)
8041                                       (const_int 8))
8042                      (zero_extract:SI (match_dup 0)
8043                                       (const_int 8)
8044                                       (const_int 8))))
8045               (clobber (reg:CC FLAGS_REG))])]
8046   "operands[0] = gen_lowpart (SImode, operands[0]);")
8047
8048 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8049 (define_insn "*andsi_1_zext"
8050   [(set (match_operand:DI 0 "register_operand" "=r")
8051         (zero_extend:DI
8052           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8053                   (match_operand:SI 2 "general_operand" "rim"))))
8054    (clobber (reg:CC FLAGS_REG))]
8055   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8056   "and{l}\t{%2, %k0|%k0, %2}"
8057   [(set_attr "type" "alu")
8058    (set_attr "mode" "SI")])
8059
8060 (define_insn "*andsi_2"
8061   [(set (reg FLAGS_REG)
8062         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8063                          (match_operand:SI 2 "general_operand" "rim,ri"))
8064                  (const_int 0)))
8065    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8066         (and:SI (match_dup 1) (match_dup 2)))]
8067   "ix86_match_ccmode (insn, CCNOmode)
8068    && ix86_binary_operator_ok (AND, SImode, operands)"
8069   "and{l}\t{%2, %0|%0, %2}"
8070   [(set_attr "type" "alu")
8071    (set_attr "mode" "SI")])
8072
8073 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8074 (define_insn "*andsi_2_zext"
8075   [(set (reg FLAGS_REG)
8076         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8077                          (match_operand:SI 2 "general_operand" "rim"))
8078                  (const_int 0)))
8079    (set (match_operand:DI 0 "register_operand" "=r")
8080         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8081   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8082    && ix86_binary_operator_ok (AND, SImode, operands)"
8083   "and{l}\t{%2, %k0|%k0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "mode" "SI")])
8086
8087 (define_expand "andhi3"
8088   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8089         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8090                 (match_operand:HI 2 "general_operand" "")))
8091    (clobber (reg:CC FLAGS_REG))]
8092   "TARGET_HIMODE_MATH"
8093   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8094
8095 (define_insn "*andhi_1"
8096   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8097         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8098                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "ix86_binary_operator_ok (AND, HImode, operands)"
8101 {
8102   switch (get_attr_type (insn))
8103     {
8104     case TYPE_IMOVX:
8105       if (GET_CODE (operands[2]) != CONST_INT)
8106         abort ();
8107       if (INTVAL (operands[2]) == 0xff)
8108         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8109       abort ();
8110
8111     default:
8112       if (! rtx_equal_p (operands[0], operands[1]))
8113         abort ();
8114
8115       return "and{w}\t{%2, %0|%0, %2}";
8116     }
8117 }
8118   [(set_attr "type" "alu,alu,imovx")
8119    (set_attr "length_immediate" "*,*,0")
8120    (set_attr "mode" "HI,HI,SI")])
8121
8122 (define_insn "*andhi_2"
8123   [(set (reg FLAGS_REG)
8124         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8125                          (match_operand:HI 2 "general_operand" "rim,ri"))
8126                  (const_int 0)))
8127    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8128         (and:HI (match_dup 1) (match_dup 2)))]
8129   "ix86_match_ccmode (insn, CCNOmode)
8130    && ix86_binary_operator_ok (AND, HImode, operands)"
8131   "and{w}\t{%2, %0|%0, %2}"
8132   [(set_attr "type" "alu")
8133    (set_attr "mode" "HI")])
8134
8135 (define_expand "andqi3"
8136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8137         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8138                 (match_operand:QI 2 "general_operand" "")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "TARGET_QIMODE_MATH"
8141   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8142
8143 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8144 (define_insn "*andqi_1"
8145   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8146         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8147                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8148    (clobber (reg:CC FLAGS_REG))]
8149   "ix86_binary_operator_ok (AND, QImode, operands)"
8150   "@
8151    and{b}\t{%2, %0|%0, %2}
8152    and{b}\t{%2, %0|%0, %2}
8153    and{l}\t{%k2, %k0|%k0, %k2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "QI,QI,SI")])
8156
8157 (define_insn "*andqi_1_slp"
8158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8159         (and:QI (match_dup 0)
8160                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8161    (clobber (reg:CC FLAGS_REG))]
8162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8164   "and{b}\t{%1, %0|%0, %1}"
8165   [(set_attr "type" "alu1")
8166    (set_attr "mode" "QI")])
8167
8168 (define_insn "*andqi_2_maybe_si"
8169   [(set (reg FLAGS_REG)
8170         (compare (and:QI
8171                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8172                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8173                  (const_int 0)))
8174    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8175         (and:QI (match_dup 1) (match_dup 2)))]
8176   "ix86_binary_operator_ok (AND, QImode, operands)
8177    && ix86_match_ccmode (insn,
8178                          GET_CODE (operands[2]) == CONST_INT
8179                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8180 {
8181   if (which_alternative == 2)
8182     {
8183       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8184         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8185       return "and{l}\t{%2, %k0|%k0, %2}";
8186     }
8187   return "and{b}\t{%2, %0|%0, %2}";
8188 }
8189   [(set_attr "type" "alu")
8190    (set_attr "mode" "QI,QI,SI")])
8191
8192 (define_insn "*andqi_2"
8193   [(set (reg FLAGS_REG)
8194         (compare (and:QI
8195                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8196                    (match_operand:QI 2 "general_operand" "qim,qi"))
8197                  (const_int 0)))
8198    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8199         (and:QI (match_dup 1) (match_dup 2)))]
8200   "ix86_match_ccmode (insn, CCNOmode)
8201    && ix86_binary_operator_ok (AND, QImode, operands)"
8202   "and{b}\t{%2, %0|%0, %2}"
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "QI")])
8205
8206 (define_insn "*andqi_2_slp"
8207   [(set (reg FLAGS_REG)
8208         (compare (and:QI
8209                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8210                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8211                  (const_int 0)))
8212    (set (strict_low_part (match_dup 0))
8213         (and:QI (match_dup 0) (match_dup 1)))]
8214   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8215    && ix86_match_ccmode (insn, CCNOmode)
8216    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8217   "and{b}\t{%1, %0|%0, %1}"
8218   [(set_attr "type" "alu1")
8219    (set_attr "mode" "QI")])
8220
8221 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8222 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8223 ;; for a QImode operand, which of course failed.
8224
8225 (define_insn "andqi_ext_0"
8226   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8227                          (const_int 8)
8228                          (const_int 8))
8229         (and:SI 
8230           (zero_extract:SI
8231             (match_operand 1 "ext_register_operand" "0")
8232             (const_int 8)
8233             (const_int 8))
8234           (match_operand 2 "const_int_operand" "n")))
8235    (clobber (reg:CC FLAGS_REG))]
8236   ""
8237   "and{b}\t{%2, %h0|%h0, %2}"
8238   [(set_attr "type" "alu")
8239    (set_attr "length_immediate" "1")
8240    (set_attr "mode" "QI")])
8241
8242 ;; Generated by peephole translating test to and.  This shows up
8243 ;; often in fp comparisons.
8244
8245 (define_insn "*andqi_ext_0_cc"
8246   [(set (reg FLAGS_REG)
8247         (compare
8248           (and:SI
8249             (zero_extract:SI
8250               (match_operand 1 "ext_register_operand" "0")
8251               (const_int 8)
8252               (const_int 8))
8253             (match_operand 2 "const_int_operand" "n"))
8254           (const_int 0)))
8255    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8256                          (const_int 8)
8257                          (const_int 8))
8258         (and:SI 
8259           (zero_extract:SI
8260             (match_dup 1)
8261             (const_int 8)
8262             (const_int 8))
8263           (match_dup 2)))]
8264   "ix86_match_ccmode (insn, CCNOmode)"
8265   "and{b}\t{%2, %h0|%h0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "length_immediate" "1")
8268    (set_attr "mode" "QI")])
8269
8270 (define_insn "*andqi_ext_1"
8271   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272                          (const_int 8)
8273                          (const_int 8))
8274         (and:SI 
8275           (zero_extract:SI
8276             (match_operand 1 "ext_register_operand" "0")
8277             (const_int 8)
8278             (const_int 8))
8279           (zero_extend:SI
8280             (match_operand:QI 2 "general_operand" "Qm"))))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "!TARGET_64BIT"
8283   "and{b}\t{%2, %h0|%h0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "length_immediate" "0")
8286    (set_attr "mode" "QI")])
8287
8288 (define_insn "*andqi_ext_1_rex64"
8289   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290                          (const_int 8)
8291                          (const_int 8))
8292         (and:SI 
8293           (zero_extract:SI
8294             (match_operand 1 "ext_register_operand" "0")
8295             (const_int 8)
8296             (const_int 8))
8297           (zero_extend:SI
8298             (match_operand 2 "ext_register_operand" "Q"))))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "TARGET_64BIT"
8301   "and{b}\t{%2, %h0|%h0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "length_immediate" "0")
8304    (set_attr "mode" "QI")])
8305
8306 (define_insn "*andqi_ext_2"
8307   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8308                          (const_int 8)
8309                          (const_int 8))
8310         (and:SI
8311           (zero_extract:SI
8312             (match_operand 1 "ext_register_operand" "%0")
8313             (const_int 8)
8314             (const_int 8))
8315           (zero_extract:SI
8316             (match_operand 2 "ext_register_operand" "Q")
8317             (const_int 8)
8318             (const_int 8))))
8319    (clobber (reg:CC FLAGS_REG))]
8320   ""
8321   "and{b}\t{%h2, %h0|%h0, %h2}"
8322   [(set_attr "type" "alu")
8323    (set_attr "length_immediate" "0")
8324    (set_attr "mode" "QI")])
8325
8326 ;; Convert wide AND instructions with immediate operand to shorter QImode
8327 ;; equivalents when possible.
8328 ;; Don't do the splitting with memory operands, since it introduces risk
8329 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8330 ;; for size, but that can (should?) be handled by generic code instead.
8331 (define_split
8332   [(set (match_operand 0 "register_operand" "")
8333         (and (match_operand 1 "register_operand" "")
8334              (match_operand 2 "const_int_operand" "")))
8335    (clobber (reg:CC FLAGS_REG))]
8336    "reload_completed
8337     && QI_REG_P (operands[0])
8338     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8339     && !(~INTVAL (operands[2]) & ~(255 << 8))
8340     && GET_MODE (operands[0]) != QImode"
8341   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8342                    (and:SI (zero_extract:SI (match_dup 1)
8343                                             (const_int 8) (const_int 8))
8344                            (match_dup 2)))
8345               (clobber (reg:CC FLAGS_REG))])]
8346   "operands[0] = gen_lowpart (SImode, operands[0]);
8347    operands[1] = gen_lowpart (SImode, operands[1]);
8348    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8349
8350 ;; Since AND can be encoded with sign extended immediate, this is only
8351 ;; profitable when 7th bit is not set.
8352 (define_split
8353   [(set (match_operand 0 "register_operand" "")
8354         (and (match_operand 1 "general_operand" "")
8355              (match_operand 2 "const_int_operand" "")))
8356    (clobber (reg:CC FLAGS_REG))]
8357    "reload_completed
8358     && ANY_QI_REG_P (operands[0])
8359     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8360     && !(~INTVAL (operands[2]) & ~255)
8361     && !(INTVAL (operands[2]) & 128)
8362     && GET_MODE (operands[0]) != QImode"
8363   [(parallel [(set (strict_low_part (match_dup 0))
8364                    (and:QI (match_dup 1)
8365                            (match_dup 2)))
8366               (clobber (reg:CC FLAGS_REG))])]
8367   "operands[0] = gen_lowpart (QImode, operands[0]);
8368    operands[1] = gen_lowpart (QImode, operands[1]);
8369    operands[2] = gen_lowpart (QImode, operands[2]);")
8370 \f
8371 ;; Logical inclusive OR instructions
8372
8373 ;; %%% This used to optimize known byte-wide and operations to memory.
8374 ;; If this is considered useful, it should be done with splitters.
8375
8376 (define_expand "iordi3"
8377   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8378         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8379                 (match_operand:DI 2 "x86_64_general_operand" "")))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "TARGET_64BIT"
8382   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8383
8384 (define_insn "*iordi_1_rex64"
8385   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8386         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8387                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8388    (clobber (reg:CC FLAGS_REG))]
8389   "TARGET_64BIT
8390    && ix86_binary_operator_ok (IOR, DImode, operands)"
8391   "or{q}\t{%2, %0|%0, %2}"
8392   [(set_attr "type" "alu")
8393    (set_attr "mode" "DI")])
8394
8395 (define_insn "*iordi_2_rex64"
8396   [(set (reg FLAGS_REG)
8397         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8398                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8399                  (const_int 0)))
8400    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8401         (ior:DI (match_dup 1) (match_dup 2)))]
8402   "TARGET_64BIT
8403    && ix86_match_ccmode (insn, CCNOmode)
8404    && ix86_binary_operator_ok (IOR, DImode, operands)"
8405   "or{q}\t{%2, %0|%0, %2}"
8406   [(set_attr "type" "alu")
8407    (set_attr "mode" "DI")])
8408
8409 (define_insn "*iordi_3_rex64"
8410   [(set (reg FLAGS_REG)
8411         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8412                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8413                  (const_int 0)))
8414    (clobber (match_scratch:DI 0 "=r"))]
8415   "TARGET_64BIT
8416    && ix86_match_ccmode (insn, CCNOmode)
8417    && ix86_binary_operator_ok (IOR, DImode, operands)"
8418   "or{q}\t{%2, %0|%0, %2}"
8419   [(set_attr "type" "alu")
8420    (set_attr "mode" "DI")])
8421
8422
8423 (define_expand "iorsi3"
8424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8425         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8426                 (match_operand:SI 2 "general_operand" "")))
8427    (clobber (reg:CC FLAGS_REG))]
8428   ""
8429   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8430
8431 (define_insn "*iorsi_1"
8432   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8433         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8434                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8435    (clobber (reg:CC FLAGS_REG))]
8436   "ix86_binary_operator_ok (IOR, SImode, operands)"
8437   "or{l}\t{%2, %0|%0, %2}"
8438   [(set_attr "type" "alu")
8439    (set_attr "mode" "SI")])
8440
8441 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8442 (define_insn "*iorsi_1_zext"
8443   [(set (match_operand:DI 0 "register_operand" "=rm")
8444         (zero_extend:DI
8445           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8446                   (match_operand:SI 2 "general_operand" "rim"))))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8449   "or{l}\t{%2, %k0|%k0, %2}"
8450   [(set_attr "type" "alu")
8451    (set_attr "mode" "SI")])
8452
8453 (define_insn "*iorsi_1_zext_imm"
8454   [(set (match_operand:DI 0 "register_operand" "=rm")
8455         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8456                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8457    (clobber (reg:CC FLAGS_REG))]
8458   "TARGET_64BIT"
8459   "or{l}\t{%2, %k0|%k0, %2}"
8460   [(set_attr "type" "alu")
8461    (set_attr "mode" "SI")])
8462
8463 (define_insn "*iorsi_2"
8464   [(set (reg FLAGS_REG)
8465         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8466                          (match_operand:SI 2 "general_operand" "rim,ri"))
8467                  (const_int 0)))
8468    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8469         (ior:SI (match_dup 1) (match_dup 2)))]
8470   "ix86_match_ccmode (insn, CCNOmode)
8471    && ix86_binary_operator_ok (IOR, SImode, operands)"
8472   "or{l}\t{%2, %0|%0, %2}"
8473   [(set_attr "type" "alu")
8474    (set_attr "mode" "SI")])
8475
8476 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8477 ;; ??? Special case for immediate operand is missing - it is tricky.
8478 (define_insn "*iorsi_2_zext"
8479   [(set (reg FLAGS_REG)
8480         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8481                          (match_operand:SI 2 "general_operand" "rim"))
8482                  (const_int 0)))
8483    (set (match_operand:DI 0 "register_operand" "=r")
8484         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8485   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8486    && ix86_binary_operator_ok (IOR, SImode, operands)"
8487   "or{l}\t{%2, %k0|%k0, %2}"
8488   [(set_attr "type" "alu")
8489    (set_attr "mode" "SI")])
8490
8491 (define_insn "*iorsi_2_zext_imm"
8492   [(set (reg FLAGS_REG)
8493         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8494                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8495                  (const_int 0)))
8496    (set (match_operand:DI 0 "register_operand" "=r")
8497         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8498   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8499    && ix86_binary_operator_ok (IOR, SImode, operands)"
8500   "or{l}\t{%2, %k0|%k0, %2}"
8501   [(set_attr "type" "alu")
8502    (set_attr "mode" "SI")])
8503
8504 (define_insn "*iorsi_3"
8505   [(set (reg FLAGS_REG)
8506         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8507                          (match_operand:SI 2 "general_operand" "rim"))
8508                  (const_int 0)))
8509    (clobber (match_scratch:SI 0 "=r"))]
8510   "ix86_match_ccmode (insn, CCNOmode)
8511    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8512   "or{l}\t{%2, %0|%0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "SI")])
8515
8516 (define_expand "iorhi3"
8517   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8518         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8519                 (match_operand:HI 2 "general_operand" "")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_HIMODE_MATH"
8522   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8523
8524 (define_insn "*iorhi_1"
8525   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8526         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8527                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "ix86_binary_operator_ok (IOR, HImode, operands)"
8530   "or{w}\t{%2, %0|%0, %2}"
8531   [(set_attr "type" "alu")
8532    (set_attr "mode" "HI")])
8533
8534 (define_insn "*iorhi_2"
8535   [(set (reg FLAGS_REG)
8536         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8537                          (match_operand:HI 2 "general_operand" "rim,ri"))
8538                  (const_int 0)))
8539    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8540         (ior:HI (match_dup 1) (match_dup 2)))]
8541   "ix86_match_ccmode (insn, CCNOmode)
8542    && ix86_binary_operator_ok (IOR, HImode, operands)"
8543   "or{w}\t{%2, %0|%0, %2}"
8544   [(set_attr "type" "alu")
8545    (set_attr "mode" "HI")])
8546
8547 (define_insn "*iorhi_3"
8548   [(set (reg FLAGS_REG)
8549         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8550                          (match_operand:HI 2 "general_operand" "rim"))
8551                  (const_int 0)))
8552    (clobber (match_scratch:HI 0 "=r"))]
8553   "ix86_match_ccmode (insn, CCNOmode)
8554    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8555   "or{w}\t{%2, %0|%0, %2}"
8556   [(set_attr "type" "alu")
8557    (set_attr "mode" "HI")])
8558
8559 (define_expand "iorqi3"
8560   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8561         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8562                 (match_operand:QI 2 "general_operand" "")))
8563    (clobber (reg:CC FLAGS_REG))]
8564   "TARGET_QIMODE_MATH"
8565   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8566
8567 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8568 (define_insn "*iorqi_1"
8569   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8570         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8571                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "ix86_binary_operator_ok (IOR, QImode, operands)"
8574   "@
8575    or{b}\t{%2, %0|%0, %2}
8576    or{b}\t{%2, %0|%0, %2}
8577    or{l}\t{%k2, %k0|%k0, %k2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "QI,QI,SI")])
8580
8581 (define_insn "*iorqi_1_slp"
8582   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8583         (ior:QI (match_dup 0)
8584                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8587    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8588   "or{b}\t{%1, %0|%0, %1}"
8589   [(set_attr "type" "alu1")
8590    (set_attr "mode" "QI")])
8591
8592 (define_insn "*iorqi_2"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8595                          (match_operand:QI 2 "general_operand" "qim,qi"))
8596                  (const_int 0)))
8597    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8598         (ior:QI (match_dup 1) (match_dup 2)))]
8599   "ix86_match_ccmode (insn, CCNOmode)
8600    && ix86_binary_operator_ok (IOR, QImode, operands)"
8601   "or{b}\t{%2, %0|%0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "QI")])
8604
8605 (define_insn "*iorqi_2_slp"
8606   [(set (reg FLAGS_REG)
8607         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608                          (match_operand:QI 1 "general_operand" "qim,qi"))
8609                  (const_int 0)))
8610    (set (strict_low_part (match_dup 0))
8611         (ior:QI (match_dup 0) (match_dup 1)))]
8612   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8615   "or{b}\t{%1, %0|%0, %1}"
8616   [(set_attr "type" "alu1")
8617    (set_attr "mode" "QI")])
8618
8619 (define_insn "*iorqi_3"
8620   [(set (reg FLAGS_REG)
8621         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8622                          (match_operand:QI 2 "general_operand" "qim"))
8623                  (const_int 0)))
8624    (clobber (match_scratch:QI 0 "=q"))]
8625   "ix86_match_ccmode (insn, CCNOmode)
8626    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8627   "or{b}\t{%2, %0|%0, %2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "mode" "QI")])
8630
8631 (define_insn "iorqi_ext_0"
8632   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8633                          (const_int 8)
8634                          (const_int 8))
8635         (ior:SI 
8636           (zero_extract:SI
8637             (match_operand 1 "ext_register_operand" "0")
8638             (const_int 8)
8639             (const_int 8))
8640           (match_operand 2 "const_int_operand" "n")))
8641    (clobber (reg:CC FLAGS_REG))]
8642   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8643   "or{b}\t{%2, %h0|%h0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "length_immediate" "1")
8646    (set_attr "mode" "QI")])
8647
8648 (define_insn "*iorqi_ext_1"
8649   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8650                          (const_int 8)
8651                          (const_int 8))
8652         (ior:SI 
8653           (zero_extract:SI
8654             (match_operand 1 "ext_register_operand" "0")
8655             (const_int 8)
8656             (const_int 8))
8657           (zero_extend:SI
8658             (match_operand:QI 2 "general_operand" "Qm"))))
8659    (clobber (reg:CC FLAGS_REG))]
8660   "!TARGET_64BIT
8661    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8662   "or{b}\t{%2, %h0|%h0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "length_immediate" "0")
8665    (set_attr "mode" "QI")])
8666
8667 (define_insn "*iorqi_ext_1_rex64"
8668   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8669                          (const_int 8)
8670                          (const_int 8))
8671         (ior:SI 
8672           (zero_extract:SI
8673             (match_operand 1 "ext_register_operand" "0")
8674             (const_int 8)
8675             (const_int 8))
8676           (zero_extend:SI
8677             (match_operand 2 "ext_register_operand" "Q"))))
8678    (clobber (reg:CC FLAGS_REG))]
8679   "TARGET_64BIT
8680    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8681   "or{b}\t{%2, %h0|%h0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "length_immediate" "0")
8684    (set_attr "mode" "QI")])
8685
8686 (define_insn "*iorqi_ext_2"
8687   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8688                          (const_int 8)
8689                          (const_int 8))
8690         (ior:SI 
8691           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8692                            (const_int 8)
8693                            (const_int 8))
8694           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8695                            (const_int 8)
8696                            (const_int 8))))
8697    (clobber (reg:CC FLAGS_REG))]
8698   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8699   "ior{b}\t{%h2, %h0|%h0, %h2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "length_immediate" "0")
8702    (set_attr "mode" "QI")])
8703
8704 (define_split
8705   [(set (match_operand 0 "register_operand" "")
8706         (ior (match_operand 1 "register_operand" "")
8707              (match_operand 2 "const_int_operand" "")))
8708    (clobber (reg:CC FLAGS_REG))]
8709    "reload_completed
8710     && QI_REG_P (operands[0])
8711     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8712     && !(INTVAL (operands[2]) & ~(255 << 8))
8713     && GET_MODE (operands[0]) != QImode"
8714   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8715                    (ior:SI (zero_extract:SI (match_dup 1)
8716                                             (const_int 8) (const_int 8))
8717                            (match_dup 2)))
8718               (clobber (reg:CC FLAGS_REG))])]
8719   "operands[0] = gen_lowpart (SImode, operands[0]);
8720    operands[1] = gen_lowpart (SImode, operands[1]);
8721    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8722
8723 ;; Since OR can be encoded with sign extended immediate, this is only
8724 ;; profitable when 7th bit is set.
8725 (define_split
8726   [(set (match_operand 0 "register_operand" "")
8727         (ior (match_operand 1 "general_operand" "")
8728              (match_operand 2 "const_int_operand" "")))
8729    (clobber (reg:CC FLAGS_REG))]
8730    "reload_completed
8731     && ANY_QI_REG_P (operands[0])
8732     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8733     && !(INTVAL (operands[2]) & ~255)
8734     && (INTVAL (operands[2]) & 128)
8735     && GET_MODE (operands[0]) != QImode"
8736   [(parallel [(set (strict_low_part (match_dup 0))
8737                    (ior:QI (match_dup 1)
8738                            (match_dup 2)))
8739               (clobber (reg:CC FLAGS_REG))])]
8740   "operands[0] = gen_lowpart (QImode, operands[0]);
8741    operands[1] = gen_lowpart (QImode, operands[1]);
8742    operands[2] = gen_lowpart (QImode, operands[2]);")
8743 \f
8744 ;; Logical XOR instructions
8745
8746 ;; %%% This used to optimize known byte-wide and operations to memory.
8747 ;; If this is considered useful, it should be done with splitters.
8748
8749 (define_expand "xordi3"
8750   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8751         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8752                 (match_operand:DI 2 "x86_64_general_operand" "")))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "TARGET_64BIT"
8755   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8756
8757 (define_insn "*xordi_1_rex64"
8758   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8759         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8760                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "TARGET_64BIT
8763    && ix86_binary_operator_ok (XOR, DImode, operands)"
8764   "@
8765    xor{q}\t{%2, %0|%0, %2}
8766    xor{q}\t{%2, %0|%0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "mode" "DI,DI")])
8769
8770 (define_insn "*xordi_2_rex64"
8771   [(set (reg FLAGS_REG)
8772         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8773                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8774                  (const_int 0)))
8775    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8776         (xor:DI (match_dup 1) (match_dup 2)))]
8777   "TARGET_64BIT
8778    && ix86_match_ccmode (insn, CCNOmode)
8779    && ix86_binary_operator_ok (XOR, DImode, operands)"
8780   "@
8781    xor{q}\t{%2, %0|%0, %2}
8782    xor{q}\t{%2, %0|%0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "DI,DI")])
8785
8786 (define_insn "*xordi_3_rex64"
8787   [(set (reg FLAGS_REG)
8788         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8789                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8790                  (const_int 0)))
8791    (clobber (match_scratch:DI 0 "=r"))]
8792   "TARGET_64BIT
8793    && ix86_match_ccmode (insn, CCNOmode)
8794    && ix86_binary_operator_ok (XOR, DImode, operands)"
8795   "xor{q}\t{%2, %0|%0, %2}"
8796   [(set_attr "type" "alu")
8797    (set_attr "mode" "DI")])
8798
8799 (define_expand "xorsi3"
8800   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8801         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8802                 (match_operand:SI 2 "general_operand" "")))
8803    (clobber (reg:CC FLAGS_REG))]
8804   ""
8805   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8806
8807 (define_insn "*xorsi_1"
8808   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8809         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8810                 (match_operand:SI 2 "general_operand" "ri,rm")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "ix86_binary_operator_ok (XOR, SImode, operands)"
8813   "xor{l}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "SI")])
8816
8817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8818 ;; Add speccase for immediates
8819 (define_insn "*xorsi_1_zext"
8820   [(set (match_operand:DI 0 "register_operand" "=r")
8821         (zero_extend:DI
8822           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8823                   (match_operand:SI 2 "general_operand" "rim"))))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8826   "xor{l}\t{%2, %k0|%k0, %2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "mode" "SI")])
8829
8830 (define_insn "*xorsi_1_zext_imm"
8831   [(set (match_operand:DI 0 "register_operand" "=r")
8832         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8833                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8834    (clobber (reg:CC FLAGS_REG))]
8835   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8836   "xor{l}\t{%2, %k0|%k0, %2}"
8837   [(set_attr "type" "alu")
8838    (set_attr "mode" "SI")])
8839
8840 (define_insn "*xorsi_2"
8841   [(set (reg FLAGS_REG)
8842         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8843                          (match_operand:SI 2 "general_operand" "rim,ri"))
8844                  (const_int 0)))
8845    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8846         (xor:SI (match_dup 1) (match_dup 2)))]
8847   "ix86_match_ccmode (insn, CCNOmode)
8848    && ix86_binary_operator_ok (XOR, SImode, operands)"
8849   "xor{l}\t{%2, %0|%0, %2}"
8850   [(set_attr "type" "alu")
8851    (set_attr "mode" "SI")])
8852
8853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8854 ;; ??? Special case for immediate operand is missing - it is tricky.
8855 (define_insn "*xorsi_2_zext"
8856   [(set (reg FLAGS_REG)
8857         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8858                          (match_operand:SI 2 "general_operand" "rim"))
8859                  (const_int 0)))
8860    (set (match_operand:DI 0 "register_operand" "=r")
8861         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8862   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8863    && ix86_binary_operator_ok (XOR, SImode, operands)"
8864   "xor{l}\t{%2, %k0|%k0, %2}"
8865   [(set_attr "type" "alu")
8866    (set_attr "mode" "SI")])
8867
8868 (define_insn "*xorsi_2_zext_imm"
8869   [(set (reg FLAGS_REG)
8870         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8871                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8872                  (const_int 0)))
8873    (set (match_operand:DI 0 "register_operand" "=r")
8874         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8875   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8876    && ix86_binary_operator_ok (XOR, SImode, operands)"
8877   "xor{l}\t{%2, %k0|%k0, %2}"
8878   [(set_attr "type" "alu")
8879    (set_attr "mode" "SI")])
8880
8881 (define_insn "*xorsi_3"
8882   [(set (reg FLAGS_REG)
8883         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8884                          (match_operand:SI 2 "general_operand" "rim"))
8885                  (const_int 0)))
8886    (clobber (match_scratch:SI 0 "=r"))]
8887   "ix86_match_ccmode (insn, CCNOmode)
8888    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8889   "xor{l}\t{%2, %0|%0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "SI")])
8892
8893 (define_expand "xorhi3"
8894   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8895         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8896                 (match_operand:HI 2 "general_operand" "")))
8897    (clobber (reg:CC FLAGS_REG))]
8898   "TARGET_HIMODE_MATH"
8899   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8900
8901 (define_insn "*xorhi_1"
8902   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8903         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8904                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "ix86_binary_operator_ok (XOR, HImode, operands)"
8907   "xor{w}\t{%2, %0|%0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "mode" "HI")])
8910
8911 (define_insn "*xorhi_2"
8912   [(set (reg FLAGS_REG)
8913         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8914                          (match_operand:HI 2 "general_operand" "rim,ri"))
8915                  (const_int 0)))
8916    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8917         (xor:HI (match_dup 1) (match_dup 2)))]
8918   "ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_binary_operator_ok (XOR, HImode, operands)"
8920   "xor{w}\t{%2, %0|%0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "HI")])
8923
8924 (define_insn "*xorhi_3"
8925   [(set (reg FLAGS_REG)
8926         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8927                          (match_operand:HI 2 "general_operand" "rim"))
8928                  (const_int 0)))
8929    (clobber (match_scratch:HI 0 "=r"))]
8930   "ix86_match_ccmode (insn, CCNOmode)
8931    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8932   "xor{w}\t{%2, %0|%0, %2}"
8933   [(set_attr "type" "alu")
8934    (set_attr "mode" "HI")])
8935
8936 (define_expand "xorqi3"
8937   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8938         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8939                 (match_operand:QI 2 "general_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "TARGET_QIMODE_MATH"
8942   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8943
8944 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8945 (define_insn "*xorqi_1"
8946   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8947         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8948                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "ix86_binary_operator_ok (XOR, QImode, operands)"
8951   "@
8952    xor{b}\t{%2, %0|%0, %2}
8953    xor{b}\t{%2, %0|%0, %2}
8954    xor{l}\t{%k2, %k0|%k0, %k2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "QI,QI,SI")])
8957
8958 (define_insn "*xorqi_1_slp"
8959   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8960         (xor:QI (match_dup 0)
8961                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8964    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8965   "xor{b}\t{%1, %0|%0, %1}"
8966   [(set_attr "type" "alu1")
8967    (set_attr "mode" "QI")])
8968
8969 (define_insn "xorqi_ext_0"
8970   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8971                          (const_int 8)
8972                          (const_int 8))
8973         (xor:SI 
8974           (zero_extract:SI
8975             (match_operand 1 "ext_register_operand" "0")
8976             (const_int 8)
8977             (const_int 8))
8978           (match_operand 2 "const_int_operand" "n")))
8979    (clobber (reg:CC FLAGS_REG))]
8980   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8981   "xor{b}\t{%2, %h0|%h0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "length_immediate" "1")
8984    (set_attr "mode" "QI")])
8985
8986 (define_insn "*xorqi_ext_1"
8987   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8988                          (const_int 8)
8989                          (const_int 8))
8990         (xor:SI 
8991           (zero_extract:SI
8992             (match_operand 1 "ext_register_operand" "0")
8993             (const_int 8)
8994             (const_int 8))
8995           (zero_extend:SI
8996             (match_operand:QI 2 "general_operand" "Qm"))))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "!TARGET_64BIT
8999    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9000   "xor{b}\t{%2, %h0|%h0, %2}"
9001   [(set_attr "type" "alu")
9002    (set_attr "length_immediate" "0")
9003    (set_attr "mode" "QI")])
9004
9005 (define_insn "*xorqi_ext_1_rex64"
9006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9007                          (const_int 8)
9008                          (const_int 8))
9009         (xor:SI 
9010           (zero_extract:SI
9011             (match_operand 1 "ext_register_operand" "0")
9012             (const_int 8)
9013             (const_int 8))
9014           (zero_extend:SI
9015             (match_operand 2 "ext_register_operand" "Q"))))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "TARGET_64BIT
9018    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9019   "xor{b}\t{%2, %h0|%h0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "length_immediate" "0")
9022    (set_attr "mode" "QI")])
9023
9024 (define_insn "*xorqi_ext_2"
9025   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9026                          (const_int 8)
9027                          (const_int 8))
9028         (xor:SI 
9029           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9030                            (const_int 8)
9031                            (const_int 8))
9032           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9033                            (const_int 8)
9034                            (const_int 8))))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9037   "xor{b}\t{%h2, %h0|%h0, %h2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "length_immediate" "0")
9040    (set_attr "mode" "QI")])
9041
9042 (define_insn "*xorqi_cc_1"
9043   [(set (reg FLAGS_REG)
9044         (compare
9045           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9046                   (match_operand:QI 2 "general_operand" "qim,qi"))
9047           (const_int 0)))
9048    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9049         (xor:QI (match_dup 1) (match_dup 2)))]
9050   "ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, QImode, operands)"
9052   "xor{b}\t{%2, %0|%0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "QI")])
9055
9056 (define_insn "*xorqi_2_slp"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9059                          (match_operand:QI 1 "general_operand" "qim,qi"))
9060                  (const_int 0)))
9061    (set (strict_low_part (match_dup 0))
9062         (xor:QI (match_dup 0) (match_dup 1)))]
9063   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9064    && ix86_match_ccmode (insn, CCNOmode)
9065    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9066   "xor{b}\t{%1, %0|%0, %1}"
9067   [(set_attr "type" "alu1")
9068    (set_attr "mode" "QI")])
9069
9070 (define_insn "*xorqi_cc_2"
9071   [(set (reg FLAGS_REG)
9072         (compare
9073           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9074                   (match_operand:QI 2 "general_operand" "qim"))
9075           (const_int 0)))
9076    (clobber (match_scratch:QI 0 "=q"))]
9077   "ix86_match_ccmode (insn, CCNOmode)
9078    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9079   "xor{b}\t{%2, %0|%0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "mode" "QI")])
9082
9083 (define_insn "*xorqi_cc_ext_1"
9084   [(set (reg FLAGS_REG)
9085         (compare
9086           (xor:SI
9087             (zero_extract:SI
9088               (match_operand 1 "ext_register_operand" "0")
9089               (const_int 8)
9090               (const_int 8))
9091             (match_operand:QI 2 "general_operand" "qmn"))
9092           (const_int 0)))
9093    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9094                          (const_int 8)
9095                          (const_int 8))
9096         (xor:SI 
9097           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9098           (match_dup 2)))]
9099   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9100   "xor{b}\t{%2, %h0|%h0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "mode" "QI")])
9103
9104 (define_insn "*xorqi_cc_ext_1_rex64"
9105   [(set (reg FLAGS_REG)
9106         (compare
9107           (xor:SI
9108             (zero_extract:SI
9109               (match_operand 1 "ext_register_operand" "0")
9110               (const_int 8)
9111               (const_int 8))
9112             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9113           (const_int 0)))
9114    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115                          (const_int 8)
9116                          (const_int 8))
9117         (xor:SI 
9118           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9119           (match_dup 2)))]
9120   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9121   "xor{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "mode" "QI")])
9124
9125 (define_expand "xorqi_cc_ext_1"
9126   [(parallel [
9127      (set (reg:CCNO FLAGS_REG)
9128           (compare:CCNO
9129             (xor:SI
9130               (zero_extract:SI
9131                 (match_operand 1 "ext_register_operand" "")
9132                 (const_int 8)
9133                 (const_int 8))
9134               (match_operand:QI 2 "general_operand" ""))
9135             (const_int 0)))
9136      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9137                            (const_int 8)
9138                            (const_int 8))
9139           (xor:SI 
9140             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9141             (match_dup 2)))])]
9142   ""
9143   "")
9144
9145 (define_split
9146   [(set (match_operand 0 "register_operand" "")
9147         (xor (match_operand 1 "register_operand" "")
9148              (match_operand 2 "const_int_operand" "")))
9149    (clobber (reg:CC FLAGS_REG))]
9150    "reload_completed
9151     && QI_REG_P (operands[0])
9152     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9153     && !(INTVAL (operands[2]) & ~(255 << 8))
9154     && GET_MODE (operands[0]) != QImode"
9155   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9156                    (xor:SI (zero_extract:SI (match_dup 1)
9157                                             (const_int 8) (const_int 8))
9158                            (match_dup 2)))
9159               (clobber (reg:CC FLAGS_REG))])]
9160   "operands[0] = gen_lowpart (SImode, operands[0]);
9161    operands[1] = gen_lowpart (SImode, operands[1]);
9162    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9163
9164 ;; Since XOR can be encoded with sign extended immediate, this is only
9165 ;; profitable when 7th bit is set.
9166 (define_split
9167   [(set (match_operand 0 "register_operand" "")
9168         (xor (match_operand 1 "general_operand" "")
9169              (match_operand 2 "const_int_operand" "")))
9170    (clobber (reg:CC FLAGS_REG))]
9171    "reload_completed
9172     && ANY_QI_REG_P (operands[0])
9173     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9174     && !(INTVAL (operands[2]) & ~255)
9175     && (INTVAL (operands[2]) & 128)
9176     && GET_MODE (operands[0]) != QImode"
9177   [(parallel [(set (strict_low_part (match_dup 0))
9178                    (xor:QI (match_dup 1)
9179                            (match_dup 2)))
9180               (clobber (reg:CC FLAGS_REG))])]
9181   "operands[0] = gen_lowpart (QImode, operands[0]);
9182    operands[1] = gen_lowpart (QImode, operands[1]);
9183    operands[2] = gen_lowpart (QImode, operands[2]);")
9184 \f
9185 ;; Negation instructions
9186
9187 (define_expand "negdi2"
9188   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9189                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9190               (clobber (reg:CC FLAGS_REG))])]
9191   ""
9192   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9193
9194 (define_insn "*negdi2_1"
9195   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9196         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9197    (clobber (reg:CC FLAGS_REG))]
9198   "!TARGET_64BIT
9199    && ix86_unary_operator_ok (NEG, DImode, operands)"
9200   "#")
9201
9202 (define_split
9203   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9204         (neg:DI (match_operand:DI 1 "general_operand" "")))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "!TARGET_64BIT && reload_completed"
9207   [(parallel
9208     [(set (reg:CCZ FLAGS_REG)
9209           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9210      (set (match_dup 0) (neg:SI (match_dup 2)))])
9211    (parallel
9212     [(set (match_dup 1)
9213           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9214                             (match_dup 3))
9215                    (const_int 0)))
9216      (clobber (reg:CC FLAGS_REG))])
9217    (parallel
9218     [(set (match_dup 1)
9219           (neg:SI (match_dup 1)))
9220      (clobber (reg:CC FLAGS_REG))])]
9221   "split_di (operands+1, 1, operands+2, operands+3);
9222    split_di (operands+0, 1, operands+0, operands+1);")
9223
9224 (define_insn "*negdi2_1_rex64"
9225   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9226         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9227    (clobber (reg:CC FLAGS_REG))]
9228   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9229   "neg{q}\t%0"
9230   [(set_attr "type" "negnot")
9231    (set_attr "mode" "DI")])
9232
9233 ;; The problem with neg is that it does not perform (compare x 0),
9234 ;; it really performs (compare 0 x), which leaves us with the zero
9235 ;; flag being the only useful item.
9236
9237 (define_insn "*negdi2_cmpz_rex64"
9238   [(set (reg:CCZ FLAGS_REG)
9239         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9240                      (const_int 0)))
9241    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9242         (neg:DI (match_dup 1)))]
9243   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9244   "neg{q}\t%0"
9245   [(set_attr "type" "negnot")
9246    (set_attr "mode" "DI")])
9247
9248
9249 (define_expand "negsi2"
9250   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9251                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9252               (clobber (reg:CC FLAGS_REG))])]
9253   ""
9254   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9255
9256 (define_insn "*negsi2_1"
9257   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9258         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9259    (clobber (reg:CC FLAGS_REG))]
9260   "ix86_unary_operator_ok (NEG, SImode, operands)"
9261   "neg{l}\t%0"
9262   [(set_attr "type" "negnot")
9263    (set_attr "mode" "SI")])
9264
9265 ;; Combine is quite creative about this pattern.
9266 (define_insn "*negsi2_1_zext"
9267   [(set (match_operand:DI 0 "register_operand" "=r")
9268         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9269                                         (const_int 32)))
9270                      (const_int 32)))
9271    (clobber (reg:CC FLAGS_REG))]
9272   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9273   "neg{l}\t%k0"
9274   [(set_attr "type" "negnot")
9275    (set_attr "mode" "SI")])
9276
9277 ;; The problem with neg is that it does not perform (compare x 0),
9278 ;; it really performs (compare 0 x), which leaves us with the zero
9279 ;; flag being the only useful item.
9280
9281 (define_insn "*negsi2_cmpz"
9282   [(set (reg:CCZ FLAGS_REG)
9283         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9284                      (const_int 0)))
9285    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9286         (neg:SI (match_dup 1)))]
9287   "ix86_unary_operator_ok (NEG, SImode, operands)"
9288   "neg{l}\t%0"
9289   [(set_attr "type" "negnot")
9290    (set_attr "mode" "SI")])
9291
9292 (define_insn "*negsi2_cmpz_zext"
9293   [(set (reg:CCZ FLAGS_REG)
9294         (compare:CCZ (lshiftrt:DI
9295                        (neg:DI (ashift:DI
9296                                  (match_operand:DI 1 "register_operand" "0")
9297                                  (const_int 32)))
9298                        (const_int 32))
9299                      (const_int 0)))
9300    (set (match_operand:DI 0 "register_operand" "=r")
9301         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9302                                         (const_int 32)))
9303                      (const_int 32)))]
9304   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9305   "neg{l}\t%k0"
9306   [(set_attr "type" "negnot")
9307    (set_attr "mode" "SI")])
9308
9309 (define_expand "neghi2"
9310   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9311                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9312               (clobber (reg:CC FLAGS_REG))])]
9313   "TARGET_HIMODE_MATH"
9314   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9315
9316 (define_insn "*neghi2_1"
9317   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9318         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "ix86_unary_operator_ok (NEG, HImode, operands)"
9321   "neg{w}\t%0"
9322   [(set_attr "type" "negnot")
9323    (set_attr "mode" "HI")])
9324
9325 (define_insn "*neghi2_cmpz"
9326   [(set (reg:CCZ FLAGS_REG)
9327         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9328                      (const_int 0)))
9329    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9330         (neg:HI (match_dup 1)))]
9331   "ix86_unary_operator_ok (NEG, HImode, operands)"
9332   "neg{w}\t%0"
9333   [(set_attr "type" "negnot")
9334    (set_attr "mode" "HI")])
9335
9336 (define_expand "negqi2"
9337   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9338                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9339               (clobber (reg:CC FLAGS_REG))])]
9340   "TARGET_QIMODE_MATH"
9341   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9342
9343 (define_insn "*negqi2_1"
9344   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9345         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9346    (clobber (reg:CC FLAGS_REG))]
9347   "ix86_unary_operator_ok (NEG, QImode, operands)"
9348   "neg{b}\t%0"
9349   [(set_attr "type" "negnot")
9350    (set_attr "mode" "QI")])
9351
9352 (define_insn "*negqi2_cmpz"
9353   [(set (reg:CCZ FLAGS_REG)
9354         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9355                      (const_int 0)))
9356    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9357         (neg:QI (match_dup 1)))]
9358   "ix86_unary_operator_ok (NEG, QImode, operands)"
9359   "neg{b}\t%0"
9360   [(set_attr "type" "negnot")
9361    (set_attr "mode" "QI")])
9362
9363 ;; Changing of sign for FP values is doable using integer unit too.
9364
9365 (define_expand "negsf2"
9366   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9367         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9368   "TARGET_80387 || TARGET_SSE_MATH"
9369   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9370
9371 (define_expand "abssf2"
9372   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9373         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9374   "TARGET_80387 || TARGET_SSE_MATH"
9375   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9376
9377 (define_insn "*absnegsf2_mixed"
9378   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9379         (match_operator:SF 3 "absneg_operator"
9380           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9381    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9384    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9385   "#")
9386
9387 (define_insn "*absnegsf2_sse"
9388   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9389         (match_operator:SF 3 "absneg_operator"
9390           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9391    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9392    (clobber (reg:CC FLAGS_REG))]
9393   "TARGET_SSE_MATH
9394    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9395   "#")
9396
9397 (define_insn "*absnegsf2_i387"
9398   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9399         (match_operator:SF 3 "absneg_operator"
9400           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9401    (use (match_operand 2 "" ""))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_80387 && !TARGET_SSE_MATH
9404    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9405   "#")
9406
9407 (define_expand "copysignsf3"
9408   [(match_operand:SF 0 "register_operand" "")
9409    (match_operand:SF 1 "nonmemory_operand" "")
9410    (match_operand:SF 2 "register_operand" "")]
9411   "TARGET_SSE_MATH"
9412 {
9413   ix86_expand_copysign (operands);
9414   DONE;
9415 })
9416
9417 (define_insn_and_split "copysignsf3_const"
9418   [(set (match_operand:SF 0 "register_operand"          "=x")
9419         (unspec:SF
9420           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9421            (match_operand:SF 2 "register_operand"       "0")
9422            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9423           UNSPEC_COPYSIGN))]
9424   "TARGET_SSE_MATH"
9425   "#"
9426   "&& reload_completed"
9427   [(const_int 0)]
9428 {
9429   ix86_split_copysign_const (operands);
9430   DONE;
9431 })
9432
9433 (define_insn "copysignsf3_var"
9434   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9435         (unspec:SF
9436           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9437            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9438            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9439            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9440           UNSPEC_COPYSIGN))
9441    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9442   "TARGET_SSE_MATH"
9443   "#")
9444
9445 (define_split
9446   [(set (match_operand:SF 0 "register_operand" "")
9447         (unspec:SF
9448           [(match_operand:SF 2 "register_operand" "")
9449            (match_operand:SF 3 "register_operand" "")
9450            (match_operand:V4SF 4 "" "")
9451            (match_operand:V4SF 5 "" "")]
9452           UNSPEC_COPYSIGN))
9453    (clobber (match_scratch:V4SF 1 ""))]
9454   "TARGET_SSE_MATH && reload_completed"
9455   [(const_int 0)]
9456 {
9457   ix86_split_copysign_var (operands);
9458   DONE;
9459 })
9460
9461 (define_expand "negdf2"
9462   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9463         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9464   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9465   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9466
9467 (define_expand "absdf2"
9468   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9469         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9470   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9471   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9472
9473 (define_insn "*absnegdf2_mixed"
9474   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9475         (match_operator:DF 3 "absneg_operator"
9476           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9477    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9478    (clobber (reg:CC FLAGS_REG))]
9479   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9480    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9481   "#")
9482
9483 (define_insn "*absnegdf2_sse"
9484   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9485         (match_operator:DF 3 "absneg_operator"
9486           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9487    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "TARGET_SSE2 && TARGET_SSE_MATH
9490    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9491   "#")
9492
9493 (define_insn "*absnegdf2_i387"
9494   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9495         (match_operator:DF 3 "absneg_operator"
9496           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9497    (use (match_operand 2 "" ""))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9500    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9501   "#")
9502
9503 (define_expand "copysigndf3"
9504   [(match_operand:DF 0 "register_operand" "")
9505    (match_operand:DF 1 "nonmemory_operand" "")
9506    (match_operand:DF 2 "register_operand" "")]
9507   "TARGET_SSE2 && TARGET_SSE_MATH"
9508 {
9509   ix86_expand_copysign (operands);
9510   DONE;
9511 })
9512
9513 (define_insn_and_split "copysigndf3_const"
9514   [(set (match_operand:DF 0 "register_operand"          "=x")
9515         (unspec:DF
9516           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9517            (match_operand:DF 2 "register_operand"       "0")
9518            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9519           UNSPEC_COPYSIGN))]
9520   "TARGET_SSE2 && TARGET_SSE_MATH"
9521   "#"
9522   "&& reload_completed"
9523   [(const_int 0)]
9524 {
9525   ix86_split_copysign_const (operands);
9526   DONE;
9527 })
9528
9529 (define_insn "copysigndf3_var"
9530   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9531         (unspec:DF
9532           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9533            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9534            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9535            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9536           UNSPEC_COPYSIGN))
9537    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9538   "TARGET_SSE2 && TARGET_SSE_MATH"
9539   "#")
9540
9541 (define_split
9542   [(set (match_operand:DF 0 "register_operand" "")
9543         (unspec:DF
9544           [(match_operand:DF 2 "register_operand" "")
9545            (match_operand:DF 3 "register_operand" "")
9546            (match_operand:V2DF 4 "" "")
9547            (match_operand:V2DF 5 "" "")]
9548           UNSPEC_COPYSIGN))
9549    (clobber (match_scratch:V2DF 1 ""))]
9550   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9551   [(const_int 0)]
9552 {
9553   ix86_split_copysign_var (operands);
9554   DONE;
9555 })
9556
9557 (define_expand "negxf2"
9558   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9559         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9560   "TARGET_80387"
9561   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9562
9563 (define_expand "absxf2"
9564   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9565         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9566   "TARGET_80387"
9567   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9568
9569 (define_insn "*absnegxf2_i387"
9570   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9571         (match_operator:XF 3 "absneg_operator"
9572           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9573    (use (match_operand 2 "" ""))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "TARGET_80387
9576    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9577   "#")
9578
9579 ;; Splitters for fp abs and neg.
9580
9581 (define_split
9582   [(set (match_operand 0 "fp_register_operand" "")
9583         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9584    (use (match_operand 2 "" ""))
9585    (clobber (reg:CC FLAGS_REG))]
9586   "reload_completed"
9587   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9588
9589 (define_split
9590   [(set (match_operand 0 "register_operand" "")
9591         (match_operator 3 "absneg_operator"
9592           [(match_operand 1 "register_operand" "")]))
9593    (use (match_operand 2 "nonimmediate_operand" ""))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "reload_completed && SSE_REG_P (operands[0])"
9596   [(set (match_dup 0) (match_dup 3))]
9597 {
9598   enum machine_mode mode = GET_MODE (operands[0]);
9599   enum machine_mode vmode = GET_MODE (operands[2]);
9600   rtx tmp;
9601   
9602   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9603   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9604   if (operands_match_p (operands[0], operands[2]))
9605     {
9606       tmp = operands[1];
9607       operands[1] = operands[2];
9608       operands[2] = tmp;
9609     }
9610   if (GET_CODE (operands[3]) == ABS)
9611     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9612   else
9613     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9614   operands[3] = tmp;
9615 })
9616
9617 (define_split
9618   [(set (match_operand:SF 0 "register_operand" "")
9619         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9620    (use (match_operand:V4SF 2 "" ""))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "reload_completed"
9623   [(parallel [(set (match_dup 0) (match_dup 1))
9624               (clobber (reg:CC FLAGS_REG))])]
9625
9626   rtx tmp;
9627   operands[0] = gen_lowpart (SImode, operands[0]);
9628   if (GET_CODE (operands[1]) == ABS)
9629     {
9630       tmp = gen_int_mode (0x7fffffff, SImode);
9631       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9632     }
9633   else
9634     {
9635       tmp = gen_int_mode (0x80000000, SImode);
9636       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9637     }
9638   operands[1] = tmp;
9639 })
9640
9641 (define_split
9642   [(set (match_operand:DF 0 "register_operand" "")
9643         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9644    (use (match_operand 2 "" ""))
9645    (clobber (reg:CC FLAGS_REG))]
9646   "reload_completed"
9647   [(parallel [(set (match_dup 0) (match_dup 1))
9648               (clobber (reg:CC FLAGS_REG))])]
9649 {
9650   rtx tmp;
9651   if (TARGET_64BIT)
9652     {
9653       tmp = gen_lowpart (DImode, operands[0]);
9654       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9655       operands[0] = tmp;
9656
9657       if (GET_CODE (operands[1]) == ABS)
9658         tmp = const0_rtx;
9659       else
9660         tmp = gen_rtx_NOT (DImode, tmp);
9661     }
9662   else
9663     {
9664       operands[0] = gen_highpart (SImode, operands[0]);
9665       if (GET_CODE (operands[1]) == ABS)
9666         {
9667           tmp = gen_int_mode (0x7fffffff, SImode);
9668           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9669         }
9670       else
9671         {
9672           tmp = gen_int_mode (0x80000000, SImode);
9673           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9674         }
9675     }
9676   operands[1] = tmp;
9677 })
9678
9679 (define_split
9680   [(set (match_operand:XF 0 "register_operand" "")
9681         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9682    (use (match_operand 2 "" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "reload_completed"
9685   [(parallel [(set (match_dup 0) (match_dup 1))
9686               (clobber (reg:CC FLAGS_REG))])]
9687 {
9688   rtx tmp;
9689   operands[0] = gen_rtx_REG (SImode,
9690                              true_regnum (operands[0])
9691                              + (TARGET_64BIT ? 1 : 2));
9692   if (GET_CODE (operands[1]) == ABS)
9693     {
9694       tmp = GEN_INT (0x7fff);
9695       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9696     }
9697   else
9698     {
9699       tmp = GEN_INT (0x8000);
9700       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9701     }
9702   operands[1] = tmp;
9703 })
9704
9705 (define_split
9706   [(set (match_operand 0 "memory_operand" "")
9707         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9708    (use (match_operand 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "reload_completed"
9711   [(parallel [(set (match_dup 0) (match_dup 1))
9712               (clobber (reg:CC FLAGS_REG))])]
9713 {
9714   enum machine_mode mode = GET_MODE (operands[0]);
9715   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9716   rtx tmp;
9717
9718   operands[0] = adjust_address (operands[0], QImode, size - 1);
9719   if (GET_CODE (operands[1]) == ABS)
9720     {
9721       tmp = gen_int_mode (0x7f, QImode);
9722       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9723     }
9724   else
9725     {
9726       tmp = gen_int_mode (0x80, QImode);
9727       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9728     }
9729   operands[1] = tmp;
9730 })
9731
9732 ;; Conditionalize these after reload. If they match before reload, we 
9733 ;; lose the clobber and ability to use integer instructions.
9734
9735 (define_insn "*negsf2_1"
9736   [(set (match_operand:SF 0 "register_operand" "=f")
9737         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9738   "TARGET_80387 && reload_completed"
9739   "fchs"
9740   [(set_attr "type" "fsgn")
9741    (set_attr "mode" "SF")])
9742
9743 (define_insn "*negdf2_1"
9744   [(set (match_operand:DF 0 "register_operand" "=f")
9745         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9746   "TARGET_80387 && reload_completed"
9747   "fchs"
9748   [(set_attr "type" "fsgn")
9749    (set_attr "mode" "DF")])
9750
9751 (define_insn "*negxf2_1"
9752   [(set (match_operand:XF 0 "register_operand" "=f")
9753         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9754   "TARGET_80387 && reload_completed"
9755   "fchs"
9756   [(set_attr "type" "fsgn")
9757    (set_attr "mode" "XF")])
9758
9759 (define_insn "*abssf2_1"
9760   [(set (match_operand:SF 0 "register_operand" "=f")
9761         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9762   "TARGET_80387 && reload_completed"
9763   "fabs"
9764   [(set_attr "type" "fsgn")
9765    (set_attr "mode" "SF")])
9766
9767 (define_insn "*absdf2_1"
9768   [(set (match_operand:DF 0 "register_operand" "=f")
9769         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9770   "TARGET_80387 && reload_completed"
9771   "fabs"
9772   [(set_attr "type" "fsgn")
9773    (set_attr "mode" "DF")])
9774
9775 (define_insn "*absxf2_1"
9776   [(set (match_operand:XF 0 "register_operand" "=f")
9777         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9778   "TARGET_80387 && reload_completed"
9779   "fabs"
9780   [(set_attr "type" "fsgn")
9781    (set_attr "mode" "DF")])
9782
9783 (define_insn "*negextendsfdf2"
9784   [(set (match_operand:DF 0 "register_operand" "=f")
9785         (neg:DF (float_extend:DF
9786                   (match_operand:SF 1 "register_operand" "0"))))]
9787   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9788   "fchs"
9789   [(set_attr "type" "fsgn")
9790    (set_attr "mode" "DF")])
9791
9792 (define_insn "*negextenddfxf2"
9793   [(set (match_operand:XF 0 "register_operand" "=f")
9794         (neg:XF (float_extend:XF
9795                   (match_operand:DF 1 "register_operand" "0"))))]
9796   "TARGET_80387"
9797   "fchs"
9798   [(set_attr "type" "fsgn")
9799    (set_attr "mode" "XF")])
9800
9801 (define_insn "*negextendsfxf2"
9802   [(set (match_operand:XF 0 "register_operand" "=f")
9803         (neg:XF (float_extend:XF
9804                   (match_operand:SF 1 "register_operand" "0"))))]
9805   "TARGET_80387"
9806   "fchs"
9807   [(set_attr "type" "fsgn")
9808    (set_attr "mode" "XF")])
9809
9810 (define_insn "*absextendsfdf2"
9811   [(set (match_operand:DF 0 "register_operand" "=f")
9812         (abs:DF (float_extend:DF
9813                   (match_operand:SF 1 "register_operand" "0"))))]
9814   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9815   "fabs"
9816   [(set_attr "type" "fsgn")
9817    (set_attr "mode" "DF")])
9818
9819 (define_insn "*absextenddfxf2"
9820   [(set (match_operand:XF 0 "register_operand" "=f")
9821         (abs:XF (float_extend:XF
9822           (match_operand:DF 1 "register_operand" "0"))))]
9823   "TARGET_80387"
9824   "fabs"
9825   [(set_attr "type" "fsgn")
9826    (set_attr "mode" "XF")])
9827
9828 (define_insn "*absextendsfxf2"
9829   [(set (match_operand:XF 0 "register_operand" "=f")
9830         (abs:XF (float_extend:XF
9831           (match_operand:SF 1 "register_operand" "0"))))]
9832   "TARGET_80387"
9833   "fabs"
9834   [(set_attr "type" "fsgn")
9835    (set_attr "mode" "XF")])
9836 \f
9837 ;; One complement instructions
9838
9839 (define_expand "one_cmpldi2"
9840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9841         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9842   "TARGET_64BIT"
9843   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9844
9845 (define_insn "*one_cmpldi2_1_rex64"
9846   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9847         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9848   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9849   "not{q}\t%0"
9850   [(set_attr "type" "negnot")
9851    (set_attr "mode" "DI")])
9852
9853 (define_insn "*one_cmpldi2_2_rex64"
9854   [(set (reg FLAGS_REG)
9855         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9856                  (const_int 0)))
9857    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9858         (not:DI (match_dup 1)))]
9859   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9860    && ix86_unary_operator_ok (NOT, DImode, operands)"
9861   "#"
9862   [(set_attr "type" "alu1")
9863    (set_attr "mode" "DI")])
9864
9865 (define_split
9866   [(set (match_operand 0 "flags_reg_operand" "")
9867         (match_operator 2 "compare_operator"
9868           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9869            (const_int 0)]))
9870    (set (match_operand:DI 1 "nonimmediate_operand" "")
9871         (not:DI (match_dup 3)))]
9872   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9873   [(parallel [(set (match_dup 0)
9874                    (match_op_dup 2
9875                      [(xor:DI (match_dup 3) (const_int -1))
9876                       (const_int 0)]))
9877               (set (match_dup 1)
9878                    (xor:DI (match_dup 3) (const_int -1)))])]
9879   "")
9880
9881 (define_expand "one_cmplsi2"
9882   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9883         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9884   ""
9885   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9886
9887 (define_insn "*one_cmplsi2_1"
9888   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9889         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9890   "ix86_unary_operator_ok (NOT, SImode, operands)"
9891   "not{l}\t%0"
9892   [(set_attr "type" "negnot")
9893    (set_attr "mode" "SI")])
9894
9895 ;; ??? Currently never generated - xor is used instead.
9896 (define_insn "*one_cmplsi2_1_zext"
9897   [(set (match_operand:DI 0 "register_operand" "=r")
9898         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9899   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9900   "not{l}\t%k0"
9901   [(set_attr "type" "negnot")
9902    (set_attr "mode" "SI")])
9903
9904 (define_insn "*one_cmplsi2_2"
9905   [(set (reg FLAGS_REG)
9906         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9907                  (const_int 0)))
9908    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9909         (not:SI (match_dup 1)))]
9910   "ix86_match_ccmode (insn, CCNOmode)
9911    && ix86_unary_operator_ok (NOT, SImode, operands)"
9912   "#"
9913   [(set_attr "type" "alu1")
9914    (set_attr "mode" "SI")])
9915
9916 (define_split
9917   [(set (match_operand 0 "flags_reg_operand" "")
9918         (match_operator 2 "compare_operator"
9919           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9920            (const_int 0)]))
9921    (set (match_operand:SI 1 "nonimmediate_operand" "")
9922         (not:SI (match_dup 3)))]
9923   "ix86_match_ccmode (insn, CCNOmode)"
9924   [(parallel [(set (match_dup 0)
9925                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9926                                     (const_int 0)]))
9927               (set (match_dup 1)
9928                    (xor:SI (match_dup 3) (const_int -1)))])]
9929   "")
9930
9931 ;; ??? Currently never generated - xor is used instead.
9932 (define_insn "*one_cmplsi2_2_zext"
9933   [(set (reg FLAGS_REG)
9934         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9935                  (const_int 0)))
9936    (set (match_operand:DI 0 "register_operand" "=r")
9937         (zero_extend:DI (not:SI (match_dup 1))))]
9938   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9939    && ix86_unary_operator_ok (NOT, SImode, operands)"
9940   "#"
9941   [(set_attr "type" "alu1")
9942    (set_attr "mode" "SI")])
9943
9944 (define_split
9945   [(set (match_operand 0 "flags_reg_operand" "")
9946         (match_operator 2 "compare_operator"
9947           [(not:SI (match_operand:SI 3 "register_operand" ""))
9948            (const_int 0)]))
9949    (set (match_operand:DI 1 "register_operand" "")
9950         (zero_extend:DI (not:SI (match_dup 3))))]
9951   "ix86_match_ccmode (insn, CCNOmode)"
9952   [(parallel [(set (match_dup 0)
9953                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9954                                     (const_int 0)]))
9955               (set (match_dup 1)
9956                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9957   "")
9958
9959 (define_expand "one_cmplhi2"
9960   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9961         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9962   "TARGET_HIMODE_MATH"
9963   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9964
9965 (define_insn "*one_cmplhi2_1"
9966   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9967         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9968   "ix86_unary_operator_ok (NOT, HImode, operands)"
9969   "not{w}\t%0"
9970   [(set_attr "type" "negnot")
9971    (set_attr "mode" "HI")])
9972
9973 (define_insn "*one_cmplhi2_2"
9974   [(set (reg FLAGS_REG)
9975         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9976                  (const_int 0)))
9977    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9978         (not:HI (match_dup 1)))]
9979   "ix86_match_ccmode (insn, CCNOmode)
9980    && ix86_unary_operator_ok (NEG, HImode, operands)"
9981   "#"
9982   [(set_attr "type" "alu1")
9983    (set_attr "mode" "HI")])
9984
9985 (define_split
9986   [(set (match_operand 0 "flags_reg_operand" "")
9987         (match_operator 2 "compare_operator"
9988           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9989            (const_int 0)]))
9990    (set (match_operand:HI 1 "nonimmediate_operand" "")
9991         (not:HI (match_dup 3)))]
9992   "ix86_match_ccmode (insn, CCNOmode)"
9993   [(parallel [(set (match_dup 0)
9994                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9995                                     (const_int 0)]))
9996               (set (match_dup 1)
9997                    (xor:HI (match_dup 3) (const_int -1)))])]
9998   "")
9999
10000 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10001 (define_expand "one_cmplqi2"
10002   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10003         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10004   "TARGET_QIMODE_MATH"
10005   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10006
10007 (define_insn "*one_cmplqi2_1"
10008   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10009         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10010   "ix86_unary_operator_ok (NOT, QImode, operands)"
10011   "@
10012    not{b}\t%0
10013    not{l}\t%k0"
10014   [(set_attr "type" "negnot")
10015    (set_attr "mode" "QI,SI")])
10016
10017 (define_insn "*one_cmplqi2_2"
10018   [(set (reg FLAGS_REG)
10019         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10020                  (const_int 0)))
10021    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10022         (not:QI (match_dup 1)))]
10023   "ix86_match_ccmode (insn, CCNOmode)
10024    && ix86_unary_operator_ok (NOT, QImode, operands)"
10025   "#"
10026   [(set_attr "type" "alu1")
10027    (set_attr "mode" "QI")])
10028
10029 (define_split
10030   [(set (match_operand 0 "flags_reg_operand" "")
10031         (match_operator 2 "compare_operator"
10032           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10033            (const_int 0)]))
10034    (set (match_operand:QI 1 "nonimmediate_operand" "")
10035         (not:QI (match_dup 3)))]
10036   "ix86_match_ccmode (insn, CCNOmode)"
10037   [(parallel [(set (match_dup 0)
10038                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10039                                     (const_int 0)]))
10040               (set (match_dup 1)
10041                    (xor:QI (match_dup 3) (const_int -1)))])]
10042   "")
10043 \f
10044 ;; Arithmetic shift instructions
10045
10046 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10047 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10048 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10049 ;; from the assembler input.
10050 ;;
10051 ;; This instruction shifts the target reg/mem as usual, but instead of
10052 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10053 ;; is a left shift double, bits are taken from the high order bits of
10054 ;; reg, else if the insn is a shift right double, bits are taken from the
10055 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10056 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10057 ;;
10058 ;; Since sh[lr]d does not change the `reg' operand, that is done
10059 ;; separately, making all shifts emit pairs of shift double and normal
10060 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10061 ;; support a 63 bit shift, each shift where the count is in a reg expands
10062 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10063 ;;
10064 ;; If the shift count is a constant, we need never emit more than one
10065 ;; shift pair, instead using moves and sign extension for counts greater
10066 ;; than 31.
10067
10068 (define_expand "ashldi3"
10069   [(set (match_operand:DI 0 "shiftdi_operand" "")
10070         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10071                    (match_operand:QI 2 "nonmemory_operand" "")))]
10072   ""
10073   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10074
10075 (define_insn "*ashldi3_1_rex64"
10076   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10077         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10078                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10079    (clobber (reg:CC FLAGS_REG))]
10080   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10081 {
10082   switch (get_attr_type (insn))
10083     {
10084     case TYPE_ALU:
10085       if (operands[2] != const1_rtx)
10086         abort ();
10087       if (!rtx_equal_p (operands[0], operands[1]))
10088         abort ();
10089       return "add{q}\t{%0, %0|%0, %0}";
10090
10091     case TYPE_LEA:
10092       if (GET_CODE (operands[2]) != CONST_INT
10093           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10094         abort ();
10095       operands[1] = gen_rtx_MULT (DImode, operands[1],
10096                                   GEN_INT (1 << INTVAL (operands[2])));
10097       return "lea{q}\t{%a1, %0|%0, %a1}";
10098
10099     default:
10100       if (REG_P (operands[2]))
10101         return "sal{q}\t{%b2, %0|%0, %b2}";
10102       else if (operands[2] == const1_rtx
10103                && (TARGET_SHIFT1 || optimize_size))
10104         return "sal{q}\t%0";
10105       else
10106         return "sal{q}\t{%2, %0|%0, %2}";
10107     }
10108 }
10109   [(set (attr "type")
10110      (cond [(eq_attr "alternative" "1")
10111               (const_string "lea")
10112             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10113                           (const_int 0))
10114                       (match_operand 0 "register_operand" ""))
10115                  (match_operand 2 "const1_operand" ""))
10116               (const_string "alu")
10117            ]
10118            (const_string "ishift")))
10119    (set_attr "mode" "DI")])
10120
10121 ;; Convert lea to the lea pattern to avoid flags dependency.
10122 (define_split
10123   [(set (match_operand:DI 0 "register_operand" "")
10124         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10125                    (match_operand:QI 2 "immediate_operand" "")))
10126    (clobber (reg:CC FLAGS_REG))]
10127   "TARGET_64BIT && reload_completed
10128    && true_regnum (operands[0]) != true_regnum (operands[1])"
10129   [(set (match_dup 0)
10130         (mult:DI (match_dup 1)
10131                  (match_dup 2)))]
10132   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10133
10134 ;; This pattern can't accept a variable shift count, since shifts by
10135 ;; zero don't affect the flags.  We assume that shifts by constant
10136 ;; zero are optimized away.
10137 (define_insn "*ashldi3_cmp_rex64"
10138   [(set (reg FLAGS_REG)
10139         (compare
10140           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10141                      (match_operand:QI 2 "immediate_operand" "e"))
10142           (const_int 0)))
10143    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10144         (ashift:DI (match_dup 1) (match_dup 2)))]
10145   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10146    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10147 {
10148   switch (get_attr_type (insn))
10149     {
10150     case TYPE_ALU:
10151       if (operands[2] != const1_rtx)
10152         abort ();
10153       return "add{q}\t{%0, %0|%0, %0}";
10154
10155     default:
10156       if (REG_P (operands[2]))
10157         return "sal{q}\t{%b2, %0|%0, %b2}";
10158       else if (operands[2] == const1_rtx
10159                && (TARGET_SHIFT1 || optimize_size))
10160         return "sal{q}\t%0";
10161       else
10162         return "sal{q}\t{%2, %0|%0, %2}";
10163     }
10164 }
10165   [(set (attr "type")
10166      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10167                           (const_int 0))
10168                       (match_operand 0 "register_operand" ""))
10169                  (match_operand 2 "const1_operand" ""))
10170               (const_string "alu")
10171            ]
10172            (const_string "ishift")))
10173    (set_attr "mode" "DI")])
10174
10175 (define_insn "*ashldi3_1"
10176   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10177         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10178                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10179    (clobber (reg:CC FLAGS_REG))]
10180   "!TARGET_64BIT"
10181   "#"
10182   [(set_attr "type" "multi")])
10183
10184 ;; By default we don't ask for a scratch register, because when DImode
10185 ;; values are manipulated, registers are already at a premium.  But if
10186 ;; we have one handy, we won't turn it away.
10187 (define_peephole2
10188   [(match_scratch:SI 3 "r")
10189    (parallel [(set (match_operand:DI 0 "register_operand" "")
10190                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10191                               (match_operand:QI 2 "nonmemory_operand" "")))
10192               (clobber (reg:CC FLAGS_REG))])
10193    (match_dup 3)]
10194   "!TARGET_64BIT && TARGET_CMOVE"
10195   [(const_int 0)]
10196   "ix86_split_ashldi (operands, operands[3]); DONE;")
10197
10198 (define_split
10199   [(set (match_operand:DI 0 "register_operand" "")
10200         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10201                    (match_operand:QI 2 "nonmemory_operand" "")))
10202    (clobber (reg:CC FLAGS_REG))]
10203   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10204   [(const_int 0)]
10205   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10206
10207 (define_insn "x86_shld_1"
10208   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10209         (ior:SI (ashift:SI (match_dup 0)
10210                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10211                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10212                   (minus:QI (const_int 32) (match_dup 2)))))
10213    (clobber (reg:CC FLAGS_REG))]
10214   ""
10215   "@
10216    shld{l}\t{%2, %1, %0|%0, %1, %2}
10217    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10218   [(set_attr "type" "ishift")
10219    (set_attr "prefix_0f" "1")
10220    (set_attr "mode" "SI")
10221    (set_attr "pent_pair" "np")
10222    (set_attr "athlon_decode" "vector")])
10223
10224 (define_expand "x86_shift_adj_1"
10225   [(set (reg:CCZ FLAGS_REG)
10226         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10227                              (const_int 32))
10228                      (const_int 0)))
10229    (set (match_operand:SI 0 "register_operand" "")
10230         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10231                          (match_operand:SI 1 "register_operand" "")
10232                          (match_dup 0)))
10233    (set (match_dup 1)
10234         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10235                          (match_operand:SI 3 "register_operand" "r")
10236                          (match_dup 1)))]
10237   "TARGET_CMOVE"
10238   "")
10239
10240 (define_expand "x86_shift_adj_2"
10241   [(use (match_operand:SI 0 "register_operand" ""))
10242    (use (match_operand:SI 1 "register_operand" ""))
10243    (use (match_operand:QI 2 "register_operand" ""))]
10244   ""
10245 {
10246   rtx label = gen_label_rtx ();
10247   rtx tmp;
10248
10249   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10250
10251   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10252   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10253   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10254                               gen_rtx_LABEL_REF (VOIDmode, label),
10255                               pc_rtx);
10256   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10257   JUMP_LABEL (tmp) = label;
10258
10259   emit_move_insn (operands[0], operands[1]);
10260   ix86_expand_clear (operands[1]);
10261
10262   emit_label (label);
10263   LABEL_NUSES (label) = 1;
10264
10265   DONE;
10266 })
10267
10268 (define_expand "ashlsi3"
10269   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10270         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10271                    (match_operand:QI 2 "nonmemory_operand" "")))
10272    (clobber (reg:CC FLAGS_REG))]
10273   ""
10274   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10275
10276 (define_insn "*ashlsi3_1"
10277   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10278         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10279                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10282 {
10283   switch (get_attr_type (insn))
10284     {
10285     case TYPE_ALU:
10286       if (operands[2] != const1_rtx)
10287         abort ();
10288       if (!rtx_equal_p (operands[0], operands[1]))
10289         abort ();
10290       return "add{l}\t{%0, %0|%0, %0}";
10291
10292     case TYPE_LEA:
10293       return "#";
10294
10295     default:
10296       if (REG_P (operands[2]))
10297         return "sal{l}\t{%b2, %0|%0, %b2}";
10298       else if (operands[2] == const1_rtx
10299                && (TARGET_SHIFT1 || optimize_size))
10300         return "sal{l}\t%0";
10301       else
10302         return "sal{l}\t{%2, %0|%0, %2}";
10303     }
10304 }
10305   [(set (attr "type")
10306      (cond [(eq_attr "alternative" "1")
10307               (const_string "lea")
10308             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10309                           (const_int 0))
10310                       (match_operand 0 "register_operand" ""))
10311                  (match_operand 2 "const1_operand" ""))
10312               (const_string "alu")
10313            ]
10314            (const_string "ishift")))
10315    (set_attr "mode" "SI")])
10316
10317 ;; Convert lea to the lea pattern to avoid flags dependency.
10318 (define_split
10319   [(set (match_operand 0 "register_operand" "")
10320         (ashift (match_operand 1 "index_register_operand" "")
10321                 (match_operand:QI 2 "const_int_operand" "")))
10322    (clobber (reg:CC FLAGS_REG))]
10323   "reload_completed
10324    && true_regnum (operands[0]) != true_regnum (operands[1])
10325    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10326   [(const_int 0)]
10327 {
10328   rtx pat;
10329   enum machine_mode mode = GET_MODE (operands[0]);
10330
10331   if (GET_MODE_SIZE (mode) < 4)
10332     operands[0] = gen_lowpart (SImode, operands[0]);
10333   if (mode != Pmode)
10334     operands[1] = gen_lowpart (Pmode, operands[1]);
10335   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10336
10337   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10338   if (Pmode != SImode)
10339     pat = gen_rtx_SUBREG (SImode, pat, 0);
10340   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10341   DONE;
10342 })
10343
10344 ;; Rare case of shifting RSP is handled by generating move and shift
10345 (define_split
10346   [(set (match_operand 0 "register_operand" "")
10347         (ashift (match_operand 1 "register_operand" "")
10348                 (match_operand:QI 2 "const_int_operand" "")))
10349    (clobber (reg:CC FLAGS_REG))]
10350   "reload_completed
10351    && true_regnum (operands[0]) != true_regnum (operands[1])"
10352   [(const_int 0)]
10353 {
10354   rtx pat, clob;
10355   emit_move_insn (operands[1], operands[0]);
10356   pat = gen_rtx_SET (VOIDmode, operands[0],
10357                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10358                                      operands[0], operands[2]));
10359   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10360   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10361   DONE;
10362 })
10363
10364 (define_insn "*ashlsi3_1_zext"
10365   [(set (match_operand:DI 0 "register_operand" "=r,r")
10366         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10367                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10368    (clobber (reg:CC FLAGS_REG))]
10369   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10370 {
10371   switch (get_attr_type (insn))
10372     {
10373     case TYPE_ALU:
10374       if (operands[2] != const1_rtx)
10375         abort ();
10376       return "add{l}\t{%k0, %k0|%k0, %k0}";
10377
10378     case TYPE_LEA:
10379       return "#";
10380
10381     default:
10382       if (REG_P (operands[2]))
10383         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10384       else if (operands[2] == const1_rtx
10385                && (TARGET_SHIFT1 || optimize_size))
10386         return "sal{l}\t%k0";
10387       else
10388         return "sal{l}\t{%2, %k0|%k0, %2}";
10389     }
10390 }
10391   [(set (attr "type")
10392      (cond [(eq_attr "alternative" "1")
10393               (const_string "lea")
10394             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10395                      (const_int 0))
10396                  (match_operand 2 "const1_operand" ""))
10397               (const_string "alu")
10398            ]
10399            (const_string "ishift")))
10400    (set_attr "mode" "SI")])
10401
10402 ;; Convert lea to the lea pattern to avoid flags dependency.
10403 (define_split
10404   [(set (match_operand:DI 0 "register_operand" "")
10405         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10406                                 (match_operand:QI 2 "const_int_operand" ""))))
10407    (clobber (reg:CC FLAGS_REG))]
10408   "TARGET_64BIT && reload_completed
10409    && true_regnum (operands[0]) != true_regnum (operands[1])"
10410   [(set (match_dup 0) (zero_extend:DI
10411                         (subreg:SI (mult:SI (match_dup 1)
10412                                             (match_dup 2)) 0)))]
10413 {
10414   operands[1] = gen_lowpart (Pmode, operands[1]);
10415   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10416 })
10417
10418 ;; This pattern can't accept a variable shift count, since shifts by
10419 ;; zero don't affect the flags.  We assume that shifts by constant
10420 ;; zero are optimized away.
10421 (define_insn "*ashlsi3_cmp"
10422   [(set (reg FLAGS_REG)
10423         (compare
10424           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10425                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10426           (const_int 0)))
10427    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10428         (ashift:SI (match_dup 1) (match_dup 2)))]
10429   "ix86_match_ccmode (insn, CCGOCmode)
10430    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10431 {
10432   switch (get_attr_type (insn))
10433     {
10434     case TYPE_ALU:
10435       if (operands[2] != const1_rtx)
10436         abort ();
10437       return "add{l}\t{%0, %0|%0, %0}";
10438
10439     default:
10440       if (REG_P (operands[2]))
10441         return "sal{l}\t{%b2, %0|%0, %b2}";
10442       else if (operands[2] == const1_rtx
10443                && (TARGET_SHIFT1 || optimize_size))
10444         return "sal{l}\t%0";
10445       else
10446         return "sal{l}\t{%2, %0|%0, %2}";
10447     }
10448 }
10449   [(set (attr "type")
10450      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10451                           (const_int 0))
10452                       (match_operand 0 "register_operand" ""))
10453                  (match_operand 2 "const1_operand" ""))
10454               (const_string "alu")
10455            ]
10456            (const_string "ishift")))
10457    (set_attr "mode" "SI")])
10458
10459 (define_insn "*ashlsi3_cmp_zext"
10460   [(set (reg FLAGS_REG)
10461         (compare
10462           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10463                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10464           (const_int 0)))
10465    (set (match_operand:DI 0 "register_operand" "=r")
10466         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10467   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10468    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10469 {
10470   switch (get_attr_type (insn))
10471     {
10472     case TYPE_ALU:
10473       if (operands[2] != const1_rtx)
10474         abort ();
10475       return "add{l}\t{%k0, %k0|%k0, %k0}";
10476
10477     default:
10478       if (REG_P (operands[2]))
10479         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10480       else if (operands[2] == const1_rtx
10481                && (TARGET_SHIFT1 || optimize_size))
10482         return "sal{l}\t%k0";
10483       else
10484         return "sal{l}\t{%2, %k0|%k0, %2}";
10485     }
10486 }
10487   [(set (attr "type")
10488      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10489                      (const_int 0))
10490                  (match_operand 2 "const1_operand" ""))
10491               (const_string "alu")
10492            ]
10493            (const_string "ishift")))
10494    (set_attr "mode" "SI")])
10495
10496 (define_expand "ashlhi3"
10497   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10498         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10499                    (match_operand:QI 2 "nonmemory_operand" "")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "TARGET_HIMODE_MATH"
10502   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10503
10504 (define_insn "*ashlhi3_1_lea"
10505   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10506         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10507                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10508    (clobber (reg:CC FLAGS_REG))]
10509   "!TARGET_PARTIAL_REG_STALL
10510    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10511 {
10512   switch (get_attr_type (insn))
10513     {
10514     case TYPE_LEA:
10515       return "#";
10516     case TYPE_ALU:
10517       if (operands[2] != const1_rtx)
10518         abort ();
10519       return "add{w}\t{%0, %0|%0, %0}";
10520
10521     default:
10522       if (REG_P (operands[2]))
10523         return "sal{w}\t{%b2, %0|%0, %b2}";
10524       else if (operands[2] == const1_rtx
10525                && (TARGET_SHIFT1 || optimize_size))
10526         return "sal{w}\t%0";
10527       else
10528         return "sal{w}\t{%2, %0|%0, %2}";
10529     }
10530 }
10531   [(set (attr "type")
10532      (cond [(eq_attr "alternative" "1")
10533               (const_string "lea")
10534             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10535                           (const_int 0))
10536                       (match_operand 0 "register_operand" ""))
10537                  (match_operand 2 "const1_operand" ""))
10538               (const_string "alu")
10539            ]
10540            (const_string "ishift")))
10541    (set_attr "mode" "HI,SI")])
10542
10543 (define_insn "*ashlhi3_1"
10544   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10545         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10546                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10547    (clobber (reg:CC FLAGS_REG))]
10548   "TARGET_PARTIAL_REG_STALL
10549    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10550 {
10551   switch (get_attr_type (insn))
10552     {
10553     case TYPE_ALU:
10554       if (operands[2] != const1_rtx)
10555         abort ();
10556       return "add{w}\t{%0, %0|%0, %0}";
10557
10558     default:
10559       if (REG_P (operands[2]))
10560         return "sal{w}\t{%b2, %0|%0, %b2}";
10561       else if (operands[2] == const1_rtx
10562                && (TARGET_SHIFT1 || optimize_size))
10563         return "sal{w}\t%0";
10564       else
10565         return "sal{w}\t{%2, %0|%0, %2}";
10566     }
10567 }
10568   [(set (attr "type")
10569      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10570                           (const_int 0))
10571                       (match_operand 0 "register_operand" ""))
10572                  (match_operand 2 "const1_operand" ""))
10573               (const_string "alu")
10574            ]
10575            (const_string "ishift")))
10576    (set_attr "mode" "HI")])
10577
10578 ;; This pattern can't accept a variable shift count, since shifts by
10579 ;; zero don't affect the flags.  We assume that shifts by constant
10580 ;; zero are optimized away.
10581 (define_insn "*ashlhi3_cmp"
10582   [(set (reg FLAGS_REG)
10583         (compare
10584           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10585                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10586           (const_int 0)))
10587    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10588         (ashift:HI (match_dup 1) (match_dup 2)))]
10589   "ix86_match_ccmode (insn, CCGOCmode)
10590    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10591 {
10592   switch (get_attr_type (insn))
10593     {
10594     case TYPE_ALU:
10595       if (operands[2] != const1_rtx)
10596         abort ();
10597       return "add{w}\t{%0, %0|%0, %0}";
10598
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{w}\t{%b2, %0|%0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{w}\t%0";
10605       else
10606         return "sal{w}\t{%2, %0|%0, %2}";
10607     }
10608 }
10609   [(set (attr "type")
10610      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10611                           (const_int 0))
10612                       (match_operand 0 "register_operand" ""))
10613                  (match_operand 2 "const1_operand" ""))
10614               (const_string "alu")
10615            ]
10616            (const_string "ishift")))
10617    (set_attr "mode" "HI")])
10618
10619 (define_expand "ashlqi3"
10620   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10622                    (match_operand:QI 2 "nonmemory_operand" "")))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_QIMODE_MATH"
10625   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10626
10627 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10628
10629 (define_insn "*ashlqi3_1_lea"
10630   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10631         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10632                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "!TARGET_PARTIAL_REG_STALL
10635    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10636 {
10637   switch (get_attr_type (insn))
10638     {
10639     case TYPE_LEA:
10640       return "#";
10641     case TYPE_ALU:
10642       if (operands[2] != const1_rtx)
10643         abort ();
10644       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10645         return "add{l}\t{%k0, %k0|%k0, %k0}";
10646       else
10647         return "add{b}\t{%0, %0|%0, %0}";
10648
10649     default:
10650       if (REG_P (operands[2]))
10651         {
10652           if (get_attr_mode (insn) == MODE_SI)
10653             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10654           else
10655             return "sal{b}\t{%b2, %0|%0, %b2}";
10656         }
10657       else if (operands[2] == const1_rtx
10658                && (TARGET_SHIFT1 || optimize_size))
10659         {
10660           if (get_attr_mode (insn) == MODE_SI)
10661             return "sal{l}\t%0";
10662           else
10663             return "sal{b}\t%0";
10664         }
10665       else
10666         {
10667           if (get_attr_mode (insn) == MODE_SI)
10668             return "sal{l}\t{%2, %k0|%k0, %2}";
10669           else
10670             return "sal{b}\t{%2, %0|%0, %2}";
10671         }
10672     }
10673 }
10674   [(set (attr "type")
10675      (cond [(eq_attr "alternative" "2")
10676               (const_string "lea")
10677             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10678                           (const_int 0))
10679                       (match_operand 0 "register_operand" ""))
10680                  (match_operand 2 "const1_operand" ""))
10681               (const_string "alu")
10682            ]
10683            (const_string "ishift")))
10684    (set_attr "mode" "QI,SI,SI")])
10685
10686 (define_insn "*ashlqi3_1"
10687   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10688         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10689                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10690    (clobber (reg:CC FLAGS_REG))]
10691   "TARGET_PARTIAL_REG_STALL
10692    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10693 {
10694   switch (get_attr_type (insn))
10695     {
10696     case TYPE_ALU:
10697       if (operands[2] != const1_rtx)
10698         abort ();
10699       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10700         return "add{l}\t{%k0, %k0|%k0, %k0}";
10701       else
10702         return "add{b}\t{%0, %0|%0, %0}";
10703
10704     default:
10705       if (REG_P (operands[2]))
10706         {
10707           if (get_attr_mode (insn) == MODE_SI)
10708             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10709           else
10710             return "sal{b}\t{%b2, %0|%0, %b2}";
10711         }
10712       else if (operands[2] == const1_rtx
10713                && (TARGET_SHIFT1 || optimize_size))
10714         {
10715           if (get_attr_mode (insn) == MODE_SI)
10716             return "sal{l}\t%0";
10717           else
10718             return "sal{b}\t%0";
10719         }
10720       else
10721         {
10722           if (get_attr_mode (insn) == MODE_SI)
10723             return "sal{l}\t{%2, %k0|%k0, %2}";
10724           else
10725             return "sal{b}\t{%2, %0|%0, %2}";
10726         }
10727     }
10728 }
10729   [(set (attr "type")
10730      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10731                           (const_int 0))
10732                       (match_operand 0 "register_operand" ""))
10733                  (match_operand 2 "const1_operand" ""))
10734               (const_string "alu")
10735            ]
10736            (const_string "ishift")))
10737    (set_attr "mode" "QI,SI")])
10738
10739 ;; This pattern can't accept a variable shift count, since shifts by
10740 ;; zero don't affect the flags.  We assume that shifts by constant
10741 ;; zero are optimized away.
10742 (define_insn "*ashlqi3_cmp"
10743   [(set (reg FLAGS_REG)
10744         (compare
10745           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10746                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10747           (const_int 0)))
10748    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10749         (ashift:QI (match_dup 1) (match_dup 2)))]
10750   "ix86_match_ccmode (insn, CCGOCmode)
10751    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10752 {
10753   switch (get_attr_type (insn))
10754     {
10755     case TYPE_ALU:
10756       if (operands[2] != const1_rtx)
10757         abort ();
10758       return "add{b}\t{%0, %0|%0, %0}";
10759
10760     default:
10761       if (REG_P (operands[2]))
10762         return "sal{b}\t{%b2, %0|%0, %b2}";
10763       else if (operands[2] == const1_rtx
10764                && (TARGET_SHIFT1 || optimize_size))
10765         return "sal{b}\t%0";
10766       else
10767         return "sal{b}\t{%2, %0|%0, %2}";
10768     }
10769 }
10770   [(set (attr "type")
10771      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10772                           (const_int 0))
10773                       (match_operand 0 "register_operand" ""))
10774                  (match_operand 2 "const1_operand" ""))
10775               (const_string "alu")
10776            ]
10777            (const_string "ishift")))
10778    (set_attr "mode" "QI")])
10779
10780 ;; See comment above `ashldi3' about how this works.
10781
10782 (define_expand "ashrdi3"
10783   [(set (match_operand:DI 0 "shiftdi_operand" "")
10784         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10785                      (match_operand:QI 2 "nonmemory_operand" "")))]
10786   ""
10787   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10788
10789 (define_insn "*ashrdi3_63_rex64"
10790   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10791         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10792                      (match_operand:DI 2 "const_int_operand" "i,i")))
10793    (clobber (reg:CC FLAGS_REG))]
10794   "TARGET_64BIT && INTVAL (operands[2]) == 63
10795    && (TARGET_USE_CLTD || optimize_size)
10796    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10797   "@
10798    {cqto|cqo}
10799    sar{q}\t{%2, %0|%0, %2}"
10800   [(set_attr "type" "imovx,ishift")
10801    (set_attr "prefix_0f" "0,*")
10802    (set_attr "length_immediate" "0,*")
10803    (set_attr "modrm" "0,1")
10804    (set_attr "mode" "DI")])
10805
10806 (define_insn "*ashrdi3_1_one_bit_rex64"
10807   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10808         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809                      (match_operand:QI 2 "const1_operand" "")))
10810    (clobber (reg:CC FLAGS_REG))]
10811   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10812    && (TARGET_SHIFT1 || optimize_size)"
10813   "sar{q}\t%0"
10814   [(set_attr "type" "ishift")
10815    (set (attr "length") 
10816      (if_then_else (match_operand:DI 0 "register_operand" "") 
10817         (const_string "2")
10818         (const_string "*")))])
10819
10820 (define_insn "*ashrdi3_1_rex64"
10821   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10822         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10823                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10824    (clobber (reg:CC FLAGS_REG))]
10825   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10826   "@
10827    sar{q}\t{%2, %0|%0, %2}
10828    sar{q}\t{%b2, %0|%0, %b2}"
10829   [(set_attr "type" "ishift")
10830    (set_attr "mode" "DI")])
10831
10832 ;; This pattern can't accept a variable shift count, since shifts by
10833 ;; zero don't affect the flags.  We assume that shifts by constant
10834 ;; zero are optimized away.
10835 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10836   [(set (reg FLAGS_REG)
10837         (compare
10838           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10839                        (match_operand:QI 2 "const1_operand" ""))
10840           (const_int 0)))
10841    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10843   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10844    && (TARGET_SHIFT1 || optimize_size)
10845    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10846   "sar{q}\t%0"
10847   [(set_attr "type" "ishift")
10848    (set (attr "length") 
10849      (if_then_else (match_operand:DI 0 "register_operand" "") 
10850         (const_string "2")
10851         (const_string "*")))])
10852
10853 ;; This pattern can't accept a variable shift count, since shifts by
10854 ;; zero don't affect the flags.  We assume that shifts by constant
10855 ;; zero are optimized away.
10856 (define_insn "*ashrdi3_cmp_rex64"
10857   [(set (reg FLAGS_REG)
10858         (compare
10859           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10860                        (match_operand:QI 2 "const_int_operand" "n"))
10861           (const_int 0)))
10862    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10863         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10864   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10865    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10866   "sar{q}\t{%2, %0|%0, %2}"
10867   [(set_attr "type" "ishift")
10868    (set_attr "mode" "DI")])
10869
10870 (define_insn "*ashrdi3_1"
10871   [(set (match_operand:DI 0 "register_operand" "=r")
10872         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10873                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10874    (clobber (reg:CC FLAGS_REG))]
10875   "!TARGET_64BIT"
10876   "#"
10877   [(set_attr "type" "multi")])
10878
10879 ;; By default we don't ask for a scratch register, because when DImode
10880 ;; values are manipulated, registers are already at a premium.  But if
10881 ;; we have one handy, we won't turn it away.
10882 (define_peephole2
10883   [(match_scratch:SI 3 "r")
10884    (parallel [(set (match_operand:DI 0 "register_operand" "")
10885                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10886                                 (match_operand:QI 2 "nonmemory_operand" "")))
10887               (clobber (reg:CC FLAGS_REG))])
10888    (match_dup 3)]
10889   "!TARGET_64BIT && TARGET_CMOVE"
10890   [(const_int 0)]
10891   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10892
10893 (define_split
10894   [(set (match_operand:DI 0 "register_operand" "")
10895         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10896                      (match_operand:QI 2 "nonmemory_operand" "")))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10899   [(const_int 0)]
10900   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10901
10902 (define_insn "x86_shrd_1"
10903   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10904         (ior:SI (ashiftrt:SI (match_dup 0)
10905                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10906                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10907                   (minus:QI (const_int 32) (match_dup 2)))))
10908    (clobber (reg:CC FLAGS_REG))]
10909   ""
10910   "@
10911    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10912    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10913   [(set_attr "type" "ishift")
10914    (set_attr "prefix_0f" "1")
10915    (set_attr "pent_pair" "np")
10916    (set_attr "mode" "SI")])
10917
10918 (define_expand "x86_shift_adj_3"
10919   [(use (match_operand:SI 0 "register_operand" ""))
10920    (use (match_operand:SI 1 "register_operand" ""))
10921    (use (match_operand:QI 2 "register_operand" ""))]
10922   ""
10923 {
10924   rtx label = gen_label_rtx ();
10925   rtx tmp;
10926
10927   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10928
10929   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10930   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10931   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10932                               gen_rtx_LABEL_REF (VOIDmode, label),
10933                               pc_rtx);
10934   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10935   JUMP_LABEL (tmp) = label;
10936
10937   emit_move_insn (operands[0], operands[1]);
10938   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10939
10940   emit_label (label);
10941   LABEL_NUSES (label) = 1;
10942
10943   DONE;
10944 })
10945
10946 (define_insn "ashrsi3_31"
10947   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10948         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10949                      (match_operand:SI 2 "const_int_operand" "i,i")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10952    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10953   "@
10954    {cltd|cdq}
10955    sar{l}\t{%2, %0|%0, %2}"
10956   [(set_attr "type" "imovx,ishift")
10957    (set_attr "prefix_0f" "0,*")
10958    (set_attr "length_immediate" "0,*")
10959    (set_attr "modrm" "0,1")
10960    (set_attr "mode" "SI")])
10961
10962 (define_insn "*ashrsi3_31_zext"
10963   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10964         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10965                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10966    (clobber (reg:CC FLAGS_REG))]
10967   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10968    && INTVAL (operands[2]) == 31
10969    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10970   "@
10971    {cltd|cdq}
10972    sar{l}\t{%2, %k0|%k0, %2}"
10973   [(set_attr "type" "imovx,ishift")
10974    (set_attr "prefix_0f" "0,*")
10975    (set_attr "length_immediate" "0,*")
10976    (set_attr "modrm" "0,1")
10977    (set_attr "mode" "SI")])
10978
10979 (define_expand "ashrsi3"
10980   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10981         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10982                      (match_operand:QI 2 "nonmemory_operand" "")))
10983    (clobber (reg:CC FLAGS_REG))]
10984   ""
10985   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10986
10987 (define_insn "*ashrsi3_1_one_bit"
10988   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10989         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10990                      (match_operand:QI 2 "const1_operand" "")))
10991    (clobber (reg:CC FLAGS_REG))]
10992   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10993    && (TARGET_SHIFT1 || optimize_size)"
10994   "sar{l}\t%0"
10995   [(set_attr "type" "ishift")
10996    (set (attr "length") 
10997      (if_then_else (match_operand:SI 0 "register_operand" "") 
10998         (const_string "2")
10999         (const_string "*")))])
11000
11001 (define_insn "*ashrsi3_1_one_bit_zext"
11002   [(set (match_operand:DI 0 "register_operand" "=r")
11003         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11004                                      (match_operand:QI 2 "const1_operand" ""))))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11007    && (TARGET_SHIFT1 || optimize_size)"
11008   "sar{l}\t%k0"
11009   [(set_attr "type" "ishift")
11010    (set_attr "length" "2")])
11011
11012 (define_insn "*ashrsi3_1"
11013   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11014         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11015                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11016    (clobber (reg:CC FLAGS_REG))]
11017   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11018   "@
11019    sar{l}\t{%2, %0|%0, %2}
11020    sar{l}\t{%b2, %0|%0, %b2}"
11021   [(set_attr "type" "ishift")
11022    (set_attr "mode" "SI")])
11023
11024 (define_insn "*ashrsi3_1_zext"
11025   [(set (match_operand:DI 0 "register_operand" "=r,r")
11026         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11027                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11030   "@
11031    sar{l}\t{%2, %k0|%k0, %2}
11032    sar{l}\t{%b2, %k0|%k0, %b2}"
11033   [(set_attr "type" "ishift")
11034    (set_attr "mode" "SI")])
11035
11036 ;; This pattern can't accept a variable shift count, since shifts by
11037 ;; zero don't affect the flags.  We assume that shifts by constant
11038 ;; zero are optimized away.
11039 (define_insn "*ashrsi3_one_bit_cmp"
11040   [(set (reg FLAGS_REG)
11041         (compare
11042           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11043                        (match_operand:QI 2 "const1_operand" ""))
11044           (const_int 0)))
11045    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11046         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11047   "ix86_match_ccmode (insn, CCGOCmode)
11048    && (TARGET_SHIFT1 || optimize_size)
11049    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11050   "sar{l}\t%0"
11051   [(set_attr "type" "ishift")
11052    (set (attr "length") 
11053      (if_then_else (match_operand:SI 0 "register_operand" "") 
11054         (const_string "2")
11055         (const_string "*")))])
11056
11057 (define_insn "*ashrsi3_one_bit_cmp_zext"
11058   [(set (reg FLAGS_REG)
11059         (compare
11060           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11061                        (match_operand:QI 2 "const1_operand" ""))
11062           (const_int 0)))
11063    (set (match_operand:DI 0 "register_operand" "=r")
11064         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11065   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11066    && (TARGET_SHIFT1 || optimize_size)
11067    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11068   "sar{l}\t%k0"
11069   [(set_attr "type" "ishift")
11070    (set_attr "length" "2")])
11071
11072 ;; This pattern can't accept a variable shift count, since shifts by
11073 ;; zero don't affect the flags.  We assume that shifts by constant
11074 ;; zero are optimized away.
11075 (define_insn "*ashrsi3_cmp"
11076   [(set (reg FLAGS_REG)
11077         (compare
11078           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11079                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11080           (const_int 0)))
11081    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11082         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11083   "ix86_match_ccmode (insn, CCGOCmode)
11084    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11085   "sar{l}\t{%2, %0|%0, %2}"
11086   [(set_attr "type" "ishift")
11087    (set_attr "mode" "SI")])
11088
11089 (define_insn "*ashrsi3_cmp_zext"
11090   [(set (reg FLAGS_REG)
11091         (compare
11092           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11093                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11094           (const_int 0)))
11095    (set (match_operand:DI 0 "register_operand" "=r")
11096         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11097   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11098    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11099   "sar{l}\t{%2, %k0|%k0, %2}"
11100   [(set_attr "type" "ishift")
11101    (set_attr "mode" "SI")])
11102
11103 (define_expand "ashrhi3"
11104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11105         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11106                      (match_operand:QI 2 "nonmemory_operand" "")))
11107    (clobber (reg:CC FLAGS_REG))]
11108   "TARGET_HIMODE_MATH"
11109   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11110
11111 (define_insn "*ashrhi3_1_one_bit"
11112   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11113         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11114                      (match_operand:QI 2 "const1_operand" "")))
11115    (clobber (reg:CC FLAGS_REG))]
11116   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11117    && (TARGET_SHIFT1 || optimize_size)"
11118   "sar{w}\t%0"
11119   [(set_attr "type" "ishift")
11120    (set (attr "length") 
11121      (if_then_else (match_operand 0 "register_operand" "") 
11122         (const_string "2")
11123         (const_string "*")))])
11124
11125 (define_insn "*ashrhi3_1"
11126   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11127         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11128                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11131   "@
11132    sar{w}\t{%2, %0|%0, %2}
11133    sar{w}\t{%b2, %0|%0, %b2}"
11134   [(set_attr "type" "ishift")
11135    (set_attr "mode" "HI")])
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 "*ashrhi3_one_bit_cmp"
11141   [(set (reg FLAGS_REG)
11142         (compare
11143           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11144                        (match_operand:QI 2 "const1_operand" ""))
11145           (const_int 0)))
11146    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11147         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11148   "ix86_match_ccmode (insn, CCGOCmode)
11149    && (TARGET_SHIFT1 || optimize_size)
11150    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11151   "sar{w}\t%0"
11152   [(set_attr "type" "ishift")
11153    (set (attr "length") 
11154      (if_then_else (match_operand 0 "register_operand" "") 
11155         (const_string "2")
11156         (const_string "*")))])
11157
11158 ;; This pattern can't accept a variable shift count, since shifts by
11159 ;; zero don't affect the flags.  We assume that shifts by constant
11160 ;; zero are optimized away.
11161 (define_insn "*ashrhi3_cmp"
11162   [(set (reg FLAGS_REG)
11163         (compare
11164           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11165                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11166           (const_int 0)))
11167    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11168         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11169   "ix86_match_ccmode (insn, CCGOCmode)
11170    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11171   "sar{w}\t{%2, %0|%0, %2}"
11172   [(set_attr "type" "ishift")
11173    (set_attr "mode" "HI")])
11174
11175 (define_expand "ashrqi3"
11176   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11177         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11178                      (match_operand:QI 2 "nonmemory_operand" "")))
11179    (clobber (reg:CC FLAGS_REG))]
11180   "TARGET_QIMODE_MATH"
11181   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11182
11183 (define_insn "*ashrqi3_1_one_bit"
11184   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11185         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11186                      (match_operand:QI 2 "const1_operand" "")))
11187    (clobber (reg:CC FLAGS_REG))]
11188   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11189    && (TARGET_SHIFT1 || optimize_size)"
11190   "sar{b}\t%0"
11191   [(set_attr "type" "ishift")
11192    (set (attr "length") 
11193      (if_then_else (match_operand 0 "register_operand" "") 
11194         (const_string "2")
11195         (const_string "*")))])
11196
11197 (define_insn "*ashrqi3_1_one_bit_slp"
11198   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11199         (ashiftrt:QI (match_dup 0)
11200                      (match_operand:QI 1 "const1_operand" "")))
11201    (clobber (reg:CC FLAGS_REG))]
11202   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11203    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11204    && (TARGET_SHIFT1 || optimize_size)"
11205   "sar{b}\t%0"
11206   [(set_attr "type" "ishift1")
11207    (set (attr "length") 
11208      (if_then_else (match_operand 0 "register_operand" "") 
11209         (const_string "2")
11210         (const_string "*")))])
11211
11212 (define_insn "*ashrqi3_1"
11213   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11214         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11215                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11216    (clobber (reg:CC FLAGS_REG))]
11217   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11218   "@
11219    sar{b}\t{%2, %0|%0, %2}
11220    sar{b}\t{%b2, %0|%0, %b2}"
11221   [(set_attr "type" "ishift")
11222    (set_attr "mode" "QI")])
11223
11224 (define_insn "*ashrqi3_1_slp"
11225   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11226         (ashiftrt:QI (match_dup 0)
11227                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11228    (clobber (reg:CC FLAGS_REG))]
11229   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11230    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11231   "@
11232    sar{b}\t{%1, %0|%0, %1}
11233    sar{b}\t{%b1, %0|%0, %b1}"
11234   [(set_attr "type" "ishift1")
11235    (set_attr "mode" "QI")])
11236
11237 ;; This pattern can't accept a variable shift count, since shifts by
11238 ;; zero don't affect the flags.  We assume that shifts by constant
11239 ;; zero are optimized away.
11240 (define_insn "*ashrqi3_one_bit_cmp"
11241   [(set (reg FLAGS_REG)
11242         (compare
11243           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11244                        (match_operand:QI 2 "const1_operand" "I"))
11245           (const_int 0)))
11246    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11247         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11248   "ix86_match_ccmode (insn, CCGOCmode)
11249    && (TARGET_SHIFT1 || optimize_size)
11250    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11251   "sar{b}\t%0"
11252   [(set_attr "type" "ishift")
11253    (set (attr "length") 
11254      (if_then_else (match_operand 0 "register_operand" "") 
11255         (const_string "2")
11256         (const_string "*")))])
11257
11258 ;; This pattern can't accept a variable shift count, since shifts by
11259 ;; zero don't affect the flags.  We assume that shifts by constant
11260 ;; zero are optimized away.
11261 (define_insn "*ashrqi3_cmp"
11262   [(set (reg FLAGS_REG)
11263         (compare
11264           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11265                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11266           (const_int 0)))
11267    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11268         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11269   "ix86_match_ccmode (insn, CCGOCmode)
11270    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11271   "sar{b}\t{%2, %0|%0, %2}"
11272   [(set_attr "type" "ishift")
11273    (set_attr "mode" "QI")])
11274 \f
11275 ;; Logical shift instructions
11276
11277 ;; See comment above `ashldi3' about how this works.
11278
11279 (define_expand "lshrdi3"
11280   [(set (match_operand:DI 0 "shiftdi_operand" "")
11281         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11282                      (match_operand:QI 2 "nonmemory_operand" "")))]
11283   ""
11284   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11285
11286 (define_insn "*lshrdi3_1_one_bit_rex64"
11287   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11288         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11289                      (match_operand:QI 2 "const1_operand" "")))
11290    (clobber (reg:CC FLAGS_REG))]
11291   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11292    && (TARGET_SHIFT1 || optimize_size)"
11293   "shr{q}\t%0"
11294   [(set_attr "type" "ishift")
11295    (set (attr "length") 
11296      (if_then_else (match_operand:DI 0 "register_operand" "") 
11297         (const_string "2")
11298         (const_string "*")))])
11299
11300 (define_insn "*lshrdi3_1_rex64"
11301   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11302         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11303                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11306   "@
11307    shr{q}\t{%2, %0|%0, %2}
11308    shr{q}\t{%b2, %0|%0, %b2}"
11309   [(set_attr "type" "ishift")
11310    (set_attr "mode" "DI")])
11311
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags.  We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11316   [(set (reg FLAGS_REG)
11317         (compare
11318           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11319                        (match_operand:QI 2 "const1_operand" ""))
11320           (const_int 0)))
11321    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11322         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11323   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11324    && (TARGET_SHIFT1 || optimize_size)
11325    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11326   "shr{q}\t%0"
11327   [(set_attr "type" "ishift")
11328    (set (attr "length") 
11329      (if_then_else (match_operand:DI 0 "register_operand" "") 
11330         (const_string "2")
11331         (const_string "*")))])
11332
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags.  We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*lshrdi3_cmp_rex64"
11337   [(set (reg FLAGS_REG)
11338         (compare
11339           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340                        (match_operand:QI 2 "const_int_operand" "e"))
11341           (const_int 0)))
11342    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11344   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11346   "shr{q}\t{%2, %0|%0, %2}"
11347   [(set_attr "type" "ishift")
11348    (set_attr "mode" "DI")])
11349
11350 (define_insn "*lshrdi3_1"
11351   [(set (match_operand:DI 0 "register_operand" "=r")
11352         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11353                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11354    (clobber (reg:CC FLAGS_REG))]
11355   "!TARGET_64BIT"
11356   "#"
11357   [(set_attr "type" "multi")])
11358
11359 ;; By default we don't ask for a scratch register, because when DImode
11360 ;; values are manipulated, registers are already at a premium.  But if
11361 ;; we have one handy, we won't turn it away.
11362 (define_peephole2
11363   [(match_scratch:SI 3 "r")
11364    (parallel [(set (match_operand:DI 0 "register_operand" "")
11365                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11366                                 (match_operand:QI 2 "nonmemory_operand" "")))
11367               (clobber (reg:CC FLAGS_REG))])
11368    (match_dup 3)]
11369   "!TARGET_64BIT && TARGET_CMOVE"
11370   [(const_int 0)]
11371   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11372
11373 (define_split 
11374   [(set (match_operand:DI 0 "register_operand" "")
11375         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11376                      (match_operand:QI 2 "nonmemory_operand" "")))
11377    (clobber (reg:CC FLAGS_REG))]
11378   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11379   [(const_int 0)]
11380   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11381
11382 (define_expand "lshrsi3"
11383   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11384         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11385                      (match_operand:QI 2 "nonmemory_operand" "")))
11386    (clobber (reg:CC FLAGS_REG))]
11387   ""
11388   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11389
11390 (define_insn "*lshrsi3_1_one_bit"
11391   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11392         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11393                      (match_operand:QI 2 "const1_operand" "")))
11394    (clobber (reg:CC FLAGS_REG))]
11395   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11396    && (TARGET_SHIFT1 || optimize_size)"
11397   "shr{l}\t%0"
11398   [(set_attr "type" "ishift")
11399    (set (attr "length") 
11400      (if_then_else (match_operand:SI 0 "register_operand" "") 
11401         (const_string "2")
11402         (const_string "*")))])
11403
11404 (define_insn "*lshrsi3_1_one_bit_zext"
11405   [(set (match_operand:DI 0 "register_operand" "=r")
11406         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11407                      (match_operand:QI 2 "const1_operand" "")))
11408    (clobber (reg:CC FLAGS_REG))]
11409   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11410    && (TARGET_SHIFT1 || optimize_size)"
11411   "shr{l}\t%k0"
11412   [(set_attr "type" "ishift")
11413    (set_attr "length" "2")])
11414
11415 (define_insn "*lshrsi3_1"
11416   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11417         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11418                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421   "@
11422    shr{l}\t{%2, %0|%0, %2}
11423    shr{l}\t{%b2, %0|%0, %b2}"
11424   [(set_attr "type" "ishift")
11425    (set_attr "mode" "SI")])
11426
11427 (define_insn "*lshrsi3_1_zext"
11428   [(set (match_operand:DI 0 "register_operand" "=r,r")
11429         (zero_extend:DI
11430           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11431                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11432    (clobber (reg:CC FLAGS_REG))]
11433   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11434   "@
11435    shr{l}\t{%2, %k0|%k0, %2}
11436    shr{l}\t{%b2, %k0|%k0, %b2}"
11437   [(set_attr "type" "ishift")
11438    (set_attr "mode" "SI")])
11439
11440 ;; This pattern can't accept a variable shift count, since shifts by
11441 ;; zero don't affect the flags.  We assume that shifts by constant
11442 ;; zero are optimized away.
11443 (define_insn "*lshrsi3_one_bit_cmp"
11444   [(set (reg FLAGS_REG)
11445         (compare
11446           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11447                        (match_operand:QI 2 "const1_operand" ""))
11448           (const_int 0)))
11449    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11450         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11451   "ix86_match_ccmode (insn, CCGOCmode)
11452    && (TARGET_SHIFT1 || optimize_size)
11453    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11454   "shr{l}\t%0"
11455   [(set_attr "type" "ishift")
11456    (set (attr "length") 
11457      (if_then_else (match_operand:SI 0 "register_operand" "") 
11458         (const_string "2")
11459         (const_string "*")))])
11460
11461 (define_insn "*lshrsi3_cmp_one_bit_zext"
11462   [(set (reg FLAGS_REG)
11463         (compare
11464           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11465                        (match_operand:QI 2 "const1_operand" ""))
11466           (const_int 0)))
11467    (set (match_operand:DI 0 "register_operand" "=r")
11468         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11469   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11470    && (TARGET_SHIFT1 || optimize_size)
11471    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11472   "shr{l}\t%k0"
11473   [(set_attr "type" "ishift")
11474    (set_attr "length" "2")])
11475
11476 ;; This pattern can't accept a variable shift count, since shifts by
11477 ;; zero don't affect the flags.  We assume that shifts by constant
11478 ;; zero are optimized away.
11479 (define_insn "*lshrsi3_cmp"
11480   [(set (reg FLAGS_REG)
11481         (compare
11482           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11483                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11484           (const_int 0)))
11485    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11486         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11487   "ix86_match_ccmode (insn, CCGOCmode)
11488    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11489   "shr{l}\t{%2, %0|%0, %2}"
11490   [(set_attr "type" "ishift")
11491    (set_attr "mode" "SI")])
11492
11493 (define_insn "*lshrsi3_cmp_zext"
11494   [(set (reg FLAGS_REG)
11495         (compare
11496           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11497                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11498           (const_int 0)))
11499    (set (match_operand:DI 0 "register_operand" "=r")
11500         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11501   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11502    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11503   "shr{l}\t{%2, %k0|%k0, %2}"
11504   [(set_attr "type" "ishift")
11505    (set_attr "mode" "SI")])
11506
11507 (define_expand "lshrhi3"
11508   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11509         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11510                      (match_operand:QI 2 "nonmemory_operand" "")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "TARGET_HIMODE_MATH"
11513   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11514
11515 (define_insn "*lshrhi3_1_one_bit"
11516   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11517         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11518                      (match_operand:QI 2 "const1_operand" "")))
11519    (clobber (reg:CC FLAGS_REG))]
11520   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11521    && (TARGET_SHIFT1 || optimize_size)"
11522   "shr{w}\t%0"
11523   [(set_attr "type" "ishift")
11524    (set (attr "length") 
11525      (if_then_else (match_operand 0 "register_operand" "") 
11526         (const_string "2")
11527         (const_string "*")))])
11528
11529 (define_insn "*lshrhi3_1"
11530   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11531         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11532                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11535   "@
11536    shr{w}\t{%2, %0|%0, %2}
11537    shr{w}\t{%b2, %0|%0, %b2}"
11538   [(set_attr "type" "ishift")
11539    (set_attr "mode" "HI")])
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 "*lshrhi3_one_bit_cmp"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11548                        (match_operand:QI 2 "const1_operand" ""))
11549           (const_int 0)))
11550    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11551         (lshiftrt:HI (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{w}\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 ;; This pattern can't accept a variable shift count, since shifts by
11563 ;; zero don't affect the flags.  We assume that shifts by constant
11564 ;; zero are optimized away.
11565 (define_insn "*lshrhi3_cmp"
11566   [(set (reg FLAGS_REG)
11567         (compare
11568           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11569                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11570           (const_int 0)))
11571    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11572         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11573   "ix86_match_ccmode (insn, CCGOCmode)
11574    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11575   "shr{w}\t{%2, %0|%0, %2}"
11576   [(set_attr "type" "ishift")
11577    (set_attr "mode" "HI")])
11578
11579 (define_expand "lshrqi3"
11580   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11581         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11582                      (match_operand:QI 2 "nonmemory_operand" "")))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "TARGET_QIMODE_MATH"
11585   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11586
11587 (define_insn "*lshrqi3_1_one_bit"
11588   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11589         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11590                      (match_operand:QI 2 "const1_operand" "")))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11593    && (TARGET_SHIFT1 || optimize_size)"
11594   "shr{b}\t%0"
11595   [(set_attr "type" "ishift")
11596    (set (attr "length") 
11597      (if_then_else (match_operand 0 "register_operand" "") 
11598         (const_string "2")
11599         (const_string "*")))])
11600
11601 (define_insn "*lshrqi3_1_one_bit_slp"
11602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11603         (lshiftrt:QI (match_dup 0)
11604                      (match_operand:QI 1 "const1_operand" "")))
11605    (clobber (reg:CC FLAGS_REG))]
11606   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11607    && (TARGET_SHIFT1 || optimize_size)"
11608   "shr{b}\t%0"
11609   [(set_attr "type" "ishift1")
11610    (set (attr "length") 
11611      (if_then_else (match_operand 0 "register_operand" "") 
11612         (const_string "2")
11613         (const_string "*")))])
11614
11615 (define_insn "*lshrqi3_1"
11616   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11617         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11618                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11619    (clobber (reg:CC FLAGS_REG))]
11620   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11621   "@
11622    shr{b}\t{%2, %0|%0, %2}
11623    shr{b}\t{%b2, %0|%0, %b2}"
11624   [(set_attr "type" "ishift")
11625    (set_attr "mode" "QI")])
11626
11627 (define_insn "*lshrqi3_1_slp"
11628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11629         (lshiftrt:QI (match_dup 0)
11630                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11631    (clobber (reg:CC FLAGS_REG))]
11632   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11633    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11634   "@
11635    shr{b}\t{%1, %0|%0, %1}
11636    shr{b}\t{%b1, %0|%0, %b1}"
11637   [(set_attr "type" "ishift1")
11638    (set_attr "mode" "QI")])
11639
11640 ;; This pattern can't accept a variable shift count, since shifts by
11641 ;; zero don't affect the flags.  We assume that shifts by constant
11642 ;; zero are optimized away.
11643 (define_insn "*lshrqi2_one_bit_cmp"
11644   [(set (reg FLAGS_REG)
11645         (compare
11646           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11647                        (match_operand:QI 2 "const1_operand" ""))
11648           (const_int 0)))
11649    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11650         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11651   "ix86_match_ccmode (insn, CCGOCmode)
11652    && (TARGET_SHIFT1 || optimize_size)
11653    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11654   "shr{b}\t%0"
11655   [(set_attr "type" "ishift")
11656    (set (attr "length") 
11657      (if_then_else (match_operand:SI 0 "register_operand" "") 
11658         (const_string "2")
11659         (const_string "*")))])
11660
11661 ;; This pattern can't accept a variable shift count, since shifts by
11662 ;; zero don't affect the flags.  We assume that shifts by constant
11663 ;; zero are optimized away.
11664 (define_insn "*lshrqi2_cmp"
11665   [(set (reg FLAGS_REG)
11666         (compare
11667           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11668                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11669           (const_int 0)))
11670    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11671         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11672   "ix86_match_ccmode (insn, CCGOCmode)
11673    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11674   "shr{b}\t{%2, %0|%0, %2}"
11675   [(set_attr "type" "ishift")
11676    (set_attr "mode" "QI")])
11677 \f
11678 ;; Rotate instructions
11679
11680 (define_expand "rotldi3"
11681   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11682         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11683                    (match_operand:QI 2 "nonmemory_operand" "")))
11684    (clobber (reg:CC FLAGS_REG))]
11685   "TARGET_64BIT"
11686   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11687
11688 (define_insn "*rotlsi3_1_one_bit_rex64"
11689   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11690         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11691                    (match_operand:QI 2 "const1_operand" "")))
11692    (clobber (reg:CC FLAGS_REG))]
11693   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11694    && (TARGET_SHIFT1 || optimize_size)"
11695   "rol{q}\t%0"
11696   [(set_attr "type" "rotate")
11697    (set (attr "length") 
11698      (if_then_else (match_operand:DI 0 "register_operand" "") 
11699         (const_string "2")
11700         (const_string "*")))])
11701
11702 (define_insn "*rotldi3_1_rex64"
11703   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11704         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11705                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11708   "@
11709    rol{q}\t{%2, %0|%0, %2}
11710    rol{q}\t{%b2, %0|%0, %b2}"
11711   [(set_attr "type" "rotate")
11712    (set_attr "mode" "DI")])
11713
11714 (define_expand "rotlsi3"
11715   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11716         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11717                    (match_operand:QI 2 "nonmemory_operand" "")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   ""
11720   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11721
11722 (define_insn "*rotlsi3_1_one_bit"
11723   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11724         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11725                    (match_operand:QI 2 "const1_operand" "")))
11726    (clobber (reg:CC FLAGS_REG))]
11727   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11728    && (TARGET_SHIFT1 || optimize_size)"
11729   "rol{l}\t%0"
11730   [(set_attr "type" "rotate")
11731    (set (attr "length") 
11732      (if_then_else (match_operand:SI 0 "register_operand" "") 
11733         (const_string "2")
11734         (const_string "*")))])
11735
11736 (define_insn "*rotlsi3_1_one_bit_zext"
11737   [(set (match_operand:DI 0 "register_operand" "=r")
11738         (zero_extend:DI
11739           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11740                      (match_operand:QI 2 "const1_operand" ""))))
11741    (clobber (reg:CC FLAGS_REG))]
11742   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11743    && (TARGET_SHIFT1 || optimize_size)"
11744   "rol{l}\t%k0"
11745   [(set_attr "type" "rotate")
11746    (set_attr "length" "2")])
11747
11748 (define_insn "*rotlsi3_1"
11749   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752    (clobber (reg:CC FLAGS_REG))]
11753   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11754   "@
11755    rol{l}\t{%2, %0|%0, %2}
11756    rol{l}\t{%b2, %0|%0, %b2}"
11757   [(set_attr "type" "rotate")
11758    (set_attr "mode" "SI")])
11759
11760 (define_insn "*rotlsi3_1_zext"
11761   [(set (match_operand:DI 0 "register_operand" "=r,r")
11762         (zero_extend:DI
11763           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11764                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765    (clobber (reg:CC FLAGS_REG))]
11766   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11767   "@
11768    rol{l}\t{%2, %k0|%k0, %2}
11769    rol{l}\t{%b2, %k0|%k0, %b2}"
11770   [(set_attr "type" "rotate")
11771    (set_attr "mode" "SI")])
11772
11773 (define_expand "rotlhi3"
11774   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11775         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11776                    (match_operand:QI 2 "nonmemory_operand" "")))
11777    (clobber (reg:CC FLAGS_REG))]
11778   "TARGET_HIMODE_MATH"
11779   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11780
11781 (define_insn "*rotlhi3_1_one_bit"
11782   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11783         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11784                    (match_operand:QI 2 "const1_operand" "")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11787    && (TARGET_SHIFT1 || optimize_size)"
11788   "rol{w}\t%0"
11789   [(set_attr "type" "rotate")
11790    (set (attr "length") 
11791      (if_then_else (match_operand 0 "register_operand" "") 
11792         (const_string "2")
11793         (const_string "*")))])
11794
11795 (define_insn "*rotlhi3_1"
11796   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11797         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11798                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11801   "@
11802    rol{w}\t{%2, %0|%0, %2}
11803    rol{w}\t{%b2, %0|%0, %b2}"
11804   [(set_attr "type" "rotate")
11805    (set_attr "mode" "HI")])
11806
11807 (define_expand "rotlqi3"
11808   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11809         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11810                    (match_operand:QI 2 "nonmemory_operand" "")))
11811    (clobber (reg:CC FLAGS_REG))]
11812   "TARGET_QIMODE_MATH"
11813   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11814
11815 (define_insn "*rotlqi3_1_one_bit_slp"
11816   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11817         (rotate:QI (match_dup 0)
11818                    (match_operand:QI 1 "const1_operand" "")))
11819    (clobber (reg:CC FLAGS_REG))]
11820   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11821    && (TARGET_SHIFT1 || optimize_size)"
11822   "rol{b}\t%0"
11823   [(set_attr "type" "rotate1")
11824    (set (attr "length") 
11825      (if_then_else (match_operand 0 "register_operand" "") 
11826         (const_string "2")
11827         (const_string "*")))])
11828
11829 (define_insn "*rotlqi3_1_one_bit"
11830   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11831         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11832                    (match_operand:QI 2 "const1_operand" "")))
11833    (clobber (reg:CC FLAGS_REG))]
11834   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11835    && (TARGET_SHIFT1 || optimize_size)"
11836   "rol{b}\t%0"
11837   [(set_attr "type" "rotate")
11838    (set (attr "length") 
11839      (if_then_else (match_operand 0 "register_operand" "") 
11840         (const_string "2")
11841         (const_string "*")))])
11842
11843 (define_insn "*rotlqi3_1_slp"
11844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11845         (rotate:QI (match_dup 0)
11846                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11850   "@
11851    rol{b}\t{%1, %0|%0, %1}
11852    rol{b}\t{%b1, %0|%0, %b1}"
11853   [(set_attr "type" "rotate1")
11854    (set_attr "mode" "QI")])
11855
11856 (define_insn "*rotlqi3_1"
11857   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11858         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11859                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11860    (clobber (reg:CC FLAGS_REG))]
11861   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11862   "@
11863    rol{b}\t{%2, %0|%0, %2}
11864    rol{b}\t{%b2, %0|%0, %b2}"
11865   [(set_attr "type" "rotate")
11866    (set_attr "mode" "QI")])
11867
11868 (define_expand "rotrdi3"
11869   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11870         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11871                      (match_operand:QI 2 "nonmemory_operand" "")))
11872    (clobber (reg:CC FLAGS_REG))]
11873   "TARGET_64BIT"
11874   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11875
11876 (define_insn "*rotrdi3_1_one_bit_rex64"
11877   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11878         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11879                      (match_operand:QI 2 "const1_operand" "")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11882    && (TARGET_SHIFT1 || optimize_size)"
11883   "ror{q}\t%0"
11884   [(set_attr "type" "rotate")
11885    (set (attr "length") 
11886      (if_then_else (match_operand:DI 0 "register_operand" "") 
11887         (const_string "2")
11888         (const_string "*")))])
11889
11890 (define_insn "*rotrdi3_1_rex64"
11891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11892         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11893                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11896   "@
11897    ror{q}\t{%2, %0|%0, %2}
11898    ror{q}\t{%b2, %0|%0, %b2}"
11899   [(set_attr "type" "rotate")
11900    (set_attr "mode" "DI")])
11901
11902 (define_expand "rotrsi3"
11903   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11904         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11905                      (match_operand:QI 2 "nonmemory_operand" "")))
11906    (clobber (reg:CC FLAGS_REG))]
11907   ""
11908   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11909
11910 (define_insn "*rotrsi3_1_one_bit"
11911   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11912         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11913                      (match_operand:QI 2 "const1_operand" "")))
11914    (clobber (reg:CC FLAGS_REG))]
11915   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11916    && (TARGET_SHIFT1 || optimize_size)"
11917   "ror{l}\t%0"
11918   [(set_attr "type" "rotate")
11919    (set (attr "length") 
11920      (if_then_else (match_operand:SI 0 "register_operand" "") 
11921         (const_string "2")
11922         (const_string "*")))])
11923
11924 (define_insn "*rotrsi3_1_one_bit_zext"
11925   [(set (match_operand:DI 0 "register_operand" "=r")
11926         (zero_extend:DI
11927           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11928                        (match_operand:QI 2 "const1_operand" ""))))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11931    && (TARGET_SHIFT1 || optimize_size)"
11932   "ror{l}\t%k0"
11933   [(set_attr "type" "rotate")
11934    (set (attr "length") 
11935      (if_then_else (match_operand:SI 0 "register_operand" "") 
11936         (const_string "2")
11937         (const_string "*")))])
11938
11939 (define_insn "*rotrsi3_1"
11940   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11941         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11942                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11945   "@
11946    ror{l}\t{%2, %0|%0, %2}
11947    ror{l}\t{%b2, %0|%0, %b2}"
11948   [(set_attr "type" "rotate")
11949    (set_attr "mode" "SI")])
11950
11951 (define_insn "*rotrsi3_1_zext"
11952   [(set (match_operand:DI 0 "register_operand" "=r,r")
11953         (zero_extend:DI
11954           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11955                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11956    (clobber (reg:CC FLAGS_REG))]
11957   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11958   "@
11959    ror{l}\t{%2, %k0|%k0, %2}
11960    ror{l}\t{%b2, %k0|%k0, %b2}"
11961   [(set_attr "type" "rotate")
11962    (set_attr "mode" "SI")])
11963
11964 (define_expand "rotrhi3"
11965   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11966         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11967                      (match_operand:QI 2 "nonmemory_operand" "")))
11968    (clobber (reg:CC FLAGS_REG))]
11969   "TARGET_HIMODE_MATH"
11970   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11971
11972 (define_insn "*rotrhi3_one_bit"
11973   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11974         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11975                      (match_operand:QI 2 "const1_operand" "")))
11976    (clobber (reg:CC FLAGS_REG))]
11977   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11978    && (TARGET_SHIFT1 || optimize_size)"
11979   "ror{w}\t%0"
11980   [(set_attr "type" "rotate")
11981    (set (attr "length") 
11982      (if_then_else (match_operand 0 "register_operand" "") 
11983         (const_string "2")
11984         (const_string "*")))])
11985
11986 (define_insn "*rotrhi3"
11987   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11988         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11989                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11992   "@
11993    ror{w}\t{%2, %0|%0, %2}
11994    ror{w}\t{%b2, %0|%0, %b2}"
11995   [(set_attr "type" "rotate")
11996    (set_attr "mode" "HI")])
11997
11998 (define_expand "rotrqi3"
11999   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12000         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12001                      (match_operand:QI 2 "nonmemory_operand" "")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "TARGET_QIMODE_MATH"
12004   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12005
12006 (define_insn "*rotrqi3_1_one_bit"
12007   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12008         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12009                      (match_operand:QI 2 "const1_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12012    && (TARGET_SHIFT1 || optimize_size)"
12013   "ror{b}\t%0"
12014   [(set_attr "type" "rotate")
12015    (set (attr "length") 
12016      (if_then_else (match_operand 0 "register_operand" "") 
12017         (const_string "2")
12018         (const_string "*")))])
12019
12020 (define_insn "*rotrqi3_1_one_bit_slp"
12021   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12022         (rotatert:QI (match_dup 0)
12023                      (match_operand:QI 1 "const1_operand" "")))
12024    (clobber (reg:CC FLAGS_REG))]
12025   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12026    && (TARGET_SHIFT1 || optimize_size)"
12027   "ror{b}\t%0"
12028   [(set_attr "type" "rotate1")
12029    (set (attr "length") 
12030      (if_then_else (match_operand 0 "register_operand" "") 
12031         (const_string "2")
12032         (const_string "*")))])
12033
12034 (define_insn "*rotrqi3_1"
12035   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12036         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12037                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12038    (clobber (reg:CC FLAGS_REG))]
12039   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12040   "@
12041    ror{b}\t{%2, %0|%0, %2}
12042    ror{b}\t{%b2, %0|%0, %b2}"
12043   [(set_attr "type" "rotate")
12044    (set_attr "mode" "QI")])
12045
12046 (define_insn "*rotrqi3_1_slp"
12047   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12048         (rotatert:QI (match_dup 0)
12049                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12050    (clobber (reg:CC FLAGS_REG))]
12051   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12052    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12053   "@
12054    ror{b}\t{%1, %0|%0, %1}
12055    ror{b}\t{%b1, %0|%0, %b1}"
12056   [(set_attr "type" "rotate1")
12057    (set_attr "mode" "QI")])
12058 \f
12059 ;; Bit set / bit test instructions
12060
12061 (define_expand "extv"
12062   [(set (match_operand:SI 0 "register_operand" "")
12063         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12064                          (match_operand:SI 2 "immediate_operand" "")
12065                          (match_operand:SI 3 "immediate_operand" "")))]
12066   ""
12067 {
12068   /* Handle extractions from %ah et al.  */
12069   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12070     FAIL;
12071
12072   /* From mips.md: extract_bit_field doesn't verify that our source
12073      matches the predicate, so check it again here.  */
12074   if (! ext_register_operand (operands[1], VOIDmode))
12075     FAIL;
12076 })
12077
12078 (define_expand "extzv"
12079   [(set (match_operand:SI 0 "register_operand" "")
12080         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12081                          (match_operand:SI 2 "immediate_operand" "")
12082                          (match_operand:SI 3 "immediate_operand" "")))]
12083   ""
12084 {
12085   /* Handle extractions from %ah et al.  */
12086   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12087     FAIL;
12088
12089   /* From mips.md: extract_bit_field doesn't verify that our source
12090      matches the predicate, so check it again here.  */
12091   if (! ext_register_operand (operands[1], VOIDmode))
12092     FAIL;
12093 })
12094
12095 (define_expand "insv"
12096   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12097                       (match_operand 1 "immediate_operand" "")
12098                       (match_operand 2 "immediate_operand" ""))
12099         (match_operand 3 "register_operand" ""))]
12100   ""
12101 {
12102   /* Handle extractions from %ah et al.  */
12103   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12104     FAIL;
12105
12106   /* From mips.md: insert_bit_field doesn't verify that our source
12107      matches the predicate, so check it again here.  */
12108   if (! ext_register_operand (operands[0], VOIDmode))
12109     FAIL;
12110
12111   if (TARGET_64BIT)
12112     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12113   else
12114     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12115
12116   DONE;
12117 })
12118
12119 ;; %%% bts, btr, btc, bt.
12120 ;; In general these instructions are *slow* when applied to memory,
12121 ;; since they enforce atomic operation.  When applied to registers,
12122 ;; it depends on the cpu implementation.  They're never faster than
12123 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12124 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12125 ;; within the instruction itself, so operating on bits in the high
12126 ;; 32-bits of a register becomes easier.
12127 ;;
12128 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12129 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12130 ;; negdf respectively, so they can never be disabled entirely.
12131
12132 (define_insn "*btsq"
12133   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12134                          (const_int 1)
12135                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12136         (const_int 1))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12139   "bts{q} %1,%0"
12140   [(set_attr "type" "alu1")])
12141
12142 (define_insn "*btrq"
12143   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12144                          (const_int 1)
12145                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12146         (const_int 0))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12149   "btr{q} %1,%0"
12150   [(set_attr "type" "alu1")])
12151
12152 (define_insn "*btcq"
12153   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12154                          (const_int 1)
12155                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12156         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12159   "btc{q} %1,%0"
12160   [(set_attr "type" "alu1")])
12161
12162 ;; Allow Nocona to avoid these instructions if a register is available.
12163
12164 (define_peephole2
12165   [(match_scratch:DI 2 "r")
12166    (parallel [(set (zero_extract:DI
12167                      (match_operand:DI 0 "register_operand" "")
12168                      (const_int 1)
12169                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12170                    (const_int 1))
12171               (clobber (reg:CC FLAGS_REG))])]
12172   "TARGET_64BIT && !TARGET_USE_BT"
12173   [(const_int 0)]
12174 {
12175   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12176   rtx op1;
12177
12178   if (HOST_BITS_PER_WIDE_INT >= 64)
12179     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12180   else if (i < HOST_BITS_PER_WIDE_INT)
12181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12182   else
12183     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12184
12185   op1 = immed_double_const (lo, hi, DImode);
12186   if (i >= 31)
12187     {
12188       emit_move_insn (operands[2], op1);
12189       op1 = operands[2];
12190     }
12191
12192   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12193   DONE;
12194 })
12195
12196 (define_peephole2
12197   [(match_scratch:DI 2 "r")
12198    (parallel [(set (zero_extract:DI
12199                      (match_operand:DI 0 "register_operand" "")
12200                      (const_int 1)
12201                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12202                    (const_int 0))
12203               (clobber (reg:CC FLAGS_REG))])]
12204   "TARGET_64BIT && !TARGET_USE_BT"
12205   [(const_int 0)]
12206 {
12207   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12208   rtx op1;
12209
12210   if (HOST_BITS_PER_WIDE_INT >= 64)
12211     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12212   else if (i < HOST_BITS_PER_WIDE_INT)
12213     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12214   else
12215     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12216
12217   op1 = immed_double_const (~lo, ~hi, DImode);
12218   if (i >= 32)
12219     {
12220       emit_move_insn (operands[2], op1);
12221       op1 = operands[2];
12222     }
12223
12224   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12225   DONE;
12226 })
12227
12228 (define_peephole2
12229   [(match_scratch:DI 2 "r")
12230    (parallel [(set (zero_extract:DI
12231                      (match_operand:DI 0 "register_operand" "")
12232                      (const_int 1)
12233                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12234               (not:DI (zero_extract:DI
12235                         (match_dup 0) (const_int 1) (match_dup 1))))
12236               (clobber (reg:CC FLAGS_REG))])]
12237   "TARGET_64BIT && !TARGET_USE_BT"
12238   [(const_int 0)]
12239 {
12240   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12241   rtx op1;
12242
12243   if (HOST_BITS_PER_WIDE_INT >= 64)
12244     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12245   else if (i < HOST_BITS_PER_WIDE_INT)
12246     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12247   else
12248     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12249
12250   op1 = immed_double_const (lo, hi, DImode);
12251   if (i >= 31)
12252     {
12253       emit_move_insn (operands[2], op1);
12254       op1 = operands[2];
12255     }
12256
12257   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12258   DONE;
12259 })
12260 \f
12261 ;; Store-flag instructions.
12262
12263 ;; For all sCOND expanders, also expand the compare or test insn that
12264 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12265
12266 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12267 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12268 ;; way, which can later delete the movzx if only QImode is needed.
12269
12270 (define_expand "seq"
12271   [(set (match_operand:QI 0 "register_operand" "")
12272         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12273   ""
12274   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12275
12276 (define_expand "sne"
12277   [(set (match_operand:QI 0 "register_operand" "")
12278         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12279   ""
12280   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12281
12282 (define_expand "sgt"
12283   [(set (match_operand:QI 0 "register_operand" "")
12284         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12285   ""
12286   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12287
12288 (define_expand "sgtu"
12289   [(set (match_operand:QI 0 "register_operand" "")
12290         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12291   ""
12292   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12293
12294 (define_expand "slt"
12295   [(set (match_operand:QI 0 "register_operand" "")
12296         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12297   ""
12298   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12299
12300 (define_expand "sltu"
12301   [(set (match_operand:QI 0 "register_operand" "")
12302         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12303   ""
12304   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12305
12306 (define_expand "sge"
12307   [(set (match_operand:QI 0 "register_operand" "")
12308         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12309   ""
12310   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12311
12312 (define_expand "sgeu"
12313   [(set (match_operand:QI 0 "register_operand" "")
12314         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12315   ""
12316   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12317
12318 (define_expand "sle"
12319   [(set (match_operand:QI 0 "register_operand" "")
12320         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12321   ""
12322   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12323
12324 (define_expand "sleu"
12325   [(set (match_operand:QI 0 "register_operand" "")
12326         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12327   ""
12328   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12329
12330 (define_expand "sunordered"
12331   [(set (match_operand:QI 0 "register_operand" "")
12332         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12333   "TARGET_80387 || TARGET_SSE"
12334   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12335
12336 (define_expand "sordered"
12337   [(set (match_operand:QI 0 "register_operand" "")
12338         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12339   "TARGET_80387"
12340   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12341
12342 (define_expand "suneq"
12343   [(set (match_operand:QI 0 "register_operand" "")
12344         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12345   "TARGET_80387 || TARGET_SSE"
12346   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12347
12348 (define_expand "sunge"
12349   [(set (match_operand:QI 0 "register_operand" "")
12350         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12351   "TARGET_80387 || TARGET_SSE"
12352   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12353
12354 (define_expand "sungt"
12355   [(set (match_operand:QI 0 "register_operand" "")
12356         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12357   "TARGET_80387 || TARGET_SSE"
12358   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12359
12360 (define_expand "sunle"
12361   [(set (match_operand:QI 0 "register_operand" "")
12362         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12363   "TARGET_80387 || TARGET_SSE"
12364   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12365
12366 (define_expand "sunlt"
12367   [(set (match_operand:QI 0 "register_operand" "")
12368         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12369   "TARGET_80387 || TARGET_SSE"
12370   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12371
12372 (define_expand "sltgt"
12373   [(set (match_operand:QI 0 "register_operand" "")
12374         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12375   "TARGET_80387 || TARGET_SSE"
12376   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12377
12378 (define_insn "*setcc_1"
12379   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12380         (match_operator:QI 1 "ix86_comparison_operator"
12381           [(reg FLAGS_REG) (const_int 0)]))]
12382   ""
12383   "set%C1\t%0"
12384   [(set_attr "type" "setcc")
12385    (set_attr "mode" "QI")])
12386
12387 (define_insn "*setcc_2"
12388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12389         (match_operator:QI 1 "ix86_comparison_operator"
12390           [(reg FLAGS_REG) (const_int 0)]))]
12391   ""
12392   "set%C1\t%0"
12393   [(set_attr "type" "setcc")
12394    (set_attr "mode" "QI")])
12395
12396 ;; In general it is not safe to assume too much about CCmode registers,
12397 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12398 ;; conditions this is safe on x86, so help combine not create
12399 ;;
12400 ;;      seta    %al
12401 ;;      testb   %al, %al
12402 ;;      sete    %al
12403
12404 (define_split 
12405   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12406         (ne:QI (match_operator 1 "ix86_comparison_operator"
12407                  [(reg FLAGS_REG) (const_int 0)])
12408             (const_int 0)))]
12409   ""
12410   [(set (match_dup 0) (match_dup 1))]
12411 {
12412   PUT_MODE (operands[1], QImode);
12413 })
12414
12415 (define_split 
12416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12417         (ne:QI (match_operator 1 "ix86_comparison_operator"
12418                  [(reg FLAGS_REG) (const_int 0)])
12419             (const_int 0)))]
12420   ""
12421   [(set (match_dup 0) (match_dup 1))]
12422 {
12423   PUT_MODE (operands[1], QImode);
12424 })
12425
12426 (define_split 
12427   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12428         (eq:QI (match_operator 1 "ix86_comparison_operator"
12429                  [(reg FLAGS_REG) (const_int 0)])
12430             (const_int 0)))]
12431   ""
12432   [(set (match_dup 0) (match_dup 1))]
12433 {
12434   rtx new_op1 = copy_rtx (operands[1]);
12435   operands[1] = new_op1;
12436   PUT_MODE (new_op1, QImode);
12437   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12438                                              GET_MODE (XEXP (new_op1, 0))));
12439
12440   /* Make sure that (a) the CCmode we have for the flags is strong
12441      enough for the reversed compare or (b) we have a valid FP compare.  */
12442   if (! ix86_comparison_operator (new_op1, VOIDmode))
12443     FAIL;
12444 })
12445
12446 (define_split 
12447   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12448         (eq:QI (match_operator 1 "ix86_comparison_operator"
12449                  [(reg FLAGS_REG) (const_int 0)])
12450             (const_int 0)))]
12451   ""
12452   [(set (match_dup 0) (match_dup 1))]
12453 {
12454   rtx new_op1 = copy_rtx (operands[1]);
12455   operands[1] = new_op1;
12456   PUT_MODE (new_op1, QImode);
12457   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12458                                              GET_MODE (XEXP (new_op1, 0))));
12459
12460   /* Make sure that (a) the CCmode we have for the flags is strong
12461      enough for the reversed compare or (b) we have a valid FP compare.  */
12462   if (! ix86_comparison_operator (new_op1, VOIDmode))
12463     FAIL;
12464 })
12465
12466 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12467 ;; subsequent logical operations are used to imitate conditional moves.
12468 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12469 ;; it directly.
12470
12471 (define_insn "*sse_setccsf"
12472   [(set (match_operand:SF 0 "register_operand" "=x")
12473         (match_operator:SF 1 "sse_comparison_operator"
12474           [(match_operand:SF 2 "register_operand" "0")
12475            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12476   "TARGET_SSE"
12477   "cmp%D1ss\t{%3, %0|%0, %3}"
12478   [(set_attr "type" "ssecmp")
12479    (set_attr "mode" "SF")])
12480
12481 (define_insn "*sse_setccdf"
12482   [(set (match_operand:DF 0 "register_operand" "=Y")
12483         (match_operator:DF 1 "sse_comparison_operator"
12484           [(match_operand:DF 2 "register_operand" "0")
12485            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12486   "TARGET_SSE2"
12487   "cmp%D1sd\t{%3, %0|%0, %3}"
12488   [(set_attr "type" "ssecmp")
12489    (set_attr "mode" "DF")])
12490 \f
12491 ;; Basic conditional jump instructions.
12492 ;; We ignore the overflow flag for signed branch instructions.
12493
12494 ;; For all bCOND expanders, also expand the compare or test insn that
12495 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12496
12497 (define_expand "beq"
12498   [(set (pc)
12499         (if_then_else (match_dup 1)
12500                       (label_ref (match_operand 0 "" ""))
12501                       (pc)))]
12502   ""
12503   "ix86_expand_branch (EQ, operands[0]); DONE;")
12504
12505 (define_expand "bne"
12506   [(set (pc)
12507         (if_then_else (match_dup 1)
12508                       (label_ref (match_operand 0 "" ""))
12509                       (pc)))]
12510   ""
12511   "ix86_expand_branch (NE, operands[0]); DONE;")
12512
12513 (define_expand "bgt"
12514   [(set (pc)
12515         (if_then_else (match_dup 1)
12516                       (label_ref (match_operand 0 "" ""))
12517                       (pc)))]
12518   ""
12519   "ix86_expand_branch (GT, operands[0]); DONE;")
12520
12521 (define_expand "bgtu"
12522   [(set (pc)
12523         (if_then_else (match_dup 1)
12524                       (label_ref (match_operand 0 "" ""))
12525                       (pc)))]
12526   ""
12527   "ix86_expand_branch (GTU, operands[0]); DONE;")
12528
12529 (define_expand "blt"
12530   [(set (pc)
12531         (if_then_else (match_dup 1)
12532                       (label_ref (match_operand 0 "" ""))
12533                       (pc)))]
12534   ""
12535   "ix86_expand_branch (LT, operands[0]); DONE;")
12536
12537 (define_expand "bltu"
12538   [(set (pc)
12539         (if_then_else (match_dup 1)
12540                       (label_ref (match_operand 0 "" ""))
12541                       (pc)))]
12542   ""
12543   "ix86_expand_branch (LTU, operands[0]); DONE;")
12544
12545 (define_expand "bge"
12546   [(set (pc)
12547         (if_then_else (match_dup 1)
12548                       (label_ref (match_operand 0 "" ""))
12549                       (pc)))]
12550   ""
12551   "ix86_expand_branch (GE, operands[0]); DONE;")
12552
12553 (define_expand "bgeu"
12554   [(set (pc)
12555         (if_then_else (match_dup 1)
12556                       (label_ref (match_operand 0 "" ""))
12557                       (pc)))]
12558   ""
12559   "ix86_expand_branch (GEU, operands[0]); DONE;")
12560
12561 (define_expand "ble"
12562   [(set (pc)
12563         (if_then_else (match_dup 1)
12564                       (label_ref (match_operand 0 "" ""))
12565                       (pc)))]
12566   ""
12567   "ix86_expand_branch (LE, operands[0]); DONE;")
12568
12569 (define_expand "bleu"
12570   [(set (pc)
12571         (if_then_else (match_dup 1)
12572                       (label_ref (match_operand 0 "" ""))
12573                       (pc)))]
12574   ""
12575   "ix86_expand_branch (LEU, operands[0]); DONE;")
12576
12577 (define_expand "bunordered"
12578   [(set (pc)
12579         (if_then_else (match_dup 1)
12580                       (label_ref (match_operand 0 "" ""))
12581                       (pc)))]
12582   "TARGET_80387 || TARGET_SSE_MATH"
12583   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12584
12585 (define_expand "bordered"
12586   [(set (pc)
12587         (if_then_else (match_dup 1)
12588                       (label_ref (match_operand 0 "" ""))
12589                       (pc)))]
12590   "TARGET_80387 || TARGET_SSE_MATH"
12591   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12592
12593 (define_expand "buneq"
12594   [(set (pc)
12595         (if_then_else (match_dup 1)
12596                       (label_ref (match_operand 0 "" ""))
12597                       (pc)))]
12598   "TARGET_80387 || TARGET_SSE_MATH"
12599   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12600
12601 (define_expand "bunge"
12602   [(set (pc)
12603         (if_then_else (match_dup 1)
12604                       (label_ref (match_operand 0 "" ""))
12605                       (pc)))]
12606   "TARGET_80387 || TARGET_SSE_MATH"
12607   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12608
12609 (define_expand "bungt"
12610   [(set (pc)
12611         (if_then_else (match_dup 1)
12612                       (label_ref (match_operand 0 "" ""))
12613                       (pc)))]
12614   "TARGET_80387 || TARGET_SSE_MATH"
12615   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12616
12617 (define_expand "bunle"
12618   [(set (pc)
12619         (if_then_else (match_dup 1)
12620                       (label_ref (match_operand 0 "" ""))
12621                       (pc)))]
12622   "TARGET_80387 || TARGET_SSE_MATH"
12623   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12624
12625 (define_expand "bunlt"
12626   [(set (pc)
12627         (if_then_else (match_dup 1)
12628                       (label_ref (match_operand 0 "" ""))
12629                       (pc)))]
12630   "TARGET_80387 || TARGET_SSE_MATH"
12631   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12632
12633 (define_expand "bltgt"
12634   [(set (pc)
12635         (if_then_else (match_dup 1)
12636                       (label_ref (match_operand 0 "" ""))
12637                       (pc)))]
12638   "TARGET_80387 || TARGET_SSE_MATH"
12639   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12640
12641 (define_insn "*jcc_1"
12642   [(set (pc)
12643         (if_then_else (match_operator 1 "ix86_comparison_operator"
12644                                       [(reg FLAGS_REG) (const_int 0)])
12645                       (label_ref (match_operand 0 "" ""))
12646                       (pc)))]
12647   ""
12648   "%+j%C1\t%l0"
12649   [(set_attr "type" "ibr")
12650    (set_attr "modrm" "0")
12651    (set (attr "length")
12652            (if_then_else (and (ge (minus (match_dup 0) (pc))
12653                                   (const_int -126))
12654                               (lt (minus (match_dup 0) (pc))
12655                                   (const_int 128)))
12656              (const_int 2)
12657              (const_int 6)))])
12658
12659 (define_insn "*jcc_2"
12660   [(set (pc)
12661         (if_then_else (match_operator 1 "ix86_comparison_operator"
12662                                       [(reg FLAGS_REG) (const_int 0)])
12663                       (pc)
12664                       (label_ref (match_operand 0 "" ""))))]
12665   ""
12666   "%+j%c1\t%l0"
12667   [(set_attr "type" "ibr")
12668    (set_attr "modrm" "0")
12669    (set (attr "length")
12670            (if_then_else (and (ge (minus (match_dup 0) (pc))
12671                                   (const_int -126))
12672                               (lt (minus (match_dup 0) (pc))
12673                                   (const_int 128)))
12674              (const_int 2)
12675              (const_int 6)))])
12676
12677 ;; In general it is not safe to assume too much about CCmode registers,
12678 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12679 ;; conditions this is safe on x86, so help combine not create
12680 ;;
12681 ;;      seta    %al
12682 ;;      testb   %al, %al
12683 ;;      je      Lfoo
12684
12685 (define_split 
12686   [(set (pc)
12687         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12688                                       [(reg FLAGS_REG) (const_int 0)])
12689                           (const_int 0))
12690                       (label_ref (match_operand 1 "" ""))
12691                       (pc)))]
12692   ""
12693   [(set (pc)
12694         (if_then_else (match_dup 0)
12695                       (label_ref (match_dup 1))
12696                       (pc)))]
12697 {
12698   PUT_MODE (operands[0], VOIDmode);
12699 })
12700   
12701 (define_split 
12702   [(set (pc)
12703         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12704                                       [(reg FLAGS_REG) (const_int 0)])
12705                           (const_int 0))
12706                       (label_ref (match_operand 1 "" ""))
12707                       (pc)))]
12708   ""
12709   [(set (pc)
12710         (if_then_else (match_dup 0)
12711                       (label_ref (match_dup 1))
12712                       (pc)))]
12713 {
12714   rtx new_op0 = copy_rtx (operands[0]);
12715   operands[0] = new_op0;
12716   PUT_MODE (new_op0, VOIDmode);
12717   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12718                                              GET_MODE (XEXP (new_op0, 0))));
12719
12720   /* Make sure that (a) the CCmode we have for the flags is strong
12721      enough for the reversed compare or (b) we have a valid FP compare.  */
12722   if (! ix86_comparison_operator (new_op0, VOIDmode))
12723     FAIL;
12724 })
12725
12726 ;; Define combination compare-and-branch fp compare instructions to use
12727 ;; during early optimization.  Splitting the operation apart early makes
12728 ;; for bad code when we want to reverse the operation.
12729
12730 (define_insn "*fp_jcc_1_mixed"
12731   [(set (pc)
12732         (if_then_else (match_operator 0 "comparison_operator"
12733                         [(match_operand 1 "register_operand" "f#x,x#f")
12734                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12735           (label_ref (match_operand 3 "" ""))
12736           (pc)))
12737    (clobber (reg:CCFP FPSR_REG))
12738    (clobber (reg:CCFP FLAGS_REG))]
12739   "TARGET_MIX_SSE_I387
12740    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12741    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12742    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12743   "#")
12744
12745 (define_insn "*fp_jcc_1_sse"
12746   [(set (pc)
12747         (if_then_else (match_operator 0 "comparison_operator"
12748                         [(match_operand 1 "register_operand" "x")
12749                          (match_operand 2 "nonimmediate_operand" "xm")])
12750           (label_ref (match_operand 3 "" ""))
12751           (pc)))
12752    (clobber (reg:CCFP FPSR_REG))
12753    (clobber (reg:CCFP FLAGS_REG))]
12754   "TARGET_SSE_MATH
12755    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12756    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12757    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12758   "#")
12759
12760 (define_insn "*fp_jcc_1_387"
12761   [(set (pc)
12762         (if_then_else (match_operator 0 "comparison_operator"
12763                         [(match_operand 1 "register_operand" "f")
12764                          (match_operand 2 "register_operand" "f")])
12765           (label_ref (match_operand 3 "" ""))
12766           (pc)))
12767    (clobber (reg:CCFP FPSR_REG))
12768    (clobber (reg:CCFP FLAGS_REG))]
12769   "TARGET_CMOVE && TARGET_80387
12770    && FLOAT_MODE_P (GET_MODE (operands[1]))
12771    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12772    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12773   "#")
12774
12775 (define_insn "*fp_jcc_2_mixed"
12776   [(set (pc)
12777         (if_then_else (match_operator 0 "comparison_operator"
12778                         [(match_operand 1 "register_operand" "f#x,x#f")
12779                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12780           (pc)
12781           (label_ref (match_operand 3 "" ""))))
12782    (clobber (reg:CCFP FPSR_REG))
12783    (clobber (reg:CCFP FLAGS_REG))]
12784   "TARGET_MIX_SSE_I387
12785    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12786    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12787    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12788   "#")
12789
12790 (define_insn "*fp_jcc_2_sse"
12791   [(set (pc)
12792         (if_then_else (match_operator 0 "comparison_operator"
12793                         [(match_operand 1 "register_operand" "x")
12794                          (match_operand 2 "nonimmediate_operand" "xm")])
12795           (pc)
12796           (label_ref (match_operand 3 "" ""))))
12797    (clobber (reg:CCFP FPSR_REG))
12798    (clobber (reg:CCFP FLAGS_REG))]
12799   "TARGET_SSE_MATH
12800    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12801    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12802    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12803   "#")
12804
12805 (define_insn "*fp_jcc_2_387"
12806   [(set (pc)
12807         (if_then_else (match_operator 0 "comparison_operator"
12808                         [(match_operand 1 "register_operand" "f")
12809                          (match_operand 2 "register_operand" "f")])
12810           (pc)
12811           (label_ref (match_operand 3 "" ""))))
12812    (clobber (reg:CCFP FPSR_REG))
12813    (clobber (reg:CCFP FLAGS_REG))]
12814   "TARGET_CMOVE && TARGET_80387
12815    && FLOAT_MODE_P (GET_MODE (operands[1]))
12816    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12817    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12818   "#")
12819
12820 (define_insn "*fp_jcc_3_387"
12821   [(set (pc)
12822         (if_then_else (match_operator 0 "comparison_operator"
12823                         [(match_operand 1 "register_operand" "f")
12824                          (match_operand 2 "nonimmediate_operand" "fm")])
12825           (label_ref (match_operand 3 "" ""))
12826           (pc)))
12827    (clobber (reg:CCFP FPSR_REG))
12828    (clobber (reg:CCFP FLAGS_REG))
12829    (clobber (match_scratch:HI 4 "=a"))]
12830   "TARGET_80387
12831    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12832    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12833    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12834    && SELECT_CC_MODE (GET_CODE (operands[0]),
12835                       operands[1], operands[2]) == CCFPmode
12836    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12837   "#")
12838
12839 (define_insn "*fp_jcc_4_387"
12840   [(set (pc)
12841         (if_then_else (match_operator 0 "comparison_operator"
12842                         [(match_operand 1 "register_operand" "f")
12843                          (match_operand 2 "nonimmediate_operand" "fm")])
12844           (pc)
12845           (label_ref (match_operand 3 "" ""))))
12846    (clobber (reg:CCFP FPSR_REG))
12847    (clobber (reg:CCFP FLAGS_REG))
12848    (clobber (match_scratch:HI 4 "=a"))]
12849   "TARGET_80387
12850    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12851    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12852    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12853    && SELECT_CC_MODE (GET_CODE (operands[0]),
12854                       operands[1], operands[2]) == CCFPmode
12855    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12856   "#")
12857
12858 (define_insn "*fp_jcc_5_387"
12859   [(set (pc)
12860         (if_then_else (match_operator 0 "comparison_operator"
12861                         [(match_operand 1 "register_operand" "f")
12862                          (match_operand 2 "register_operand" "f")])
12863           (label_ref (match_operand 3 "" ""))
12864           (pc)))
12865    (clobber (reg:CCFP FPSR_REG))
12866    (clobber (reg:CCFP FLAGS_REG))
12867    (clobber (match_scratch:HI 4 "=a"))]
12868   "TARGET_80387
12869    && FLOAT_MODE_P (GET_MODE (operands[1]))
12870    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12871    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12872   "#")
12873
12874 (define_insn "*fp_jcc_6_387"
12875   [(set (pc)
12876         (if_then_else (match_operator 0 "comparison_operator"
12877                         [(match_operand 1 "register_operand" "f")
12878                          (match_operand 2 "register_operand" "f")])
12879           (pc)
12880           (label_ref (match_operand 3 "" ""))))
12881    (clobber (reg:CCFP FPSR_REG))
12882    (clobber (reg:CCFP FLAGS_REG))
12883    (clobber (match_scratch:HI 4 "=a"))]
12884   "TARGET_80387
12885    && FLOAT_MODE_P (GET_MODE (operands[1]))
12886    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12887    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12888   "#")
12889
12890 (define_insn "*fp_jcc_7_387"
12891   [(set (pc)
12892         (if_then_else (match_operator 0 "comparison_operator"
12893                         [(match_operand 1 "register_operand" "f")
12894                          (match_operand 2 "const0_operand" "X")])
12895           (label_ref (match_operand 3 "" ""))
12896           (pc)))
12897    (clobber (reg:CCFP FPSR_REG))
12898    (clobber (reg:CCFP FLAGS_REG))
12899    (clobber (match_scratch:HI 4 "=a"))]
12900   "TARGET_80387
12901    && FLOAT_MODE_P (GET_MODE (operands[1]))
12902    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12903    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12904    && SELECT_CC_MODE (GET_CODE (operands[0]),
12905                       operands[1], operands[2]) == CCFPmode
12906    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12907   "#")
12908
12909 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12910 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12911 ;; with a precedence over other operators and is always put in the first
12912 ;; place. Swap condition and operands to match ficom instruction.
12913
12914 (define_insn "*fp_jcc_8<mode>_387"
12915   [(set (pc)
12916         (if_then_else (match_operator 0 "comparison_operator"
12917                         [(match_operator 1 "float_operator"
12918                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12919                            (match_operand 3 "register_operand" "f,f")])
12920           (label_ref (match_operand 4 "" ""))
12921           (pc)))
12922    (clobber (reg:CCFP FPSR_REG))
12923    (clobber (reg:CCFP FLAGS_REG))
12924    (clobber (match_scratch:HI 5 "=a,a"))]
12925   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12926    && FLOAT_MODE_P (GET_MODE (operands[3]))
12927    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12928    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12929    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12930    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12931   "#")
12932
12933 (define_split
12934   [(set (pc)
12935         (if_then_else (match_operator 0 "comparison_operator"
12936                         [(match_operand 1 "register_operand" "")
12937                          (match_operand 2 "nonimmediate_operand" "")])
12938           (match_operand 3 "" "")
12939           (match_operand 4 "" "")))
12940    (clobber (reg:CCFP FPSR_REG))
12941    (clobber (reg:CCFP FLAGS_REG))]
12942   "reload_completed"
12943   [(const_int 0)]
12944 {
12945   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12946                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12947   DONE;
12948 })
12949
12950 (define_split
12951   [(set (pc)
12952         (if_then_else (match_operator 0 "comparison_operator"
12953                         [(match_operand 1 "register_operand" "")
12954                          (match_operand 2 "general_operand" "")])
12955           (match_operand 3 "" "")
12956           (match_operand 4 "" "")))
12957    (clobber (reg:CCFP FPSR_REG))
12958    (clobber (reg:CCFP FLAGS_REG))
12959    (clobber (match_scratch:HI 5 "=a"))]
12960   "reload_completed"
12961   [(const_int 0)]
12962 {
12963   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12964                         operands[3], operands[4], operands[5], NULL_RTX);
12965   DONE;
12966 })
12967
12968 (define_split
12969   [(set (pc)
12970         (if_then_else (match_operator 0 "comparison_operator"
12971                         [(match_operator 1 "float_operator"
12972                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12973                            (match_operand 3 "register_operand" "")])
12974           (match_operand 4 "" "")
12975           (match_operand 5 "" "")))
12976    (clobber (reg:CCFP FPSR_REG))
12977    (clobber (reg:CCFP FLAGS_REG))
12978    (clobber (match_scratch:HI 6 "=a"))]
12979   "reload_completed"
12980   [(const_int 0)]
12981 {
12982   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12983   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12984                         operands[3], operands[7],
12985                         operands[4], operands[5], operands[6], NULL_RTX);
12986   DONE;
12987 })
12988
12989 ;; %%% Kill this when reload knows how to do it.
12990 (define_split
12991   [(set (pc)
12992         (if_then_else (match_operator 0 "comparison_operator"
12993                         [(match_operator 1 "float_operator"
12994                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12995                            (match_operand 3 "register_operand" "")])
12996           (match_operand 4 "" "")
12997           (match_operand 5 "" "")))
12998    (clobber (reg:CCFP FPSR_REG))
12999    (clobber (reg:CCFP FLAGS_REG))
13000    (clobber (match_scratch:HI 6 "=a"))]
13001   "reload_completed"
13002   [(const_int 0)]
13003 {
13004   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13005   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13006   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13007                         operands[3], operands[7],
13008                         operands[4], operands[5], operands[6], operands[2]);
13009   DONE;
13010 })
13011 \f
13012 ;; Unconditional and other jump instructions
13013
13014 (define_insn "jump"
13015   [(set (pc)
13016         (label_ref (match_operand 0 "" "")))]
13017   ""
13018   "jmp\t%l0"
13019   [(set_attr "type" "ibr")
13020    (set (attr "length")
13021            (if_then_else (and (ge (minus (match_dup 0) (pc))
13022                                   (const_int -126))
13023                               (lt (minus (match_dup 0) (pc))
13024                                   (const_int 128)))
13025              (const_int 2)
13026              (const_int 5)))
13027    (set_attr "modrm" "0")])
13028
13029 (define_expand "indirect_jump"
13030   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13031   ""
13032   "")
13033
13034 (define_insn "*indirect_jump"
13035   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13036   "!TARGET_64BIT"
13037   "jmp\t%A0"
13038   [(set_attr "type" "ibr")
13039    (set_attr "length_immediate" "0")])
13040
13041 (define_insn "*indirect_jump_rtx64"
13042   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13043   "TARGET_64BIT"
13044   "jmp\t%A0"
13045   [(set_attr "type" "ibr")
13046    (set_attr "length_immediate" "0")])
13047
13048 (define_expand "tablejump"
13049   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13050               (use (label_ref (match_operand 1 "" "")))])]
13051   ""
13052 {
13053   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13054      relative.  Convert the relative address to an absolute address.  */
13055   if (flag_pic)
13056     {
13057       rtx op0, op1;
13058       enum rtx_code code;
13059
13060       if (TARGET_64BIT)
13061         {
13062           code = PLUS;
13063           op0 = operands[0];
13064           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13065         }
13066       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13067         {
13068           code = PLUS;
13069           op0 = operands[0];
13070           op1 = pic_offset_table_rtx;
13071         }
13072       else
13073         {
13074           code = MINUS;
13075           op0 = pic_offset_table_rtx;
13076           op1 = operands[0];
13077         }
13078
13079       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13080                                          OPTAB_DIRECT);
13081     }
13082 })
13083
13084 (define_insn "*tablejump_1"
13085   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13086    (use (label_ref (match_operand 1 "" "")))]
13087   "!TARGET_64BIT"
13088   "jmp\t%A0"
13089   [(set_attr "type" "ibr")
13090    (set_attr "length_immediate" "0")])
13091
13092 (define_insn "*tablejump_1_rtx64"
13093   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13094    (use (label_ref (match_operand 1 "" "")))]
13095   "TARGET_64BIT"
13096   "jmp\t%A0"
13097   [(set_attr "type" "ibr")
13098    (set_attr "length_immediate" "0")])
13099 \f
13100 ;; Loop instruction
13101 ;;
13102 ;; This is all complicated by the fact that since this is a jump insn
13103 ;; we must handle our own reloads.
13104
13105 (define_expand "doloop_end"
13106   [(use (match_operand 0 "" ""))        ; loop pseudo
13107    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13108    (use (match_operand 2 "" ""))        ; max iterations
13109    (use (match_operand 3 "" ""))        ; loop level 
13110    (use (match_operand 4 "" ""))]       ; label
13111   "!TARGET_64BIT && TARGET_USE_LOOP"
13112   "                                 
13113 {
13114   /* Only use cloop on innermost loops.  */
13115   if (INTVAL (operands[3]) > 1)
13116     FAIL;
13117   if (GET_MODE (operands[0]) != SImode)
13118     FAIL;
13119   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13120                                            operands[0]));
13121   DONE;
13122 }")
13123
13124 (define_insn "doloop_end_internal"
13125   [(set (pc)
13126         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13127                           (const_int 1))
13128                       (label_ref (match_operand 0 "" ""))
13129                       (pc)))
13130    (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13131         (plus:SI (match_dup 1)
13132                  (const_int -1)))
13133    (clobber (match_scratch:SI 3 "=X,X,r"))
13134    (clobber (reg:CC FLAGS_REG))]
13135   "!TARGET_64BIT && TARGET_USE_LOOP
13136    && (reload_in_progress || reload_completed
13137        || register_operand (operands[2], VOIDmode))"
13138 {
13139   if (which_alternative != 0)
13140     return "#";
13141   if (get_attr_length (insn) == 2)
13142     return "%+loop\t%l0";
13143   else
13144     return "dec{l}\t%1\;%+jne\t%l0";
13145 }
13146   [(set (attr "length")
13147         (if_then_else (and (eq_attr "alternative" "0")
13148                            (and (ge (minus (match_dup 0) (pc))
13149                                     (const_int -126))
13150                                 (lt (minus (match_dup 0) (pc))
13151                                     (const_int 128))))
13152                       (const_int 2)
13153                       (const_int 16)))
13154    ;; We don't know the type before shorten branches.  Optimistically expect
13155    ;; the loop instruction to match.
13156    (set (attr "type") (const_string "ibr"))])
13157
13158 (define_split
13159   [(set (pc)
13160         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13161                           (const_int 1))
13162                       (match_operand 0 "" "")
13163                       (pc)))
13164    (set (match_dup 1)
13165         (plus:SI (match_dup 1)
13166                  (const_int -1)))
13167    (clobber (match_scratch:SI 2 ""))
13168    (clobber (reg:CC FLAGS_REG))]
13169   "!TARGET_64BIT && TARGET_USE_LOOP
13170    && reload_completed
13171    && REGNO (operands[1]) != 2"
13172   [(parallel [(set (reg:CCZ FLAGS_REG)
13173                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13174                                  (const_int 0)))
13175               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13176    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13177                            (match_dup 0)
13178                            (pc)))]
13179   "")
13180   
13181 (define_split
13182   [(set (pc)
13183         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13184                           (const_int 1))
13185                       (match_operand 0 "" "")
13186                       (pc)))
13187    (set (match_operand:SI 2 "nonimmediate_operand" "")
13188         (plus:SI (match_dup 1)
13189                  (const_int -1)))
13190    (clobber (match_scratch:SI 3 ""))
13191    (clobber (reg:CC FLAGS_REG))]
13192   "!TARGET_64BIT && TARGET_USE_LOOP
13193    && reload_completed
13194    && (! REG_P (operands[2])
13195        || ! rtx_equal_p (operands[1], operands[2]))"
13196   [(set (match_dup 3) (match_dup 1))
13197    (parallel [(set (reg:CCZ FLAGS_REG)
13198                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13199                                 (const_int 0)))
13200               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13201    (set (match_dup 2) (match_dup 3))
13202    (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13203                            (match_dup 0)
13204                            (pc)))]
13205   "")
13206
13207 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13208
13209 (define_peephole2
13210   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13211    (set (match_operand:QI 1 "register_operand" "")
13212         (match_operator:QI 2 "ix86_comparison_operator"
13213           [(reg FLAGS_REG) (const_int 0)]))
13214    (set (match_operand 3 "q_regs_operand" "")
13215         (zero_extend (match_dup 1)))]
13216   "(peep2_reg_dead_p (3, operands[1])
13217     || operands_match_p (operands[1], operands[3]))
13218    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13219   [(set (match_dup 4) (match_dup 0))
13220    (set (strict_low_part (match_dup 5))
13221         (match_dup 2))]
13222 {
13223   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13224   operands[5] = gen_lowpart (QImode, operands[3]);
13225   ix86_expand_clear (operands[3]);
13226 })
13227
13228 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13229
13230 (define_peephole2
13231   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13232    (set (match_operand:QI 1 "register_operand" "")
13233         (match_operator:QI 2 "ix86_comparison_operator"
13234           [(reg FLAGS_REG) (const_int 0)]))
13235    (parallel [(set (match_operand 3 "q_regs_operand" "")
13236                    (zero_extend (match_dup 1)))
13237               (clobber (reg:CC FLAGS_REG))])]
13238   "(peep2_reg_dead_p (3, operands[1])
13239     || operands_match_p (operands[1], operands[3]))
13240    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13241   [(set (match_dup 4) (match_dup 0))
13242    (set (strict_low_part (match_dup 5))
13243         (match_dup 2))]
13244 {
13245   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13246   operands[5] = gen_lowpart (QImode, operands[3]);
13247   ix86_expand_clear (operands[3]);
13248 })
13249 \f
13250 ;; Call instructions.
13251
13252 ;; The predicates normally associated with named expanders are not properly
13253 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13254 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13255
13256 ;; Call subroutine returning no value.
13257
13258 (define_expand "call_pop"
13259   [(parallel [(call (match_operand:QI 0 "" "")
13260                     (match_operand:SI 1 "" ""))
13261               (set (reg:SI SP_REG)
13262                    (plus:SI (reg:SI SP_REG)
13263                             (match_operand:SI 3 "" "")))])]
13264   "!TARGET_64BIT"
13265 {
13266   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13267   DONE;
13268 })
13269
13270 (define_insn "*call_pop_0"
13271   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13272          (match_operand:SI 1 "" ""))
13273    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13274                             (match_operand:SI 2 "immediate_operand" "")))]
13275   "!TARGET_64BIT"
13276 {
13277   if (SIBLING_CALL_P (insn))
13278     return "jmp\t%P0";
13279   else
13280     return "call\t%P0";
13281 }
13282   [(set_attr "type" "call")])
13283   
13284 (define_insn "*call_pop_1"
13285   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13286          (match_operand:SI 1 "" ""))
13287    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13288                             (match_operand:SI 2 "immediate_operand" "i")))]
13289   "!TARGET_64BIT"
13290 {
13291   if (constant_call_address_operand (operands[0], Pmode))
13292     {
13293       if (SIBLING_CALL_P (insn))
13294         return "jmp\t%P0";
13295       else
13296         return "call\t%P0";
13297     }
13298   if (SIBLING_CALL_P (insn))
13299     return "jmp\t%A0";
13300   else
13301     return "call\t%A0";
13302 }
13303   [(set_attr "type" "call")])
13304
13305 (define_expand "call"
13306   [(call (match_operand:QI 0 "" "")
13307          (match_operand 1 "" ""))
13308    (use (match_operand 2 "" ""))]
13309   ""
13310 {
13311   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13312   DONE;
13313 })
13314
13315 (define_expand "sibcall"
13316   [(call (match_operand:QI 0 "" "")
13317          (match_operand 1 "" ""))
13318    (use (match_operand 2 "" ""))]
13319   ""
13320 {
13321   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13322   DONE;
13323 })
13324
13325 (define_insn "*call_0"
13326   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13327          (match_operand 1 "" ""))]
13328   ""
13329 {
13330   if (SIBLING_CALL_P (insn))
13331     return "jmp\t%P0";
13332   else
13333     return "call\t%P0";
13334 }
13335   [(set_attr "type" "call")])
13336
13337 (define_insn "*call_1"
13338   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13339          (match_operand 1 "" ""))]
13340   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13341 {
13342   if (constant_call_address_operand (operands[0], Pmode))
13343     return "call\t%P0";
13344   return "call\t%A0";
13345 }
13346   [(set_attr "type" "call")])
13347
13348 (define_insn "*sibcall_1"
13349   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13350          (match_operand 1 "" ""))]
13351   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13352 {
13353   if (constant_call_address_operand (operands[0], Pmode))
13354     return "jmp\t%P0";
13355   return "jmp\t%A0";
13356 }
13357   [(set_attr "type" "call")])
13358
13359 (define_insn "*call_1_rex64"
13360   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13361          (match_operand 1 "" ""))]
13362   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13363 {
13364   if (constant_call_address_operand (operands[0], Pmode))
13365     return "call\t%P0";
13366   return "call\t%A0";
13367 }
13368   [(set_attr "type" "call")])
13369
13370 (define_insn "*sibcall_1_rex64"
13371   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13372          (match_operand 1 "" ""))]
13373   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13374   "jmp\t%P0"
13375   [(set_attr "type" "call")])
13376
13377 (define_insn "*sibcall_1_rex64_v"
13378   [(call (mem:QI (reg:DI 40))
13379          (match_operand 0 "" ""))]
13380   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13381   "jmp\t*%%r11"
13382   [(set_attr "type" "call")])
13383
13384
13385 ;; Call subroutine, returning value in operand 0
13386
13387 (define_expand "call_value_pop"
13388   [(parallel [(set (match_operand 0 "" "")
13389                    (call (match_operand:QI 1 "" "")
13390                          (match_operand:SI 2 "" "")))
13391               (set (reg:SI SP_REG)
13392                    (plus:SI (reg:SI SP_REG)
13393                             (match_operand:SI 4 "" "")))])]
13394   "!TARGET_64BIT"
13395 {
13396   ix86_expand_call (operands[0], operands[1], operands[2],
13397                     operands[3], operands[4], 0);
13398   DONE;
13399 })
13400
13401 (define_expand "call_value"
13402   [(set (match_operand 0 "" "")
13403         (call (match_operand:QI 1 "" "")
13404               (match_operand:SI 2 "" "")))
13405    (use (match_operand:SI 3 "" ""))]
13406   ;; Operand 2 not used on the i386.
13407   ""
13408 {
13409   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13410   DONE;
13411 })
13412
13413 (define_expand "sibcall_value"
13414   [(set (match_operand 0 "" "")
13415         (call (match_operand:QI 1 "" "")
13416               (match_operand:SI 2 "" "")))
13417    (use (match_operand:SI 3 "" ""))]
13418   ;; Operand 2 not used on the i386.
13419   ""
13420 {
13421   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13422   DONE;
13423 })
13424
13425 ;; Call subroutine returning any type.
13426
13427 (define_expand "untyped_call"
13428   [(parallel [(call (match_operand 0 "" "")
13429                     (const_int 0))
13430               (match_operand 1 "" "")
13431               (match_operand 2 "" "")])]
13432   ""
13433 {
13434   int i;
13435
13436   /* In order to give reg-stack an easier job in validating two
13437      coprocessor registers as containing a possible return value,
13438      simply pretend the untyped call returns a complex long double
13439      value.  */
13440
13441   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13442                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13443                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13444                     NULL, 0);
13445
13446   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13447     {
13448       rtx set = XVECEXP (operands[2], 0, i);
13449       emit_move_insn (SET_DEST (set), SET_SRC (set));
13450     }
13451
13452   /* The optimizer does not know that the call sets the function value
13453      registers we stored in the result block.  We avoid problems by
13454      claiming that all hard registers are used and clobbered at this
13455      point.  */
13456   emit_insn (gen_blockage (const0_rtx));
13457
13458   DONE;
13459 })
13460 \f
13461 ;; Prologue and epilogue instructions
13462
13463 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13464 ;; all of memory.  This blocks insns from being moved across this point.
13465
13466 (define_insn "blockage"
13467   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13468   ""
13469   ""
13470   [(set_attr "length" "0")])
13471
13472 ;; Insn emitted into the body of a function to return from a function.
13473 ;; This is only done if the function's epilogue is known to be simple.
13474 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13475
13476 (define_expand "return"
13477   [(return)]
13478   "ix86_can_use_return_insn_p ()"
13479 {
13480   if (current_function_pops_args)
13481     {
13482       rtx popc = GEN_INT (current_function_pops_args);
13483       emit_jump_insn (gen_return_pop_internal (popc));
13484       DONE;
13485     }
13486 })
13487
13488 (define_insn "return_internal"
13489   [(return)]
13490   "reload_completed"
13491   "ret"
13492   [(set_attr "length" "1")
13493    (set_attr "length_immediate" "0")
13494    (set_attr "modrm" "0")])
13495
13496 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13497 ;; instruction Athlon and K8 have.
13498
13499 (define_insn "return_internal_long"
13500   [(return)
13501    (unspec [(const_int 0)] UNSPEC_REP)]
13502   "reload_completed"
13503   "rep {;} ret"
13504   [(set_attr "length" "1")
13505    (set_attr "length_immediate" "0")
13506    (set_attr "prefix_rep" "1")
13507    (set_attr "modrm" "0")])
13508
13509 (define_insn "return_pop_internal"
13510   [(return)
13511    (use (match_operand:SI 0 "const_int_operand" ""))]
13512   "reload_completed"
13513   "ret\t%0"
13514   [(set_attr "length" "3")
13515    (set_attr "length_immediate" "2")
13516    (set_attr "modrm" "0")])
13517
13518 (define_insn "return_indirect_internal"
13519   [(return)
13520    (use (match_operand:SI 0 "register_operand" "r"))]
13521   "reload_completed"
13522   "jmp\t%A0"
13523   [(set_attr "type" "ibr")
13524    (set_attr "length_immediate" "0")])
13525
13526 (define_insn "nop"
13527   [(const_int 0)]
13528   ""
13529   "nop"
13530   [(set_attr "length" "1")
13531    (set_attr "length_immediate" "0")
13532    (set_attr "modrm" "0")])
13533
13534 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13535 ;; branch prediction penalty for the third jump in a 16-byte
13536 ;; block on K8.
13537
13538 (define_insn "align"
13539   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13540   ""
13541 {
13542 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13543   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13544 #else
13545   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13546      The align insn is used to avoid 3 jump instructions in the row to improve
13547      branch prediction and the benefits hardly outweight the cost of extra 8
13548      nops on the average inserted by full alignment pseudo operation.  */
13549 #endif
13550   return "";
13551 }
13552   [(set_attr "length" "16")])
13553
13554 (define_expand "prologue"
13555   [(const_int 1)]
13556   ""
13557   "ix86_expand_prologue (); DONE;")
13558
13559 (define_insn "set_got"
13560   [(set (match_operand:SI 0 "register_operand" "=r")
13561         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13562    (clobber (reg:CC FLAGS_REG))]
13563   "!TARGET_64BIT"
13564   { return output_set_got (operands[0]); }
13565   [(set_attr "type" "multi")
13566    (set_attr "length" "12")])
13567
13568 (define_expand "epilogue"
13569   [(const_int 1)]
13570   ""
13571   "ix86_expand_epilogue (1); DONE;")
13572
13573 (define_expand "sibcall_epilogue"
13574   [(const_int 1)]
13575   ""
13576   "ix86_expand_epilogue (0); DONE;")
13577
13578 (define_expand "eh_return"
13579   [(use (match_operand 0 "register_operand" ""))]
13580   ""
13581 {
13582   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13583
13584   /* Tricky bit: we write the address of the handler to which we will
13585      be returning into someone else's stack frame, one word below the
13586      stack address we wish to restore.  */
13587   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13588   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13589   tmp = gen_rtx_MEM (Pmode, tmp);
13590   emit_move_insn (tmp, ra);
13591
13592   if (Pmode == SImode)
13593     emit_jump_insn (gen_eh_return_si (sa));
13594   else
13595     emit_jump_insn (gen_eh_return_di (sa));
13596   emit_barrier ();
13597   DONE;
13598 })
13599
13600 (define_insn_and_split "eh_return_si"
13601   [(set (pc) 
13602         (unspec [(match_operand:SI 0 "register_operand" "c")]
13603                  UNSPEC_EH_RETURN))]
13604   "!TARGET_64BIT"
13605   "#"
13606   "reload_completed"
13607   [(const_int 1)]
13608   "ix86_expand_epilogue (2); DONE;")
13609
13610 (define_insn_and_split "eh_return_di"
13611   [(set (pc) 
13612         (unspec [(match_operand:DI 0 "register_operand" "c")]
13613                  UNSPEC_EH_RETURN))]
13614   "TARGET_64BIT"
13615   "#"
13616   "reload_completed"
13617   [(const_int 1)]
13618   "ix86_expand_epilogue (2); DONE;")
13619
13620 (define_insn "leave"
13621   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13622    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13623    (clobber (mem:BLK (scratch)))]
13624   "!TARGET_64BIT"
13625   "leave"
13626   [(set_attr "type" "leave")])
13627
13628 (define_insn "leave_rex64"
13629   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13630    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13631    (clobber (mem:BLK (scratch)))]
13632   "TARGET_64BIT"
13633   "leave"
13634   [(set_attr "type" "leave")])
13635 \f
13636 (define_expand "ffssi2"
13637   [(parallel
13638      [(set (match_operand:SI 0 "register_operand" "") 
13639            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13640       (clobber (match_scratch:SI 2 ""))
13641       (clobber (reg:CC FLAGS_REG))])]
13642   ""
13643   "")
13644
13645 (define_insn_and_split "*ffs_cmove"
13646   [(set (match_operand:SI 0 "register_operand" "=r") 
13647         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13648    (clobber (match_scratch:SI 2 "=&r"))
13649    (clobber (reg:CC FLAGS_REG))]
13650   "TARGET_CMOVE"
13651   "#"
13652   "&& reload_completed"
13653   [(set (match_dup 2) (const_int -1))
13654    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13655               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13656    (set (match_dup 0) (if_then_else:SI
13657                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13658                         (match_dup 2)
13659                         (match_dup 0)))
13660    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13661               (clobber (reg:CC FLAGS_REG))])]
13662   "")
13663
13664 (define_insn_and_split "*ffs_no_cmove"
13665   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13666         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13667    (clobber (match_scratch:SI 2 "=&q"))
13668    (clobber (reg:CC FLAGS_REG))]
13669   ""
13670   "#"
13671   "reload_completed"
13672   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13673               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13674    (set (strict_low_part (match_dup 3))
13675         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13676    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13677               (clobber (reg:CC FLAGS_REG))])
13678    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13679               (clobber (reg:CC FLAGS_REG))])
13680    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13681               (clobber (reg:CC FLAGS_REG))])]
13682 {
13683   operands[3] = gen_lowpart (QImode, operands[2]);
13684   ix86_expand_clear (operands[2]);
13685 })
13686
13687 (define_insn "*ffssi_1"
13688   [(set (reg:CCZ FLAGS_REG)
13689         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13690                      (const_int 0)))
13691    (set (match_operand:SI 0 "register_operand" "=r")
13692         (ctz:SI (match_dup 1)))]
13693   ""
13694   "bsf{l}\t{%1, %0|%0, %1}"
13695   [(set_attr "prefix_0f" "1")])
13696
13697 (define_expand "ffsdi2"
13698   [(parallel
13699      [(set (match_operand:DI 0 "register_operand" "") 
13700            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13701       (clobber (match_scratch:DI 2 ""))
13702       (clobber (reg:CC FLAGS_REG))])]
13703   "TARGET_64BIT && TARGET_CMOVE"
13704   "")
13705
13706 (define_insn_and_split "*ffs_rex64"
13707   [(set (match_operand:DI 0 "register_operand" "=r") 
13708         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13709    (clobber (match_scratch:DI 2 "=&r"))
13710    (clobber (reg:CC FLAGS_REG))]
13711   "TARGET_64BIT && TARGET_CMOVE"
13712   "#"
13713   "&& reload_completed"
13714   [(set (match_dup 2) (const_int -1))
13715    (parallel [(set (reg:CCZ FLAGS_REG)
13716                    (compare:CCZ (match_dup 1) (const_int 0)))
13717               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13718    (set (match_dup 0) (if_then_else:DI
13719                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13720                         (match_dup 2)
13721                         (match_dup 0)))
13722    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13723               (clobber (reg:CC FLAGS_REG))])]
13724   "")
13725
13726 (define_insn "*ffsdi_1"
13727   [(set (reg:CCZ FLAGS_REG)
13728         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13729                      (const_int 0)))
13730    (set (match_operand:DI 0 "register_operand" "=r")
13731         (ctz:DI (match_dup 1)))]
13732   "TARGET_64BIT"
13733   "bsf{q}\t{%1, %0|%0, %1}"
13734   [(set_attr "prefix_0f" "1")])
13735
13736 (define_insn "ctzsi2"
13737   [(set (match_operand:SI 0 "register_operand" "=r")
13738         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13739    (clobber (reg:CC FLAGS_REG))]
13740   ""
13741   "bsf{l}\t{%1, %0|%0, %1}"
13742   [(set_attr "prefix_0f" "1")])
13743
13744 (define_insn "ctzdi2"
13745   [(set (match_operand:DI 0 "register_operand" "=r")
13746         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13747    (clobber (reg:CC FLAGS_REG))]
13748   "TARGET_64BIT"
13749   "bsf{q}\t{%1, %0|%0, %1}"
13750   [(set_attr "prefix_0f" "1")])
13751
13752 (define_expand "clzsi2"
13753   [(parallel
13754      [(set (match_operand:SI 0 "register_operand" "")
13755            (minus:SI (const_int 31)
13756                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13757       (clobber (reg:CC FLAGS_REG))])
13758    (parallel
13759      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13760       (clobber (reg:CC FLAGS_REG))])]
13761   ""
13762   "")
13763
13764 (define_insn "*bsr"
13765   [(set (match_operand:SI 0 "register_operand" "=r")
13766         (minus:SI (const_int 31)
13767                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13768    (clobber (reg:CC FLAGS_REG))]
13769   ""
13770   "bsr{l}\t{%1, %0|%0, %1}"
13771   [(set_attr "prefix_0f" "1")])
13772
13773 (define_expand "clzdi2"
13774   [(parallel
13775      [(set (match_operand:DI 0 "register_operand" "")
13776            (minus:DI (const_int 63)
13777                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13778       (clobber (reg:CC FLAGS_REG))])
13779    (parallel
13780      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13781       (clobber (reg:CC FLAGS_REG))])]
13782   "TARGET_64BIT"
13783   "")
13784
13785 (define_insn "*bsr_rex64"
13786   [(set (match_operand:DI 0 "register_operand" "=r")
13787         (minus:DI (const_int 63)
13788                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13789    (clobber (reg:CC FLAGS_REG))]
13790   "TARGET_64BIT"
13791   "bsr{q}\t{%1, %0|%0, %1}"
13792   [(set_attr "prefix_0f" "1")])
13793 \f
13794 ;; Thread-local storage patterns for ELF.
13795 ;;
13796 ;; Note that these code sequences must appear exactly as shown
13797 ;; in order to allow linker relaxation.
13798
13799 (define_insn "*tls_global_dynamic_32_gnu"
13800   [(set (match_operand:SI 0 "register_operand" "=a")
13801         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13802                     (match_operand:SI 2 "tls_symbolic_operand" "")
13803                     (match_operand:SI 3 "call_insn_operand" "")]
13804                     UNSPEC_TLS_GD))
13805    (clobber (match_scratch:SI 4 "=d"))
13806    (clobber (match_scratch:SI 5 "=c"))
13807    (clobber (reg:CC FLAGS_REG))]
13808   "!TARGET_64BIT && TARGET_GNU_TLS"
13809   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13810   [(set_attr "type" "multi")
13811    (set_attr "length" "12")])
13812
13813 (define_insn "*tls_global_dynamic_32_sun"
13814   [(set (match_operand:SI 0 "register_operand" "=a")
13815         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13816                     (match_operand:SI 2 "tls_symbolic_operand" "")
13817                     (match_operand:SI 3 "call_insn_operand" "")]
13818                     UNSPEC_TLS_GD))
13819    (clobber (match_scratch:SI 4 "=d"))
13820    (clobber (match_scratch:SI 5 "=c"))
13821    (clobber (reg:CC FLAGS_REG))]
13822   "!TARGET_64BIT && TARGET_SUN_TLS"
13823   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13824         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13825   [(set_attr "type" "multi")
13826    (set_attr "length" "14")])
13827
13828 (define_expand "tls_global_dynamic_32"
13829   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13830                    (unspec:SI
13831                     [(match_dup 2)
13832                      (match_operand:SI 1 "tls_symbolic_operand" "")
13833                      (match_dup 3)]
13834                     UNSPEC_TLS_GD))
13835               (clobber (match_scratch:SI 4 ""))
13836               (clobber (match_scratch:SI 5 ""))
13837               (clobber (reg:CC FLAGS_REG))])]
13838   ""
13839 {
13840   if (flag_pic)
13841     operands[2] = pic_offset_table_rtx;
13842   else
13843     {
13844       operands[2] = gen_reg_rtx (Pmode);
13845       emit_insn (gen_set_got (operands[2]));
13846     }
13847   operands[3] = ix86_tls_get_addr ();
13848 })
13849
13850 (define_insn "*tls_global_dynamic_64"
13851   [(set (match_operand:DI 0 "register_operand" "=a")
13852         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13853                       (match_operand:DI 3 "" "")))
13854    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13855               UNSPEC_TLS_GD)]
13856   "TARGET_64BIT"
13857   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13858   [(set_attr "type" "multi")
13859    (set_attr "length" "16")])
13860
13861 (define_expand "tls_global_dynamic_64"
13862   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13863                    (call (mem:QI (match_dup 2)) (const_int 0)))
13864               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13865                          UNSPEC_TLS_GD)])]
13866   ""
13867 {
13868   operands[2] = ix86_tls_get_addr ();
13869 })
13870
13871 (define_insn "*tls_local_dynamic_base_32_gnu"
13872   [(set (match_operand:SI 0 "register_operand" "=a")
13873         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13874                     (match_operand:SI 2 "call_insn_operand" "")]
13875                    UNSPEC_TLS_LD_BASE))
13876    (clobber (match_scratch:SI 3 "=d"))
13877    (clobber (match_scratch:SI 4 "=c"))
13878    (clobber (reg:CC FLAGS_REG))]
13879   "!TARGET_64BIT && TARGET_GNU_TLS"
13880   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13881   [(set_attr "type" "multi")
13882    (set_attr "length" "11")])
13883
13884 (define_insn "*tls_local_dynamic_base_32_sun"
13885   [(set (match_operand:SI 0 "register_operand" "=a")
13886         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13887                     (match_operand:SI 2 "call_insn_operand" "")]
13888                    UNSPEC_TLS_LD_BASE))
13889    (clobber (match_scratch:SI 3 "=d"))
13890    (clobber (match_scratch:SI 4 "=c"))
13891    (clobber (reg:CC FLAGS_REG))]
13892   "!TARGET_64BIT && TARGET_SUN_TLS"
13893   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13894         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13895   [(set_attr "type" "multi")
13896    (set_attr "length" "13")])
13897
13898 (define_expand "tls_local_dynamic_base_32"
13899   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13900                    (unspec:SI [(match_dup 1) (match_dup 2)]
13901                               UNSPEC_TLS_LD_BASE))
13902               (clobber (match_scratch:SI 3 ""))
13903               (clobber (match_scratch:SI 4 ""))
13904               (clobber (reg:CC FLAGS_REG))])]
13905   ""
13906 {
13907   if (flag_pic)
13908     operands[1] = pic_offset_table_rtx;
13909   else
13910     {
13911       operands[1] = gen_reg_rtx (Pmode);
13912       emit_insn (gen_set_got (operands[1]));
13913     }
13914   operands[2] = ix86_tls_get_addr ();
13915 })
13916
13917 (define_insn "*tls_local_dynamic_base_64"
13918   [(set (match_operand:DI 0 "register_operand" "=a")
13919         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13920                       (match_operand:DI 2 "" "")))
13921    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13922   "TARGET_64BIT"
13923   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13924   [(set_attr "type" "multi")
13925    (set_attr "length" "12")])
13926
13927 (define_expand "tls_local_dynamic_base_64"
13928   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13929                    (call (mem:QI (match_dup 1)) (const_int 0)))
13930               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13931   ""
13932 {
13933   operands[1] = ix86_tls_get_addr ();
13934 })
13935
13936 ;; Local dynamic of a single variable is a lose.  Show combine how
13937 ;; to convert that back to global dynamic.
13938
13939 (define_insn_and_split "*tls_local_dynamic_32_once"
13940   [(set (match_operand:SI 0 "register_operand" "=a")
13941         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13942                              (match_operand:SI 2 "call_insn_operand" "")]
13943                             UNSPEC_TLS_LD_BASE)
13944                  (const:SI (unspec:SI
13945                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13946                             UNSPEC_DTPOFF))))
13947    (clobber (match_scratch:SI 4 "=d"))
13948    (clobber (match_scratch:SI 5 "=c"))
13949    (clobber (reg:CC FLAGS_REG))]
13950   ""
13951   "#"
13952   ""
13953   [(parallel [(set (match_dup 0)
13954                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13955                               UNSPEC_TLS_GD))
13956               (clobber (match_dup 4))
13957               (clobber (match_dup 5))
13958               (clobber (reg:CC FLAGS_REG))])]
13959   "")
13960
13961 ;; Load and add the thread base pointer from %gs:0.
13962
13963 (define_insn "*load_tp_si"
13964   [(set (match_operand:SI 0 "register_operand" "=r")
13965         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13966   "!TARGET_64BIT"
13967   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13968   [(set_attr "type" "imov")
13969    (set_attr "modrm" "0")
13970    (set_attr "length" "7")
13971    (set_attr "memory" "load")
13972    (set_attr "imm_disp" "false")])
13973
13974 (define_insn "*add_tp_si"
13975   [(set (match_operand:SI 0 "register_operand" "=r")
13976         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13977                  (match_operand:SI 1 "register_operand" "0")))
13978    (clobber (reg:CC FLAGS_REG))]
13979   "!TARGET_64BIT"
13980   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13981   [(set_attr "type" "alu")
13982    (set_attr "modrm" "0")
13983    (set_attr "length" "7")
13984    (set_attr "memory" "load")
13985    (set_attr "imm_disp" "false")])
13986
13987 (define_insn "*load_tp_di"
13988   [(set (match_operand:DI 0 "register_operand" "=r")
13989         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13990   "TARGET_64BIT"
13991   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13992   [(set_attr "type" "imov")
13993    (set_attr "modrm" "0")
13994    (set_attr "length" "7")
13995    (set_attr "memory" "load")
13996    (set_attr "imm_disp" "false")])
13997
13998 (define_insn "*add_tp_di"
13999   [(set (match_operand:DI 0 "register_operand" "=r")
14000         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14001                  (match_operand:DI 1 "register_operand" "0")))
14002    (clobber (reg:CC FLAGS_REG))]
14003   "TARGET_64BIT"
14004   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14005   [(set_attr "type" "alu")
14006    (set_attr "modrm" "0")
14007    (set_attr "length" "7")
14008    (set_attr "memory" "load")
14009    (set_attr "imm_disp" "false")])
14010 \f
14011 ;; These patterns match the binary 387 instructions for addM3, subM3,
14012 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14013 ;; SFmode.  The first is the normal insn, the second the same insn but
14014 ;; with one operand a conversion, and the third the same insn but with
14015 ;; the other operand a conversion.  The conversion may be SFmode or
14016 ;; SImode if the target mode DFmode, but only SImode if the target mode
14017 ;; is SFmode.
14018
14019 ;; Gcc is slightly more smart about handling normal two address instructions
14020 ;; so use special patterns for add and mull.
14021
14022 (define_insn "*fop_sf_comm_mixed"
14023   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14024         (match_operator:SF 3 "binary_fp_operator"
14025                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14026                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14027   "TARGET_MIX_SSE_I387
14028    && COMMUTATIVE_ARITH_P (operands[3])
14029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14030   "* return output_387_binary_op (insn, operands);"
14031   [(set (attr "type") 
14032         (if_then_else (eq_attr "alternative" "1")
14033            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14034               (const_string "ssemul")
14035               (const_string "sseadd"))
14036            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14037               (const_string "fmul")
14038               (const_string "fop"))))
14039    (set_attr "mode" "SF")])
14040
14041 (define_insn "*fop_sf_comm_sse"
14042   [(set (match_operand:SF 0 "register_operand" "=x")
14043         (match_operator:SF 3 "binary_fp_operator"
14044                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14045                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14046   "TARGET_SSE_MATH
14047    && COMMUTATIVE_ARITH_P (operands[3])
14048    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14049   "* return output_387_binary_op (insn, operands);"
14050   [(set (attr "type") 
14051         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14052            (const_string "ssemul")
14053            (const_string "sseadd")))
14054    (set_attr "mode" "SF")])
14055
14056 (define_insn "*fop_sf_comm_i387"
14057   [(set (match_operand:SF 0 "register_operand" "=f")
14058         (match_operator:SF 3 "binary_fp_operator"
14059                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14060                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14061   "TARGET_80387
14062    && COMMUTATIVE_ARITH_P (operands[3])
14063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14064   "* return output_387_binary_op (insn, operands);"
14065   [(set (attr "type") 
14066         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14067            (const_string "fmul")
14068            (const_string "fop")))
14069    (set_attr "mode" "SF")])
14070
14071 (define_insn "*fop_sf_1_mixed"
14072   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14073         (match_operator:SF 3 "binary_fp_operator"
14074                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14075                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14076   "TARGET_MIX_SSE_I387
14077    && !COMMUTATIVE_ARITH_P (operands[3])
14078    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14079   "* return output_387_binary_op (insn, operands);"
14080   [(set (attr "type") 
14081         (cond [(and (eq_attr "alternative" "2")
14082                     (match_operand:SF 3 "mult_operator" ""))
14083                  (const_string "ssemul")
14084                (and (eq_attr "alternative" "2")
14085                     (match_operand:SF 3 "div_operator" ""))
14086                  (const_string "ssediv")
14087                (eq_attr "alternative" "2")
14088                  (const_string "sseadd")
14089                (match_operand:SF 3 "mult_operator" "") 
14090                  (const_string "fmul")
14091                (match_operand:SF 3 "div_operator" "") 
14092                  (const_string "fdiv")
14093               ]
14094               (const_string "fop")))
14095    (set_attr "mode" "SF")])
14096
14097 (define_insn "*fop_sf_1_sse"
14098   [(set (match_operand:SF 0 "register_operand" "=x")
14099         (match_operator:SF 3 "binary_fp_operator"
14100                         [(match_operand:SF 1 "register_operand" "0")
14101                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14102   "TARGET_SSE_MATH
14103    && !COMMUTATIVE_ARITH_P (operands[3])"
14104   "* return output_387_binary_op (insn, operands);"
14105   [(set (attr "type") 
14106         (cond [(match_operand:SF 3 "mult_operator" "")
14107                  (const_string "ssemul")
14108                (match_operand:SF 3 "div_operator" "")
14109                  (const_string "ssediv")
14110               ]
14111               (const_string "sseadd")))
14112    (set_attr "mode" "SF")])
14113
14114 ;; This pattern is not fully shadowed by the pattern above.
14115 (define_insn "*fop_sf_1_i387"
14116   [(set (match_operand:SF 0 "register_operand" "=f,f")
14117         (match_operator:SF 3 "binary_fp_operator"
14118                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14119                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14120   "TARGET_80387 && !TARGET_SSE_MATH
14121    && !COMMUTATIVE_ARITH_P (operands[3])
14122    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14123   "* return output_387_binary_op (insn, operands);"
14124   [(set (attr "type") 
14125         (cond [(match_operand:SF 3 "mult_operator" "") 
14126                  (const_string "fmul")
14127                (match_operand:SF 3 "div_operator" "") 
14128                  (const_string "fdiv")
14129               ]
14130               (const_string "fop")))
14131    (set_attr "mode" "SF")])
14132
14133 ;; ??? Add SSE splitters for these!
14134 (define_insn "*fop_sf_2<mode>_i387"
14135   [(set (match_operand:SF 0 "register_operand" "=f,f")
14136         (match_operator:SF 3 "binary_fp_operator"
14137           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14138            (match_operand:SF 2 "register_operand" "0,0")]))]
14139   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14140   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14141   [(set (attr "type") 
14142         (cond [(match_operand:SF 3 "mult_operator" "") 
14143                  (const_string "fmul")
14144                (match_operand:SF 3 "div_operator" "") 
14145                  (const_string "fdiv")
14146               ]
14147               (const_string "fop")))
14148    (set_attr "fp_int_src" "true")
14149    (set_attr "mode" "<MODE>")])
14150
14151 (define_insn "*fop_sf_3<mode>_i387"
14152   [(set (match_operand:SF 0 "register_operand" "=f,f")
14153         (match_operator:SF 3 "binary_fp_operator"
14154           [(match_operand:SF 1 "register_operand" "0,0")
14155            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14156   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14157   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14158   [(set (attr "type") 
14159         (cond [(match_operand:SF 3 "mult_operator" "") 
14160                  (const_string "fmul")
14161                (match_operand:SF 3 "div_operator" "") 
14162                  (const_string "fdiv")
14163               ]
14164               (const_string "fop")))
14165    (set_attr "fp_int_src" "true")
14166    (set_attr "mode" "<MODE>")])
14167
14168 (define_insn "*fop_df_comm_mixed"
14169   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14170         (match_operator:DF 3 "binary_fp_operator"
14171                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14172                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14173   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14174    && COMMUTATIVE_ARITH_P (operands[3])
14175    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14176   "* return output_387_binary_op (insn, operands);"
14177   [(set (attr "type") 
14178         (if_then_else (eq_attr "alternative" "1")
14179            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14180               (const_string "ssemul")
14181               (const_string "sseadd"))
14182            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14183               (const_string "fmul")
14184               (const_string "fop"))))
14185    (set_attr "mode" "DF")])
14186
14187 (define_insn "*fop_df_comm_sse"
14188   [(set (match_operand:DF 0 "register_operand" "=Y")
14189         (match_operator:DF 3 "binary_fp_operator"
14190                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14191                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14192   "TARGET_SSE2 && TARGET_SSE_MATH
14193    && COMMUTATIVE_ARITH_P (operands[3])
14194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14195   "* return output_387_binary_op (insn, operands);"
14196   [(set (attr "type") 
14197         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14198            (const_string "ssemul")
14199            (const_string "sseadd")))
14200    (set_attr "mode" "DF")])
14201
14202 (define_insn "*fop_df_comm_i387"
14203   [(set (match_operand:DF 0 "register_operand" "=f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14206                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14207   "TARGET_80387
14208    && COMMUTATIVE_ARITH_P (operands[3])
14209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14210   "* return output_387_binary_op (insn, operands);"
14211   [(set (attr "type") 
14212         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14213            (const_string "fmul")
14214            (const_string "fop")))
14215    (set_attr "mode" "DF")])
14216
14217 (define_insn "*fop_df_1_mixed"
14218   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14219         (match_operator:DF 3 "binary_fp_operator"
14220                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14221                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14222   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14223    && !COMMUTATIVE_ARITH_P (operands[3])
14224    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14225   "* return output_387_binary_op (insn, operands);"
14226   [(set (attr "type") 
14227         (cond [(and (eq_attr "alternative" "2")
14228                     (match_operand:SF 3 "mult_operator" ""))
14229                  (const_string "ssemul")
14230                (and (eq_attr "alternative" "2")
14231                     (match_operand:SF 3 "div_operator" ""))
14232                  (const_string "ssediv")
14233                (eq_attr "alternative" "2")
14234                  (const_string "sseadd")
14235                (match_operand:DF 3 "mult_operator" "") 
14236                  (const_string "fmul")
14237                (match_operand:DF 3 "div_operator" "") 
14238                  (const_string "fdiv")
14239               ]
14240               (const_string "fop")))
14241    (set_attr "mode" "DF")])
14242
14243 (define_insn "*fop_df_1_sse"
14244   [(set (match_operand:DF 0 "register_operand" "=Y")
14245         (match_operator:DF 3 "binary_fp_operator"
14246                         [(match_operand:DF 1 "register_operand" "0")
14247                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14248   "TARGET_SSE2 && TARGET_SSE_MATH
14249    && !COMMUTATIVE_ARITH_P (operands[3])"
14250   "* return output_387_binary_op (insn, operands);"
14251   [(set_attr "mode" "DF")
14252    (set (attr "type") 
14253         (cond [(match_operand:SF 3 "mult_operator" "")
14254                  (const_string "ssemul")
14255                (match_operand:SF 3 "div_operator" "")
14256                  (const_string "ssediv")
14257               ]
14258               (const_string "sseadd")))])
14259
14260 ;; This pattern is not fully shadowed by the pattern above.
14261 (define_insn "*fop_df_1_i387"
14262   [(set (match_operand:DF 0 "register_operand" "=f,f")
14263         (match_operator:DF 3 "binary_fp_operator"
14264                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14265                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14266   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14267    && !COMMUTATIVE_ARITH_P (operands[3])
14268    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14269   "* return output_387_binary_op (insn, operands);"
14270   [(set (attr "type") 
14271         (cond [(match_operand:DF 3 "mult_operator" "") 
14272                  (const_string "fmul")
14273                (match_operand:DF 3 "div_operator" "")
14274                  (const_string "fdiv")
14275               ]
14276               (const_string "fop")))
14277    (set_attr "mode" "DF")])
14278
14279 ;; ??? Add SSE splitters for these!
14280 (define_insn "*fop_df_2<mode>_i387"
14281   [(set (match_operand:DF 0 "register_operand" "=f,f")
14282         (match_operator:DF 3 "binary_fp_operator"
14283            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14284             (match_operand:DF 2 "register_operand" "0,0")]))]
14285   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14286    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14287   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14288   [(set (attr "type") 
14289         (cond [(match_operand:DF 3 "mult_operator" "") 
14290                  (const_string "fmul")
14291                (match_operand:DF 3 "div_operator" "") 
14292                  (const_string "fdiv")
14293               ]
14294               (const_string "fop")))
14295    (set_attr "fp_int_src" "true")
14296    (set_attr "mode" "<MODE>")])
14297
14298 (define_insn "*fop_df_3<mode>_i387"
14299   [(set (match_operand:DF 0 "register_operand" "=f,f")
14300         (match_operator:DF 3 "binary_fp_operator"
14301            [(match_operand:DF 1 "register_operand" "0,0")
14302             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14303   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14304    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14305   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14306   [(set (attr "type") 
14307         (cond [(match_operand:DF 3 "mult_operator" "") 
14308                  (const_string "fmul")
14309                (match_operand:DF 3 "div_operator" "") 
14310                  (const_string "fdiv")
14311               ]
14312               (const_string "fop")))
14313    (set_attr "fp_int_src" "true")
14314    (set_attr "mode" "<MODE>")])
14315
14316 (define_insn "*fop_df_4_i387"
14317   [(set (match_operand:DF 0 "register_operand" "=f,f")
14318         (match_operator:DF 3 "binary_fp_operator"
14319            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14320             (match_operand:DF 2 "register_operand" "0,f")]))]
14321   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14323   "* return output_387_binary_op (insn, operands);"
14324   [(set (attr "type") 
14325         (cond [(match_operand:DF 3 "mult_operator" "") 
14326                  (const_string "fmul")
14327                (match_operand:DF 3 "div_operator" "") 
14328                  (const_string "fdiv")
14329               ]
14330               (const_string "fop")))
14331    (set_attr "mode" "SF")])
14332
14333 (define_insn "*fop_df_5_i387"
14334   [(set (match_operand:DF 0 "register_operand" "=f,f")
14335         (match_operator:DF 3 "binary_fp_operator"
14336           [(match_operand:DF 1 "register_operand" "0,f")
14337            (float_extend:DF
14338             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14339   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14340   "* return output_387_binary_op (insn, operands);"
14341   [(set (attr "type") 
14342         (cond [(match_operand:DF 3 "mult_operator" "") 
14343                  (const_string "fmul")
14344                (match_operand:DF 3 "div_operator" "") 
14345                  (const_string "fdiv")
14346               ]
14347               (const_string "fop")))
14348    (set_attr "mode" "SF")])
14349
14350 (define_insn "*fop_df_6_i387"
14351   [(set (match_operand:DF 0 "register_operand" "=f,f")
14352         (match_operator:DF 3 "binary_fp_operator"
14353           [(float_extend:DF
14354             (match_operand:SF 1 "register_operand" "0,f"))
14355            (float_extend:DF
14356             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14357   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14358   "* return output_387_binary_op (insn, operands);"
14359   [(set (attr "type") 
14360         (cond [(match_operand:DF 3 "mult_operator" "") 
14361                  (const_string "fmul")
14362                (match_operand:DF 3 "div_operator" "") 
14363                  (const_string "fdiv")
14364               ]
14365               (const_string "fop")))
14366    (set_attr "mode" "SF")])
14367
14368 (define_insn "*fop_xf_comm_i387"
14369   [(set (match_operand:XF 0 "register_operand" "=f")
14370         (match_operator:XF 3 "binary_fp_operator"
14371                         [(match_operand:XF 1 "register_operand" "%0")
14372                          (match_operand:XF 2 "register_operand" "f")]))]
14373   "TARGET_80387
14374    && COMMUTATIVE_ARITH_P (operands[3])"
14375   "* return output_387_binary_op (insn, operands);"
14376   [(set (attr "type") 
14377         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14378            (const_string "fmul")
14379            (const_string "fop")))
14380    (set_attr "mode" "XF")])
14381
14382 (define_insn "*fop_xf_1_i387"
14383   [(set (match_operand:XF 0 "register_operand" "=f,f")
14384         (match_operator:XF 3 "binary_fp_operator"
14385                         [(match_operand:XF 1 "register_operand" "0,f")
14386                          (match_operand:XF 2 "register_operand" "f,0")]))]
14387   "TARGET_80387
14388    && !COMMUTATIVE_ARITH_P (operands[3])"
14389   "* return output_387_binary_op (insn, operands);"
14390   [(set (attr "type") 
14391         (cond [(match_operand:XF 3 "mult_operator" "") 
14392                  (const_string "fmul")
14393                (match_operand:XF 3 "div_operator" "") 
14394                  (const_string "fdiv")
14395               ]
14396               (const_string "fop")))
14397    (set_attr "mode" "XF")])
14398
14399 (define_insn "*fop_xf_2<mode>_i387"
14400   [(set (match_operand:XF 0 "register_operand" "=f,f")
14401         (match_operator:XF 3 "binary_fp_operator"
14402            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14403             (match_operand:XF 2 "register_operand" "0,0")]))]
14404   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14405   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14406   [(set (attr "type") 
14407         (cond [(match_operand:XF 3 "mult_operator" "") 
14408                  (const_string "fmul")
14409                (match_operand:XF 3 "div_operator" "") 
14410                  (const_string "fdiv")
14411               ]
14412               (const_string "fop")))
14413    (set_attr "fp_int_src" "true")
14414    (set_attr "mode" "<MODE>")])
14415
14416 (define_insn "*fop_xf_3<mode>_i387"
14417   [(set (match_operand:XF 0 "register_operand" "=f,f")
14418         (match_operator:XF 3 "binary_fp_operator"
14419           [(match_operand:XF 1 "register_operand" "0,0")
14420            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14421   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14422   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14423   [(set (attr "type") 
14424         (cond [(match_operand:XF 3 "mult_operator" "") 
14425                  (const_string "fmul")
14426                (match_operand:XF 3 "div_operator" "") 
14427                  (const_string "fdiv")
14428               ]
14429               (const_string "fop")))
14430    (set_attr "fp_int_src" "true")
14431    (set_attr "mode" "<MODE>")])
14432
14433 (define_insn "*fop_xf_4_i387"
14434   [(set (match_operand:XF 0 "register_operand" "=f,f")
14435         (match_operator:XF 3 "binary_fp_operator"
14436            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14437             (match_operand:XF 2 "register_operand" "0,f")]))]
14438   "TARGET_80387"
14439   "* return output_387_binary_op (insn, operands);"
14440   [(set (attr "type") 
14441         (cond [(match_operand:XF 3 "mult_operator" "") 
14442                  (const_string "fmul")
14443                (match_operand:XF 3 "div_operator" "") 
14444                  (const_string "fdiv")
14445               ]
14446               (const_string "fop")))
14447    (set_attr "mode" "SF")])
14448
14449 (define_insn "*fop_xf_5_i387"
14450   [(set (match_operand:XF 0 "register_operand" "=f,f")
14451         (match_operator:XF 3 "binary_fp_operator"
14452           [(match_operand:XF 1 "register_operand" "0,f")
14453            (float_extend:XF
14454             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14455   "TARGET_80387"
14456   "* return output_387_binary_op (insn, operands);"
14457   [(set (attr "type") 
14458         (cond [(match_operand:XF 3 "mult_operator" "") 
14459                  (const_string "fmul")
14460                (match_operand:XF 3 "div_operator" "") 
14461                  (const_string "fdiv")
14462               ]
14463               (const_string "fop")))
14464    (set_attr "mode" "SF")])
14465
14466 (define_insn "*fop_xf_6_i387"
14467   [(set (match_operand:XF 0 "register_operand" "=f,f")
14468         (match_operator:XF 3 "binary_fp_operator"
14469           [(float_extend:XF
14470             (match_operand 1 "register_operand" "0,f"))
14471            (float_extend:XF
14472             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14473   "TARGET_80387"
14474   "* return output_387_binary_op (insn, operands);"
14475   [(set (attr "type") 
14476         (cond [(match_operand:XF 3 "mult_operator" "") 
14477                  (const_string "fmul")
14478                (match_operand:XF 3 "div_operator" "") 
14479                  (const_string "fdiv")
14480               ]
14481               (const_string "fop")))
14482    (set_attr "mode" "SF")])
14483
14484 (define_split
14485   [(set (match_operand 0 "register_operand" "")
14486         (match_operator 3 "binary_fp_operator"
14487            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14488             (match_operand 2 "register_operand" "")]))]
14489   "TARGET_80387 && reload_completed
14490    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14491   [(const_int 0)]
14492
14493   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14494   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14495   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14496                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14497                                           GET_MODE (operands[3]),
14498                                           operands[4],
14499                                           operands[2])));
14500   ix86_free_from_memory (GET_MODE (operands[1]));
14501   DONE;
14502 })
14503
14504 (define_split
14505   [(set (match_operand 0 "register_operand" "")
14506         (match_operator 3 "binary_fp_operator"
14507            [(match_operand 1 "register_operand" "")
14508             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14509   "TARGET_80387 && reload_completed
14510    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14511   [(const_int 0)]
14512 {
14513   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14514   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14515   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14516                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14517                                           GET_MODE (operands[3]),
14518                                           operands[1],
14519                                           operands[4])));
14520   ix86_free_from_memory (GET_MODE (operands[2]));
14521   DONE;
14522 })
14523 \f
14524 ;; FPU special functions.
14525
14526 (define_expand "sqrtsf2"
14527   [(set (match_operand:SF 0 "register_operand" "")
14528         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14529   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14530 {
14531   if (!TARGET_SSE_MATH)
14532     operands[1] = force_reg (SFmode, operands[1]);
14533 })
14534
14535 (define_insn "*sqrtsf2_mixed"
14536   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14537         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14538   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14539   "@
14540    fsqrt
14541    sqrtss\t{%1, %0|%0, %1}"
14542   [(set_attr "type" "fpspc,sse")
14543    (set_attr "mode" "SF,SF")
14544    (set_attr "athlon_decode" "direct,*")])
14545
14546 (define_insn "*sqrtsf2_sse"
14547   [(set (match_operand:SF 0 "register_operand" "=x")
14548         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14549   "TARGET_SSE_MATH"
14550   "sqrtss\t{%1, %0|%0, %1}"
14551   [(set_attr "type" "sse")
14552    (set_attr "mode" "SF")
14553    (set_attr "athlon_decode" "*")])
14554
14555 (define_insn "*sqrtsf2_i387"
14556   [(set (match_operand:SF 0 "register_operand" "=f")
14557         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14558   "TARGET_USE_FANCY_MATH_387"
14559   "fsqrt"
14560   [(set_attr "type" "fpspc")
14561    (set_attr "mode" "SF")
14562    (set_attr "athlon_decode" "direct")])
14563
14564 (define_expand "sqrtdf2"
14565   [(set (match_operand:DF 0 "register_operand" "")
14566         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14567   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14568 {
14569   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14570     operands[1] = force_reg (DFmode, operands[1]);
14571 })
14572
14573 (define_insn "*sqrtdf2_mixed"
14574   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14575         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14576   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14577   "@
14578    fsqrt
14579    sqrtsd\t{%1, %0|%0, %1}"
14580   [(set_attr "type" "fpspc,sse")
14581    (set_attr "mode" "DF,DF")
14582    (set_attr "athlon_decode" "direct,*")])
14583
14584 (define_insn "*sqrtdf2_sse"
14585   [(set (match_operand:DF 0 "register_operand" "=Y")
14586         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14587   "TARGET_SSE2 && TARGET_SSE_MATH"
14588   "sqrtsd\t{%1, %0|%0, %1}"
14589   [(set_attr "type" "sse")
14590    (set_attr "mode" "DF")
14591    (set_attr "athlon_decode" "*")])
14592
14593 (define_insn "*sqrtdf2_i387"
14594   [(set (match_operand:DF 0 "register_operand" "=f")
14595         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14596   "TARGET_USE_FANCY_MATH_387"
14597   "fsqrt"
14598   [(set_attr "type" "fpspc")
14599    (set_attr "mode" "DF")
14600    (set_attr "athlon_decode" "direct")])
14601
14602 (define_insn "*sqrtextendsfdf2_i387"
14603   [(set (match_operand:DF 0 "register_operand" "=f")
14604         (sqrt:DF (float_extend:DF
14605                   (match_operand:SF 1 "register_operand" "0"))))]
14606   "TARGET_USE_FANCY_MATH_387
14607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14608   "fsqrt"
14609   [(set_attr "type" "fpspc")
14610    (set_attr "mode" "DF")
14611    (set_attr "athlon_decode" "direct")])
14612
14613 (define_insn "sqrtxf2"
14614   [(set (match_operand:XF 0 "register_operand" "=f")
14615         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14616   "TARGET_USE_FANCY_MATH_387 
14617    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14618   "fsqrt"
14619   [(set_attr "type" "fpspc")
14620    (set_attr "mode" "XF")
14621    (set_attr "athlon_decode" "direct")])
14622
14623 (define_insn "*sqrtextendsfxf2_i387"
14624   [(set (match_operand:XF 0 "register_operand" "=f")
14625         (sqrt:XF (float_extend:XF
14626                   (match_operand:SF 1 "register_operand" "0"))))]
14627   "TARGET_USE_FANCY_MATH_387"
14628   "fsqrt"
14629   [(set_attr "type" "fpspc")
14630    (set_attr "mode" "XF")
14631    (set_attr "athlon_decode" "direct")])
14632
14633 (define_insn "*sqrtextenddfxf2_i387"
14634   [(set (match_operand:XF 0 "register_operand" "=f")
14635         (sqrt:XF (float_extend:XF
14636                   (match_operand:DF 1 "register_operand" "0"))))]
14637   "TARGET_USE_FANCY_MATH_387"
14638   "fsqrt"
14639   [(set_attr "type" "fpspc")
14640    (set_attr "mode" "XF")
14641    (set_attr "athlon_decode" "direct")])
14642
14643 (define_insn "fpremxf4"
14644   [(set (match_operand:XF 0 "register_operand" "=f")
14645         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14646                     (match_operand:XF 3 "register_operand" "1")]
14647                    UNSPEC_FPREM_F))
14648    (set (match_operand:XF 1 "register_operand" "=u")
14649         (unspec:XF [(match_dup 2) (match_dup 3)]
14650                    UNSPEC_FPREM_U))
14651    (set (reg:CCFP FPSR_REG)
14652         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14653   "TARGET_USE_FANCY_MATH_387
14654    && flag_unsafe_math_optimizations"
14655   "fprem"
14656   [(set_attr "type" "fpspc")
14657    (set_attr "mode" "XF")])
14658
14659 (define_expand "fmodsf3"
14660   [(use (match_operand:SF 0 "register_operand" ""))
14661    (use (match_operand:SF 1 "register_operand" ""))
14662    (use (match_operand:SF 2 "register_operand" ""))]
14663   "TARGET_USE_FANCY_MATH_387
14664    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14665    && flag_unsafe_math_optimizations"
14666 {
14667   rtx label = gen_label_rtx ();
14668
14669   rtx op1 = gen_reg_rtx (XFmode);
14670   rtx op2 = gen_reg_rtx (XFmode);
14671
14672   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14673   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14674
14675   emit_label (label);
14676
14677   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14678   ix86_emit_fp_unordered_jump (label);
14679
14680   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14681   DONE;
14682 })
14683
14684 (define_expand "fmoddf3"
14685   [(use (match_operand:DF 0 "register_operand" ""))
14686    (use (match_operand:DF 1 "register_operand" ""))
14687    (use (match_operand:DF 2 "register_operand" ""))]
14688   "TARGET_USE_FANCY_MATH_387
14689    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14690    && flag_unsafe_math_optimizations"
14691 {
14692   rtx label = gen_label_rtx ();
14693
14694   rtx op1 = gen_reg_rtx (XFmode);
14695   rtx op2 = gen_reg_rtx (XFmode);
14696
14697   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14698   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14699
14700   emit_label (label);
14701
14702   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14703   ix86_emit_fp_unordered_jump (label);
14704
14705   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14706   DONE;
14707 })
14708
14709 (define_expand "fmodxf3"
14710   [(use (match_operand:XF 0 "register_operand" ""))
14711    (use (match_operand:XF 1 "register_operand" ""))
14712    (use (match_operand:XF 2 "register_operand" ""))]
14713   "TARGET_USE_FANCY_MATH_387
14714    && flag_unsafe_math_optimizations"
14715 {
14716   rtx label = gen_label_rtx ();
14717
14718   emit_label (label);
14719
14720   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14721                            operands[1], operands[2]));
14722   ix86_emit_fp_unordered_jump (label);
14723
14724   emit_move_insn (operands[0], operands[1]);
14725   DONE;
14726 })
14727
14728 (define_insn "fprem1xf4"
14729   [(set (match_operand:XF 0 "register_operand" "=f")
14730         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14731                     (match_operand:XF 3 "register_operand" "1")]
14732                    UNSPEC_FPREM1_F))
14733    (set (match_operand:XF 1 "register_operand" "=u")
14734         (unspec:XF [(match_dup 2) (match_dup 3)]
14735                    UNSPEC_FPREM1_U))
14736    (set (reg:CCFP FPSR_REG)
14737         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14738   "TARGET_USE_FANCY_MATH_387
14739    && flag_unsafe_math_optimizations"
14740   "fprem1"
14741   [(set_attr "type" "fpspc")
14742    (set_attr "mode" "XF")])
14743
14744 (define_expand "dremsf3"
14745   [(use (match_operand:SF 0 "register_operand" ""))
14746    (use (match_operand:SF 1 "register_operand" ""))
14747    (use (match_operand:SF 2 "register_operand" ""))]
14748   "TARGET_USE_FANCY_MATH_387
14749    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14750    && flag_unsafe_math_optimizations"
14751 {
14752   rtx label = gen_label_rtx ();
14753
14754   rtx op1 = gen_reg_rtx (XFmode);
14755   rtx op2 = gen_reg_rtx (XFmode);
14756
14757   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14758   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14759
14760   emit_label (label);
14761
14762   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14763   ix86_emit_fp_unordered_jump (label);
14764
14765   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14766   DONE;
14767 })
14768
14769 (define_expand "dremdf3"
14770   [(use (match_operand:DF 0 "register_operand" ""))
14771    (use (match_operand:DF 1 "register_operand" ""))
14772    (use (match_operand:DF 2 "register_operand" ""))]
14773   "TARGET_USE_FANCY_MATH_387
14774    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14775    && flag_unsafe_math_optimizations"
14776 {
14777   rtx label = gen_label_rtx ();
14778
14779   rtx op1 = gen_reg_rtx (XFmode);
14780   rtx op2 = gen_reg_rtx (XFmode);
14781
14782   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14783   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14784
14785   emit_label (label);
14786
14787   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14788   ix86_emit_fp_unordered_jump (label);
14789
14790   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14791   DONE;
14792 })
14793
14794 (define_expand "dremxf3"
14795   [(use (match_operand:XF 0 "register_operand" ""))
14796    (use (match_operand:XF 1 "register_operand" ""))
14797    (use (match_operand:XF 2 "register_operand" ""))]
14798   "TARGET_USE_FANCY_MATH_387
14799    && flag_unsafe_math_optimizations"
14800 {
14801   rtx label = gen_label_rtx ();
14802
14803   emit_label (label);
14804
14805   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14806                             operands[1], operands[2]));
14807   ix86_emit_fp_unordered_jump (label);
14808
14809   emit_move_insn (operands[0], operands[1]);
14810   DONE;
14811 })
14812
14813 (define_insn "*sindf2"
14814   [(set (match_operand:DF 0 "register_operand" "=f")
14815         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14816   "TARGET_USE_FANCY_MATH_387
14817    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14818    && flag_unsafe_math_optimizations"
14819   "fsin"
14820   [(set_attr "type" "fpspc")
14821    (set_attr "mode" "DF")])
14822
14823 (define_insn "*sinsf2"
14824   [(set (match_operand:SF 0 "register_operand" "=f")
14825         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14826   "TARGET_USE_FANCY_MATH_387
14827    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14828    && flag_unsafe_math_optimizations"
14829   "fsin"
14830   [(set_attr "type" "fpspc")
14831    (set_attr "mode" "SF")])
14832
14833 (define_insn "*sinextendsfdf2"
14834   [(set (match_operand:DF 0 "register_operand" "=f")
14835         (unspec:DF [(float_extend:DF
14836                      (match_operand:SF 1 "register_operand" "0"))]
14837                    UNSPEC_SIN))]
14838   "TARGET_USE_FANCY_MATH_387
14839    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14840    && flag_unsafe_math_optimizations"
14841   "fsin"
14842   [(set_attr "type" "fpspc")
14843    (set_attr "mode" "DF")])
14844
14845 (define_insn "*sinxf2"
14846   [(set (match_operand:XF 0 "register_operand" "=f")
14847         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14848   "TARGET_USE_FANCY_MATH_387
14849    && flag_unsafe_math_optimizations"
14850   "fsin"
14851   [(set_attr "type" "fpspc")
14852    (set_attr "mode" "XF")])
14853
14854 (define_insn "*cosdf2"
14855   [(set (match_operand:DF 0 "register_operand" "=f")
14856         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14857   "TARGET_USE_FANCY_MATH_387
14858    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14859    && flag_unsafe_math_optimizations"
14860   "fcos"
14861   [(set_attr "type" "fpspc")
14862    (set_attr "mode" "DF")])
14863
14864 (define_insn "*cossf2"
14865   [(set (match_operand:SF 0 "register_operand" "=f")
14866         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14867   "TARGET_USE_FANCY_MATH_387
14868    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14869    && flag_unsafe_math_optimizations"
14870   "fcos"
14871   [(set_attr "type" "fpspc")
14872    (set_attr "mode" "SF")])
14873
14874 (define_insn "*cosextendsfdf2"
14875   [(set (match_operand:DF 0 "register_operand" "=f")
14876         (unspec:DF [(float_extend:DF
14877                      (match_operand:SF 1 "register_operand" "0"))]
14878                    UNSPEC_COS))]
14879   "TARGET_USE_FANCY_MATH_387
14880    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14881    && flag_unsafe_math_optimizations"
14882   "fcos"
14883   [(set_attr "type" "fpspc")
14884    (set_attr "mode" "DF")])
14885
14886 (define_insn "*cosxf2"
14887   [(set (match_operand:XF 0 "register_operand" "=f")
14888         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14889   "TARGET_USE_FANCY_MATH_387
14890    && flag_unsafe_math_optimizations"
14891   "fcos"
14892   [(set_attr "type" "fpspc")
14893    (set_attr "mode" "XF")])
14894
14895 ;; With sincos pattern defined, sin and cos builtin function will be
14896 ;; expanded to sincos pattern with one of its outputs left unused. 
14897 ;; Cse pass  will detected, if two sincos patterns can be combined,
14898 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14899 ;; depending on the unused output.
14900
14901 (define_insn "sincosdf3"
14902   [(set (match_operand:DF 0 "register_operand" "=f")
14903         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14904                    UNSPEC_SINCOS_COS))
14905    (set (match_operand:DF 1 "register_operand" "=u")
14906         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14907   "TARGET_USE_FANCY_MATH_387
14908    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14909    && flag_unsafe_math_optimizations"
14910   "fsincos"
14911   [(set_attr "type" "fpspc")
14912    (set_attr "mode" "DF")])
14913
14914 (define_split
14915   [(set (match_operand:DF 0 "register_operand" "")
14916         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14917                    UNSPEC_SINCOS_COS))
14918    (set (match_operand:DF 1 "register_operand" "")
14919         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14920   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14921    && !reload_completed && !reload_in_progress"
14922   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14923   "")
14924
14925 (define_split
14926   [(set (match_operand:DF 0 "register_operand" "")
14927         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14928                    UNSPEC_SINCOS_COS))
14929    (set (match_operand:DF 1 "register_operand" "")
14930         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14931   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14932    && !reload_completed && !reload_in_progress"
14933   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14934   "")
14935
14936 (define_insn "sincossf3"
14937   [(set (match_operand:SF 0 "register_operand" "=f")
14938         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14939                    UNSPEC_SINCOS_COS))
14940    (set (match_operand:SF 1 "register_operand" "=u")
14941         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14942   "TARGET_USE_FANCY_MATH_387
14943    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14944    && flag_unsafe_math_optimizations"
14945   "fsincos"
14946   [(set_attr "type" "fpspc")
14947    (set_attr "mode" "SF")])
14948
14949 (define_split
14950   [(set (match_operand:SF 0 "register_operand" "")
14951         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14952                    UNSPEC_SINCOS_COS))
14953    (set (match_operand:SF 1 "register_operand" "")
14954         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14955   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14956    && !reload_completed && !reload_in_progress"
14957   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14958   "")
14959
14960 (define_split
14961   [(set (match_operand:SF 0 "register_operand" "")
14962         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14963                    UNSPEC_SINCOS_COS))
14964    (set (match_operand:SF 1 "register_operand" "")
14965         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14966   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14967    && !reload_completed && !reload_in_progress"
14968   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14969   "")
14970
14971 (define_insn "*sincosextendsfdf3"
14972   [(set (match_operand:DF 0 "register_operand" "=f")
14973         (unspec:DF [(float_extend:DF
14974                      (match_operand:SF 2 "register_operand" "0"))]
14975                    UNSPEC_SINCOS_COS))
14976    (set (match_operand:DF 1 "register_operand" "=u")
14977         (unspec:DF [(float_extend:DF
14978                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14979   "TARGET_USE_FANCY_MATH_387
14980    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14981    && flag_unsafe_math_optimizations"
14982   "fsincos"
14983   [(set_attr "type" "fpspc")
14984    (set_attr "mode" "DF")])
14985
14986 (define_split
14987   [(set (match_operand:DF 0 "register_operand" "")
14988         (unspec:DF [(float_extend:DF
14989                      (match_operand:SF 2 "register_operand" ""))]
14990                    UNSPEC_SINCOS_COS))
14991    (set (match_operand:DF 1 "register_operand" "")
14992         (unspec:DF [(float_extend:DF
14993                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14994   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14995    && !reload_completed && !reload_in_progress"
14996   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14997                                    (match_dup 2))] UNSPEC_SIN))]
14998   "")
14999
15000 (define_split
15001   [(set (match_operand:DF 0 "register_operand" "")
15002         (unspec:DF [(float_extend:DF
15003                      (match_operand:SF 2 "register_operand" ""))]
15004                    UNSPEC_SINCOS_COS))
15005    (set (match_operand:DF 1 "register_operand" "")
15006         (unspec:DF [(float_extend:DF
15007                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15008   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15009    && !reload_completed && !reload_in_progress"
15010   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15011                                    (match_dup 2))] UNSPEC_COS))]
15012   "")
15013
15014 (define_insn "sincosxf3"
15015   [(set (match_operand:XF 0 "register_operand" "=f")
15016         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15017                    UNSPEC_SINCOS_COS))
15018    (set (match_operand:XF 1 "register_operand" "=u")
15019         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15020   "TARGET_USE_FANCY_MATH_387
15021    && flag_unsafe_math_optimizations"
15022   "fsincos"
15023   [(set_attr "type" "fpspc")
15024    (set_attr "mode" "XF")])
15025
15026 (define_split
15027   [(set (match_operand:XF 0 "register_operand" "")
15028         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15029                    UNSPEC_SINCOS_COS))
15030    (set (match_operand:XF 1 "register_operand" "")
15031         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15032   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15033    && !reload_completed && !reload_in_progress"
15034   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15035   "")
15036
15037 (define_split
15038   [(set (match_operand:XF 0 "register_operand" "")
15039         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15040                    UNSPEC_SINCOS_COS))
15041    (set (match_operand:XF 1 "register_operand" "")
15042         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15043   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15044    && !reload_completed && !reload_in_progress"
15045   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15046   "")
15047
15048 (define_insn "*tandf3_1"
15049   [(set (match_operand:DF 0 "register_operand" "=f")
15050         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15051                    UNSPEC_TAN_ONE))
15052    (set (match_operand:DF 1 "register_operand" "=u")
15053         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15054   "TARGET_USE_FANCY_MATH_387
15055    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15056    && flag_unsafe_math_optimizations"
15057   "fptan"
15058   [(set_attr "type" "fpspc")
15059    (set_attr "mode" "DF")])
15060
15061 ;; optimize sequence: fptan
15062 ;;                    fstp    %st(0)
15063 ;;                    fld1
15064 ;; into fptan insn.
15065
15066 (define_peephole2
15067   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15068                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15069                              UNSPEC_TAN_ONE))
15070              (set (match_operand:DF 1 "register_operand" "")
15071                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15072    (set (match_dup 0)
15073         (match_operand:DF 3 "immediate_operand" ""))]
15074   "standard_80387_constant_p (operands[3]) == 2"
15075   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15076              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15077   "")
15078
15079 (define_expand "tandf2"
15080   [(parallel [(set (match_dup 2)
15081                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15082                               UNSPEC_TAN_ONE))
15083               (set (match_operand:DF 0 "register_operand" "")
15084                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15085   "TARGET_USE_FANCY_MATH_387
15086    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15087    && flag_unsafe_math_optimizations"
15088 {
15089   operands[2] = gen_reg_rtx (DFmode);
15090 })
15091
15092 (define_insn "*tansf3_1"
15093   [(set (match_operand:SF 0 "register_operand" "=f")
15094         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15095                    UNSPEC_TAN_ONE))
15096    (set (match_operand:SF 1 "register_operand" "=u")
15097         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15100    && flag_unsafe_math_optimizations"
15101   "fptan"
15102   [(set_attr "type" "fpspc")
15103    (set_attr "mode" "SF")])
15104
15105 ;; optimize sequence: fptan
15106 ;;                    fstp    %st(0)
15107 ;;                    fld1
15108 ;; into fptan insn.
15109
15110 (define_peephole2
15111   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15112                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15113                              UNSPEC_TAN_ONE))
15114              (set (match_operand:SF 1 "register_operand" "")
15115                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15116    (set (match_dup 0)
15117         (match_operand:SF 3 "immediate_operand" ""))]
15118   "standard_80387_constant_p (operands[3]) == 2"
15119   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15120              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15121   "")
15122
15123 (define_expand "tansf2"
15124   [(parallel [(set (match_dup 2)
15125                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15126                               UNSPEC_TAN_ONE))
15127               (set (match_operand:SF 0 "register_operand" "")
15128                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15129   "TARGET_USE_FANCY_MATH_387
15130    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15131    && flag_unsafe_math_optimizations"
15132 {
15133   operands[2] = gen_reg_rtx (SFmode);
15134 })
15135
15136 (define_insn "*tanxf3_1"
15137   [(set (match_operand:XF 0 "register_operand" "=f")
15138         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15139                    UNSPEC_TAN_ONE))
15140    (set (match_operand:XF 1 "register_operand" "=u")
15141         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15142   "TARGET_USE_FANCY_MATH_387
15143    && flag_unsafe_math_optimizations"
15144   "fptan"
15145   [(set_attr "type" "fpspc")
15146    (set_attr "mode" "XF")])
15147
15148 ;; optimize sequence: fptan
15149 ;;                    fstp    %st(0)
15150 ;;                    fld1
15151 ;; into fptan insn.
15152
15153 (define_peephole2
15154   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15155                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15156                              UNSPEC_TAN_ONE))
15157              (set (match_operand:XF 1 "register_operand" "")
15158                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15159    (set (match_dup 0)
15160         (match_operand:XF 3 "immediate_operand" ""))]
15161   "standard_80387_constant_p (operands[3]) == 2"
15162   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15163              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15164   "")
15165
15166 (define_expand "tanxf2"
15167   [(parallel [(set (match_dup 2)
15168                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15169                               UNSPEC_TAN_ONE))
15170               (set (match_operand:XF 0 "register_operand" "")
15171                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15172   "TARGET_USE_FANCY_MATH_387
15173    && flag_unsafe_math_optimizations"
15174 {
15175   operands[2] = gen_reg_rtx (XFmode);
15176 })
15177
15178 (define_insn "atan2df3_1"
15179   [(set (match_operand:DF 0 "register_operand" "=f")
15180         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15181                     (match_operand:DF 1 "register_operand" "u")]
15182                    UNSPEC_FPATAN))
15183    (clobber (match_scratch:DF 3 "=1"))]
15184   "TARGET_USE_FANCY_MATH_387
15185    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15186    && flag_unsafe_math_optimizations"
15187   "fpatan"
15188   [(set_attr "type" "fpspc")
15189    (set_attr "mode" "DF")])
15190
15191 (define_expand "atan2df3"
15192   [(use (match_operand:DF 0 "register_operand" ""))
15193    (use (match_operand:DF 2 "register_operand" ""))
15194    (use (match_operand:DF 1 "register_operand" ""))]
15195   "TARGET_USE_FANCY_MATH_387
15196    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15197    && flag_unsafe_math_optimizations"
15198 {
15199   rtx copy = gen_reg_rtx (DFmode);
15200   emit_move_insn (copy, operands[1]);
15201   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15202   DONE;
15203 })
15204
15205 (define_expand "atandf2"
15206   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15207                    (unspec:DF [(match_dup 2)
15208                                (match_operand:DF 1 "register_operand" "")]
15209                     UNSPEC_FPATAN))
15210               (clobber (match_scratch:DF 3 ""))])]
15211   "TARGET_USE_FANCY_MATH_387
15212    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15213    && flag_unsafe_math_optimizations"
15214 {
15215   operands[2] = gen_reg_rtx (DFmode);
15216   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15217 })
15218
15219 (define_insn "atan2sf3_1"
15220   [(set (match_operand:SF 0 "register_operand" "=f")
15221         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15222                     (match_operand:SF 1 "register_operand" "u")]
15223                    UNSPEC_FPATAN))
15224    (clobber (match_scratch:SF 3 "=1"))]
15225   "TARGET_USE_FANCY_MATH_387
15226    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15227    && flag_unsafe_math_optimizations"
15228   "fpatan"
15229   [(set_attr "type" "fpspc")
15230    (set_attr "mode" "SF")])
15231
15232 (define_expand "atan2sf3"
15233   [(use (match_operand:SF 0 "register_operand" ""))
15234    (use (match_operand:SF 2 "register_operand" ""))
15235    (use (match_operand:SF 1 "register_operand" ""))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15238    && flag_unsafe_math_optimizations"
15239 {
15240   rtx copy = gen_reg_rtx (SFmode);
15241   emit_move_insn (copy, operands[1]);
15242   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15243   DONE;
15244 })
15245
15246 (define_expand "atansf2"
15247   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15248                    (unspec:SF [(match_dup 2)
15249                                (match_operand:SF 1 "register_operand" "")]
15250                     UNSPEC_FPATAN))
15251               (clobber (match_scratch:SF 3 ""))])]
15252   "TARGET_USE_FANCY_MATH_387
15253    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15254    && flag_unsafe_math_optimizations"
15255 {
15256   operands[2] = gen_reg_rtx (SFmode);
15257   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15258 })
15259
15260 (define_insn "atan2xf3_1"
15261   [(set (match_operand:XF 0 "register_operand" "=f")
15262         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15263                     (match_operand:XF 1 "register_operand" "u")]
15264                    UNSPEC_FPATAN))
15265    (clobber (match_scratch:XF 3 "=1"))]
15266   "TARGET_USE_FANCY_MATH_387
15267    && flag_unsafe_math_optimizations"
15268   "fpatan"
15269   [(set_attr "type" "fpspc")
15270    (set_attr "mode" "XF")])
15271
15272 (define_expand "atan2xf3"
15273   [(use (match_operand:XF 0 "register_operand" ""))
15274    (use (match_operand:XF 2 "register_operand" ""))
15275    (use (match_operand:XF 1 "register_operand" ""))]
15276   "TARGET_USE_FANCY_MATH_387
15277    && flag_unsafe_math_optimizations"
15278 {
15279   rtx copy = gen_reg_rtx (XFmode);
15280   emit_move_insn (copy, operands[1]);
15281   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15282   DONE;
15283 })
15284
15285 (define_expand "atanxf2"
15286   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15287                    (unspec:XF [(match_dup 2)
15288                                (match_operand:XF 1 "register_operand" "")]
15289                     UNSPEC_FPATAN))
15290               (clobber (match_scratch:XF 3 ""))])]
15291   "TARGET_USE_FANCY_MATH_387
15292    && flag_unsafe_math_optimizations"
15293 {
15294   operands[2] = gen_reg_rtx (XFmode);
15295   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15296 })
15297
15298 (define_expand "asindf2"
15299   [(set (match_dup 2)
15300         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15301    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15302    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15303    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15304    (parallel [(set (match_dup 7)
15305                    (unspec:XF [(match_dup 6) (match_dup 2)]
15306                               UNSPEC_FPATAN))
15307               (clobber (match_scratch:XF 8 ""))])
15308    (set (match_operand:DF 0 "register_operand" "")
15309         (float_truncate:DF (match_dup 7)))]
15310   "TARGET_USE_FANCY_MATH_387
15311    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15312    && flag_unsafe_math_optimizations"
15313 {
15314   int i;
15315
15316   for (i=2; i<8; i++)
15317     operands[i] = gen_reg_rtx (XFmode);
15318
15319   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15320 })
15321
15322 (define_expand "asinsf2"
15323   [(set (match_dup 2)
15324         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15325    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15326    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15327    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15328    (parallel [(set (match_dup 7)
15329                    (unspec:XF [(match_dup 6) (match_dup 2)]
15330                               UNSPEC_FPATAN))
15331               (clobber (match_scratch:XF 8 ""))])
15332    (set (match_operand:SF 0 "register_operand" "")
15333         (float_truncate:SF (match_dup 7)))]
15334   "TARGET_USE_FANCY_MATH_387
15335    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15336    && flag_unsafe_math_optimizations"
15337 {
15338   int i;
15339
15340   for (i=2; i<8; i++)
15341     operands[i] = gen_reg_rtx (XFmode);
15342
15343   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15344 })
15345
15346 (define_expand "asinxf2"
15347   [(set (match_dup 2)
15348         (mult:XF (match_operand:XF 1 "register_operand" "")
15349                  (match_dup 1)))
15350    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15351    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15352    (parallel [(set (match_operand:XF 0 "register_operand" "")
15353                    (unspec:XF [(match_dup 5) (match_dup 1)]
15354                               UNSPEC_FPATAN))
15355               (clobber (match_scratch:XF 6 ""))])]
15356   "TARGET_USE_FANCY_MATH_387
15357    && flag_unsafe_math_optimizations"
15358 {
15359   int i;
15360
15361   for (i=2; i<6; i++)
15362     operands[i] = gen_reg_rtx (XFmode);
15363
15364   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15365 })
15366
15367 (define_expand "acosdf2"
15368   [(set (match_dup 2)
15369         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15370    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15371    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15372    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15373    (parallel [(set (match_dup 7)
15374                    (unspec:XF [(match_dup 2) (match_dup 6)]
15375                               UNSPEC_FPATAN))
15376               (clobber (match_scratch:XF 8 ""))])
15377    (set (match_operand:DF 0 "register_operand" "")
15378         (float_truncate:DF (match_dup 7)))]
15379   "TARGET_USE_FANCY_MATH_387
15380    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15381    && flag_unsafe_math_optimizations"
15382 {
15383   int i;
15384
15385   for (i=2; i<8; i++)
15386     operands[i] = gen_reg_rtx (XFmode);
15387
15388   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15389 })
15390
15391 (define_expand "acossf2"
15392   [(set (match_dup 2)
15393         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15394    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15395    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15396    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15397    (parallel [(set (match_dup 7)
15398                    (unspec:XF [(match_dup 2) (match_dup 6)]
15399                               UNSPEC_FPATAN))
15400               (clobber (match_scratch:XF 8 ""))])
15401    (set (match_operand:SF 0 "register_operand" "")
15402         (float_truncate:SF (match_dup 7)))]
15403   "TARGET_USE_FANCY_MATH_387
15404    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15405    && flag_unsafe_math_optimizations"
15406 {
15407   int i;
15408
15409   for (i=2; i<8; i++)
15410     operands[i] = gen_reg_rtx (XFmode);
15411
15412   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15413 })
15414
15415 (define_expand "acosxf2"
15416   [(set (match_dup 2)
15417         (mult:XF (match_operand:XF 1 "register_operand" "")
15418                  (match_dup 1)))
15419    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15420    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15421    (parallel [(set (match_operand:XF 0 "register_operand" "")
15422                    (unspec:XF [(match_dup 1) (match_dup 5)]
15423                               UNSPEC_FPATAN))
15424               (clobber (match_scratch:XF 6 ""))])]
15425   "TARGET_USE_FANCY_MATH_387
15426    && flag_unsafe_math_optimizations"
15427 {
15428   int i;
15429
15430   for (i=2; i<6; i++)
15431     operands[i] = gen_reg_rtx (XFmode);
15432
15433   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15434 })
15435
15436 (define_insn "fyl2x_xf3"
15437   [(set (match_operand:XF 0 "register_operand" "=f")
15438         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15439                     (match_operand:XF 1 "register_operand" "u")]
15440                    UNSPEC_FYL2X))
15441    (clobber (match_scratch:XF 3 "=1"))]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations"
15444   "fyl2x"
15445   [(set_attr "type" "fpspc")
15446    (set_attr "mode" "XF")])
15447
15448 (define_expand "logsf2"
15449   [(set (match_dup 2)
15450         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15451    (parallel [(set (match_dup 4)
15452                    (unspec:XF [(match_dup 2)
15453                                (match_dup 3)] UNSPEC_FYL2X))
15454               (clobber (match_scratch:XF 5 ""))])
15455    (set (match_operand:SF 0 "register_operand" "")
15456         (float_truncate:SF (match_dup 4)))]
15457   "TARGET_USE_FANCY_MATH_387
15458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459    && flag_unsafe_math_optimizations"
15460 {
15461   rtx temp;
15462
15463   operands[2] = gen_reg_rtx (XFmode);
15464   operands[3] = gen_reg_rtx (XFmode);
15465   operands[4] = gen_reg_rtx (XFmode);
15466
15467   temp = standard_80387_constant_rtx (4); /* fldln2 */
15468   emit_move_insn (operands[3], temp);
15469 })
15470
15471 (define_expand "logdf2"
15472   [(set (match_dup 2)
15473         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15474    (parallel [(set (match_dup 4)
15475                    (unspec:XF [(match_dup 2)
15476                                (match_dup 3)] UNSPEC_FYL2X))
15477               (clobber (match_scratch:XF 5 ""))])
15478    (set (match_operand:DF 0 "register_operand" "")
15479         (float_truncate:DF (match_dup 4)))]
15480   "TARGET_USE_FANCY_MATH_387
15481    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15482    && flag_unsafe_math_optimizations"
15483 {
15484   rtx temp;
15485
15486   operands[2] = gen_reg_rtx (XFmode);
15487   operands[3] = gen_reg_rtx (XFmode);
15488   operands[4] = gen_reg_rtx (XFmode);
15489
15490   temp = standard_80387_constant_rtx (4); /* fldln2 */
15491   emit_move_insn (operands[3], temp);
15492 })
15493
15494 (define_expand "logxf2"
15495   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15496                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15497                                (match_dup 2)] UNSPEC_FYL2X))
15498               (clobber (match_scratch:XF 3 ""))])]
15499   "TARGET_USE_FANCY_MATH_387
15500    && flag_unsafe_math_optimizations"
15501 {
15502   rtx temp;
15503
15504   operands[2] = gen_reg_rtx (XFmode);
15505   temp = standard_80387_constant_rtx (4); /* fldln2 */
15506   emit_move_insn (operands[2], temp);
15507 })
15508
15509 (define_expand "log10sf2"
15510   [(set (match_dup 2)
15511         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15512    (parallel [(set (match_dup 4)
15513                    (unspec:XF [(match_dup 2)
15514                                (match_dup 3)] UNSPEC_FYL2X))
15515               (clobber (match_scratch:XF 5 ""))])
15516    (set (match_operand:SF 0 "register_operand" "")
15517         (float_truncate:SF (match_dup 4)))]
15518   "TARGET_USE_FANCY_MATH_387
15519    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15520    && flag_unsafe_math_optimizations"
15521 {
15522   rtx temp;
15523
15524   operands[2] = gen_reg_rtx (XFmode);
15525   operands[3] = gen_reg_rtx (XFmode);
15526   operands[4] = gen_reg_rtx (XFmode);
15527
15528   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15529   emit_move_insn (operands[3], temp);
15530 })
15531
15532 (define_expand "log10df2"
15533   [(set (match_dup 2)
15534         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15535    (parallel [(set (match_dup 4)
15536                    (unspec:XF [(match_dup 2)
15537                                (match_dup 3)] UNSPEC_FYL2X))
15538               (clobber (match_scratch:XF 5 ""))])
15539    (set (match_operand:DF 0 "register_operand" "")
15540         (float_truncate:DF (match_dup 4)))]
15541   "TARGET_USE_FANCY_MATH_387
15542    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15543    && flag_unsafe_math_optimizations"
15544 {
15545   rtx temp;
15546
15547   operands[2] = gen_reg_rtx (XFmode);
15548   operands[3] = gen_reg_rtx (XFmode);
15549   operands[4] = gen_reg_rtx (XFmode);
15550
15551   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15552   emit_move_insn (operands[3], temp);
15553 })
15554
15555 (define_expand "log10xf2"
15556   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15557                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15558                                (match_dup 2)] UNSPEC_FYL2X))
15559               (clobber (match_scratch:XF 3 ""))])]
15560   "TARGET_USE_FANCY_MATH_387
15561    && flag_unsafe_math_optimizations"
15562 {
15563   rtx temp;
15564
15565   operands[2] = gen_reg_rtx (XFmode);
15566   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15567   emit_move_insn (operands[2], temp);
15568 })
15569
15570 (define_expand "log2sf2"
15571   [(set (match_dup 2)
15572         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15573    (parallel [(set (match_dup 4)
15574                    (unspec:XF [(match_dup 2)
15575                                (match_dup 3)] UNSPEC_FYL2X))
15576               (clobber (match_scratch:XF 5 ""))])
15577    (set (match_operand:SF 0 "register_operand" "")
15578         (float_truncate:SF (match_dup 4)))]
15579   "TARGET_USE_FANCY_MATH_387
15580    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15581    && flag_unsafe_math_optimizations"
15582 {
15583   operands[2] = gen_reg_rtx (XFmode);
15584   operands[3] = gen_reg_rtx (XFmode);
15585   operands[4] = gen_reg_rtx (XFmode);
15586
15587   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15588 })
15589
15590 (define_expand "log2df2"
15591   [(set (match_dup 2)
15592         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15593    (parallel [(set (match_dup 4)
15594                    (unspec:XF [(match_dup 2)
15595                                (match_dup 3)] UNSPEC_FYL2X))
15596               (clobber (match_scratch:XF 5 ""))])
15597    (set (match_operand:DF 0 "register_operand" "")
15598         (float_truncate:DF (match_dup 4)))]
15599   "TARGET_USE_FANCY_MATH_387
15600    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15601    && flag_unsafe_math_optimizations"
15602 {
15603   operands[2] = gen_reg_rtx (XFmode);
15604   operands[3] = gen_reg_rtx (XFmode);
15605   operands[4] = gen_reg_rtx (XFmode);
15606
15607   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15608 })
15609
15610 (define_expand "log2xf2"
15611   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15612                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15613                                (match_dup 2)] UNSPEC_FYL2X))
15614               (clobber (match_scratch:XF 3 ""))])]
15615   "TARGET_USE_FANCY_MATH_387
15616    && flag_unsafe_math_optimizations"
15617 {
15618   operands[2] = gen_reg_rtx (XFmode);
15619   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15620 })
15621
15622 (define_insn "fyl2xp1_xf3"
15623   [(set (match_operand:XF 0 "register_operand" "=f")
15624         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15625                     (match_operand:XF 1 "register_operand" "u")]
15626                    UNSPEC_FYL2XP1))
15627    (clobber (match_scratch:XF 3 "=1"))]
15628   "TARGET_USE_FANCY_MATH_387
15629    && flag_unsafe_math_optimizations"
15630   "fyl2xp1"
15631   [(set_attr "type" "fpspc")
15632    (set_attr "mode" "XF")])
15633
15634 (define_expand "log1psf2"
15635   [(use (match_operand:SF 0 "register_operand" ""))
15636    (use (match_operand:SF 1 "register_operand" ""))]
15637   "TARGET_USE_FANCY_MATH_387
15638    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15639    && flag_unsafe_math_optimizations"
15640 {
15641   rtx op0 = gen_reg_rtx (XFmode);
15642   rtx op1 = gen_reg_rtx (XFmode);
15643
15644   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15645   ix86_emit_i387_log1p (op0, op1);
15646   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15647   DONE;
15648 })
15649
15650 (define_expand "log1pdf2"
15651   [(use (match_operand:DF 0 "register_operand" ""))
15652    (use (match_operand:DF 1 "register_operand" ""))]
15653   "TARGET_USE_FANCY_MATH_387
15654    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15655    && flag_unsafe_math_optimizations"
15656 {
15657   rtx op0 = gen_reg_rtx (XFmode);
15658   rtx op1 = gen_reg_rtx (XFmode);
15659
15660   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15661   ix86_emit_i387_log1p (op0, op1);
15662   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15663   DONE;
15664 })
15665
15666 (define_expand "log1pxf2"
15667   [(use (match_operand:XF 0 "register_operand" ""))
15668    (use (match_operand:XF 1 "register_operand" ""))]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15671 {
15672   ix86_emit_i387_log1p (operands[0], operands[1]);
15673   DONE;
15674 })
15675
15676 (define_insn "*fxtractxf3"
15677   [(set (match_operand:XF 0 "register_operand" "=f")
15678         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15679                    UNSPEC_XTRACT_FRACT))
15680    (set (match_operand:XF 1 "register_operand" "=u")
15681         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15684   "fxtract"
15685   [(set_attr "type" "fpspc")
15686    (set_attr "mode" "XF")])
15687
15688 (define_expand "logbsf2"
15689   [(set (match_dup 2)
15690         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15691    (parallel [(set (match_dup 3)
15692                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15693               (set (match_dup 4)
15694                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15695    (set (match_operand:SF 0 "register_operand" "")
15696         (float_truncate:SF (match_dup 4)))]
15697   "TARGET_USE_FANCY_MATH_387
15698    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15699    && flag_unsafe_math_optimizations"
15700 {
15701   operands[2] = gen_reg_rtx (XFmode);
15702   operands[3] = gen_reg_rtx (XFmode);
15703   operands[4] = gen_reg_rtx (XFmode);
15704 })
15705
15706 (define_expand "logbdf2"
15707   [(set (match_dup 2)
15708         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15709    (parallel [(set (match_dup 3)
15710                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15711               (set (match_dup 4)
15712                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15713    (set (match_operand:DF 0 "register_operand" "")
15714         (float_truncate:DF (match_dup 4)))]
15715   "TARGET_USE_FANCY_MATH_387
15716    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15717    && flag_unsafe_math_optimizations"
15718 {
15719   operands[2] = gen_reg_rtx (XFmode);
15720   operands[3] = gen_reg_rtx (XFmode);
15721   operands[4] = gen_reg_rtx (XFmode);
15722 })
15723
15724 (define_expand "logbxf2"
15725   [(parallel [(set (match_dup 2)
15726                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15727                               UNSPEC_XTRACT_FRACT))
15728               (set (match_operand:XF 0 "register_operand" "")
15729                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15732 {
15733   operands[2] = gen_reg_rtx (XFmode);
15734 })
15735
15736 (define_expand "ilogbsi2"
15737   [(parallel [(set (match_dup 2)
15738                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15739                               UNSPEC_XTRACT_FRACT))
15740               (set (match_operand:XF 3 "register_operand" "")
15741                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15742    (parallel [(set (match_operand:SI 0 "register_operand" "")
15743                    (fix:SI (match_dup 3)))
15744               (clobber (reg:CC FLAGS_REG))])]
15745   "TARGET_USE_FANCY_MATH_387
15746    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15747    && flag_unsafe_math_optimizations"
15748 {
15749   operands[2] = gen_reg_rtx (XFmode);
15750   operands[3] = gen_reg_rtx (XFmode);
15751 })
15752
15753 (define_insn "*f2xm1xf2"
15754   [(set (match_operand:XF 0 "register_operand" "=f")
15755         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15756          UNSPEC_F2XM1))]
15757   "TARGET_USE_FANCY_MATH_387
15758    && flag_unsafe_math_optimizations"
15759   "f2xm1"
15760   [(set_attr "type" "fpspc")
15761    (set_attr "mode" "XF")])
15762
15763 (define_insn "*fscalexf4"
15764   [(set (match_operand:XF 0 "register_operand" "=f")
15765         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15766                     (match_operand:XF 3 "register_operand" "1")]
15767                    UNSPEC_FSCALE_FRACT))
15768    (set (match_operand:XF 1 "register_operand" "=u")
15769         (unspec:XF [(match_dup 2) (match_dup 3)]
15770                    UNSPEC_FSCALE_EXP))]
15771   "TARGET_USE_FANCY_MATH_387
15772    && flag_unsafe_math_optimizations"
15773   "fscale"
15774   [(set_attr "type" "fpspc")
15775    (set_attr "mode" "XF")])
15776
15777 (define_expand "expsf2"
15778   [(set (match_dup 2)
15779         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15780    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15781    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15782    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15783    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15784    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15785    (parallel [(set (match_dup 10)
15786                    (unspec:XF [(match_dup 9) (match_dup 5)]
15787                               UNSPEC_FSCALE_FRACT))
15788               (set (match_dup 11)
15789                    (unspec:XF [(match_dup 9) (match_dup 5)]
15790                               UNSPEC_FSCALE_EXP))])
15791    (set (match_operand:SF 0 "register_operand" "")
15792         (float_truncate:SF (match_dup 10)))]
15793   "TARGET_USE_FANCY_MATH_387
15794    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15795    && flag_unsafe_math_optimizations"
15796 {
15797   rtx temp;
15798   int i;
15799
15800   for (i=2; i<12; i++)
15801     operands[i] = gen_reg_rtx (XFmode);
15802   temp = standard_80387_constant_rtx (5); /* fldl2e */
15803   emit_move_insn (operands[3], temp);
15804   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15805 })
15806
15807 (define_expand "expdf2"
15808   [(set (match_dup 2)
15809         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15810    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15811    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15812    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15813    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15814    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15815    (parallel [(set (match_dup 10)
15816                    (unspec:XF [(match_dup 9) (match_dup 5)]
15817                               UNSPEC_FSCALE_FRACT))
15818               (set (match_dup 11)
15819                    (unspec:XF [(match_dup 9) (match_dup 5)]
15820                               UNSPEC_FSCALE_EXP))])
15821    (set (match_operand:DF 0 "register_operand" "")
15822         (float_truncate:DF (match_dup 10)))]
15823   "TARGET_USE_FANCY_MATH_387
15824    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15825    && flag_unsafe_math_optimizations"
15826 {
15827   rtx temp;
15828   int i;
15829
15830   for (i=2; i<12; i++)
15831     operands[i] = gen_reg_rtx (XFmode);
15832   temp = standard_80387_constant_rtx (5); /* fldl2e */
15833   emit_move_insn (operands[3], temp);
15834   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15835 })
15836
15837 (define_expand "expxf2"
15838   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15839                                (match_dup 2)))
15840    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15841    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15842    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15843    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15844    (parallel [(set (match_operand:XF 0 "register_operand" "")
15845                    (unspec:XF [(match_dup 8) (match_dup 4)]
15846                               UNSPEC_FSCALE_FRACT))
15847               (set (match_dup 9)
15848                    (unspec:XF [(match_dup 8) (match_dup 4)]
15849                               UNSPEC_FSCALE_EXP))])]
15850   "TARGET_USE_FANCY_MATH_387
15851    && flag_unsafe_math_optimizations"
15852 {
15853   rtx temp;
15854   int i;
15855
15856   for (i=2; i<10; i++)
15857     operands[i] = gen_reg_rtx (XFmode);
15858   temp = standard_80387_constant_rtx (5); /* fldl2e */
15859   emit_move_insn (operands[2], temp);
15860   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15861 })
15862
15863 (define_expand "exp10sf2"
15864   [(set (match_dup 2)
15865         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15866    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15867    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15868    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15869    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15870    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15871    (parallel [(set (match_dup 10)
15872                    (unspec:XF [(match_dup 9) (match_dup 5)]
15873                               UNSPEC_FSCALE_FRACT))
15874               (set (match_dup 11)
15875                    (unspec:XF [(match_dup 9) (match_dup 5)]
15876                               UNSPEC_FSCALE_EXP))])
15877    (set (match_operand:SF 0 "register_operand" "")
15878         (float_truncate:SF (match_dup 10)))]
15879   "TARGET_USE_FANCY_MATH_387
15880    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15881    && flag_unsafe_math_optimizations"
15882 {
15883   rtx temp;
15884   int i;
15885
15886   for (i=2; i<12; i++)
15887     operands[i] = gen_reg_rtx (XFmode);
15888   temp = standard_80387_constant_rtx (6); /* fldl2t */
15889   emit_move_insn (operands[3], temp);
15890   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15891 })
15892
15893 (define_expand "exp10df2"
15894   [(set (match_dup 2)
15895         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15896    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15897    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15898    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15899    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15900    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15901    (parallel [(set (match_dup 10)
15902                    (unspec:XF [(match_dup 9) (match_dup 5)]
15903                               UNSPEC_FSCALE_FRACT))
15904               (set (match_dup 11)
15905                    (unspec:XF [(match_dup 9) (match_dup 5)]
15906                               UNSPEC_FSCALE_EXP))])
15907    (set (match_operand:DF 0 "register_operand" "")
15908         (float_truncate:DF (match_dup 10)))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15911    && flag_unsafe_math_optimizations"
15912 {
15913   rtx temp;
15914   int i;
15915
15916   for (i=2; i<12; i++)
15917     operands[i] = gen_reg_rtx (XFmode);
15918   temp = standard_80387_constant_rtx (6); /* fldl2t */
15919   emit_move_insn (operands[3], temp);
15920   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15921 })
15922
15923 (define_expand "exp10xf2"
15924   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15925                                (match_dup 2)))
15926    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15927    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15928    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15929    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15930    (parallel [(set (match_operand:XF 0 "register_operand" "")
15931                    (unspec:XF [(match_dup 8) (match_dup 4)]
15932                               UNSPEC_FSCALE_FRACT))
15933               (set (match_dup 9)
15934                    (unspec:XF [(match_dup 8) (match_dup 4)]
15935                               UNSPEC_FSCALE_EXP))])]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15938 {
15939   rtx temp;
15940   int i;
15941
15942   for (i=2; i<10; i++)
15943     operands[i] = gen_reg_rtx (XFmode);
15944   temp = standard_80387_constant_rtx (6); /* fldl2t */
15945   emit_move_insn (operands[2], temp);
15946   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15947 })
15948
15949 (define_expand "exp2sf2"
15950   [(set (match_dup 2)
15951         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15952    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15953    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15954    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15955    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15956    (parallel [(set (match_dup 8)
15957                    (unspec:XF [(match_dup 7) (match_dup 3)]
15958                               UNSPEC_FSCALE_FRACT))
15959               (set (match_dup 9)
15960                    (unspec:XF [(match_dup 7) (match_dup 3)]
15961                               UNSPEC_FSCALE_EXP))])
15962    (set (match_operand:SF 0 "register_operand" "")
15963         (float_truncate:SF (match_dup 8)))]
15964   "TARGET_USE_FANCY_MATH_387
15965    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15966    && flag_unsafe_math_optimizations"
15967 {
15968   int i;
15969
15970   for (i=2; i<10; i++)
15971     operands[i] = gen_reg_rtx (XFmode);
15972   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15973 })
15974
15975 (define_expand "exp2df2"
15976   [(set (match_dup 2)
15977         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15978    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15979    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15981    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15982    (parallel [(set (match_dup 8)
15983                    (unspec:XF [(match_dup 7) (match_dup 3)]
15984                               UNSPEC_FSCALE_FRACT))
15985               (set (match_dup 9)
15986                    (unspec:XF [(match_dup 7) (match_dup 3)]
15987                               UNSPEC_FSCALE_EXP))])
15988    (set (match_operand:DF 0 "register_operand" "")
15989         (float_truncate:DF (match_dup 8)))]
15990   "TARGET_USE_FANCY_MATH_387
15991    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15992    && flag_unsafe_math_optimizations"
15993 {
15994   int i;
15995
15996   for (i=2; i<10; i++)
15997     operands[i] = gen_reg_rtx (XFmode);
15998   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15999 })
16000
16001 (define_expand "exp2xf2"
16002   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16003    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16004    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16005    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16006    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16007    (parallel [(set (match_operand:XF 0 "register_operand" "")
16008                    (unspec:XF [(match_dup 7) (match_dup 3)]
16009                               UNSPEC_FSCALE_FRACT))
16010               (set (match_dup 8)
16011                    (unspec:XF [(match_dup 7) (match_dup 3)]
16012                               UNSPEC_FSCALE_EXP))])]
16013   "TARGET_USE_FANCY_MATH_387
16014    && flag_unsafe_math_optimizations"
16015 {
16016   int i;
16017
16018   for (i=2; i<9; i++)
16019     operands[i] = gen_reg_rtx (XFmode);
16020   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16021 })
16022
16023 (define_expand "expm1df2"
16024   [(set (match_dup 2)
16025         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16027    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16028    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16029    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16030    (parallel [(set (match_dup 8)
16031                    (unspec:XF [(match_dup 7) (match_dup 5)]
16032                               UNSPEC_FSCALE_FRACT))
16033                    (set (match_dup 9)
16034                    (unspec:XF [(match_dup 7) (match_dup 5)]
16035                               UNSPEC_FSCALE_EXP))])
16036    (parallel [(set (match_dup 11)
16037                    (unspec:XF [(match_dup 10) (match_dup 9)]
16038                               UNSPEC_FSCALE_FRACT))
16039               (set (match_dup 12)
16040                    (unspec:XF [(match_dup 10) (match_dup 9)]
16041                               UNSPEC_FSCALE_EXP))])
16042    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16043    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16044    (set (match_operand:DF 0 "register_operand" "")
16045         (float_truncate:DF (match_dup 14)))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048    && flag_unsafe_math_optimizations"
16049 {
16050   rtx temp;
16051   int i;
16052
16053   for (i=2; i<15; i++)
16054     operands[i] = gen_reg_rtx (XFmode);
16055   temp = standard_80387_constant_rtx (5); /* fldl2e */
16056   emit_move_insn (operands[3], temp);
16057   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16058 })
16059
16060 (define_expand "expm1sf2"
16061   [(set (match_dup 2)
16062         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16063    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16064    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16065    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16066    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16067    (parallel [(set (match_dup 8)
16068                    (unspec:XF [(match_dup 7) (match_dup 5)]
16069                               UNSPEC_FSCALE_FRACT))
16070                    (set (match_dup 9)
16071                    (unspec:XF [(match_dup 7) (match_dup 5)]
16072                               UNSPEC_FSCALE_EXP))])
16073    (parallel [(set (match_dup 11)
16074                    (unspec:XF [(match_dup 10) (match_dup 9)]
16075                               UNSPEC_FSCALE_FRACT))
16076               (set (match_dup 12)
16077                    (unspec:XF [(match_dup 10) (match_dup 9)]
16078                               UNSPEC_FSCALE_EXP))])
16079    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16080    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16081    (set (match_operand:SF 0 "register_operand" "")
16082         (float_truncate:SF (match_dup 14)))]
16083   "TARGET_USE_FANCY_MATH_387
16084    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16085    && flag_unsafe_math_optimizations"
16086 {
16087   rtx temp;
16088   int i;
16089
16090   for (i=2; i<15; i++)
16091     operands[i] = gen_reg_rtx (XFmode);
16092   temp = standard_80387_constant_rtx (5); /* fldl2e */
16093   emit_move_insn (operands[3], temp);
16094   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16095 })
16096
16097 (define_expand "expm1xf2"
16098   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16099                                (match_dup 2)))
16100    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16101    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16102    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16103    (parallel [(set (match_dup 7)
16104                    (unspec:XF [(match_dup 6) (match_dup 4)]
16105                               UNSPEC_FSCALE_FRACT))
16106                    (set (match_dup 8)
16107                    (unspec:XF [(match_dup 6) (match_dup 4)]
16108                               UNSPEC_FSCALE_EXP))])
16109    (parallel [(set (match_dup 10)
16110                    (unspec:XF [(match_dup 9) (match_dup 8)]
16111                               UNSPEC_FSCALE_FRACT))
16112               (set (match_dup 11)
16113                    (unspec:XF [(match_dup 9) (match_dup 8)]
16114                               UNSPEC_FSCALE_EXP))])
16115    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16116    (set (match_operand:XF 0 "register_operand" "")
16117         (plus:XF (match_dup 12) (match_dup 7)))]
16118   "TARGET_USE_FANCY_MATH_387
16119    && flag_unsafe_math_optimizations"
16120 {
16121   rtx temp;
16122   int i;
16123
16124   for (i=2; i<13; i++)
16125     operands[i] = gen_reg_rtx (XFmode);
16126   temp = standard_80387_constant_rtx (5); /* fldl2e */
16127   emit_move_insn (operands[2], temp);
16128   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16129 })
16130
16131 (define_expand "ldexpdf3"
16132   [(set (match_dup 3)
16133         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16134    (set (match_dup 4)
16135         (float:XF (match_operand:SI 2 "register_operand" "")))
16136    (parallel [(set (match_dup 5)
16137                    (unspec:XF [(match_dup 3) (match_dup 4)]
16138                               UNSPEC_FSCALE_FRACT))
16139               (set (match_dup 6)
16140                    (unspec:XF [(match_dup 3) (match_dup 4)]
16141                               UNSPEC_FSCALE_EXP))])
16142    (set (match_operand:DF 0 "register_operand" "")
16143         (float_truncate:DF (match_dup 5)))]
16144   "TARGET_USE_FANCY_MATH_387
16145    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16146    && flag_unsafe_math_optimizations"
16147 {
16148   int i;
16149
16150   for (i=3; i<7; i++)
16151     operands[i] = gen_reg_rtx (XFmode);
16152 })
16153
16154 (define_expand "ldexpsf3"
16155   [(set (match_dup 3)
16156         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16157    (set (match_dup 4)
16158         (float:XF (match_operand:SI 2 "register_operand" "")))
16159    (parallel [(set (match_dup 5)
16160                    (unspec:XF [(match_dup 3) (match_dup 4)]
16161                               UNSPEC_FSCALE_FRACT))
16162               (set (match_dup 6)
16163                    (unspec:XF [(match_dup 3) (match_dup 4)]
16164                               UNSPEC_FSCALE_EXP))])
16165    (set (match_operand:SF 0 "register_operand" "")
16166         (float_truncate:SF (match_dup 5)))]
16167   "TARGET_USE_FANCY_MATH_387
16168    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16169    && flag_unsafe_math_optimizations"
16170 {
16171   int i;
16172
16173   for (i=3; i<7; i++)
16174     operands[i] = gen_reg_rtx (XFmode);
16175 })
16176
16177 (define_expand "ldexpxf3"
16178   [(set (match_dup 3)
16179         (float:XF (match_operand:SI 2 "register_operand" "")))
16180    (parallel [(set (match_operand:XF 0 " register_operand" "")
16181                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16182                                (match_dup 3)]
16183                               UNSPEC_FSCALE_FRACT))
16184               (set (match_dup 4)
16185                    (unspec:XF [(match_dup 1) (match_dup 3)]
16186                               UNSPEC_FSCALE_EXP))])]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189 {
16190   int i;
16191
16192   for (i=3; i<5; i++)
16193     operands[i] = gen_reg_rtx (XFmode);
16194 })
16195 \f
16196
16197 (define_insn "frndintxf2"
16198   [(set (match_operand:XF 0 "register_operand" "=f")
16199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16200          UNSPEC_FRNDINT))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && flag_unsafe_math_optimizations"
16203   "frndint"
16204   [(set_attr "type" "fpspc")
16205    (set_attr "mode" "XF")])
16206
16207 (define_expand "rintdf2"
16208   [(use (match_operand:DF 0 "register_operand" ""))
16209    (use (match_operand:DF 1 "register_operand" ""))]
16210   "TARGET_USE_FANCY_MATH_387
16211    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16212    && flag_unsafe_math_optimizations"
16213 {
16214   rtx op0 = gen_reg_rtx (XFmode);
16215   rtx op1 = gen_reg_rtx (XFmode);
16216
16217   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16218   emit_insn (gen_frndintxf2 (op0, op1));
16219
16220   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16221   DONE;
16222 })
16223
16224 (define_expand "rintsf2"
16225   [(use (match_operand:SF 0 "register_operand" ""))
16226    (use (match_operand:SF 1 "register_operand" ""))]
16227   "TARGET_USE_FANCY_MATH_387
16228    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16229    && flag_unsafe_math_optimizations"
16230 {
16231   rtx op0 = gen_reg_rtx (XFmode);
16232   rtx op1 = gen_reg_rtx (XFmode);
16233
16234   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16235   emit_insn (gen_frndintxf2 (op0, op1));
16236
16237   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16238   DONE;
16239 })
16240
16241 (define_expand "rintxf2"
16242   [(use (match_operand:XF 0 "register_operand" ""))
16243    (use (match_operand:XF 1 "register_operand" ""))]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16246 {
16247   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16248   DONE;
16249 })
16250
16251 (define_insn "fistdi2"
16252   [(set (match_operand:DI 0 "memory_operand" "=m")
16253         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16254          UNSPEC_FIST))
16255    (clobber (match_scratch:XF 2 "=&1f"))]
16256   "TARGET_USE_FANCY_MATH_387
16257    && flag_unsafe_math_optimizations"
16258   "* return output_fix_trunc (insn, operands, 0);"
16259   [(set_attr "type" "fpspc")
16260    (set_attr "mode" "DI")])
16261
16262 (define_insn "fistdi2_with_temp"
16263   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16264         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16265          UNSPEC_FIST))
16266    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16267    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16268   "TARGET_USE_FANCY_MATH_387
16269    && flag_unsafe_math_optimizations"
16270   "#"
16271   [(set_attr "type" "fpspc")
16272    (set_attr "mode" "DI")])
16273
16274 (define_split 
16275   [(set (match_operand:DI 0 "register_operand" "")
16276         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16277          UNSPEC_FIST))
16278    (clobber (match_operand:DI 2 "memory_operand" ""))
16279    (clobber (match_scratch 3 ""))]
16280   "reload_completed"
16281   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16282               (clobber (match_dup 3))])
16283    (set (match_dup 0) (match_dup 2))]
16284   "")
16285
16286 (define_split 
16287   [(set (match_operand:DI 0 "memory_operand" "")
16288         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16289          UNSPEC_FIST))
16290    (clobber (match_operand:DI 2 "memory_operand" ""))
16291    (clobber (match_scratch 3 ""))]
16292   "reload_completed"
16293   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16294               (clobber (match_dup 3))])]
16295   "")
16296
16297 (define_insn "fist<mode>2"
16298   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16299         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16300          UNSPEC_FIST))]
16301   "TARGET_USE_FANCY_MATH_387
16302    && flag_unsafe_math_optimizations"
16303   "* return output_fix_trunc (insn, operands, 0);"
16304   [(set_attr "type" "fpspc")
16305    (set_attr "mode" "<MODE>")])
16306
16307 (define_insn "fist<mode>2_with_temp"
16308   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16310          UNSPEC_FIST))
16311    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16312   "TARGET_USE_FANCY_MATH_387
16313    && flag_unsafe_math_optimizations"
16314   "#"
16315   [(set_attr "type" "fpspc")
16316    (set_attr "mode" "<MODE>")])
16317
16318 (define_split 
16319   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16320         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16321          UNSPEC_FIST))
16322    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16323   "reload_completed"
16324   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16325                        UNSPEC_FIST))
16326    (set (match_dup 0) (match_dup 2))]
16327   "")
16328
16329 (define_split 
16330   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16331         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16332          UNSPEC_FIST))
16333    (clobber (match_scratch 2 ""))]
16334   "reload_completed"
16335   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16336                        UNSPEC_FIST))]
16337   "")
16338
16339 (define_expand "lrint<mode>2"
16340   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16341    (use (match_operand:XF 1 "register_operand" ""))]
16342   "TARGET_USE_FANCY_MATH_387
16343    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16344    && flag_unsafe_math_optimizations"
16345 {
16346   if (memory_operand (operands[0], VOIDmode))
16347     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16348   else
16349     {
16350       operands[2] = assign_386_stack_local (<MODE>mode, 0);
16351       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16352                                             operands[2]));
16353     }
16354   DONE;
16355 })
16356
16357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16358 (define_insn_and_split "frndintxf2_floor"
16359   [(set (match_operand:XF 0 "register_operand" "=f")
16360         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16361          UNSPEC_FRNDINT_FLOOR))
16362    (clobber (reg:CC FLAGS_REG))]
16363   "TARGET_USE_FANCY_MATH_387
16364    && flag_unsafe_math_optimizations
16365    && !(reload_completed || reload_in_progress)"
16366   "#"
16367   "&& 1"
16368   [(const_int 0)]
16369 {
16370   ix86_optimize_mode_switching = 1;
16371
16372   operands[2] = assign_386_stack_local (HImode, 1);
16373   operands[3] = assign_386_stack_local (HImode, 2);
16374
16375   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16376                                         operands[2], operands[3]));
16377   DONE;
16378 }
16379   [(set_attr "type" "frndint")
16380    (set_attr "i387_cw" "floor")
16381    (set_attr "mode" "XF")])
16382
16383 (define_insn "frndintxf2_floor_i387"
16384   [(set (match_operand:XF 0 "register_operand" "=f")
16385         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16386          UNSPEC_FRNDINT_FLOOR))
16387    (use (match_operand:HI 2 "memory_operand" "m"))
16388    (use (match_operand:HI 3 "memory_operand" "m"))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && flag_unsafe_math_optimizations"
16391   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16392   [(set_attr "type" "frndint")
16393    (set_attr "i387_cw" "floor")
16394    (set_attr "mode" "XF")])
16395
16396 (define_expand "floorxf2"
16397   [(use (match_operand:XF 0 "register_operand" ""))
16398    (use (match_operand:XF 1 "register_operand" ""))]
16399   "TARGET_USE_FANCY_MATH_387
16400    && flag_unsafe_math_optimizations"
16401 {
16402   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16403   DONE;
16404 })
16405
16406 (define_expand "floordf2"
16407   [(use (match_operand:DF 0 "register_operand" ""))
16408    (use (match_operand:DF 1 "register_operand" ""))]
16409   "TARGET_USE_FANCY_MATH_387
16410    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16411    && flag_unsafe_math_optimizations"
16412 {
16413   rtx op0 = gen_reg_rtx (XFmode);
16414   rtx op1 = gen_reg_rtx (XFmode);
16415
16416   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16417   emit_insn (gen_frndintxf2_floor (op0, op1));
16418
16419   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16420   DONE;
16421 })
16422
16423 (define_expand "floorsf2"
16424   [(use (match_operand:SF 0 "register_operand" ""))
16425    (use (match_operand:SF 1 "register_operand" ""))]
16426   "TARGET_USE_FANCY_MATH_387
16427    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16428    && flag_unsafe_math_optimizations"
16429 {
16430   rtx op0 = gen_reg_rtx (XFmode);
16431   rtx op1 = gen_reg_rtx (XFmode);
16432
16433   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16434   emit_insn (gen_frndintxf2_floor (op0, op1));
16435
16436   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16437   DONE;
16438 })
16439
16440 (define_insn_and_split "*fist<mode>2_floor_1"
16441   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16442         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16443          UNSPEC_FIST_FLOOR))
16444    (clobber (reg:CC FLAGS_REG))]
16445   "TARGET_USE_FANCY_MATH_387
16446    && flag_unsafe_math_optimizations
16447    && !(reload_completed || reload_in_progress)"
16448   "#"
16449   "&& 1"
16450   [(const_int 0)]
16451 {
16452   ix86_optimize_mode_switching = 1;
16453   operands[2] = assign_386_stack_local (HImode, 1);
16454   operands[3] = assign_386_stack_local (HImode, 2);
16455   if (memory_operand (operands[0], VOIDmode))
16456     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16457                                       operands[2], operands[3]));
16458   else
16459     {
16460       operands[4] = assign_386_stack_local (<MODE>mode, 0);
16461       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16462                                                   operands[2], operands[3],
16463                                                   operands[4]));
16464     }
16465   DONE;
16466 }
16467   [(set_attr "type" "fistp")
16468    (set_attr "i387_cw" "floor")
16469    (set_attr "mode" "<MODE>")])
16470
16471 (define_insn "fistdi2_floor"
16472   [(set (match_operand:DI 0 "memory_operand" "=m")
16473         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16474          UNSPEC_FIST_FLOOR))
16475    (use (match_operand:HI 2 "memory_operand" "m"))
16476    (use (match_operand:HI 3 "memory_operand" "m"))
16477    (clobber (match_scratch:XF 4 "=&1f"))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && flag_unsafe_math_optimizations"
16480   "* return output_fix_trunc (insn, operands, 0);"
16481   [(set_attr "type" "fistp")
16482    (set_attr "i387_cw" "floor")
16483    (set_attr "mode" "DI")])
16484
16485 (define_insn "fistdi2_floor_with_temp"
16486   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16487         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16488          UNSPEC_FIST_FLOOR))
16489    (use (match_operand:HI 2 "memory_operand" "m,m"))
16490    (use (match_operand:HI 3 "memory_operand" "m,m"))
16491    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16492    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16493   "TARGET_USE_FANCY_MATH_387
16494    && flag_unsafe_math_optimizations"
16495   "#"
16496   [(set_attr "type" "fistp")
16497    (set_attr "i387_cw" "floor")
16498    (set_attr "mode" "DI")])
16499
16500 (define_split 
16501   [(set (match_operand:DI 0 "register_operand" "")
16502         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16503          UNSPEC_FIST_FLOOR))
16504    (use (match_operand:HI 2 "memory_operand" ""))
16505    (use (match_operand:HI 3 "memory_operand" ""))
16506    (clobber (match_operand:DI 4 "memory_operand" ""))
16507    (clobber (match_scratch 5 ""))]
16508   "reload_completed"
16509   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16510               (use (match_dup 2))
16511               (use (match_dup 3))
16512               (clobber (match_dup 5))])
16513    (set (match_dup 0) (match_dup 4))]
16514   "")
16515
16516 (define_split 
16517   [(set (match_operand:DI 0 "memory_operand" "")
16518         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16519          UNSPEC_FIST_FLOOR))
16520    (use (match_operand:HI 2 "memory_operand" ""))
16521    (use (match_operand:HI 3 "memory_operand" ""))
16522    (clobber (match_operand:DI 4 "memory_operand" ""))
16523    (clobber (match_scratch 5 ""))]
16524   "reload_completed"
16525   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16526               (use (match_dup 2))
16527               (use (match_dup 3))
16528               (clobber (match_dup 5))])]
16529   "")
16530
16531 (define_insn "fist<mode>2_floor"
16532   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16533         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16534          UNSPEC_FIST_FLOOR))
16535    (use (match_operand:HI 2 "memory_operand" "m"))
16536    (use (match_operand:HI 3 "memory_operand" "m"))]
16537   "TARGET_USE_FANCY_MATH_387
16538    && flag_unsafe_math_optimizations"
16539   "* return output_fix_trunc (insn, operands, 0);"
16540   [(set_attr "type" "fistp")
16541    (set_attr "i387_cw" "floor")
16542    (set_attr "mode" "<MODE>")])
16543
16544 (define_insn "fist<mode>2_floor_with_temp"
16545   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16546         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16547          UNSPEC_FIST_FLOOR))
16548    (use (match_operand:HI 2 "memory_operand" "m,m"))
16549    (use (match_operand:HI 3 "memory_operand" "m,m"))
16550    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && flag_unsafe_math_optimizations"
16553   "#"
16554   [(set_attr "type" "fistp")
16555    (set_attr "i387_cw" "floor")
16556    (set_attr "mode" "<MODE>")])
16557
16558 (define_split 
16559   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16560         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16561          UNSPEC_FIST_FLOOR))
16562    (use (match_operand:HI 2 "memory_operand" ""))
16563    (use (match_operand:HI 3 "memory_operand" ""))
16564    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16565   "reload_completed"
16566   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16567                                   UNSPEC_FIST_FLOOR))
16568               (use (match_dup 2))
16569               (use (match_dup 3))])
16570    (set (match_dup 0) (match_dup 4))]
16571   "")
16572
16573 (define_split 
16574   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16575         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16576          UNSPEC_FIST_FLOOR))
16577    (use (match_operand:HI 2 "memory_operand" ""))
16578    (use (match_operand:HI 3 "memory_operand" ""))
16579    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16580   "reload_completed"
16581   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16582                                   UNSPEC_FIST_FLOOR))
16583               (use (match_dup 2))
16584               (use (match_dup 3))])]
16585   "")
16586
16587 (define_expand "lfloor<mode>2"
16588   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16589                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16590                     UNSPEC_FIST_FLOOR))
16591               (clobber (reg:CC FLAGS_REG))])]
16592   "TARGET_USE_FANCY_MATH_387
16593    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16594    && flag_unsafe_math_optimizations"
16595   "")
16596
16597 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16598 (define_insn_and_split "frndintxf2_ceil"
16599   [(set (match_operand:XF 0 "register_operand" "=f")
16600         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16601          UNSPEC_FRNDINT_CEIL))
16602    (clobber (reg:CC FLAGS_REG))]
16603   "TARGET_USE_FANCY_MATH_387
16604    && flag_unsafe_math_optimizations
16605    && !(reload_completed || reload_in_progress)"
16606   "#"
16607   "&& 1"
16608   [(const_int 0)]
16609 {
16610   ix86_optimize_mode_switching = 1;
16611
16612   operands[2] = assign_386_stack_local (HImode, 1);
16613   operands[3] = assign_386_stack_local (HImode, 2);
16614
16615   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16616                                        operands[2], operands[3]));
16617   DONE;
16618 }
16619   [(set_attr "type" "frndint")
16620    (set_attr "i387_cw" "ceil")
16621    (set_attr "mode" "XF")])
16622
16623 (define_insn "frndintxf2_ceil_i387"
16624   [(set (match_operand:XF 0 "register_operand" "=f")
16625         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16626          UNSPEC_FRNDINT_CEIL))
16627    (use (match_operand:HI 2 "memory_operand" "m"))
16628    (use (match_operand:HI 3 "memory_operand" "m"))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && flag_unsafe_math_optimizations"
16631   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16632   [(set_attr "type" "frndint")
16633    (set_attr "i387_cw" "ceil")
16634    (set_attr "mode" "XF")])
16635
16636 (define_expand "ceilxf2"
16637   [(use (match_operand:XF 0 "register_operand" ""))
16638    (use (match_operand:XF 1 "register_operand" ""))]
16639   "TARGET_USE_FANCY_MATH_387
16640    && flag_unsafe_math_optimizations"
16641 {
16642   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16643   DONE;
16644 })
16645
16646 (define_expand "ceildf2"
16647   [(use (match_operand:DF 0 "register_operand" ""))
16648    (use (match_operand:DF 1 "register_operand" ""))]
16649   "TARGET_USE_FANCY_MATH_387
16650    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16651    && flag_unsafe_math_optimizations"
16652 {
16653   rtx op0 = gen_reg_rtx (XFmode);
16654   rtx op1 = gen_reg_rtx (XFmode);
16655
16656   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16657   emit_insn (gen_frndintxf2_ceil (op0, op1));
16658
16659   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16660   DONE;
16661 })
16662
16663 (define_expand "ceilsf2"
16664   [(use (match_operand:SF 0 "register_operand" ""))
16665    (use (match_operand:SF 1 "register_operand" ""))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16668    && flag_unsafe_math_optimizations"
16669 {
16670   rtx op0 = gen_reg_rtx (XFmode);
16671   rtx op1 = gen_reg_rtx (XFmode);
16672
16673   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16674   emit_insn (gen_frndintxf2_ceil (op0, op1));
16675
16676   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16677   DONE;
16678 })
16679
16680 (define_insn_and_split "*fist<mode>2_ceil_1"
16681   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16682         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16683          UNSPEC_FIST_CEIL))
16684    (clobber (reg:CC FLAGS_REG))]
16685   "TARGET_USE_FANCY_MATH_387
16686    && flag_unsafe_math_optimizations
16687    && !(reload_completed || reload_in_progress)"
16688   "#"
16689   "&& 1"
16690   [(const_int 0)]
16691 {
16692   ix86_optimize_mode_switching = 1;
16693   operands[2] = assign_386_stack_local (HImode, 1);
16694   operands[3] = assign_386_stack_local (HImode, 2);
16695   if (memory_operand (operands[0], VOIDmode))
16696     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16697                                      operands[2], operands[3]));
16698   else
16699     {
16700       operands[4] = assign_386_stack_local (<MODE>mode, 0);
16701       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16702                                                  operands[2], operands[3],
16703                                                  operands[4]));
16704     }
16705   DONE;
16706 }
16707   [(set_attr "type" "fistp")
16708    (set_attr "i387_cw" "ceil")
16709    (set_attr "mode" "<MODE>")])
16710
16711 (define_insn "fistdi2_ceil"
16712   [(set (match_operand:DI 0 "memory_operand" "=m")
16713         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16714          UNSPEC_FIST_CEIL))
16715    (use (match_operand:HI 2 "memory_operand" "m"))
16716    (use (match_operand:HI 3 "memory_operand" "m"))
16717    (clobber (match_scratch:XF 4 "=&1f"))]
16718   "TARGET_USE_FANCY_MATH_387
16719    && flag_unsafe_math_optimizations"
16720   "* return output_fix_trunc (insn, operands, 0);"
16721   [(set_attr "type" "fistp")
16722    (set_attr "i387_cw" "ceil")
16723    (set_attr "mode" "DI")])
16724
16725 (define_insn "fistdi2_ceil_with_temp"
16726   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16727         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16728          UNSPEC_FIST_CEIL))
16729    (use (match_operand:HI 2 "memory_operand" "m,m"))
16730    (use (match_operand:HI 3 "memory_operand" "m,m"))
16731    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16732    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && flag_unsafe_math_optimizations"
16735   "#"
16736   [(set_attr "type" "fistp")
16737    (set_attr "i387_cw" "ceil")
16738    (set_attr "mode" "DI")])
16739
16740 (define_split 
16741   [(set (match_operand:DI 0 "register_operand" "")
16742         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16743          UNSPEC_FIST_CEIL))
16744    (use (match_operand:HI 2 "memory_operand" ""))
16745    (use (match_operand:HI 3 "memory_operand" ""))
16746    (clobber (match_operand:DI 4 "memory_operand" ""))
16747    (clobber (match_scratch 5 ""))]
16748   "reload_completed"
16749   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16750               (use (match_dup 2))
16751               (use (match_dup 3))
16752               (clobber (match_dup 5))])
16753    (set (match_dup 0) (match_dup 4))]
16754   "")
16755
16756 (define_split 
16757   [(set (match_operand:DI 0 "memory_operand" "")
16758         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16759          UNSPEC_FIST_CEIL))
16760    (use (match_operand:HI 2 "memory_operand" ""))
16761    (use (match_operand:HI 3 "memory_operand" ""))
16762    (clobber (match_operand:DI 4 "memory_operand" ""))
16763    (clobber (match_scratch 5 ""))]
16764   "reload_completed"
16765   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16766               (use (match_dup 2))
16767               (use (match_dup 3))
16768               (clobber (match_dup 5))])]
16769   "")
16770
16771 (define_insn "fist<mode>2_ceil"
16772   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16773         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16774          UNSPEC_FIST_CEIL))
16775    (use (match_operand:HI 2 "memory_operand" "m"))
16776    (use (match_operand:HI 3 "memory_operand" "m"))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && flag_unsafe_math_optimizations"
16779   "* return output_fix_trunc (insn, operands, 0);"
16780   [(set_attr "type" "fistp")
16781    (set_attr "i387_cw" "ceil")
16782    (set_attr "mode" "<MODE>")])
16783
16784 (define_insn "fist<mode>2_ceil_with_temp"
16785   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16786         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16787          UNSPEC_FIST_CEIL))
16788    (use (match_operand:HI 2 "memory_operand" "m,m"))
16789    (use (match_operand:HI 3 "memory_operand" "m,m"))
16790    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && flag_unsafe_math_optimizations"
16793   "#"
16794   [(set_attr "type" "fistp")
16795    (set_attr "i387_cw" "ceil")
16796    (set_attr "mode" "<MODE>")])
16797
16798 (define_split 
16799   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16800         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16801          UNSPEC_FIST_CEIL))
16802    (use (match_operand:HI 2 "memory_operand" ""))
16803    (use (match_operand:HI 3 "memory_operand" ""))
16804    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16805   "reload_completed"
16806   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16807                                   UNSPEC_FIST_CEIL))
16808               (use (match_dup 2))
16809               (use (match_dup 3))])
16810    (set (match_dup 0) (match_dup 4))]
16811   "")
16812
16813 (define_split 
16814   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16815         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16816          UNSPEC_FIST_CEIL))
16817    (use (match_operand:HI 2 "memory_operand" ""))
16818    (use (match_operand:HI 3 "memory_operand" ""))
16819    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16820   "reload_completed"
16821   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16822                                   UNSPEC_FIST_CEIL))
16823               (use (match_dup 2))
16824               (use (match_dup 3))])]
16825   "")
16826
16827 (define_expand "lceil<mode>2"
16828   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16829                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16830                     UNSPEC_FIST_CEIL))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834    && flag_unsafe_math_optimizations"
16835   "")
16836
16837 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16838 (define_insn_and_split "frndintxf2_trunc"
16839   [(set (match_operand:XF 0 "register_operand" "=f")
16840         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16841          UNSPEC_FRNDINT_TRUNC))
16842    (clobber (reg:CC FLAGS_REG))]
16843   "TARGET_USE_FANCY_MATH_387
16844    && flag_unsafe_math_optimizations
16845    && !(reload_completed || reload_in_progress)"
16846   "#"
16847   "&& 1"
16848   [(const_int 0)]
16849 {
16850   ix86_optimize_mode_switching = 1;
16851
16852   operands[2] = assign_386_stack_local (HImode, 1);
16853   operands[3] = assign_386_stack_local (HImode, 2);
16854
16855   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16856                                         operands[2], operands[3]));
16857   DONE;
16858 }
16859   [(set_attr "type" "frndint")
16860    (set_attr "i387_cw" "trunc")
16861    (set_attr "mode" "XF")])
16862
16863 (define_insn "frndintxf2_trunc_i387"
16864   [(set (match_operand:XF 0 "register_operand" "=f")
16865         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16866          UNSPEC_FRNDINT_TRUNC))
16867    (use (match_operand:HI 2 "memory_operand" "m"))
16868    (use (match_operand:HI 3 "memory_operand" "m"))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations"
16871   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16872   [(set_attr "type" "frndint")
16873    (set_attr "i387_cw" "trunc")
16874    (set_attr "mode" "XF")])
16875
16876 (define_expand "btruncxf2"
16877   [(use (match_operand:XF 0 "register_operand" ""))
16878    (use (match_operand:XF 1 "register_operand" ""))]
16879   "TARGET_USE_FANCY_MATH_387
16880    && flag_unsafe_math_optimizations"
16881 {
16882   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16883   DONE;
16884 })
16885
16886 (define_expand "btruncdf2"
16887   [(use (match_operand:DF 0 "register_operand" ""))
16888    (use (match_operand:DF 1 "register_operand" ""))]
16889   "TARGET_USE_FANCY_MATH_387
16890    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16891    && flag_unsafe_math_optimizations"
16892 {
16893   rtx op0 = gen_reg_rtx (XFmode);
16894   rtx op1 = gen_reg_rtx (XFmode);
16895
16896   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16897   emit_insn (gen_frndintxf2_trunc (op0, op1));
16898
16899   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16900   DONE;
16901 })
16902
16903 (define_expand "btruncsf2"
16904   [(use (match_operand:SF 0 "register_operand" ""))
16905    (use (match_operand:SF 1 "register_operand" ""))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16908    && flag_unsafe_math_optimizations"
16909 {
16910   rtx op0 = gen_reg_rtx (XFmode);
16911   rtx op1 = gen_reg_rtx (XFmode);
16912
16913   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16914   emit_insn (gen_frndintxf2_trunc (op0, op1));
16915
16916   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16917   DONE;
16918 })
16919
16920 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16921 (define_insn_and_split "frndintxf2_mask_pm"
16922   [(set (match_operand:XF 0 "register_operand" "=f")
16923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16924          UNSPEC_FRNDINT_MASK_PM))
16925    (clobber (reg:CC FLAGS_REG))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && flag_unsafe_math_optimizations
16928    && !(reload_completed || reload_in_progress)"
16929   "#"
16930   "&& 1"
16931   [(const_int 0)]
16932 {
16933   ix86_optimize_mode_switching = 1;
16934
16935   operands[2] = assign_386_stack_local (HImode, 1);
16936   operands[3] = assign_386_stack_local (HImode, 2);
16937
16938   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16939                                           operands[2], operands[3]));
16940   DONE;
16941 }
16942   [(set_attr "type" "frndint")
16943    (set_attr "i387_cw" "mask_pm")
16944    (set_attr "mode" "XF")])
16945
16946 (define_insn "frndintxf2_mask_pm_i387"
16947   [(set (match_operand:XF 0 "register_operand" "=f")
16948         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16949          UNSPEC_FRNDINT_MASK_PM))
16950    (use (match_operand:HI 2 "memory_operand" "m"))
16951    (use (match_operand:HI 3 "memory_operand" "m"))]
16952   "TARGET_USE_FANCY_MATH_387
16953    && flag_unsafe_math_optimizations"
16954   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16955   [(set_attr "type" "frndint")
16956    (set_attr "i387_cw" "mask_pm")
16957    (set_attr "mode" "XF")])
16958
16959 (define_expand "nearbyintxf2"
16960   [(use (match_operand:XF 0 "register_operand" ""))
16961    (use (match_operand:XF 1 "register_operand" ""))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && flag_unsafe_math_optimizations"
16964 {
16965   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16966
16967   DONE;
16968 })
16969
16970 (define_expand "nearbyintdf2"
16971   [(use (match_operand:DF 0 "register_operand" ""))
16972    (use (match_operand:DF 1 "register_operand" ""))]
16973   "TARGET_USE_FANCY_MATH_387
16974    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16975    && flag_unsafe_math_optimizations"
16976 {
16977   rtx op0 = gen_reg_rtx (XFmode);
16978   rtx op1 = gen_reg_rtx (XFmode);
16979
16980   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16981   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16982
16983   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16984   DONE;
16985 })
16986
16987 (define_expand "nearbyintsf2"
16988   [(use (match_operand:SF 0 "register_operand" ""))
16989    (use (match_operand:SF 1 "register_operand" ""))]
16990   "TARGET_USE_FANCY_MATH_387
16991    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16992    && flag_unsafe_math_optimizations"
16993 {
16994   rtx op0 = gen_reg_rtx (XFmode);
16995   rtx op1 = gen_reg_rtx (XFmode);
16996
16997   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16998   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16999
17000   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17001   DONE;
17002 })
17003
17004 \f
17005 ;; Block operation instructions
17006
17007 (define_insn "cld"
17008  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17009  ""
17010  "cld"
17011   [(set_attr "type" "cld")])
17012
17013 (define_expand "movmemsi"
17014   [(use (match_operand:BLK 0 "memory_operand" ""))
17015    (use (match_operand:BLK 1 "memory_operand" ""))
17016    (use (match_operand:SI 2 "nonmemory_operand" ""))
17017    (use (match_operand:SI 3 "const_int_operand" ""))]
17018   "! optimize_size"
17019 {
17020  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17021    DONE;
17022  else
17023    FAIL;
17024 })
17025
17026 (define_expand "movmemdi"
17027   [(use (match_operand:BLK 0 "memory_operand" ""))
17028    (use (match_operand:BLK 1 "memory_operand" ""))
17029    (use (match_operand:DI 2 "nonmemory_operand" ""))
17030    (use (match_operand:DI 3 "const_int_operand" ""))]
17031   "TARGET_64BIT"
17032 {
17033  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17034    DONE;
17035  else
17036    FAIL;
17037 })
17038
17039 ;; Most CPUs don't like single string operations
17040 ;; Handle this case here to simplify previous expander.
17041
17042 (define_expand "strmov"
17043   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17044    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17045    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17046               (clobber (reg:CC FLAGS_REG))])
17047    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17048               (clobber (reg:CC FLAGS_REG))])]
17049   ""
17050 {
17051   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17052
17053   /* If .md ever supports :P for Pmode, these can be directly
17054      in the pattern above.  */
17055   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17056   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17057
17058   if (TARGET_SINGLE_STRINGOP || optimize_size)
17059     {
17060       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17061                                       operands[2], operands[3],
17062                                       operands[5], operands[6]));
17063       DONE;
17064     }
17065
17066   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17067 })
17068
17069 (define_expand "strmov_singleop"
17070   [(parallel [(set (match_operand 1 "memory_operand" "")
17071                    (match_operand 3 "memory_operand" ""))
17072               (set (match_operand 0 "register_operand" "")
17073                    (match_operand 4 "" ""))
17074               (set (match_operand 2 "register_operand" "")
17075                    (match_operand 5 "" ""))
17076               (use (reg:SI DIRFLAG_REG))])]
17077   "TARGET_SINGLE_STRINGOP || optimize_size"
17078   "")
17079
17080 (define_insn "*strmovdi_rex_1"
17081   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17082         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17083    (set (match_operand:DI 0 "register_operand" "=D")
17084         (plus:DI (match_dup 2)
17085                  (const_int 8)))
17086    (set (match_operand:DI 1 "register_operand" "=S")
17087         (plus:DI (match_dup 3)
17088                  (const_int 8)))
17089    (use (reg:SI DIRFLAG_REG))]
17090   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17091   "movsq"
17092   [(set_attr "type" "str")
17093    (set_attr "mode" "DI")
17094    (set_attr "memory" "both")])
17095
17096 (define_insn "*strmovsi_1"
17097   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17098         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17099    (set (match_operand:SI 0 "register_operand" "=D")
17100         (plus:SI (match_dup 2)
17101                  (const_int 4)))
17102    (set (match_operand:SI 1 "register_operand" "=S")
17103         (plus:SI (match_dup 3)
17104                  (const_int 4)))
17105    (use (reg:SI DIRFLAG_REG))]
17106   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17107   "{movsl|movsd}"
17108   [(set_attr "type" "str")
17109    (set_attr "mode" "SI")
17110    (set_attr "memory" "both")])
17111
17112 (define_insn "*strmovsi_rex_1"
17113   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17114         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17115    (set (match_operand:DI 0 "register_operand" "=D")
17116         (plus:DI (match_dup 2)
17117                  (const_int 4)))
17118    (set (match_operand:DI 1 "register_operand" "=S")
17119         (plus:DI (match_dup 3)
17120                  (const_int 4)))
17121    (use (reg:SI DIRFLAG_REG))]
17122   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17123   "{movsl|movsd}"
17124   [(set_attr "type" "str")
17125    (set_attr "mode" "SI")
17126    (set_attr "memory" "both")])
17127
17128 (define_insn "*strmovhi_1"
17129   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17130         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17131    (set (match_operand:SI 0 "register_operand" "=D")
17132         (plus:SI (match_dup 2)
17133                  (const_int 2)))
17134    (set (match_operand:SI 1 "register_operand" "=S")
17135         (plus:SI (match_dup 3)
17136                  (const_int 2)))
17137    (use (reg:SI DIRFLAG_REG))]
17138   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17139   "movsw"
17140   [(set_attr "type" "str")
17141    (set_attr "memory" "both")
17142    (set_attr "mode" "HI")])
17143
17144 (define_insn "*strmovhi_rex_1"
17145   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17146         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17147    (set (match_operand:DI 0 "register_operand" "=D")
17148         (plus:DI (match_dup 2)
17149                  (const_int 2)))
17150    (set (match_operand:DI 1 "register_operand" "=S")
17151         (plus:DI (match_dup 3)
17152                  (const_int 2)))
17153    (use (reg:SI DIRFLAG_REG))]
17154   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17155   "movsw"
17156   [(set_attr "type" "str")
17157    (set_attr "memory" "both")
17158    (set_attr "mode" "HI")])
17159
17160 (define_insn "*strmovqi_1"
17161   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17162         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17163    (set (match_operand:SI 0 "register_operand" "=D")
17164         (plus:SI (match_dup 2)
17165                  (const_int 1)))
17166    (set (match_operand:SI 1 "register_operand" "=S")
17167         (plus:SI (match_dup 3)
17168                  (const_int 1)))
17169    (use (reg:SI DIRFLAG_REG))]
17170   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17171   "movsb"
17172   [(set_attr "type" "str")
17173    (set_attr "memory" "both")
17174    (set_attr "mode" "QI")])
17175
17176 (define_insn "*strmovqi_rex_1"
17177   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17178         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17179    (set (match_operand:DI 0 "register_operand" "=D")
17180         (plus:DI (match_dup 2)
17181                  (const_int 1)))
17182    (set (match_operand:DI 1 "register_operand" "=S")
17183         (plus:DI (match_dup 3)
17184                  (const_int 1)))
17185    (use (reg:SI DIRFLAG_REG))]
17186   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17187   "movsb"
17188   [(set_attr "type" "str")
17189    (set_attr "memory" "both")
17190    (set_attr "mode" "QI")])
17191
17192 (define_expand "rep_mov"
17193   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17194               (set (match_operand 0 "register_operand" "")
17195                    (match_operand 5 "" ""))
17196               (set (match_operand 2 "register_operand" "")
17197                    (match_operand 6 "" ""))
17198               (set (match_operand 1 "memory_operand" "")
17199                    (match_operand 3 "memory_operand" ""))
17200               (use (match_dup 4))
17201               (use (reg:SI DIRFLAG_REG))])]
17202   ""
17203   "")
17204
17205 (define_insn "*rep_movdi_rex64"
17206   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17207    (set (match_operand:DI 0 "register_operand" "=D") 
17208         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17209                             (const_int 3))
17210                  (match_operand:DI 3 "register_operand" "0")))
17211    (set (match_operand:DI 1 "register_operand" "=S") 
17212         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17213                  (match_operand:DI 4 "register_operand" "1")))
17214    (set (mem:BLK (match_dup 3))
17215         (mem:BLK (match_dup 4)))
17216    (use (match_dup 5))
17217    (use (reg:SI DIRFLAG_REG))]
17218   "TARGET_64BIT"
17219   "{rep\;movsq|rep movsq}"
17220   [(set_attr "type" "str")
17221    (set_attr "prefix_rep" "1")
17222    (set_attr "memory" "both")
17223    (set_attr "mode" "DI")])
17224
17225 (define_insn "*rep_movsi"
17226   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17227    (set (match_operand:SI 0 "register_operand" "=D") 
17228         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17229                             (const_int 2))
17230                  (match_operand:SI 3 "register_operand" "0")))
17231    (set (match_operand:SI 1 "register_operand" "=S") 
17232         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17233                  (match_operand:SI 4 "register_operand" "1")))
17234    (set (mem:BLK (match_dup 3))
17235         (mem:BLK (match_dup 4)))
17236    (use (match_dup 5))
17237    (use (reg:SI DIRFLAG_REG))]
17238   "!TARGET_64BIT"
17239   "{rep\;movsl|rep movsd}"
17240   [(set_attr "type" "str")
17241    (set_attr "prefix_rep" "1")
17242    (set_attr "memory" "both")
17243    (set_attr "mode" "SI")])
17244
17245 (define_insn "*rep_movsi_rex64"
17246   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17247    (set (match_operand:DI 0 "register_operand" "=D") 
17248         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17249                             (const_int 2))
17250                  (match_operand:DI 3 "register_operand" "0")))
17251    (set (match_operand:DI 1 "register_operand" "=S") 
17252         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17253                  (match_operand:DI 4 "register_operand" "1")))
17254    (set (mem:BLK (match_dup 3))
17255         (mem:BLK (match_dup 4)))
17256    (use (match_dup 5))
17257    (use (reg:SI DIRFLAG_REG))]
17258   "TARGET_64BIT"
17259   "{rep\;movsl|rep movsd}"
17260   [(set_attr "type" "str")
17261    (set_attr "prefix_rep" "1")
17262    (set_attr "memory" "both")
17263    (set_attr "mode" "SI")])
17264
17265 (define_insn "*rep_movqi"
17266   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17267    (set (match_operand:SI 0 "register_operand" "=D") 
17268         (plus:SI (match_operand:SI 3 "register_operand" "0")
17269                  (match_operand:SI 5 "register_operand" "2")))
17270    (set (match_operand:SI 1 "register_operand" "=S") 
17271         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17272    (set (mem:BLK (match_dup 3))
17273         (mem:BLK (match_dup 4)))
17274    (use (match_dup 5))
17275    (use (reg:SI DIRFLAG_REG))]
17276   "!TARGET_64BIT"
17277   "{rep\;movsb|rep movsb}"
17278   [(set_attr "type" "str")
17279    (set_attr "prefix_rep" "1")
17280    (set_attr "memory" "both")
17281    (set_attr "mode" "SI")])
17282
17283 (define_insn "*rep_movqi_rex64"
17284   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17285    (set (match_operand:DI 0 "register_operand" "=D") 
17286         (plus:DI (match_operand:DI 3 "register_operand" "0")
17287                  (match_operand:DI 5 "register_operand" "2")))
17288    (set (match_operand:DI 1 "register_operand" "=S") 
17289         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17290    (set (mem:BLK (match_dup 3))
17291         (mem:BLK (match_dup 4)))
17292    (use (match_dup 5))
17293    (use (reg:SI DIRFLAG_REG))]
17294   "TARGET_64BIT"
17295   "{rep\;movsb|rep movsb}"
17296   [(set_attr "type" "str")
17297    (set_attr "prefix_rep" "1")
17298    (set_attr "memory" "both")
17299    (set_attr "mode" "SI")])
17300
17301 (define_expand "clrmemsi"
17302    [(use (match_operand:BLK 0 "memory_operand" ""))
17303     (use (match_operand:SI 1 "nonmemory_operand" ""))
17304     (use (match_operand 2 "const_int_operand" ""))]
17305   ""
17306 {
17307  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17308    DONE;
17309  else
17310    FAIL;
17311 })
17312
17313 (define_expand "clrmemdi"
17314    [(use (match_operand:BLK 0 "memory_operand" ""))
17315     (use (match_operand:DI 1 "nonmemory_operand" ""))
17316     (use (match_operand 2 "const_int_operand" ""))]
17317   "TARGET_64BIT"
17318 {
17319  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17320    DONE;
17321  else
17322    FAIL;
17323 })
17324
17325 ;; Most CPUs don't like single string operations
17326 ;; Handle this case here to simplify previous expander.
17327
17328 (define_expand "strset"
17329   [(set (match_operand 1 "memory_operand" "")
17330         (match_operand 2 "register_operand" ""))
17331    (parallel [(set (match_operand 0 "register_operand" "")
17332                    (match_dup 3))
17333               (clobber (reg:CC FLAGS_REG))])]
17334   ""
17335 {
17336   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17337     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17338
17339   /* If .md ever supports :P for Pmode, this can be directly
17340      in the pattern above.  */
17341   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17342                               GEN_INT (GET_MODE_SIZE (GET_MODE
17343                                                       (operands[2]))));
17344   if (TARGET_SINGLE_STRINGOP || optimize_size)
17345     {
17346       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17347                                       operands[3]));
17348       DONE;
17349     }
17350 })
17351
17352 (define_expand "strset_singleop"
17353   [(parallel [(set (match_operand 1 "memory_operand" "")
17354                    (match_operand 2 "register_operand" ""))
17355               (set (match_operand 0 "register_operand" "")
17356                    (match_operand 3 "" ""))
17357               (use (reg:SI DIRFLAG_REG))])]
17358   "TARGET_SINGLE_STRINGOP || optimize_size"
17359   "")
17360
17361 (define_insn "*strsetdi_rex_1"
17362   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17363         (match_operand:DI 2 "register_operand" "a"))
17364    (set (match_operand:DI 0 "register_operand" "=D")
17365         (plus:DI (match_dup 1)
17366                  (const_int 8)))
17367    (use (reg:SI DIRFLAG_REG))]
17368   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17369   "stosq"
17370   [(set_attr "type" "str")
17371    (set_attr "memory" "store")
17372    (set_attr "mode" "DI")])
17373
17374 (define_insn "*strsetsi_1"
17375   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17376         (match_operand:SI 2 "register_operand" "a"))
17377    (set (match_operand:SI 0 "register_operand" "=D")
17378         (plus:SI (match_dup 1)
17379                  (const_int 4)))
17380    (use (reg:SI DIRFLAG_REG))]
17381   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17382   "{stosl|stosd}"
17383   [(set_attr "type" "str")
17384    (set_attr "memory" "store")
17385    (set_attr "mode" "SI")])
17386
17387 (define_insn "*strsetsi_rex_1"
17388   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17389         (match_operand:SI 2 "register_operand" "a"))
17390    (set (match_operand:DI 0 "register_operand" "=D")
17391         (plus:DI (match_dup 1)
17392                  (const_int 4)))
17393    (use (reg:SI DIRFLAG_REG))]
17394   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17395   "{stosl|stosd}"
17396   [(set_attr "type" "str")
17397    (set_attr "memory" "store")
17398    (set_attr "mode" "SI")])
17399
17400 (define_insn "*strsethi_1"
17401   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17402         (match_operand:HI 2 "register_operand" "a"))
17403    (set (match_operand:SI 0 "register_operand" "=D")
17404         (plus:SI (match_dup 1)
17405                  (const_int 2)))
17406    (use (reg:SI DIRFLAG_REG))]
17407   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17408   "stosw"
17409   [(set_attr "type" "str")
17410    (set_attr "memory" "store")
17411    (set_attr "mode" "HI")])
17412
17413 (define_insn "*strsethi_rex_1"
17414   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17415         (match_operand:HI 2 "register_operand" "a"))
17416    (set (match_operand:DI 0 "register_operand" "=D")
17417         (plus:DI (match_dup 1)
17418                  (const_int 2)))
17419    (use (reg:SI DIRFLAG_REG))]
17420   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17421   "stosw"
17422   [(set_attr "type" "str")
17423    (set_attr "memory" "store")
17424    (set_attr "mode" "HI")])
17425
17426 (define_insn "*strsetqi_1"
17427   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17428         (match_operand:QI 2 "register_operand" "a"))
17429    (set (match_operand:SI 0 "register_operand" "=D")
17430         (plus:SI (match_dup 1)
17431                  (const_int 1)))
17432    (use (reg:SI DIRFLAG_REG))]
17433   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17434   "stosb"
17435   [(set_attr "type" "str")
17436    (set_attr "memory" "store")
17437    (set_attr "mode" "QI")])
17438
17439 (define_insn "*strsetqi_rex_1"
17440   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17441         (match_operand:QI 2 "register_operand" "a"))
17442    (set (match_operand:DI 0 "register_operand" "=D")
17443         (plus:DI (match_dup 1)
17444                  (const_int 1)))
17445    (use (reg:SI DIRFLAG_REG))]
17446   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17447   "stosb"
17448   [(set_attr "type" "str")
17449    (set_attr "memory" "store")
17450    (set_attr "mode" "QI")])
17451
17452 (define_expand "rep_stos"
17453   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17454               (set (match_operand 0 "register_operand" "")
17455                    (match_operand 4 "" ""))
17456               (set (match_operand 2 "memory_operand" "") (const_int 0))
17457               (use (match_operand 3 "register_operand" ""))
17458               (use (match_dup 1))
17459               (use (reg:SI DIRFLAG_REG))])]
17460   ""
17461   "")
17462
17463 (define_insn "*rep_stosdi_rex64"
17464   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17465    (set (match_operand:DI 0 "register_operand" "=D") 
17466         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17467                             (const_int 3))
17468                  (match_operand:DI 3 "register_operand" "0")))
17469    (set (mem:BLK (match_dup 3))
17470         (const_int 0))
17471    (use (match_operand:DI 2 "register_operand" "a"))
17472    (use (match_dup 4))
17473    (use (reg:SI DIRFLAG_REG))]
17474   "TARGET_64BIT"
17475   "{rep\;stosq|rep stosq}"
17476   [(set_attr "type" "str")
17477    (set_attr "prefix_rep" "1")
17478    (set_attr "memory" "store")
17479    (set_attr "mode" "DI")])
17480
17481 (define_insn "*rep_stossi"
17482   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17483    (set (match_operand:SI 0 "register_operand" "=D") 
17484         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17485                             (const_int 2))
17486                  (match_operand:SI 3 "register_operand" "0")))
17487    (set (mem:BLK (match_dup 3))
17488         (const_int 0))
17489    (use (match_operand:SI 2 "register_operand" "a"))
17490    (use (match_dup 4))
17491    (use (reg:SI DIRFLAG_REG))]
17492   "!TARGET_64BIT"
17493   "{rep\;stosl|rep stosd}"
17494   [(set_attr "type" "str")
17495    (set_attr "prefix_rep" "1")
17496    (set_attr "memory" "store")
17497    (set_attr "mode" "SI")])
17498
17499 (define_insn "*rep_stossi_rex64"
17500   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17501    (set (match_operand:DI 0 "register_operand" "=D") 
17502         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17503                             (const_int 2))
17504                  (match_operand:DI 3 "register_operand" "0")))
17505    (set (mem:BLK (match_dup 3))
17506         (const_int 0))
17507    (use (match_operand:SI 2 "register_operand" "a"))
17508    (use (match_dup 4))
17509    (use (reg:SI DIRFLAG_REG))]
17510   "TARGET_64BIT"
17511   "{rep\;stosl|rep stosd}"
17512   [(set_attr "type" "str")
17513    (set_attr "prefix_rep" "1")
17514    (set_attr "memory" "store")
17515    (set_attr "mode" "SI")])
17516
17517 (define_insn "*rep_stosqi"
17518   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17519    (set (match_operand:SI 0 "register_operand" "=D") 
17520         (plus:SI (match_operand:SI 3 "register_operand" "0")
17521                  (match_operand:SI 4 "register_operand" "1")))
17522    (set (mem:BLK (match_dup 3))
17523         (const_int 0))
17524    (use (match_operand:QI 2 "register_operand" "a"))
17525    (use (match_dup 4))
17526    (use (reg:SI DIRFLAG_REG))]
17527   "!TARGET_64BIT"
17528   "{rep\;stosb|rep stosb}"
17529   [(set_attr "type" "str")
17530    (set_attr "prefix_rep" "1")
17531    (set_attr "memory" "store")
17532    (set_attr "mode" "QI")])
17533
17534 (define_insn "*rep_stosqi_rex64"
17535   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17536    (set (match_operand:DI 0 "register_operand" "=D") 
17537         (plus:DI (match_operand:DI 3 "register_operand" "0")
17538                  (match_operand:DI 4 "register_operand" "1")))
17539    (set (mem:BLK (match_dup 3))
17540         (const_int 0))
17541    (use (match_operand:QI 2 "register_operand" "a"))
17542    (use (match_dup 4))
17543    (use (reg:SI DIRFLAG_REG))]
17544   "TARGET_64BIT"
17545   "{rep\;stosb|rep stosb}"
17546   [(set_attr "type" "str")
17547    (set_attr "prefix_rep" "1")
17548    (set_attr "memory" "store")
17549    (set_attr "mode" "QI")])
17550
17551 (define_expand "cmpstrsi"
17552   [(set (match_operand:SI 0 "register_operand" "")
17553         (compare:SI (match_operand:BLK 1 "general_operand" "")
17554                     (match_operand:BLK 2 "general_operand" "")))
17555    (use (match_operand 3 "general_operand" ""))
17556    (use (match_operand 4 "immediate_operand" ""))]
17557   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17558 {
17559   rtx addr1, addr2, out, outlow, count, countreg, align;
17560
17561   /* Can't use this if the user has appropriated esi or edi.  */
17562   if (global_regs[4] || global_regs[5])
17563     FAIL;
17564
17565   out = operands[0];
17566   if (GET_CODE (out) != REG)
17567     out = gen_reg_rtx (SImode);
17568
17569   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17570   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17571   if (addr1 != XEXP (operands[1], 0))
17572     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17573   if (addr2 != XEXP (operands[2], 0))
17574     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17575
17576   count = operands[3];
17577   countreg = ix86_zero_extend_to_Pmode (count);
17578
17579   /* %%% Iff we are testing strict equality, we can use known alignment
17580      to good advantage.  This may be possible with combine, particularly
17581      once cc0 is dead.  */
17582   align = operands[4];
17583
17584   emit_insn (gen_cld ());
17585   if (GET_CODE (count) == CONST_INT)
17586     {
17587       if (INTVAL (count) == 0)
17588         {
17589           emit_move_insn (operands[0], const0_rtx);
17590           DONE;
17591         }
17592       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17593                                     operands[1], operands[2]));
17594     }
17595   else
17596     {
17597       if (TARGET_64BIT)
17598         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17599       else
17600         emit_insn (gen_cmpsi_1 (countreg, countreg));
17601       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17602                                  operands[1], operands[2]));
17603     }
17604
17605   outlow = gen_lowpart (QImode, out);
17606   emit_insn (gen_cmpintqi (outlow));
17607   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17608
17609   if (operands[0] != out)
17610     emit_move_insn (operands[0], out);
17611
17612   DONE;
17613 })
17614
17615 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17616
17617 (define_expand "cmpintqi"
17618   [(set (match_dup 1)
17619         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17620    (set (match_dup 2)
17621         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17622    (parallel [(set (match_operand:QI 0 "register_operand" "")
17623                    (minus:QI (match_dup 1)
17624                              (match_dup 2)))
17625               (clobber (reg:CC FLAGS_REG))])]
17626   ""
17627   "operands[1] = gen_reg_rtx (QImode);
17628    operands[2] = gen_reg_rtx (QImode);")
17629
17630 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17631 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17632
17633 (define_expand "cmpstrqi_nz_1"
17634   [(parallel [(set (reg:CC FLAGS_REG)
17635                    (compare:CC (match_operand 4 "memory_operand" "")
17636                                (match_operand 5 "memory_operand" "")))
17637               (use (match_operand 2 "register_operand" ""))
17638               (use (match_operand:SI 3 "immediate_operand" ""))
17639               (use (reg:SI DIRFLAG_REG))
17640               (clobber (match_operand 0 "register_operand" ""))
17641               (clobber (match_operand 1 "register_operand" ""))
17642               (clobber (match_dup 2))])]
17643   ""
17644   "")
17645
17646 (define_insn "*cmpstrqi_nz_1"
17647   [(set (reg:CC FLAGS_REG)
17648         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17649                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17650    (use (match_operand:SI 6 "register_operand" "2"))
17651    (use (match_operand:SI 3 "immediate_operand" "i"))
17652    (use (reg:SI DIRFLAG_REG))
17653    (clobber (match_operand:SI 0 "register_operand" "=S"))
17654    (clobber (match_operand:SI 1 "register_operand" "=D"))
17655    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17656   "!TARGET_64BIT"
17657   "repz{\;| }cmpsb"
17658   [(set_attr "type" "str")
17659    (set_attr "mode" "QI")
17660    (set_attr "prefix_rep" "1")])
17661
17662 (define_insn "*cmpstrqi_nz_rex_1"
17663   [(set (reg:CC FLAGS_REG)
17664         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17665                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17666    (use (match_operand:DI 6 "register_operand" "2"))
17667    (use (match_operand:SI 3 "immediate_operand" "i"))
17668    (use (reg:SI DIRFLAG_REG))
17669    (clobber (match_operand:DI 0 "register_operand" "=S"))
17670    (clobber (match_operand:DI 1 "register_operand" "=D"))
17671    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17672   "TARGET_64BIT"
17673   "repz{\;| }cmpsb"
17674   [(set_attr "type" "str")
17675    (set_attr "mode" "QI")
17676    (set_attr "prefix_rep" "1")])
17677
17678 ;; The same, but the count is not known to not be zero.
17679
17680 (define_expand "cmpstrqi_1"
17681   [(parallel [(set (reg:CC FLAGS_REG)
17682                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17683                                      (const_int 0))
17684                   (compare:CC (match_operand 4 "memory_operand" "")
17685                               (match_operand 5 "memory_operand" ""))
17686                   (const_int 0)))
17687               (use (match_operand:SI 3 "immediate_operand" ""))
17688               (use (reg:CC FLAGS_REG))
17689               (use (reg:SI DIRFLAG_REG))
17690               (clobber (match_operand 0 "register_operand" ""))
17691               (clobber (match_operand 1 "register_operand" ""))
17692               (clobber (match_dup 2))])]
17693   ""
17694   "")
17695
17696 (define_insn "*cmpstrqi_1"
17697   [(set (reg:CC FLAGS_REG)
17698         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17699                              (const_int 0))
17700           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17701                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17702           (const_int 0)))
17703    (use (match_operand:SI 3 "immediate_operand" "i"))
17704    (use (reg:CC FLAGS_REG))
17705    (use (reg:SI DIRFLAG_REG))
17706    (clobber (match_operand:SI 0 "register_operand" "=S"))
17707    (clobber (match_operand:SI 1 "register_operand" "=D"))
17708    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17709   "!TARGET_64BIT"
17710   "repz{\;| }cmpsb"
17711   [(set_attr "type" "str")
17712    (set_attr "mode" "QI")
17713    (set_attr "prefix_rep" "1")])
17714
17715 (define_insn "*cmpstrqi_rex_1"
17716   [(set (reg:CC FLAGS_REG)
17717         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17718                              (const_int 0))
17719           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17720                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17721           (const_int 0)))
17722    (use (match_operand:SI 3 "immediate_operand" "i"))
17723    (use (reg:CC FLAGS_REG))
17724    (use (reg:SI DIRFLAG_REG))
17725    (clobber (match_operand:DI 0 "register_operand" "=S"))
17726    (clobber (match_operand:DI 1 "register_operand" "=D"))
17727    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17728   "TARGET_64BIT"
17729   "repz{\;| }cmpsb"
17730   [(set_attr "type" "str")
17731    (set_attr "mode" "QI")
17732    (set_attr "prefix_rep" "1")])
17733
17734 (define_expand "strlensi"
17735   [(set (match_operand:SI 0 "register_operand" "")
17736         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17737                     (match_operand:QI 2 "immediate_operand" "")
17738                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17739   ""
17740 {
17741  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17742    DONE;
17743  else
17744    FAIL;
17745 })
17746
17747 (define_expand "strlendi"
17748   [(set (match_operand:DI 0 "register_operand" "")
17749         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17750                     (match_operand:QI 2 "immediate_operand" "")
17751                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17752   ""
17753 {
17754  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17755    DONE;
17756  else
17757    FAIL;
17758 })
17759
17760 (define_expand "strlenqi_1"
17761   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17762               (use (reg:SI DIRFLAG_REG))
17763               (clobber (match_operand 1 "register_operand" ""))
17764               (clobber (reg:CC FLAGS_REG))])]
17765   ""
17766   "")
17767
17768 (define_insn "*strlenqi_1"
17769   [(set (match_operand:SI 0 "register_operand" "=&c")
17770         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17771                     (match_operand:QI 2 "register_operand" "a")
17772                     (match_operand:SI 3 "immediate_operand" "i")
17773                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17774    (use (reg:SI DIRFLAG_REG))
17775    (clobber (match_operand:SI 1 "register_operand" "=D"))
17776    (clobber (reg:CC FLAGS_REG))]
17777   "!TARGET_64BIT"
17778   "repnz{\;| }scasb"
17779   [(set_attr "type" "str")
17780    (set_attr "mode" "QI")
17781    (set_attr "prefix_rep" "1")])
17782
17783 (define_insn "*strlenqi_rex_1"
17784   [(set (match_operand:DI 0 "register_operand" "=&c")
17785         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17786                     (match_operand:QI 2 "register_operand" "a")
17787                     (match_operand:DI 3 "immediate_operand" "i")
17788                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17789    (use (reg:SI DIRFLAG_REG))
17790    (clobber (match_operand:DI 1 "register_operand" "=D"))
17791    (clobber (reg:CC FLAGS_REG))]
17792   "TARGET_64BIT"
17793   "repnz{\;| }scasb"
17794   [(set_attr "type" "str")
17795    (set_attr "mode" "QI")
17796    (set_attr "prefix_rep" "1")])
17797
17798 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17799 ;; handled in combine, but it is not currently up to the task.
17800 ;; When used for their truth value, the cmpstr* expanders generate
17801 ;; code like this:
17802 ;;
17803 ;;   repz cmpsb
17804 ;;   seta       %al
17805 ;;   setb       %dl
17806 ;;   cmpb       %al, %dl
17807 ;;   jcc        label
17808 ;;
17809 ;; The intermediate three instructions are unnecessary.
17810
17811 ;; This one handles cmpstr*_nz_1...
17812 (define_peephole2
17813   [(parallel[
17814      (set (reg:CC FLAGS_REG)
17815           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17816                       (mem:BLK (match_operand 5 "register_operand" ""))))
17817      (use (match_operand 6 "register_operand" ""))
17818      (use (match_operand:SI 3 "immediate_operand" ""))
17819      (use (reg:SI DIRFLAG_REG))
17820      (clobber (match_operand 0 "register_operand" ""))
17821      (clobber (match_operand 1 "register_operand" ""))
17822      (clobber (match_operand 2 "register_operand" ""))])
17823    (set (match_operand:QI 7 "register_operand" "")
17824         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17825    (set (match_operand:QI 8 "register_operand" "")
17826         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17827    (set (reg FLAGS_REG)
17828         (compare (match_dup 7) (match_dup 8)))
17829   ]
17830   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17831   [(parallel[
17832      (set (reg:CC FLAGS_REG)
17833           (compare:CC (mem:BLK (match_dup 4))
17834                       (mem:BLK (match_dup 5))))
17835      (use (match_dup 6))
17836      (use (match_dup 3))
17837      (use (reg:SI DIRFLAG_REG))
17838      (clobber (match_dup 0))
17839      (clobber (match_dup 1))
17840      (clobber (match_dup 2))])]
17841   "")
17842
17843 ;; ...and this one handles cmpstr*_1.
17844 (define_peephole2
17845   [(parallel[
17846      (set (reg:CC FLAGS_REG)
17847           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17848                                (const_int 0))
17849             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17850                         (mem:BLK (match_operand 5 "register_operand" "")))
17851             (const_int 0)))
17852      (use (match_operand:SI 3 "immediate_operand" ""))
17853      (use (reg:CC FLAGS_REG))
17854      (use (reg:SI DIRFLAG_REG))
17855      (clobber (match_operand 0 "register_operand" ""))
17856      (clobber (match_operand 1 "register_operand" ""))
17857      (clobber (match_operand 2 "register_operand" ""))])
17858    (set (match_operand:QI 7 "register_operand" "")
17859         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17860    (set (match_operand:QI 8 "register_operand" "")
17861         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17862    (set (reg FLAGS_REG)
17863         (compare (match_dup 7) (match_dup 8)))
17864   ]
17865   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17866   [(parallel[
17867      (set (reg:CC FLAGS_REG)
17868           (if_then_else:CC (ne (match_dup 6)
17869                                (const_int 0))
17870             (compare:CC (mem:BLK (match_dup 4))
17871                         (mem:BLK (match_dup 5)))
17872             (const_int 0)))
17873      (use (match_dup 3))
17874      (use (reg:CC FLAGS_REG))
17875      (use (reg:SI DIRFLAG_REG))
17876      (clobber (match_dup 0))
17877      (clobber (match_dup 1))
17878      (clobber (match_dup 2))])]
17879   "")
17880
17881
17882 \f
17883 ;; Conditional move instructions.
17884
17885 (define_expand "movdicc"
17886   [(set (match_operand:DI 0 "register_operand" "")
17887         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17888                          (match_operand:DI 2 "general_operand" "")
17889                          (match_operand:DI 3 "general_operand" "")))]
17890   "TARGET_64BIT"
17891   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17892
17893 (define_insn "x86_movdicc_0_m1_rex64"
17894   [(set (match_operand:DI 0 "register_operand" "=r")
17895         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17896           (const_int -1)
17897           (const_int 0)))
17898    (clobber (reg:CC FLAGS_REG))]
17899   "TARGET_64BIT"
17900   "sbb{q}\t%0, %0"
17901   ; Since we don't have the proper number of operands for an alu insn,
17902   ; fill in all the blanks.
17903   [(set_attr "type" "alu")
17904    (set_attr "pent_pair" "pu")
17905    (set_attr "memory" "none")
17906    (set_attr "imm_disp" "false")
17907    (set_attr "mode" "DI")
17908    (set_attr "length_immediate" "0")])
17909
17910 (define_insn "*movdicc_c_rex64"
17911   [(set (match_operand:DI 0 "register_operand" "=r,r")
17912         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17913                                 [(reg FLAGS_REG) (const_int 0)])
17914                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17915                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17916   "TARGET_64BIT && TARGET_CMOVE
17917    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17918   "@
17919    cmov%O2%C1\t{%2, %0|%0, %2}
17920    cmov%O2%c1\t{%3, %0|%0, %3}"
17921   [(set_attr "type" "icmov")
17922    (set_attr "mode" "DI")])
17923
17924 (define_expand "movsicc"
17925   [(set (match_operand:SI 0 "register_operand" "")
17926         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17927                          (match_operand:SI 2 "general_operand" "")
17928                          (match_operand:SI 3 "general_operand" "")))]
17929   ""
17930   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17931
17932 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17933 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17934 ;; So just document what we're doing explicitly.
17935
17936 (define_insn "x86_movsicc_0_m1"
17937   [(set (match_operand:SI 0 "register_operand" "=r")
17938         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17939           (const_int -1)
17940           (const_int 0)))
17941    (clobber (reg:CC FLAGS_REG))]
17942   ""
17943   "sbb{l}\t%0, %0"
17944   ; Since we don't have the proper number of operands for an alu insn,
17945   ; fill in all the blanks.
17946   [(set_attr "type" "alu")
17947    (set_attr "pent_pair" "pu")
17948    (set_attr "memory" "none")
17949    (set_attr "imm_disp" "false")
17950    (set_attr "mode" "SI")
17951    (set_attr "length_immediate" "0")])
17952
17953 (define_insn "*movsicc_noc"
17954   [(set (match_operand:SI 0 "register_operand" "=r,r")
17955         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17956                                 [(reg FLAGS_REG) (const_int 0)])
17957                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17958                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17959   "TARGET_CMOVE
17960    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17961   "@
17962    cmov%O2%C1\t{%2, %0|%0, %2}
17963    cmov%O2%c1\t{%3, %0|%0, %3}"
17964   [(set_attr "type" "icmov")
17965    (set_attr "mode" "SI")])
17966
17967 (define_expand "movhicc"
17968   [(set (match_operand:HI 0 "register_operand" "")
17969         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17970                          (match_operand:HI 2 "general_operand" "")
17971                          (match_operand:HI 3 "general_operand" "")))]
17972   "TARGET_HIMODE_MATH"
17973   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17974
17975 (define_insn "*movhicc_noc"
17976   [(set (match_operand:HI 0 "register_operand" "=r,r")
17977         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17978                                 [(reg FLAGS_REG) (const_int 0)])
17979                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17980                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17981   "TARGET_CMOVE
17982    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17983   "@
17984    cmov%O2%C1\t{%2, %0|%0, %2}
17985    cmov%O2%c1\t{%3, %0|%0, %3}"
17986   [(set_attr "type" "icmov")
17987    (set_attr "mode" "HI")])
17988
17989 (define_expand "movqicc"
17990   [(set (match_operand:QI 0 "register_operand" "")
17991         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17992                          (match_operand:QI 2 "general_operand" "")
17993                          (match_operand:QI 3 "general_operand" "")))]
17994   "TARGET_QIMODE_MATH"
17995   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17996
17997 (define_insn_and_split "*movqicc_noc"
17998   [(set (match_operand:QI 0 "register_operand" "=r,r")
17999         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18000                                 [(match_operand 4 "flags_reg_operand" "")
18001                                  (const_int 0)])
18002                       (match_operand:QI 2 "register_operand" "r,0")
18003                       (match_operand:QI 3 "register_operand" "0,r")))]
18004   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18005   "#"
18006   "&& reload_completed"
18007   [(set (match_dup 0)
18008         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18009                       (match_dup 2)
18010                       (match_dup 3)))]
18011   "operands[0] = gen_lowpart (SImode, operands[0]);
18012    operands[2] = gen_lowpart (SImode, operands[2]);
18013    operands[3] = gen_lowpart (SImode, operands[3]);"
18014   [(set_attr "type" "icmov")
18015    (set_attr "mode" "SI")])
18016
18017 (define_expand "movsfcc"
18018   [(set (match_operand:SF 0 "register_operand" "")
18019         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18020                          (match_operand:SF 2 "register_operand" "")
18021                          (match_operand:SF 3 "register_operand" "")))]
18022   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18023   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18024
18025 (define_insn "*movsfcc_1_387"
18026   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18027         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18028                                 [(reg FLAGS_REG) (const_int 0)])
18029                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18030                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18031   "TARGET_80387 && TARGET_CMOVE
18032    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18033   "@
18034    fcmov%F1\t{%2, %0|%0, %2}
18035    fcmov%f1\t{%3, %0|%0, %3}
18036    cmov%O2%C1\t{%2, %0|%0, %2}
18037    cmov%O2%c1\t{%3, %0|%0, %3}"
18038   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18039    (set_attr "mode" "SF,SF,SI,SI")])
18040
18041 (define_expand "movdfcc"
18042   [(set (match_operand:DF 0 "register_operand" "")
18043         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18044                          (match_operand:DF 2 "register_operand" "")
18045                          (match_operand:DF 3 "register_operand" "")))]
18046   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18047   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18048
18049 (define_insn "*movdfcc_1"
18050   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18051         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18052                                 [(reg FLAGS_REG) (const_int 0)])
18053                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18054                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18055   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18056    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18057   "@
18058    fcmov%F1\t{%2, %0|%0, %2}
18059    fcmov%f1\t{%3, %0|%0, %3}
18060    #
18061    #"
18062   [(set_attr "type" "fcmov,fcmov,multi,multi")
18063    (set_attr "mode" "DF")])
18064
18065 (define_insn "*movdfcc_1_rex64"
18066   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18067         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18068                                 [(reg FLAGS_REG) (const_int 0)])
18069                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18070                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18071   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18072    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18073   "@
18074    fcmov%F1\t{%2, %0|%0, %2}
18075    fcmov%f1\t{%3, %0|%0, %3}
18076    cmov%O2%C1\t{%2, %0|%0, %2}
18077    cmov%O2%c1\t{%3, %0|%0, %3}"
18078   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18079    (set_attr "mode" "DF")])
18080
18081 (define_split
18082   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18083         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18084                                 [(match_operand 4 "flags_reg_operand" "")
18085                                  (const_int 0)])
18086                       (match_operand:DF 2 "nonimmediate_operand" "")
18087                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18088   "!TARGET_64BIT && reload_completed"
18089   [(set (match_dup 2)
18090         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18091                       (match_dup 5)
18092                       (match_dup 7)))
18093    (set (match_dup 3)
18094         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18095                       (match_dup 6)
18096                       (match_dup 8)))]
18097   "split_di (operands+2, 1, operands+5, operands+6);
18098    split_di (operands+3, 1, operands+7, operands+8);
18099    split_di (operands, 1, operands+2, operands+3);")
18100
18101 (define_expand "movxfcc"
18102   [(set (match_operand:XF 0 "register_operand" "")
18103         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18104                          (match_operand:XF 2 "register_operand" "")
18105                          (match_operand:XF 3 "register_operand" "")))]
18106   "TARGET_80387 && TARGET_CMOVE"
18107   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18108
18109 (define_insn "*movxfcc_1"
18110   [(set (match_operand:XF 0 "register_operand" "=f,f")
18111         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18112                                 [(reg FLAGS_REG) (const_int 0)])
18113                       (match_operand:XF 2 "register_operand" "f,0")
18114                       (match_operand:XF 3 "register_operand" "0,f")))]
18115   "TARGET_80387 && TARGET_CMOVE"
18116   "@
18117    fcmov%F1\t{%2, %0|%0, %2}
18118    fcmov%f1\t{%3, %0|%0, %3}"
18119   [(set_attr "type" "fcmov")
18120    (set_attr "mode" "XF")])
18121
18122 ;; These versions of the min/max patterns are intentionally ignorant of
18123 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18124 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18125 ;; are undefined in this condition, we're certain this is correct.
18126
18127 (define_insn "sminsf3"
18128   [(set (match_operand:SF 0 "register_operand" "=x")
18129         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18130                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18131   "TARGET_SSE_MATH"
18132   "minss\t{%2, %0|%0, %2}"
18133   [(set_attr "type" "sseadd")
18134    (set_attr "mode" "SF")])
18135
18136 (define_insn "smaxsf3"
18137   [(set (match_operand:SF 0 "register_operand" "=x")
18138         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18139                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18140   "TARGET_SSE_MATH"
18141   "maxss\t{%2, %0|%0, %2}"
18142   [(set_attr "type" "sseadd")
18143    (set_attr "mode" "SF")])
18144
18145 (define_insn "smindf3"
18146   [(set (match_operand:DF 0 "register_operand" "=x")
18147         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18148                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18149   "TARGET_SSE2 && TARGET_SSE_MATH"
18150   "minsd\t{%2, %0|%0, %2}"
18151   [(set_attr "type" "sseadd")
18152    (set_attr "mode" "DF")])
18153
18154 (define_insn "smaxdf3"
18155   [(set (match_operand:DF 0 "register_operand" "=x")
18156         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18157                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18158   "TARGET_SSE2 && TARGET_SSE_MATH"
18159   "maxsd\t{%2, %0|%0, %2}"
18160   [(set_attr "type" "sseadd")
18161    (set_attr "mode" "DF")])
18162
18163 ;; These versions of the min/max patterns implement exactly the operations
18164 ;;   min = (op1 < op2 ? op1 : op2)
18165 ;;   max = (!(op1 < op2) ? op1 : op2)
18166 ;; Their operands are not commutative, and thus they may be used in the
18167 ;; presence of -0.0 and NaN.
18168
18169 (define_insn "*ieee_sminsf3"
18170   [(set (match_operand:SF 0 "register_operand" "=x")
18171         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18172                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18173                    UNSPEC_IEEE_MIN))]
18174   "TARGET_SSE_MATH"
18175   "minss\t{%2, %0|%0, %2}"
18176   [(set_attr "type" "sseadd")
18177    (set_attr "mode" "SF")])
18178
18179 (define_insn "*ieee_smaxsf3"
18180   [(set (match_operand:SF 0 "register_operand" "=x")
18181         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18182                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18183                    UNSPEC_IEEE_MAX))]
18184   "TARGET_SSE_MATH"
18185   "maxss\t{%2, %0|%0, %2}"
18186   [(set_attr "type" "sseadd")
18187    (set_attr "mode" "SF")])
18188
18189 (define_insn "*ieee_smindf3"
18190   [(set (match_operand:DF 0 "register_operand" "=x")
18191         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18192                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18193                    UNSPEC_IEEE_MIN))]
18194   "TARGET_SSE2 && TARGET_SSE_MATH"
18195   "minsd\t{%2, %0|%0, %2}"
18196   [(set_attr "type" "sseadd")
18197    (set_attr "mode" "DF")])
18198
18199 (define_insn "*ieee_smaxdf3"
18200   [(set (match_operand:DF 0 "register_operand" "=x")
18201         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18202                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18203                    UNSPEC_IEEE_MAX))]
18204   "TARGET_SSE2 && TARGET_SSE_MATH"
18205   "maxsd\t{%2, %0|%0, %2}"
18206   [(set_attr "type" "sseadd")
18207    (set_attr "mode" "DF")])
18208
18209 ;; Conditional addition patterns
18210 (define_expand "addqicc"
18211   [(match_operand:QI 0 "register_operand" "")
18212    (match_operand 1 "comparison_operator" "")
18213    (match_operand:QI 2 "register_operand" "")
18214    (match_operand:QI 3 "const_int_operand" "")]
18215   ""
18216   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18217
18218 (define_expand "addhicc"
18219   [(match_operand:HI 0 "register_operand" "")
18220    (match_operand 1 "comparison_operator" "")
18221    (match_operand:HI 2 "register_operand" "")
18222    (match_operand:HI 3 "const_int_operand" "")]
18223   ""
18224   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18225
18226 (define_expand "addsicc"
18227   [(match_operand:SI 0 "register_operand" "")
18228    (match_operand 1 "comparison_operator" "")
18229    (match_operand:SI 2 "register_operand" "")
18230    (match_operand:SI 3 "const_int_operand" "")]
18231   ""
18232   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18233
18234 (define_expand "adddicc"
18235   [(match_operand:DI 0 "register_operand" "")
18236    (match_operand 1 "comparison_operator" "")
18237    (match_operand:DI 2 "register_operand" "")
18238    (match_operand:DI 3 "const_int_operand" "")]
18239   "TARGET_64BIT"
18240   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18241
18242 \f
18243 ;; Misc patterns (?)
18244
18245 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18246 ;; Otherwise there will be nothing to keep
18247 ;; 
18248 ;; [(set (reg ebp) (reg esp))]
18249 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18250 ;;  (clobber (eflags)]
18251 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18252 ;;
18253 ;; in proper program order.
18254 (define_insn "pro_epilogue_adjust_stack_1"
18255   [(set (match_operand:SI 0 "register_operand" "=r,r")
18256         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18257                  (match_operand:SI 2 "immediate_operand" "i,i")))
18258    (clobber (reg:CC FLAGS_REG))
18259    (clobber (mem:BLK (scratch)))]
18260   "!TARGET_64BIT"
18261 {
18262   switch (get_attr_type (insn))
18263     {
18264     case TYPE_IMOV:
18265       return "mov{l}\t{%1, %0|%0, %1}";
18266
18267     case TYPE_ALU:
18268       if (GET_CODE (operands[2]) == CONST_INT
18269           && (INTVAL (operands[2]) == 128
18270               || (INTVAL (operands[2]) < 0
18271                   && INTVAL (operands[2]) != -128)))
18272         {
18273           operands[2] = GEN_INT (-INTVAL (operands[2]));
18274           return "sub{l}\t{%2, %0|%0, %2}";
18275         }
18276       return "add{l}\t{%2, %0|%0, %2}";
18277
18278     case TYPE_LEA:
18279       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18280       return "lea{l}\t{%a2, %0|%0, %a2}";
18281
18282     default:
18283       abort ();
18284     }
18285 }
18286   [(set (attr "type")
18287         (cond [(eq_attr "alternative" "0")
18288                  (const_string "alu")
18289                (match_operand:SI 2 "const0_operand" "")
18290                  (const_string "imov")
18291               ]
18292               (const_string "lea")))
18293    (set_attr "mode" "SI")])
18294
18295 (define_insn "pro_epilogue_adjust_stack_rex64"
18296   [(set (match_operand:DI 0 "register_operand" "=r,r")
18297         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18298                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18299    (clobber (reg:CC FLAGS_REG))
18300    (clobber (mem:BLK (scratch)))]
18301   "TARGET_64BIT"
18302 {
18303   switch (get_attr_type (insn))
18304     {
18305     case TYPE_IMOV:
18306       return "mov{q}\t{%1, %0|%0, %1}";
18307
18308     case TYPE_ALU:
18309       if (GET_CODE (operands[2]) == CONST_INT
18310           /* Avoid overflows.  */
18311           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18312           && (INTVAL (operands[2]) == 128
18313               || (INTVAL (operands[2]) < 0
18314                   && INTVAL (operands[2]) != -128)))
18315         {
18316           operands[2] = GEN_INT (-INTVAL (operands[2]));
18317           return "sub{q}\t{%2, %0|%0, %2}";
18318         }
18319       return "add{q}\t{%2, %0|%0, %2}";
18320
18321     case TYPE_LEA:
18322       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18323       return "lea{q}\t{%a2, %0|%0, %a2}";
18324
18325     default:
18326       abort ();
18327     }
18328 }
18329   [(set (attr "type")
18330         (cond [(eq_attr "alternative" "0")
18331                  (const_string "alu")
18332                (match_operand:DI 2 "const0_operand" "")
18333                  (const_string "imov")
18334               ]
18335               (const_string "lea")))
18336    (set_attr "mode" "DI")])
18337
18338 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18339   [(set (match_operand:DI 0 "register_operand" "=r,r")
18340         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18341                  (match_operand:DI 3 "immediate_operand" "i,i")))
18342    (use (match_operand:DI 2 "register_operand" "r,r"))
18343    (clobber (reg:CC FLAGS_REG))
18344    (clobber (mem:BLK (scratch)))]
18345   "TARGET_64BIT"
18346 {
18347   switch (get_attr_type (insn))
18348     {
18349     case TYPE_ALU:
18350       return "add{q}\t{%2, %0|%0, %2}";
18351
18352     case TYPE_LEA:
18353       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18354       return "lea{q}\t{%a2, %0|%0, %a2}";
18355
18356     default:
18357       abort ();
18358     }
18359 }
18360   [(set_attr "type" "alu,lea")
18361    (set_attr "mode" "DI")])
18362
18363 (define_expand "allocate_stack_worker"
18364   [(match_operand:SI 0 "register_operand" "")]
18365   "TARGET_STACK_PROBE"
18366 {
18367   if (reload_completed)
18368     {
18369       if (TARGET_64BIT)
18370         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18371       else
18372         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18373     }
18374   else
18375     {
18376       if (TARGET_64BIT)
18377         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18378       else
18379         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18380     }
18381   DONE;
18382 })
18383
18384 (define_insn "allocate_stack_worker_1"
18385   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18386     UNSPECV_STACK_PROBE)
18387    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18388    (clobber (match_scratch:SI 1 "=0"))
18389    (clobber (reg:CC FLAGS_REG))]
18390   "!TARGET_64BIT && TARGET_STACK_PROBE"
18391   "call\t__alloca"
18392   [(set_attr "type" "multi")
18393    (set_attr "length" "5")])
18394
18395 (define_expand "allocate_stack_worker_postreload"
18396   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18397                                     UNSPECV_STACK_PROBE)
18398               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18399               (clobber (match_dup 0))
18400               (clobber (reg:CC FLAGS_REG))])]
18401   ""
18402   "")
18403
18404 (define_insn "allocate_stack_worker_rex64"
18405   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18406     UNSPECV_STACK_PROBE)
18407    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18408    (clobber (match_scratch:DI 1 "=0"))
18409    (clobber (reg:CC FLAGS_REG))]
18410   "TARGET_64BIT && TARGET_STACK_PROBE"
18411   "call\t__alloca"
18412   [(set_attr "type" "multi")
18413    (set_attr "length" "5")])
18414
18415 (define_expand "allocate_stack_worker_rex64_postreload"
18416   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18417                                     UNSPECV_STACK_PROBE)
18418               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18419               (clobber (match_dup 0))
18420               (clobber (reg:CC FLAGS_REG))])]
18421   ""
18422   "")
18423
18424 (define_expand "allocate_stack"
18425   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18426                    (minus:SI (reg:SI SP_REG)
18427                              (match_operand:SI 1 "general_operand" "")))
18428               (clobber (reg:CC FLAGS_REG))])
18429    (parallel [(set (reg:SI SP_REG)
18430                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18431               (clobber (reg:CC FLAGS_REG))])]
18432   "TARGET_STACK_PROBE"
18433 {
18434 #ifdef CHECK_STACK_LIMIT
18435   if (GET_CODE (operands[1]) == CONST_INT
18436       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18437     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18438                            operands[1]));
18439   else 
18440 #endif
18441     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18442                                                             operands[1])));
18443
18444   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18445   DONE;
18446 })
18447
18448 (define_expand "builtin_setjmp_receiver"
18449   [(label_ref (match_operand 0 "" ""))]
18450   "!TARGET_64BIT && flag_pic"
18451 {
18452   emit_insn (gen_set_got (pic_offset_table_rtx));
18453   DONE;
18454 })
18455 \f
18456 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18457
18458 (define_split
18459   [(set (match_operand 0 "register_operand" "")
18460         (match_operator 3 "promotable_binary_operator"
18461            [(match_operand 1 "register_operand" "")
18462             (match_operand 2 "aligned_operand" "")]))
18463    (clobber (reg:CC FLAGS_REG))]
18464   "! TARGET_PARTIAL_REG_STALL && reload_completed
18465    && ((GET_MODE (operands[0]) == HImode 
18466         && ((!optimize_size && !TARGET_FAST_PREFIX)
18467             || GET_CODE (operands[2]) != CONST_INT
18468             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18469        || (GET_MODE (operands[0]) == QImode 
18470            && (TARGET_PROMOTE_QImode || optimize_size)))"
18471   [(parallel [(set (match_dup 0)
18472                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18473               (clobber (reg:CC FLAGS_REG))])]
18474   "operands[0] = gen_lowpart (SImode, operands[0]);
18475    operands[1] = gen_lowpart (SImode, operands[1]);
18476    if (GET_CODE (operands[3]) != ASHIFT)
18477      operands[2] = gen_lowpart (SImode, operands[2]);
18478    PUT_MODE (operands[3], SImode);")
18479
18480 ; Promote the QImode tests, as i386 has encoding of the AND
18481 ; instruction with 32-bit sign-extended immediate and thus the
18482 ; instruction size is unchanged, except in the %eax case for
18483 ; which it is increased by one byte, hence the ! optimize_size.
18484 (define_split
18485   [(set (match_operand 0 "flags_reg_operand" "")
18486         (match_operator 2 "compare_operator"
18487           [(and (match_operand 3 "aligned_operand" "")
18488                 (match_operand 4 "const_int_operand" ""))
18489            (const_int 0)]))
18490    (set (match_operand 1 "register_operand" "")
18491         (and (match_dup 3) (match_dup 4)))]
18492   "! TARGET_PARTIAL_REG_STALL && reload_completed
18493    /* Ensure that the operand will remain sign-extended immediate.  */
18494    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18495    && ! optimize_size
18496    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18497        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18498   [(parallel [(set (match_dup 0)
18499                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18500                                     (const_int 0)]))
18501               (set (match_dup 1)
18502                    (and:SI (match_dup 3) (match_dup 4)))])]
18503 {
18504   operands[4]
18505     = gen_int_mode (INTVAL (operands[4])
18506                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18507   operands[1] = gen_lowpart (SImode, operands[1]);
18508   operands[3] = gen_lowpart (SImode, operands[3]);
18509 })
18510
18511 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18512 ; the TEST instruction with 32-bit sign-extended immediate and thus
18513 ; the instruction size would at least double, which is not what we
18514 ; want even with ! optimize_size.
18515 (define_split
18516   [(set (match_operand 0 "flags_reg_operand" "")
18517         (match_operator 1 "compare_operator"
18518           [(and (match_operand:HI 2 "aligned_operand" "")
18519                 (match_operand:HI 3 "const_int_operand" ""))
18520            (const_int 0)]))]
18521   "! TARGET_PARTIAL_REG_STALL && reload_completed
18522    /* Ensure that the operand will remain sign-extended immediate.  */
18523    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18524    && ! TARGET_FAST_PREFIX
18525    && ! optimize_size"
18526   [(set (match_dup 0)
18527         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18528                          (const_int 0)]))]
18529 {
18530   operands[3]
18531     = gen_int_mode (INTVAL (operands[3])
18532                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18533   operands[2] = gen_lowpart (SImode, operands[2]);
18534 })
18535
18536 (define_split
18537   [(set (match_operand 0 "register_operand" "")
18538         (neg (match_operand 1 "register_operand" "")))
18539    (clobber (reg:CC FLAGS_REG))]
18540   "! TARGET_PARTIAL_REG_STALL && reload_completed
18541    && (GET_MODE (operands[0]) == HImode
18542        || (GET_MODE (operands[0]) == QImode 
18543            && (TARGET_PROMOTE_QImode || optimize_size)))"
18544   [(parallel [(set (match_dup 0)
18545                    (neg:SI (match_dup 1)))
18546               (clobber (reg:CC FLAGS_REG))])]
18547   "operands[0] = gen_lowpart (SImode, operands[0]);
18548    operands[1] = gen_lowpart (SImode, operands[1]);")
18549
18550 (define_split
18551   [(set (match_operand 0 "register_operand" "")
18552         (not (match_operand 1 "register_operand" "")))]
18553   "! TARGET_PARTIAL_REG_STALL && reload_completed
18554    && (GET_MODE (operands[0]) == HImode
18555        || (GET_MODE (operands[0]) == QImode 
18556            && (TARGET_PROMOTE_QImode || optimize_size)))"
18557   [(set (match_dup 0)
18558         (not:SI (match_dup 1)))]
18559   "operands[0] = gen_lowpart (SImode, operands[0]);
18560    operands[1] = gen_lowpart (SImode, operands[1]);")
18561
18562 (define_split 
18563   [(set (match_operand 0 "register_operand" "")
18564         (if_then_else (match_operator 1 "comparison_operator" 
18565                                 [(reg FLAGS_REG) (const_int 0)])
18566                       (match_operand 2 "register_operand" "")
18567                       (match_operand 3 "register_operand" "")))]
18568   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18569    && (GET_MODE (operands[0]) == HImode
18570        || (GET_MODE (operands[0]) == QImode 
18571            && (TARGET_PROMOTE_QImode || optimize_size)))"
18572   [(set (match_dup 0)
18573         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18574   "operands[0] = gen_lowpart (SImode, operands[0]);
18575    operands[2] = gen_lowpart (SImode, operands[2]);
18576    operands[3] = gen_lowpart (SImode, operands[3]);")
18577                         
18578 \f
18579 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18580 ;; transform a complex memory operation into two memory to register operations.
18581
18582 ;; Don't push memory operands
18583 (define_peephole2
18584   [(set (match_operand:SI 0 "push_operand" "")
18585         (match_operand:SI 1 "memory_operand" ""))
18586    (match_scratch:SI 2 "r")]
18587   "! optimize_size && ! TARGET_PUSH_MEMORY"
18588   [(set (match_dup 2) (match_dup 1))
18589    (set (match_dup 0) (match_dup 2))]
18590   "")
18591
18592 (define_peephole2
18593   [(set (match_operand:DI 0 "push_operand" "")
18594         (match_operand:DI 1 "memory_operand" ""))
18595    (match_scratch:DI 2 "r")]
18596   "! optimize_size && ! TARGET_PUSH_MEMORY"
18597   [(set (match_dup 2) (match_dup 1))
18598    (set (match_dup 0) (match_dup 2))]
18599   "")
18600
18601 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18602 ;; SImode pushes.
18603 (define_peephole2
18604   [(set (match_operand:SF 0 "push_operand" "")
18605         (match_operand:SF 1 "memory_operand" ""))
18606    (match_scratch:SF 2 "r")]
18607   "! optimize_size && ! TARGET_PUSH_MEMORY"
18608   [(set (match_dup 2) (match_dup 1))
18609    (set (match_dup 0) (match_dup 2))]
18610   "")
18611
18612 (define_peephole2
18613   [(set (match_operand:HI 0 "push_operand" "")
18614         (match_operand:HI 1 "memory_operand" ""))
18615    (match_scratch:HI 2 "r")]
18616   "! optimize_size && ! TARGET_PUSH_MEMORY"
18617   [(set (match_dup 2) (match_dup 1))
18618    (set (match_dup 0) (match_dup 2))]
18619   "")
18620
18621 (define_peephole2
18622   [(set (match_operand:QI 0 "push_operand" "")
18623         (match_operand:QI 1 "memory_operand" ""))
18624    (match_scratch:QI 2 "q")]
18625   "! optimize_size && ! TARGET_PUSH_MEMORY"
18626   [(set (match_dup 2) (match_dup 1))
18627    (set (match_dup 0) (match_dup 2))]
18628   "")
18629
18630 ;; Don't move an immediate directly to memory when the instruction
18631 ;; gets too big.
18632 (define_peephole2
18633   [(match_scratch:SI 1 "r")
18634    (set (match_operand:SI 0 "memory_operand" "")
18635         (const_int 0))]
18636   "! optimize_size
18637    && ! TARGET_USE_MOV0
18638    && TARGET_SPLIT_LONG_MOVES
18639    && get_attr_length (insn) >= ix86_cost->large_insn
18640    && peep2_regno_dead_p (0, FLAGS_REG)"
18641   [(parallel [(set (match_dup 1) (const_int 0))
18642               (clobber (reg:CC FLAGS_REG))])
18643    (set (match_dup 0) (match_dup 1))]
18644   "")
18645
18646 (define_peephole2
18647   [(match_scratch:HI 1 "r")
18648    (set (match_operand:HI 0 "memory_operand" "")
18649         (const_int 0))]
18650   "! optimize_size
18651    && ! TARGET_USE_MOV0
18652    && TARGET_SPLIT_LONG_MOVES
18653    && get_attr_length (insn) >= ix86_cost->large_insn
18654    && peep2_regno_dead_p (0, FLAGS_REG)"
18655   [(parallel [(set (match_dup 2) (const_int 0))
18656               (clobber (reg:CC FLAGS_REG))])
18657    (set (match_dup 0) (match_dup 1))]
18658   "operands[2] = gen_lowpart (SImode, operands[1]);")
18659
18660 (define_peephole2
18661   [(match_scratch:QI 1 "q")
18662    (set (match_operand:QI 0 "memory_operand" "")
18663         (const_int 0))]
18664   "! optimize_size
18665    && ! TARGET_USE_MOV0
18666    && TARGET_SPLIT_LONG_MOVES
18667    && get_attr_length (insn) >= ix86_cost->large_insn
18668    && peep2_regno_dead_p (0, FLAGS_REG)"
18669   [(parallel [(set (match_dup 2) (const_int 0))
18670               (clobber (reg:CC FLAGS_REG))])
18671    (set (match_dup 0) (match_dup 1))]
18672   "operands[2] = gen_lowpart (SImode, operands[1]);")
18673
18674 (define_peephole2
18675   [(match_scratch:SI 2 "r")
18676    (set (match_operand:SI 0 "memory_operand" "")
18677         (match_operand:SI 1 "immediate_operand" ""))]
18678   "! optimize_size
18679    && get_attr_length (insn) >= ix86_cost->large_insn
18680    && TARGET_SPLIT_LONG_MOVES"
18681   [(set (match_dup 2) (match_dup 1))
18682    (set (match_dup 0) (match_dup 2))]
18683   "")
18684
18685 (define_peephole2
18686   [(match_scratch:HI 2 "r")
18687    (set (match_operand:HI 0 "memory_operand" "")
18688         (match_operand:HI 1 "immediate_operand" ""))]
18689   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18690   && TARGET_SPLIT_LONG_MOVES"
18691   [(set (match_dup 2) (match_dup 1))
18692    (set (match_dup 0) (match_dup 2))]
18693   "")
18694
18695 (define_peephole2
18696   [(match_scratch:QI 2 "q")
18697    (set (match_operand:QI 0 "memory_operand" "")
18698         (match_operand:QI 1 "immediate_operand" ""))]
18699   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18700   && TARGET_SPLIT_LONG_MOVES"
18701   [(set (match_dup 2) (match_dup 1))
18702    (set (match_dup 0) (match_dup 2))]
18703   "")
18704
18705 ;; Don't compare memory with zero, load and use a test instead.
18706 (define_peephole2
18707   [(set (match_operand 0 "flags_reg_operand" "")
18708         (match_operator 1 "compare_operator"
18709           [(match_operand:SI 2 "memory_operand" "")
18710            (const_int 0)]))
18711    (match_scratch:SI 3 "r")]
18712   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18713   [(set (match_dup 3) (match_dup 2))
18714    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18715   "")
18716
18717 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18718 ;; Don't split NOTs with a displacement operand, because resulting XOR
18719 ;; will not be pairable anyway.
18720 ;;
18721 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18722 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18723 ;; so this split helps here as well.
18724 ;;
18725 ;; Note: Can't do this as a regular split because we can't get proper
18726 ;; lifetime information then.
18727
18728 (define_peephole2
18729   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18730         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18731   "!optimize_size
18732    && peep2_regno_dead_p (0, FLAGS_REG)
18733    && ((TARGET_PENTIUM 
18734         && (GET_CODE (operands[0]) != MEM
18735             || !memory_displacement_operand (operands[0], SImode)))
18736        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18737   [(parallel [(set (match_dup 0)
18738                    (xor:SI (match_dup 1) (const_int -1)))
18739               (clobber (reg:CC FLAGS_REG))])]
18740   "")
18741
18742 (define_peephole2
18743   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18744         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18745   "!optimize_size
18746    && peep2_regno_dead_p (0, FLAGS_REG)
18747    && ((TARGET_PENTIUM 
18748         && (GET_CODE (operands[0]) != MEM
18749             || !memory_displacement_operand (operands[0], HImode)))
18750        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18751   [(parallel [(set (match_dup 0)
18752                    (xor:HI (match_dup 1) (const_int -1)))
18753               (clobber (reg:CC FLAGS_REG))])]
18754   "")
18755
18756 (define_peephole2
18757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18758         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18759   "!optimize_size
18760    && peep2_regno_dead_p (0, FLAGS_REG)
18761    && ((TARGET_PENTIUM 
18762         && (GET_CODE (operands[0]) != MEM
18763             || !memory_displacement_operand (operands[0], QImode)))
18764        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18765   [(parallel [(set (match_dup 0)
18766                    (xor:QI (match_dup 1) (const_int -1)))
18767               (clobber (reg:CC FLAGS_REG))])]
18768   "")
18769
18770 ;; Non pairable "test imm, reg" instructions can be translated to
18771 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18772 ;; byte opcode instead of two, have a short form for byte operands),
18773 ;; so do it for other CPUs as well.  Given that the value was dead,
18774 ;; this should not create any new dependencies.  Pass on the sub-word
18775 ;; versions if we're concerned about partial register stalls.
18776
18777 (define_peephole2
18778   [(set (match_operand 0 "flags_reg_operand" "")
18779         (match_operator 1 "compare_operator"
18780           [(and:SI (match_operand:SI 2 "register_operand" "")
18781                    (match_operand:SI 3 "immediate_operand" ""))
18782            (const_int 0)]))]
18783   "ix86_match_ccmode (insn, CCNOmode)
18784    && (true_regnum (operands[2]) != 0
18785        || (GET_CODE (operands[3]) == CONST_INT
18786            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18787    && peep2_reg_dead_p (1, operands[2])"
18788   [(parallel
18789      [(set (match_dup 0)
18790            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18791                             (const_int 0)]))
18792       (set (match_dup 2)
18793            (and:SI (match_dup 2) (match_dup 3)))])]
18794   "")
18795
18796 ;; We don't need to handle HImode case, because it will be promoted to SImode
18797 ;; on ! TARGET_PARTIAL_REG_STALL
18798
18799 (define_peephole2
18800   [(set (match_operand 0 "flags_reg_operand" "")
18801         (match_operator 1 "compare_operator"
18802           [(and:QI (match_operand:QI 2 "register_operand" "")
18803                    (match_operand:QI 3 "immediate_operand" ""))
18804            (const_int 0)]))]
18805   "! TARGET_PARTIAL_REG_STALL
18806    && ix86_match_ccmode (insn, CCNOmode)
18807    && true_regnum (operands[2]) != 0
18808    && peep2_reg_dead_p (1, operands[2])"
18809   [(parallel
18810      [(set (match_dup 0)
18811            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18812                             (const_int 0)]))
18813       (set (match_dup 2)
18814            (and:QI (match_dup 2) (match_dup 3)))])]
18815   "")
18816
18817 (define_peephole2
18818   [(set (match_operand 0 "flags_reg_operand" "")
18819         (match_operator 1 "compare_operator"
18820           [(and:SI
18821              (zero_extract:SI
18822                (match_operand 2 "ext_register_operand" "")
18823                (const_int 8)
18824                (const_int 8))
18825              (match_operand 3 "const_int_operand" ""))
18826            (const_int 0)]))]
18827   "! TARGET_PARTIAL_REG_STALL
18828    && ix86_match_ccmode (insn, CCNOmode)
18829    && true_regnum (operands[2]) != 0
18830    && peep2_reg_dead_p (1, operands[2])"
18831   [(parallel [(set (match_dup 0)
18832                    (match_op_dup 1
18833                      [(and:SI
18834                         (zero_extract:SI
18835                           (match_dup 2)
18836                           (const_int 8)
18837                           (const_int 8))
18838                         (match_dup 3))
18839                       (const_int 0)]))
18840               (set (zero_extract:SI (match_dup 2)
18841                                     (const_int 8)
18842                                     (const_int 8))
18843                    (and:SI 
18844                      (zero_extract:SI
18845                        (match_dup 2)
18846                        (const_int 8)
18847                        (const_int 8))
18848                      (match_dup 3)))])]
18849   "")
18850
18851 ;; Don't do logical operations with memory inputs.
18852 (define_peephole2
18853   [(match_scratch:SI 2 "r")
18854    (parallel [(set (match_operand:SI 0 "register_operand" "")
18855                    (match_operator:SI 3 "arith_or_logical_operator"
18856                      [(match_dup 0)
18857                       (match_operand:SI 1 "memory_operand" "")]))
18858               (clobber (reg:CC FLAGS_REG))])]
18859   "! optimize_size && ! TARGET_READ_MODIFY"
18860   [(set (match_dup 2) (match_dup 1))
18861    (parallel [(set (match_dup 0)
18862                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18863               (clobber (reg:CC FLAGS_REG))])]
18864   "")
18865
18866 (define_peephole2
18867   [(match_scratch:SI 2 "r")
18868    (parallel [(set (match_operand:SI 0 "register_operand" "")
18869                    (match_operator:SI 3 "arith_or_logical_operator"
18870                      [(match_operand:SI 1 "memory_operand" "")
18871                       (match_dup 0)]))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   "! optimize_size && ! TARGET_READ_MODIFY"
18874   [(set (match_dup 2) (match_dup 1))
18875    (parallel [(set (match_dup 0)
18876                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18877               (clobber (reg:CC FLAGS_REG))])]
18878   "")
18879
18880 ; Don't do logical operations with memory outputs
18881 ;
18882 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18883 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18884 ; the same decoder scheduling characteristics as the original.
18885
18886 (define_peephole2
18887   [(match_scratch:SI 2 "r")
18888    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18889                    (match_operator:SI 3 "arith_or_logical_operator"
18890                      [(match_dup 0)
18891                       (match_operand:SI 1 "nonmemory_operand" "")]))
18892               (clobber (reg:CC FLAGS_REG))])]
18893   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18894   [(set (match_dup 2) (match_dup 0))
18895    (parallel [(set (match_dup 2)
18896                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18897               (clobber (reg:CC FLAGS_REG))])
18898    (set (match_dup 0) (match_dup 2))]
18899   "")
18900
18901 (define_peephole2
18902   [(match_scratch:SI 2 "r")
18903    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18904                    (match_operator:SI 3 "arith_or_logical_operator"
18905                      [(match_operand:SI 1 "nonmemory_operand" "")
18906                       (match_dup 0)]))
18907               (clobber (reg:CC FLAGS_REG))])]
18908   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18909   [(set (match_dup 2) (match_dup 0))
18910    (parallel [(set (match_dup 2)
18911                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18912               (clobber (reg:CC FLAGS_REG))])
18913    (set (match_dup 0) (match_dup 2))]
18914   "")
18915
18916 ;; Attempt to always use XOR for zeroing registers.
18917 (define_peephole2
18918   [(set (match_operand 0 "register_operand" "")
18919         (match_operand 1 "const0_operand" ""))]
18920   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18921    && (! TARGET_USE_MOV0 || optimize_size)
18922    && GENERAL_REG_P (operands[0])
18923    && peep2_regno_dead_p (0, FLAGS_REG)"
18924   [(parallel [(set (match_dup 0) (const_int 0))
18925               (clobber (reg:CC FLAGS_REG))])]
18926 {
18927   operands[0] = gen_lowpart (word_mode, operands[0]);
18928 })
18929
18930 (define_peephole2
18931   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18932         (const_int 0))]
18933   "(GET_MODE (operands[0]) == QImode
18934     || GET_MODE (operands[0]) == HImode)
18935    && (! TARGET_USE_MOV0 || optimize_size)
18936    && peep2_regno_dead_p (0, FLAGS_REG)"
18937   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18938               (clobber (reg:CC FLAGS_REG))])])
18939
18940 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18941 (define_peephole2
18942   [(set (match_operand 0 "register_operand" "")
18943         (const_int -1))]
18944   "(GET_MODE (operands[0]) == HImode
18945     || GET_MODE (operands[0]) == SImode 
18946     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18947    && (optimize_size || TARGET_PENTIUM)
18948    && peep2_regno_dead_p (0, FLAGS_REG)"
18949   [(parallel [(set (match_dup 0) (const_int -1))
18950               (clobber (reg:CC FLAGS_REG))])]
18951   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18952                               operands[0]);")
18953
18954 ;; Attempt to convert simple leas to adds. These can be created by
18955 ;; move expanders.
18956 (define_peephole2
18957   [(set (match_operand:SI 0 "register_operand" "")
18958         (plus:SI (match_dup 0)
18959                  (match_operand:SI 1 "nonmemory_operand" "")))]
18960   "peep2_regno_dead_p (0, FLAGS_REG)"
18961   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18962               (clobber (reg:CC FLAGS_REG))])]
18963   "")
18964
18965 (define_peephole2
18966   [(set (match_operand:SI 0 "register_operand" "")
18967         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18968                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18969   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18970   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18971               (clobber (reg:CC FLAGS_REG))])]
18972   "operands[2] = gen_lowpart (SImode, operands[2]);")
18973
18974 (define_peephole2
18975   [(set (match_operand:DI 0 "register_operand" "")
18976         (plus:DI (match_dup 0)
18977                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18978   "peep2_regno_dead_p (0, FLAGS_REG)"
18979   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18980               (clobber (reg:CC FLAGS_REG))])]
18981   "")
18982
18983 (define_peephole2
18984   [(set (match_operand:SI 0 "register_operand" "")
18985         (mult:SI (match_dup 0)
18986                  (match_operand:SI 1 "const_int_operand" "")))]
18987   "exact_log2 (INTVAL (operands[1])) >= 0
18988    && peep2_regno_dead_p (0, FLAGS_REG)"
18989   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18990               (clobber (reg:CC FLAGS_REG))])]
18991   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18992
18993 (define_peephole2
18994   [(set (match_operand:DI 0 "register_operand" "")
18995         (mult:DI (match_dup 0)
18996                  (match_operand:DI 1 "const_int_operand" "")))]
18997   "exact_log2 (INTVAL (operands[1])) >= 0
18998    && peep2_regno_dead_p (0, FLAGS_REG)"
18999   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19000               (clobber (reg:CC FLAGS_REG))])]
19001   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19002
19003 (define_peephole2
19004   [(set (match_operand:SI 0 "register_operand" "")
19005         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19006                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19007   "exact_log2 (INTVAL (operands[2])) >= 0
19008    && REGNO (operands[0]) == REGNO (operands[1])
19009    && peep2_regno_dead_p (0, FLAGS_REG)"
19010   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19011               (clobber (reg:CC FLAGS_REG))])]
19012   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19013
19014 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19015 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19016 ;; many CPUs it is also faster, since special hardware to avoid esp
19017 ;; dependencies is present.
19018
19019 ;; While some of these conversions may be done using splitters, we use peepholes
19020 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19021
19022 ;; Convert prologue esp subtractions to push.
19023 ;; We need register to push.  In order to keep verify_flow_info happy we have
19024 ;; two choices
19025 ;; - use scratch and clobber it in order to avoid dependencies
19026 ;; - use already live register
19027 ;; We can't use the second way right now, since there is no reliable way how to
19028 ;; verify that given register is live.  First choice will also most likely in
19029 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19030 ;; call clobbered registers are dead.  We may want to use base pointer as an
19031 ;; alternative when no register is available later.
19032
19033 (define_peephole2
19034   [(match_scratch:SI 0 "r")
19035    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19036               (clobber (reg:CC FLAGS_REG))
19037               (clobber (mem:BLK (scratch)))])]
19038   "optimize_size || !TARGET_SUB_ESP_4"
19039   [(clobber (match_dup 0))
19040    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19041               (clobber (mem:BLK (scratch)))])])
19042
19043 (define_peephole2
19044   [(match_scratch:SI 0 "r")
19045    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19046               (clobber (reg:CC FLAGS_REG))
19047               (clobber (mem:BLK (scratch)))])]
19048   "optimize_size || !TARGET_SUB_ESP_8"
19049   [(clobber (match_dup 0))
19050    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19051    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19052               (clobber (mem:BLK (scratch)))])])
19053
19054 ;; Convert esp subtractions to push.
19055 (define_peephole2
19056   [(match_scratch:SI 0 "r")
19057    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19058               (clobber (reg:CC FLAGS_REG))])]
19059   "optimize_size || !TARGET_SUB_ESP_4"
19060   [(clobber (match_dup 0))
19061    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19062
19063 (define_peephole2
19064   [(match_scratch:SI 0 "r")
19065    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19066               (clobber (reg:CC FLAGS_REG))])]
19067   "optimize_size || !TARGET_SUB_ESP_8"
19068   [(clobber (match_dup 0))
19069    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19070    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19071
19072 ;; Convert epilogue deallocator to pop.
19073 (define_peephole2
19074   [(match_scratch:SI 0 "r")
19075    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19076               (clobber (reg:CC FLAGS_REG))
19077               (clobber (mem:BLK (scratch)))])]
19078   "optimize_size || !TARGET_ADD_ESP_4"
19079   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19080               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19081               (clobber (mem:BLK (scratch)))])]
19082   "")
19083
19084 ;; Two pops case is tricky, since pop causes dependency on destination register.
19085 ;; We use two registers if available.
19086 (define_peephole2
19087   [(match_scratch:SI 0 "r")
19088    (match_scratch:SI 1 "r")
19089    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19090               (clobber (reg:CC FLAGS_REG))
19091               (clobber (mem:BLK (scratch)))])]
19092   "optimize_size || !TARGET_ADD_ESP_8"
19093   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19094               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19095               (clobber (mem:BLK (scratch)))])
19096    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19097               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19098   "")
19099
19100 (define_peephole2
19101   [(match_scratch:SI 0 "r")
19102    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19103               (clobber (reg:CC FLAGS_REG))
19104               (clobber (mem:BLK (scratch)))])]
19105   "optimize_size"
19106   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19107               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19108               (clobber (mem:BLK (scratch)))])
19109    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19111   "")
19112
19113 ;; Convert esp additions to pop.
19114 (define_peephole2
19115   [(match_scratch:SI 0 "r")
19116    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19117               (clobber (reg:CC FLAGS_REG))])]
19118   ""
19119   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19120               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19121   "")
19122
19123 ;; Two pops case is tricky, since pop causes dependency on destination register.
19124 ;; We use two registers if available.
19125 (define_peephole2
19126   [(match_scratch:SI 0 "r")
19127    (match_scratch:SI 1 "r")
19128    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19129               (clobber (reg:CC FLAGS_REG))])]
19130   ""
19131   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19132               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19133    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19134               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19135   "")
19136
19137 (define_peephole2
19138   [(match_scratch:SI 0 "r")
19139    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19140               (clobber (reg:CC FLAGS_REG))])]
19141   "optimize_size"
19142   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19143               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19144    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19145               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19146   "")
19147 \f
19148 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19149 ;; required and register dies.  Similarly for 128 to plus -128.
19150 (define_peephole2
19151   [(set (match_operand 0 "flags_reg_operand" "")
19152         (match_operator 1 "compare_operator"
19153           [(match_operand 2 "register_operand" "")
19154            (match_operand 3 "const_int_operand" "")]))]
19155   "(INTVAL (operands[3]) == -1
19156     || INTVAL (operands[3]) == 1
19157     || INTVAL (operands[3]) == 128)
19158    && ix86_match_ccmode (insn, CCGCmode)
19159    && peep2_reg_dead_p (1, operands[2])"
19160   [(parallel [(set (match_dup 0)
19161                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19162               (clobber (match_dup 2))])]
19163   "")
19164 \f
19165 (define_peephole2
19166   [(match_scratch:DI 0 "r")
19167    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19168               (clobber (reg:CC FLAGS_REG))
19169               (clobber (mem:BLK (scratch)))])]
19170   "optimize_size || !TARGET_SUB_ESP_4"
19171   [(clobber (match_dup 0))
19172    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19173               (clobber (mem:BLK (scratch)))])])
19174
19175 (define_peephole2
19176   [(match_scratch:DI 0 "r")
19177    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19178               (clobber (reg:CC FLAGS_REG))
19179               (clobber (mem:BLK (scratch)))])]
19180   "optimize_size || !TARGET_SUB_ESP_8"
19181   [(clobber (match_dup 0))
19182    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19183    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19184               (clobber (mem:BLK (scratch)))])])
19185
19186 ;; Convert esp subtractions to push.
19187 (define_peephole2
19188   [(match_scratch:DI 0 "r")
19189    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19190               (clobber (reg:CC FLAGS_REG))])]
19191   "optimize_size || !TARGET_SUB_ESP_4"
19192   [(clobber (match_dup 0))
19193    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19194
19195 (define_peephole2
19196   [(match_scratch:DI 0 "r")
19197    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19198               (clobber (reg:CC FLAGS_REG))])]
19199   "optimize_size || !TARGET_SUB_ESP_8"
19200   [(clobber (match_dup 0))
19201    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19202    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19203
19204 ;; Convert epilogue deallocator to pop.
19205 (define_peephole2
19206   [(match_scratch:DI 0 "r")
19207    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19208               (clobber (reg:CC FLAGS_REG))
19209               (clobber (mem:BLK (scratch)))])]
19210   "optimize_size || !TARGET_ADD_ESP_4"
19211   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19212               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19213               (clobber (mem:BLK (scratch)))])]
19214   "")
19215
19216 ;; Two pops case is tricky, since pop causes dependency on destination register.
19217 ;; We use two registers if available.
19218 (define_peephole2
19219   [(match_scratch:DI 0 "r")
19220    (match_scratch:DI 1 "r")
19221    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19222               (clobber (reg:CC FLAGS_REG))
19223               (clobber (mem:BLK (scratch)))])]
19224   "optimize_size || !TARGET_ADD_ESP_8"
19225   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19226               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19227               (clobber (mem:BLK (scratch)))])
19228    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19229               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19230   "")
19231
19232 (define_peephole2
19233   [(match_scratch:DI 0 "r")
19234    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19235               (clobber (reg:CC FLAGS_REG))
19236               (clobber (mem:BLK (scratch)))])]
19237   "optimize_size"
19238   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19239               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19240               (clobber (mem:BLK (scratch)))])
19241    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19242               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19243   "")
19244
19245 ;; Convert esp additions to pop.
19246 (define_peephole2
19247   [(match_scratch:DI 0 "r")
19248    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   ""
19251   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19252               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19253   "")
19254
19255 ;; Two pops case is tricky, since pop causes dependency on destination register.
19256 ;; We use two registers if available.
19257 (define_peephole2
19258   [(match_scratch:DI 0 "r")
19259    (match_scratch:DI 1 "r")
19260    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19261               (clobber (reg:CC FLAGS_REG))])]
19262   ""
19263   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19264               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19265    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19266               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19267   "")
19268
19269 (define_peephole2
19270   [(match_scratch:DI 0 "r")
19271    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19272               (clobber (reg:CC FLAGS_REG))])]
19273   "optimize_size"
19274   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19275               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19276    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19277               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19278   "")
19279 \f
19280 ;; Convert imul by three, five and nine into lea
19281 (define_peephole2
19282   [(parallel
19283     [(set (match_operand:SI 0 "register_operand" "")
19284           (mult:SI (match_operand:SI 1 "register_operand" "")
19285                    (match_operand:SI 2 "const_int_operand" "")))
19286      (clobber (reg:CC FLAGS_REG))])]
19287   "INTVAL (operands[2]) == 3
19288    || INTVAL (operands[2]) == 5
19289    || INTVAL (operands[2]) == 9"
19290   [(set (match_dup 0)
19291         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19292                  (match_dup 1)))]
19293   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19294
19295 (define_peephole2
19296   [(parallel
19297     [(set (match_operand:SI 0 "register_operand" "")
19298           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19299                    (match_operand:SI 2 "const_int_operand" "")))
19300      (clobber (reg:CC FLAGS_REG))])]
19301   "!optimize_size 
19302    && (INTVAL (operands[2]) == 3
19303        || INTVAL (operands[2]) == 5
19304        || INTVAL (operands[2]) == 9)"
19305   [(set (match_dup 0) (match_dup 1))
19306    (set (match_dup 0)
19307         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19308                  (match_dup 0)))]
19309   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19310
19311 (define_peephole2
19312   [(parallel
19313     [(set (match_operand:DI 0 "register_operand" "")
19314           (mult:DI (match_operand:DI 1 "register_operand" "")
19315                    (match_operand:DI 2 "const_int_operand" "")))
19316      (clobber (reg:CC FLAGS_REG))])]
19317   "TARGET_64BIT
19318    && (INTVAL (operands[2]) == 3
19319        || INTVAL (operands[2]) == 5
19320        || INTVAL (operands[2]) == 9)"
19321   [(set (match_dup 0)
19322         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19323                  (match_dup 1)))]
19324   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19325
19326 (define_peephole2
19327   [(parallel
19328     [(set (match_operand:DI 0 "register_operand" "")
19329           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19330                    (match_operand:DI 2 "const_int_operand" "")))
19331      (clobber (reg:CC FLAGS_REG))])]
19332   "TARGET_64BIT
19333    && !optimize_size 
19334    && (INTVAL (operands[2]) == 3
19335        || INTVAL (operands[2]) == 5
19336        || INTVAL (operands[2]) == 9)"
19337   [(set (match_dup 0) (match_dup 1))
19338    (set (match_dup 0)
19339         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19340                  (match_dup 0)))]
19341   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19342
19343 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19344 ;; imul $32bit_imm, reg, reg is direct decoded.
19345 (define_peephole2
19346   [(match_scratch:DI 3 "r")
19347    (parallel [(set (match_operand:DI 0 "register_operand" "")
19348                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19349                             (match_operand:DI 2 "immediate_operand" "")))
19350               (clobber (reg:CC FLAGS_REG))])]
19351   "TARGET_K8 && !optimize_size
19352    && (GET_CODE (operands[2]) != CONST_INT
19353        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19354   [(set (match_dup 3) (match_dup 1))
19355    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19356               (clobber (reg:CC FLAGS_REG))])]
19357 "")
19358
19359 (define_peephole2
19360   [(match_scratch:SI 3 "r")
19361    (parallel [(set (match_operand:SI 0 "register_operand" "")
19362                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19363                             (match_operand:SI 2 "immediate_operand" "")))
19364               (clobber (reg:CC FLAGS_REG))])]
19365   "TARGET_K8 && !optimize_size
19366    && (GET_CODE (operands[2]) != CONST_INT
19367        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19368   [(set (match_dup 3) (match_dup 1))
19369    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19370               (clobber (reg:CC FLAGS_REG))])]
19371 "")
19372
19373 (define_peephole2
19374   [(match_scratch:SI 3 "r")
19375    (parallel [(set (match_operand:DI 0 "register_operand" "")
19376                    (zero_extend:DI
19377                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19378                               (match_operand:SI 2 "immediate_operand" ""))))
19379               (clobber (reg:CC FLAGS_REG))])]
19380   "TARGET_K8 && !optimize_size
19381    && (GET_CODE (operands[2]) != CONST_INT
19382        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19383   [(set (match_dup 3) (match_dup 1))
19384    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19385               (clobber (reg:CC FLAGS_REG))])]
19386 "")
19387
19388 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19389 ;; Convert it into imul reg, reg
19390 ;; It would be better to force assembler to encode instruction using long
19391 ;; immediate, but there is apparently no way to do so.
19392 (define_peephole2
19393   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19394                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19395                             (match_operand:DI 2 "const_int_operand" "")))
19396               (clobber (reg:CC FLAGS_REG))])
19397    (match_scratch:DI 3 "r")]
19398   "TARGET_K8 && !optimize_size
19399    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19400   [(set (match_dup 3) (match_dup 2))
19401    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19402               (clobber (reg:CC FLAGS_REG))])]
19403 {
19404   if (!rtx_equal_p (operands[0], operands[1]))
19405     emit_move_insn (operands[0], operands[1]);
19406 })
19407
19408 (define_peephole2
19409   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19410                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19411                             (match_operand:SI 2 "const_int_operand" "")))
19412               (clobber (reg:CC FLAGS_REG))])
19413    (match_scratch:SI 3 "r")]
19414   "TARGET_K8 && !optimize_size
19415    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19416   [(set (match_dup 3) (match_dup 2))
19417    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19418               (clobber (reg:CC FLAGS_REG))])]
19419 {
19420   if (!rtx_equal_p (operands[0], operands[1]))
19421     emit_move_insn (operands[0], operands[1]);
19422 })
19423
19424 (define_peephole2
19425   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19426                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19427                             (match_operand:HI 2 "immediate_operand" "")))
19428               (clobber (reg:CC FLAGS_REG))])
19429    (match_scratch:HI 3 "r")]
19430   "TARGET_K8 && !optimize_size"
19431   [(set (match_dup 3) (match_dup 2))
19432    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19433               (clobber (reg:CC FLAGS_REG))])]
19434 {
19435   if (!rtx_equal_p (operands[0], operands[1]))
19436     emit_move_insn (operands[0], operands[1]);
19437 })
19438 \f
19439 ;; Call-value patterns last so that the wildcard operand does not
19440 ;; disrupt insn-recog's switch tables.
19441
19442 (define_insn "*call_value_pop_0"
19443   [(set (match_operand 0 "" "")
19444         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19445               (match_operand:SI 2 "" "")))
19446    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19447                             (match_operand:SI 3 "immediate_operand" "")))]
19448   "!TARGET_64BIT"
19449 {
19450   if (SIBLING_CALL_P (insn))
19451     return "jmp\t%P1";
19452   else
19453     return "call\t%P1";
19454 }
19455   [(set_attr "type" "callv")])
19456
19457 (define_insn "*call_value_pop_1"
19458   [(set (match_operand 0 "" "")
19459         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19460               (match_operand:SI 2 "" "")))
19461    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19462                             (match_operand:SI 3 "immediate_operand" "i")))]
19463   "!TARGET_64BIT"
19464 {
19465   if (constant_call_address_operand (operands[1], Pmode))
19466     {
19467       if (SIBLING_CALL_P (insn))
19468         return "jmp\t%P1";
19469       else
19470         return "call\t%P1";
19471     }
19472   if (SIBLING_CALL_P (insn))
19473     return "jmp\t%A1";
19474   else
19475     return "call\t%A1";
19476 }
19477   [(set_attr "type" "callv")])
19478
19479 (define_insn "*call_value_0"
19480   [(set (match_operand 0 "" "")
19481         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19482               (match_operand:SI 2 "" "")))]
19483   "!TARGET_64BIT"
19484 {
19485   if (SIBLING_CALL_P (insn))
19486     return "jmp\t%P1";
19487   else
19488     return "call\t%P1";
19489 }
19490   [(set_attr "type" "callv")])
19491
19492 (define_insn "*call_value_0_rex64"
19493   [(set (match_operand 0 "" "")
19494         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19495               (match_operand:DI 2 "const_int_operand" "")))]
19496   "TARGET_64BIT"
19497 {
19498   if (SIBLING_CALL_P (insn))
19499     return "jmp\t%P1";
19500   else
19501     return "call\t%P1";
19502 }
19503   [(set_attr "type" "callv")])
19504
19505 (define_insn "*call_value_1"
19506   [(set (match_operand 0 "" "")
19507         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19508               (match_operand:SI 2 "" "")))]
19509   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19510 {
19511   if (constant_call_address_operand (operands[1], Pmode))
19512     return "call\t%P1";
19513   return "call\t%A1";
19514 }
19515   [(set_attr "type" "callv")])
19516
19517 (define_insn "*sibcall_value_1"
19518   [(set (match_operand 0 "" "")
19519         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19520               (match_operand:SI 2 "" "")))]
19521   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19522 {
19523   if (constant_call_address_operand (operands[1], Pmode))
19524     return "jmp\t%P1";
19525   return "jmp\t%A1";
19526 }
19527   [(set_attr "type" "callv")])
19528
19529 (define_insn "*call_value_1_rex64"
19530   [(set (match_operand 0 "" "")
19531         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19532               (match_operand:DI 2 "" "")))]
19533   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19534 {
19535   if (constant_call_address_operand (operands[1], Pmode))
19536     return "call\t%P1";
19537   return "call\t%A1";
19538 }
19539   [(set_attr "type" "callv")])
19540
19541 (define_insn "*sibcall_value_1_rex64"
19542   [(set (match_operand 0 "" "")
19543         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19544               (match_operand:DI 2 "" "")))]
19545   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19546   "jmp\t%P1"
19547   [(set_attr "type" "callv")])
19548
19549 (define_insn "*sibcall_value_1_rex64_v"
19550   [(set (match_operand 0 "" "")
19551         (call (mem:QI (reg:DI 40))
19552               (match_operand:DI 1 "" "")))]
19553   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19554   "jmp\t*%%r11"
19555   [(set_attr "type" "callv")])
19556 \f
19557 (define_insn "trap"
19558   [(trap_if (const_int 1) (const_int 5))]
19559   ""
19560   "int\t$5")
19561
19562 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19563 ;;; for the sake of bounds checking.  By emitting bounds checks as
19564 ;;; conditional traps rather than as conditional jumps around
19565 ;;; unconditional traps we avoid introducing spurious basic-block
19566 ;;; boundaries and facilitate elimination of redundant checks.  In
19567 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19568 ;;; interrupt 5.
19569 ;;; 
19570 ;;; FIXME: Static branch prediction rules for ix86 are such that
19571 ;;; forward conditional branches predict as untaken.  As implemented
19572 ;;; below, pseudo conditional traps violate that rule.  We should use
19573 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19574 ;;; section loaded at the end of the text segment and branch forward
19575 ;;; there on bounds-failure, and then jump back immediately (in case
19576 ;;; the system chooses to ignore bounds violations, or to report
19577 ;;; violations and continue execution).
19578
19579 (define_expand "conditional_trap"
19580   [(trap_if (match_operator 0 "comparison_operator"
19581              [(match_dup 2) (const_int 0)])
19582             (match_operand 1 "const_int_operand" ""))]
19583   ""
19584 {
19585   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19586                               ix86_expand_compare (GET_CODE (operands[0]),
19587                                                    NULL, NULL),
19588                               operands[1]));
19589   DONE;
19590 })
19591
19592 (define_insn "*conditional_trap_1"
19593   [(trap_if (match_operator 0 "comparison_operator"
19594              [(reg FLAGS_REG) (const_int 0)])
19595             (match_operand 1 "const_int_operand" ""))]
19596   ""
19597 {
19598   operands[2] = gen_label_rtx ();
19599   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19600   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19601                              CODE_LABEL_NUMBER (operands[2]));
19602   RET;
19603 })
19604
19605 (define_expand "sse_prologue_save"
19606   [(parallel [(set (match_operand:BLK 0 "" "")
19607                    (unspec:BLK [(reg:DI 21)
19608                                 (reg:DI 22)
19609                                 (reg:DI 23)
19610                                 (reg:DI 24)
19611                                 (reg:DI 25)
19612                                 (reg:DI 26)
19613                                 (reg:DI 27)
19614                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19615               (use (match_operand:DI 1 "register_operand" ""))
19616               (use (match_operand:DI 2 "immediate_operand" ""))
19617               (use (label_ref:DI (match_operand 3 "" "")))])]
19618   "TARGET_64BIT"
19619   "")
19620
19621 (define_insn "*sse_prologue_save_insn"
19622   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19623                           (match_operand:DI 4 "const_int_operand" "n")))
19624         (unspec:BLK [(reg:DI 21)
19625                      (reg:DI 22)
19626                      (reg:DI 23)
19627                      (reg:DI 24)
19628                      (reg:DI 25)
19629                      (reg:DI 26)
19630                      (reg:DI 27)
19631                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19632    (use (match_operand:DI 1 "register_operand" "r"))
19633    (use (match_operand:DI 2 "const_int_operand" "i"))
19634    (use (label_ref:DI (match_operand 3 "" "X")))]
19635   "TARGET_64BIT
19636    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19637    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19638   "*
19639 {
19640   int i;
19641   operands[0] = gen_rtx_MEM (Pmode,
19642                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19643   output_asm_insn (\"jmp\\t%A1\", operands);
19644   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19645     {
19646       operands[4] = adjust_address (operands[0], DImode, i*16);
19647       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19648       PUT_MODE (operands[4], TImode);
19649       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19650         output_asm_insn (\"rex\", operands);
19651       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19652     }
19653   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19654                              CODE_LABEL_NUMBER (operands[3]));
19655   RET;
19656 }
19657   "
19658   [(set_attr "type" "other")
19659    (set_attr "length_immediate" "0")
19660    (set_attr "length_address" "0")
19661    (set_attr "length" "135")
19662    (set_attr "memory" "store")
19663    (set_attr "modrm" "0")
19664    (set_attr "mode" "DI")])
19665
19666 (define_expand "prefetch"
19667   [(prefetch (match_operand 0 "address_operand" "")
19668              (match_operand:SI 1 "const_int_operand" "")
19669              (match_operand:SI 2 "const_int_operand" ""))]
19670   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19671 {
19672   int rw = INTVAL (operands[1]);
19673   int locality = INTVAL (operands[2]);
19674
19675   if (rw != 0 && rw != 1)
19676     abort ();
19677   if (locality < 0 || locality > 3)
19678     abort ();
19679   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19680     abort ();
19681
19682   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19683      supported by SSE counterpart or the SSE prefetch is not available
19684      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19685      of locality.  */
19686   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19687     operands[2] = GEN_INT (3);
19688   else
19689     operands[1] = const0_rtx;
19690 })
19691
19692 (define_insn "*prefetch_sse"
19693   [(prefetch (match_operand:SI 0 "address_operand" "p")
19694              (const_int 0)
19695              (match_operand:SI 1 "const_int_operand" ""))]
19696   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19697 {
19698   static const char * const patterns[4] = {
19699    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19700   };
19701
19702   int locality = INTVAL (operands[1]);
19703   if (locality < 0 || locality > 3)
19704     abort ();
19705
19706   return patterns[locality];  
19707 }
19708   [(set_attr "type" "sse")
19709    (set_attr "memory" "none")])
19710
19711 (define_insn "*prefetch_sse_rex"
19712   [(prefetch (match_operand:DI 0 "address_operand" "p")
19713              (const_int 0)
19714              (match_operand:SI 1 "const_int_operand" ""))]
19715   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19716 {
19717   static const char * const patterns[4] = {
19718    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19719   };
19720
19721   int locality = INTVAL (operands[1]);
19722   if (locality < 0 || locality > 3)
19723     abort ();
19724
19725   return patterns[locality];  
19726 }
19727   [(set_attr "type" "sse")
19728    (set_attr "memory" "none")])
19729
19730 (define_insn "*prefetch_3dnow"
19731   [(prefetch (match_operand:SI 0 "address_operand" "p")
19732              (match_operand:SI 1 "const_int_operand" "n")
19733              (const_int 3))]
19734   "TARGET_3DNOW && !TARGET_64BIT"
19735 {
19736   if (INTVAL (operands[1]) == 0)
19737     return "prefetch\t%a0";
19738   else
19739     return "prefetchw\t%a0";
19740 }
19741   [(set_attr "type" "mmx")
19742    (set_attr "memory" "none")])
19743
19744 (define_insn "*prefetch_3dnow_rex"
19745   [(prefetch (match_operand:DI 0 "address_operand" "p")
19746              (match_operand:SI 1 "const_int_operand" "n")
19747              (const_int 3))]
19748   "TARGET_3DNOW && TARGET_64BIT"
19749 {
19750   if (INTVAL (operands[1]) == 0)
19751     return "prefetch\t%a0";
19752   else
19753     return "prefetchw\t%a0";
19754 }
19755   [(set_attr "type" "mmx")
19756    (set_attr "memory" "none")])
19757
19758 (include "sse.md")
19759 (include "mmx.md")