OSDN Git Service

PR 17886
[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, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69
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    ; SSP patterns
143    (UNSPEC_SP_SET               100)
144    (UNSPEC_SP_TEST              101)
145    (UNSPEC_SP_TLS_SET           102)
146    (UNSPEC_SP_TLS_TEST          103)
147   ])
148
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         1)
152    (UNSPECV_EMMS                2)
153    (UNSPECV_LDMXCSR             3)
154    (UNSPECV_STMXCSR             4)
155    (UNSPECV_FEMMS               5)
156    (UNSPECV_CLFLUSH             6)
157    (UNSPECV_ALIGN               7)
158    (UNSPECV_MONITOR             8)
159    (UNSPECV_MWAIT               9)
160    (UNSPECV_CMPXCHG_1           10)
161    (UNSPECV_CMPXCHG_2           11)
162    (UNSPECV_XCHG                12)
163    (UNSPECV_LOCK                13)
164   ])
165
166 ;; Registers by name.
167 (define_constants
168   [(BP_REG                       6)
169    (SP_REG                       7)
170    (FLAGS_REG                   17)
171    (FPSR_REG                    18)
172    (DIRFLAG_REG                 19)
173   ])
174
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
177
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first.  This allows for better optimization.  For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
182
183 \f
184 ;; Processor type.  This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187   (const (symbol_ref "ix86_tune")))
188
189 ;; A basic instruction type.  Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192   "other,multi,
193    alu,alu1,negnot,imov,imovx,lea,
194    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195    icmp,test,ibr,setcc,icmov,
196    push,pop,call,callv,leave,
197    str,cld,
198    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199    sselog,sselog1,sseiadd,sseishft,sseimul,
200    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202   (const_string "other"))
203
204 ;; Main data type used by the insn
205 (define_attr "mode"
206   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207   (const_string "unknown"))
208
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212            (const_string "i387")
213          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215            (const_string "sse")
216          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217            (const_string "mmx")
218          (eq_attr "type" "other")
219            (const_string "unknown")]
220          (const_string "integer")))
221
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225            (const_int 0)
226          (eq_attr "unit" "i387,sse,mmx")
227            (const_int 0)
228          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229                           imul,icmp,push,pop")
230            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231          (eq_attr "type" "imov,test")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233          (eq_attr "type" "call")
234            (if_then_else (match_operand 0 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          (eq_attr "type" "callv")
238            (if_then_else (match_operand 1 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          ;; We don't know the size before shorten_branches.  Expect
242          ;; the instruction to fit for better scheduling.
243          (eq_attr "type" "ibr")
244            (const_int 1)
245          ]
246          (symbol_ref "/* Update immediate_length and other attributes! */
247                       gcc_unreachable (),1")))
248
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252            (const_int 0)
253          (and (eq_attr "type" "call")
254               (match_operand 0 "constant_call_address_operand" ""))
255              (const_int 0)
256          (and (eq_attr "type" "callv")
257               (match_operand 1 "constant_call_address_operand" ""))
258              (const_int 0)
259          ]
260          (symbol_ref "ix86_attr_length_address_default (insn)")))
261
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264   (if_then_else (ior (eq_attr "mode" "HI")
265                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266     (const_int 1)
267     (const_int 0)))
268
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" "" 
271   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272     (const_int 1)
273     (const_int 0)))
274
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277   (if_then_else 
278     (ior (eq_attr "type" "imovx,setcc,icmov")
279          (eq_attr "unit" "sse,mmx"))
280     (const_int 1)
281     (const_int 0)))
282
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285   (cond [(and (eq_attr "mode" "DI")
286               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287            (const_int 1)
288          (and (eq_attr "mode" "QI")
289               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290                   (const_int 0)))
291            (const_int 1)
292          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293              (const_int 0))
294            (const_int 1)
295         ]
296         (const_int 0)))
297
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300   (cond [(eq_attr "type" "str,cld,leave")
301            (const_int 0)
302          (eq_attr "unit" "i387")
303            (const_int 0)
304          (and (eq_attr "type" "incdec")
305               (ior (match_operand:SI 1 "register_operand" "")
306                    (match_operand:HI 1 "register_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "push")
309               (not (match_operand 1 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "pop")
312               (not (match_operand 0 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "imov")
315               (and (match_operand 0 "register_operand" "")
316                    (match_operand 1 "immediate_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (const_int 1)))
326
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332   (cond [(eq_attr "type" "other,multi,fistp,frndint")
333            (const_int 16)
334          (eq_attr "type" "fcmp")
335            (const_int 4)
336          (eq_attr "unit" "i387")
337            (plus (const_int 2)
338                  (plus (attr "prefix_data16")
339                        (attr "length_address")))]
340          (plus (plus (attr "modrm")
341                      (plus (attr "prefix_0f")
342                            (plus (attr "prefix_rex")
343                                  (const_int 1))))
344                (plus (attr "prefix_rep")
345                      (plus (attr "prefix_data16")
346                            (plus (attr "length_immediate")
347                                  (attr "length_address")))))))
348
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
352
353 (define_attr "memory" "none,load,store,both,unknown"
354   (cond [(eq_attr "type" "other,multi,str")
355            (const_string "unknown")
356          (eq_attr "type" "lea,fcmov,fpspc,cld")
357            (const_string "none")
358          (eq_attr "type" "fistp,leave")
359            (const_string "both")
360          (eq_attr "type" "frndint")
361            (const_string "load")
362          (eq_attr "type" "push")
363            (if_then_else (match_operand 1 "memory_operand" "")
364              (const_string "both")
365              (const_string "store"))
366          (eq_attr "type" "pop")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "both")
369              (const_string "load"))
370          (eq_attr "type" "setcc")
371            (if_then_else (match_operand 0 "memory_operand" "")
372              (const_string "store")
373              (const_string "none"))
374          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375            (if_then_else (ior (match_operand 0 "memory_operand" "")
376                               (match_operand 1 "memory_operand" ""))
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "ibr")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "load")
382              (const_string "none"))
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand" "")
389              (const_string "none")
390              (const_string "load"))
391          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (and (match_operand 0 "memory_operand" "")
395               (match_operand 1 "memory_operand" ""))
396            (const_string "both")
397          (match_operand 0 "memory_operand" "")
398            (const_string "store")
399          (match_operand 1 "memory_operand" "")
400            (const_string "load")
401          (and (eq_attr "type"
402                  "!alu1,negnot,ishift1,
403                    imov,imovx,icmp,test,
404                    fmov,fcmp,fsgn,
405                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406                    mmx,mmxmov,mmxcmp,mmxcvt")
407               (match_operand 2 "memory_operand" ""))
408            (const_string "load")
409          (and (eq_attr "type" "icmov")
410               (match_operand 3 "memory_operand" ""))
411            (const_string "load")
412         ]
413         (const_string "none")))
414
415 ;; Indicates if an instruction has both an immediate and a displacement.
416
417 (define_attr "imm_disp" "false,true,unknown"
418   (cond [(eq_attr "type" "other,multi")
419            (const_string "unknown")
420          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 1 "immediate_operand" "")))
423            (const_string "true")
424          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425               (and (match_operand 0 "memory_displacement_operand" "")
426                    (match_operand 2 "immediate_operand" "")))
427            (const_string "true")
428         ]
429         (const_string "false")))
430
431 ;; Indicates if an FP operation has an integer source.
432
433 (define_attr "fp_int_src" "false,true"
434   (const_string "false"))
435
436 ;; Defines rounding mode of an FP operation.
437
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439   (const_string "any"))
440
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443   [(set_attr "length" "128")
444    (set_attr "type" "multi")])
445
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
448  
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
451
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
454
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
457  
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
460
461 \f
462 ;; Scheduling descriptions
463
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
468
469 \f
470 ;; Operand and operator predicates
471
472 (include "predicates.md")
473
474 \f
475 ;; Compare instructions.
476
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
480
481 (define_expand "cmpti"
482   [(set (reg:CC FLAGS_REG)
483         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
484                     (match_operand:TI 1 "x86_64_general_operand" "")))]
485   "TARGET_64BIT"
486 {
487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488     operands[0] = force_reg (TImode, operands[0]);
489   ix86_compare_op0 = operands[0];
490   ix86_compare_op1 = operands[1];
491   DONE;
492 })
493
494 (define_expand "cmpdi"
495   [(set (reg:CC FLAGS_REG)
496         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
497                     (match_operand:DI 1 "x86_64_general_operand" "")))]
498   ""
499 {
500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501     operands[0] = force_reg (DImode, operands[0]);
502   ix86_compare_op0 = operands[0];
503   ix86_compare_op1 = operands[1];
504   DONE;
505 })
506
507 (define_expand "cmpsi"
508   [(set (reg:CC FLAGS_REG)
509         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
510                     (match_operand:SI 1 "general_operand" "")))]
511   ""
512 {
513   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514     operands[0] = force_reg (SImode, operands[0]);
515   ix86_compare_op0 = operands[0];
516   ix86_compare_op1 = operands[1];
517   DONE;
518 })
519
520 (define_expand "cmphi"
521   [(set (reg:CC FLAGS_REG)
522         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
523                     (match_operand:HI 1 "general_operand" "")))]
524   ""
525 {
526   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527     operands[0] = force_reg (HImode, operands[0]);
528   ix86_compare_op0 = operands[0];
529   ix86_compare_op1 = operands[1];
530   DONE;
531 })
532
533 (define_expand "cmpqi"
534   [(set (reg:CC FLAGS_REG)
535         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
536                     (match_operand:QI 1 "general_operand" "")))]
537   "TARGET_QIMODE_MATH"
538 {
539   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
540     operands[0] = force_reg (QImode, operands[0]);
541   ix86_compare_op0 = operands[0];
542   ix86_compare_op1 = operands[1];
543   DONE;
544 })
545
546 (define_insn "cmpdi_ccno_1_rex64"
547   [(set (reg FLAGS_REG)
548         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
549                  (match_operand:DI 1 "const0_operand" "n,n")))]
550   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
551   "@
552    test{q}\t{%0, %0|%0, %0}
553    cmp{q}\t{%1, %0|%0, %1}"
554   [(set_attr "type" "test,icmp")
555    (set_attr "length_immediate" "0,1")
556    (set_attr "mode" "DI")])
557
558 (define_insn "*cmpdi_minus_1_rex64"
559   [(set (reg FLAGS_REG)
560         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
561                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
562                  (const_int 0)))]
563   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
564   "cmp{q}\t{%1, %0|%0, %1}"
565   [(set_attr "type" "icmp")
566    (set_attr "mode" "DI")])
567
568 (define_expand "cmpdi_1_rex64"
569   [(set (reg:CC FLAGS_REG)
570         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
571                     (match_operand:DI 1 "general_operand" "")))]
572   "TARGET_64BIT"
573   "")
574
575 (define_insn "cmpdi_1_insn_rex64"
576   [(set (reg FLAGS_REG)
577         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
578                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
579   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
580   "cmp{q}\t{%1, %0|%0, %1}"
581   [(set_attr "type" "icmp")
582    (set_attr "mode" "DI")])
583
584
585 (define_insn "*cmpsi_ccno_1"
586   [(set (reg FLAGS_REG)
587         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
588                  (match_operand:SI 1 "const0_operand" "n,n")))]
589   "ix86_match_ccmode (insn, CCNOmode)"
590   "@
591    test{l}\t{%0, %0|%0, %0}
592    cmp{l}\t{%1, %0|%0, %1}"
593   [(set_attr "type" "test,icmp")
594    (set_attr "length_immediate" "0,1")
595    (set_attr "mode" "SI")])
596
597 (define_insn "*cmpsi_minus_1"
598   [(set (reg FLAGS_REG)
599         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
600                            (match_operand:SI 1 "general_operand" "ri,mr"))
601                  (const_int 0)))]
602   "ix86_match_ccmode (insn, CCGOCmode)"
603   "cmp{l}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "SI")])
606
607 (define_expand "cmpsi_1"
608   [(set (reg:CC FLAGS_REG)
609         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
610                     (match_operand:SI 1 "general_operand" "ri,mr")))]
611   ""
612   "")
613
614 (define_insn "*cmpsi_1_insn"
615   [(set (reg FLAGS_REG)
616         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                  (match_operand:SI 1 "general_operand" "ri,mr")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619     && ix86_match_ccmode (insn, CCmode)"
620   "cmp{l}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "SI")])
623
624 (define_insn "*cmphi_ccno_1"
625   [(set (reg FLAGS_REG)
626         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
627                  (match_operand:HI 1 "const0_operand" "n,n")))]
628   "ix86_match_ccmode (insn, CCNOmode)"
629   "@
630    test{w}\t{%0, %0|%0, %0}
631    cmp{w}\t{%1, %0|%0, %1}"
632   [(set_attr "type" "test,icmp")
633    (set_attr "length_immediate" "0,1")
634    (set_attr "mode" "HI")])
635
636 (define_insn "*cmphi_minus_1"
637   [(set (reg FLAGS_REG)
638         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
639                            (match_operand:HI 1 "general_operand" "ri,mr"))
640                  (const_int 0)))]
641   "ix86_match_ccmode (insn, CCGOCmode)"
642   "cmp{w}\t{%1, %0|%0, %1}"
643   [(set_attr "type" "icmp")
644    (set_attr "mode" "HI")])
645
646 (define_insn "*cmphi_1"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:HI 1 "general_operand" "ri,mr")))]
650   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
651    && ix86_match_ccmode (insn, CCmode)"
652   "cmp{w}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "HI")])
655
656 (define_insn "*cmpqi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
659                  (match_operand:QI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{b}\t{%0, %0|%0, %0}
663    cmp{b}\t{$0, %0|%0, 0}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "QI")])
667
668 (define_insn "*cmpqi_1"
669   [(set (reg FLAGS_REG)
670         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
671                  (match_operand:QI 1 "general_operand" "qi,mq")))]
672   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
673     && ix86_match_ccmode (insn, CCmode)"
674   "cmp{b}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "QI")])
677
678 (define_insn "*cmpqi_minus_1"
679   [(set (reg FLAGS_REG)
680         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
681                            (match_operand:QI 1 "general_operand" "qi,mq"))
682                  (const_int 0)))]
683   "ix86_match_ccmode (insn, CCGOCmode)"
684   "cmp{b}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "QI")])
687
688 (define_insn "*cmpqi_ext_1"
689   [(set (reg FLAGS_REG)
690         (compare
691           (match_operand:QI 0 "general_operand" "Qm")
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 1 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)))]
697   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%h1, %0|%0, %h1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_ext_1_rex64"
703   [(set (reg FLAGS_REG)
704         (compare
705           (match_operand:QI 0 "register_operand" "Q")
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 1 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)))]
711   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712   "cmp{b}\t{%h1, %0|%0, %h1}"
713   [(set_attr "type" "icmp")
714    (set_attr "mode" "QI")])
715
716 (define_insn "*cmpqi_ext_2"
717   [(set (reg FLAGS_REG)
718         (compare
719           (subreg:QI
720             (zero_extract:SI
721               (match_operand 0 "ext_register_operand" "Q")
722               (const_int 8)
723               (const_int 8)) 0)
724           (match_operand:QI 1 "const0_operand" "n")))]
725   "ix86_match_ccmode (insn, CCNOmode)"
726   "test{b}\t%h0, %h0"
727   [(set_attr "type" "test")
728    (set_attr "length_immediate" "0")
729    (set_attr "mode" "QI")])
730
731 (define_expand "cmpqi_ext_3"
732   [(set (reg:CC FLAGS_REG)
733         (compare:CC
734           (subreg:QI
735             (zero_extract:SI
736               (match_operand 0 "ext_register_operand" "")
737               (const_int 8)
738               (const_int 8)) 0)
739           (match_operand:QI 1 "general_operand" "")))]
740   ""
741   "")
742
743 (define_insn "cmpqi_ext_3_insn"
744   [(set (reg FLAGS_REG)
745         (compare
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 0 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)
751           (match_operand:QI 1 "general_operand" "Qmn")))]
752   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753   "cmp{b}\t{%1, %h0|%h0, %1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "QI")])
756
757 (define_insn "cmpqi_ext_3_insn_rex64"
758   [(set (reg FLAGS_REG)
759         (compare
760           (subreg:QI
761             (zero_extract:SI
762               (match_operand 0 "ext_register_operand" "Q")
763               (const_int 8)
764               (const_int 8)) 0)
765           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
766   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767   "cmp{b}\t{%1, %h0|%h0, %1}"
768   [(set_attr "type" "icmp")
769    (set_attr "mode" "QI")])
770
771 (define_insn "*cmpqi_ext_4"
772   [(set (reg FLAGS_REG)
773         (compare
774           (subreg:QI
775             (zero_extract:SI
776               (match_operand 0 "ext_register_operand" "Q")
777               (const_int 8)
778               (const_int 8)) 0)
779           (subreg:QI
780             (zero_extract:SI
781               (match_operand 1 "ext_register_operand" "Q")
782               (const_int 8)
783               (const_int 8)) 0)))]
784   "ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%h1, %h0|%h0, %h1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 ;; These implement float point compares.
790 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
791 ;; which would allow mix and match FP modes on the compares.  Which is what
792 ;; the old patterns did, but with many more of them.
793
794 (define_expand "cmpxf"
795   [(set (reg:CC FLAGS_REG)
796         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
797                     (match_operand:XF 1 "nonmemory_operand" "")))]
798   "TARGET_80387"
799 {
800   ix86_compare_op0 = operands[0];
801   ix86_compare_op1 = operands[1];
802   DONE;
803 })
804
805 (define_expand "cmpdf"
806   [(set (reg:CC FLAGS_REG)
807         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
808                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
809   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
810 {
811   ix86_compare_op0 = operands[0];
812   ix86_compare_op1 = operands[1];
813   DONE;
814 })
815
816 (define_expand "cmpsf"
817   [(set (reg:CC FLAGS_REG)
818         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
819                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
820   "TARGET_80387 || TARGET_SSE_MATH"
821 {
822   ix86_compare_op0 = operands[0];
823   ix86_compare_op1 = operands[1];
824   DONE;
825 })
826
827 ;; FP compares, step 1:
828 ;; Set the FP condition codes.
829 ;;
830 ;; CCFPmode     compare with exceptions
831 ;; CCFPUmode    compare with no exceptions
832
833 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
834 ;; used to manage the reg stack popping would not be preserved.
835
836 (define_insn "*cmpfp_0"
837   [(set (match_operand:HI 0 "register_operand" "=a")
838         (unspec:HI
839           [(compare:CCFP
840              (match_operand 1 "register_operand" "f")
841              (match_operand 2 "const0_operand" "X"))]
842         UNSPEC_FNSTSW))]
843   "TARGET_80387
844    && FLOAT_MODE_P (GET_MODE (operands[1]))
845    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
846   "* return output_fp_compare (insn, operands, 0, 0);"
847   [(set_attr "type" "multi")
848    (set_attr "unit" "i387")
849    (set (attr "mode")
850      (cond [(match_operand:SF 1 "" "")
851               (const_string "SF")
852             (match_operand:DF 1 "" "")
853               (const_string "DF")
854            ]
855            (const_string "XF")))])
856
857 (define_insn "*cmpfp_sf"
858   [(set (match_operand:HI 0 "register_operand" "=a")
859         (unspec:HI
860           [(compare:CCFP
861              (match_operand:SF 1 "register_operand" "f")
862              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
863           UNSPEC_FNSTSW))]
864   "TARGET_80387"
865   "* return output_fp_compare (insn, operands, 0, 0);"
866   [(set_attr "type" "multi")
867    (set_attr "unit" "i387")
868    (set_attr "mode" "SF")])
869
870 (define_insn "*cmpfp_df"
871   [(set (match_operand:HI 0 "register_operand" "=a")
872         (unspec:HI
873           [(compare:CCFP
874              (match_operand:DF 1 "register_operand" "f")
875              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
876           UNSPEC_FNSTSW))]
877   "TARGET_80387"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set_attr "mode" "DF")])
882
883 (define_insn "*cmpfp_xf"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFP
887              (match_operand:XF 1 "register_operand" "f")
888              (match_operand:XF 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "multi")
893    (set_attr "unit" "i387")
894    (set_attr "mode" "XF")])
895
896 (define_insn "*cmpfp_u"
897   [(set (match_operand:HI 0 "register_operand" "=a")
898         (unspec:HI
899           [(compare:CCFPU
900              (match_operand 1 "register_operand" "f")
901              (match_operand 2 "register_operand" "f"))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
906   "* return output_fp_compare (insn, operands, 0, 1);"
907   [(set_attr "type" "multi")
908    (set_attr "unit" "i387")
909    (set (attr "mode")
910      (cond [(match_operand:SF 1 "" "")
911               (const_string "SF")
912             (match_operand:DF 1 "" "")
913               (const_string "DF")
914            ]
915            (const_string "XF")))])
916
917 (define_insn "*cmpfp_<mode>"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI
920           [(compare:CCFP
921              (match_operand 1 "register_operand" "f")
922              (match_operator 3 "float_operator"
923                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
924           UNSPEC_FNSTSW))]
925   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
926    && FLOAT_MODE_P (GET_MODE (operands[1]))
927    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
928   "* return output_fp_compare (insn, operands, 0, 0);"
929   [(set_attr "type" "multi")
930    (set_attr "unit" "i387")
931    (set_attr "fp_int_src" "true")
932    (set_attr "mode" "<MODE>")])
933
934 ;; FP compares, step 2
935 ;; Move the fpsw to ax.
936
937 (define_insn "x86_fnstsw_1"
938   [(set (match_operand:HI 0 "register_operand" "=a")
939         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
940   "TARGET_80387"
941   "fnstsw\t%0"
942   [(set_attr "length" "2")
943    (set_attr "mode" "SI")
944    (set_attr "unit" "i387")])
945
946 ;; FP compares, step 3
947 ;; Get ax into flags, general case.
948
949 (define_insn "x86_sahf_1"
950   [(set (reg:CC FLAGS_REG)
951         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
952   "!TARGET_64BIT"
953   "sahf"
954   [(set_attr "length" "1")
955    (set_attr "athlon_decode" "vector")
956    (set_attr "mode" "SI")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i_mixed"
961   [(set (reg:CCFP FLAGS_REG)
962         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
963                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
964   "TARGET_MIX_SSE_I387
965    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
967   "* return output_fp_compare (insn, operands, 1, 0);"
968   [(set_attr "type" "fcmp,ssecomi")
969    (set (attr "mode")
970      (if_then_else (match_operand:SF 1 "" "")
971         (const_string "SF")
972         (const_string "DF")))
973    (set_attr "athlon_decode" "vector")])
974
975 (define_insn "*cmpfp_i_sse"
976   [(set (reg:CCFP FLAGS_REG)
977         (compare:CCFP (match_operand 0 "register_operand" "x")
978                       (match_operand 1 "nonimmediate_operand" "xm")))]
979   "TARGET_SSE_MATH
980    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982   "* return output_fp_compare (insn, operands, 1, 0);"
983   [(set_attr "type" "ssecomi")
984    (set (attr "mode")
985      (if_then_else (match_operand:SF 1 "" "")
986         (const_string "SF")
987         (const_string "DF")))
988    (set_attr "athlon_decode" "vector")])
989
990 (define_insn "*cmpfp_i_i387"
991   [(set (reg:CCFP FLAGS_REG)
992         (compare:CCFP (match_operand 0 "register_operand" "f")
993                       (match_operand 1 "register_operand" "f")))]
994   "TARGET_80387 && TARGET_CMOVE
995    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
996    && FLOAT_MODE_P (GET_MODE (operands[0]))
997    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
998   "* return output_fp_compare (insn, operands, 1, 0);"
999   [(set_attr "type" "fcmp")
1000    (set (attr "mode")
1001      (cond [(match_operand:SF 1 "" "")
1002               (const_string "SF")
1003             (match_operand:DF 1 "" "")
1004               (const_string "DF")
1005            ]
1006            (const_string "XF")))
1007    (set_attr "athlon_decode" "vector")])
1008
1009 (define_insn "*cmpfp_iu_mixed"
1010   [(set (reg:CCFPU FLAGS_REG)
1011         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1012                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1013   "TARGET_MIX_SSE_I387
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 1);"
1017   [(set_attr "type" "fcmp,ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")])
1023
1024 (define_insn "*cmpfp_iu_sse"
1025   [(set (reg:CCFPU FLAGS_REG)
1026         (compare:CCFPU (match_operand 0 "register_operand" "x")
1027                        (match_operand 1 "nonimmediate_operand" "xm")))]
1028   "TARGET_SSE_MATH
1029    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031   "* return output_fp_compare (insn, operands, 1, 1);"
1032   [(set_attr "type" "ssecomi")
1033    (set (attr "mode")
1034      (if_then_else (match_operand:SF 1 "" "")
1035         (const_string "SF")
1036         (const_string "DF")))
1037    (set_attr "athlon_decode" "vector")])
1038
1039 (define_insn "*cmpfp_iu_387"
1040   [(set (reg:CCFPU FLAGS_REG)
1041         (compare:CCFPU (match_operand 0 "register_operand" "f")
1042                        (match_operand 1 "register_operand" "f")))]
1043   "TARGET_80387 && TARGET_CMOVE
1044    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1045    && FLOAT_MODE_P (GET_MODE (operands[0]))
1046    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1047   "* return output_fp_compare (insn, operands, 1, 1);"
1048   [(set_attr "type" "fcmp")
1049    (set (attr "mode")
1050      (cond [(match_operand:SF 1 "" "")
1051               (const_string "SF")
1052             (match_operand:DF 1 "" "")
1053               (const_string "DF")
1054            ]
1055            (const_string "XF")))
1056    (set_attr "athlon_decode" "vector")])
1057 \f
1058 ;; Move instructions.
1059
1060 ;; General case of fullword move.
1061
1062 (define_expand "movsi"
1063   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1064         (match_operand:SI 1 "general_operand" ""))]
1065   ""
1066   "ix86_expand_move (SImode, operands); DONE;")
1067
1068 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1069 ;; general_operand.
1070 ;;
1071 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1072 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1073 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1074 ;; targets without our curiosities, and it is just as easy to represent
1075 ;; this differently.
1076
1077 (define_insn "*pushsi2"
1078   [(set (match_operand:SI 0 "push_operand" "=<")
1079         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1080   "!TARGET_64BIT"
1081   "push{l}\t%1"
1082   [(set_attr "type" "push")
1083    (set_attr "mode" "SI")])
1084
1085 ;; For 64BIT abi we always round up to 8 bytes.
1086 (define_insn "*pushsi2_rex64"
1087   [(set (match_operand:SI 0 "push_operand" "=X")
1088         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1089   "TARGET_64BIT"
1090   "push{q}\t%q1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1093
1094 (define_insn "*pushsi2_prologue"
1095   [(set (match_operand:SI 0 "push_operand" "=<")
1096         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1097    (clobber (mem:BLK (scratch)))]
1098   "!TARGET_64BIT"
1099   "push{l}\t%1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1102
1103 (define_insn "*popsi1_epilogue"
1104   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1105         (mem:SI (reg:SI SP_REG)))
1106    (set (reg:SI SP_REG)
1107         (plus:SI (reg:SI SP_REG) (const_int 4)))
1108    (clobber (mem:BLK (scratch)))]
1109   "!TARGET_64BIT"
1110   "pop{l}\t%0"
1111   [(set_attr "type" "pop")
1112    (set_attr "mode" "SI")])
1113
1114 (define_insn "popsi1"
1115   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1116         (mem:SI (reg:SI SP_REG)))
1117    (set (reg:SI SP_REG)
1118         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1119   "!TARGET_64BIT"
1120   "pop{l}\t%0"
1121   [(set_attr "type" "pop")
1122    (set_attr "mode" "SI")])
1123
1124 (define_insn "*movsi_xor"
1125   [(set (match_operand:SI 0 "register_operand" "=r")
1126         (match_operand:SI 1 "const0_operand" "i"))
1127    (clobber (reg:CC FLAGS_REG))]
1128   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1129   "xor{l}\t{%0, %0|%0, %0}"
1130   [(set_attr "type" "alu1")
1131    (set_attr "mode" "SI")
1132    (set_attr "length_immediate" "0")])
1133  
1134 (define_insn "*movsi_or"
1135   [(set (match_operand:SI 0 "register_operand" "=r")
1136         (match_operand:SI 1 "immediate_operand" "i"))
1137    (clobber (reg:CC FLAGS_REG))]
1138   "reload_completed
1139    && operands[1] == constm1_rtx
1140    && (TARGET_PENTIUM || optimize_size)"
1141 {
1142   operands[1] = constm1_rtx;
1143   return "or{l}\t{%1, %0|%0, %1}";
1144 }
1145   [(set_attr "type" "alu1")
1146    (set_attr "mode" "SI")
1147    (set_attr "length_immediate" "1")])
1148
1149 (define_insn "*movsi_1"
1150   [(set (match_operand:SI 0 "nonimmediate_operand"
1151                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1152         (match_operand:SI 1 "general_operand"
1153                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1154   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1155 {
1156   switch (get_attr_type (insn))
1157     {
1158     case TYPE_SSELOG1:
1159       if (get_attr_mode (insn) == MODE_TI)
1160         return "pxor\t%0, %0";
1161       return "xorps\t%0, %0";
1162
1163     case TYPE_SSEMOV:
1164       switch (get_attr_mode (insn))
1165         {
1166         case MODE_TI:
1167           return "movdqa\t{%1, %0|%0, %1}";
1168         case MODE_V4SF:
1169           return "movaps\t{%1, %0|%0, %1}";
1170         case MODE_SI:
1171           return "movd\t{%1, %0|%0, %1}";
1172         case MODE_SF:
1173           return "movss\t{%1, %0|%0, %1}";
1174         default:
1175           gcc_unreachable ();
1176         }
1177
1178     case TYPE_MMXADD:
1179       return "pxor\t%0, %0";
1180
1181     case TYPE_MMXMOV:
1182       if (get_attr_mode (insn) == MODE_DI)
1183         return "movq\t{%1, %0|%0, %1}";
1184       return "movd\t{%1, %0|%0, %1}";
1185
1186     case TYPE_LEA:
1187       return "lea{l}\t{%1, %0|%0, %1}";
1188
1189     default:
1190       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1193 }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2")
1196               (const_string "mmx")
1197             (eq_attr "alternative" "3,4,5")
1198               (const_string "mmxmov")
1199             (eq_attr "alternative" "6")
1200               (const_string "sselog1")
1201             (eq_attr "alternative" "7,8,9,10,11")
1202               (const_string "ssemov")
1203             (match_operand:DI 1 "pic_32bit_operand" "")
1204               (const_string "lea")
1205            ]
1206            (const_string "imov")))
1207    (set (attr "mode")
1208      (cond [(eq_attr "alternative" "2,3")
1209               (const_string "DI")
1210             (eq_attr "alternative" "6,7")
1211               (if_then_else
1212                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1213                 (const_string "V4SF")
1214                 (const_string "TI"))
1215             (and (eq_attr "alternative" "8,9,10,11")
1216                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1217               (const_string "SF")
1218            ]
1219            (const_string "SI")))])
1220
1221 ;; Stores and loads of ax to arbitrary constant address.
1222 ;; We fake an second form of instruction to force reload to load address
1223 ;; into register when rax is not available
1224 (define_insn "*movabssi_1_rex64"
1225   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1226         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1227   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1228   "@
1229    movabs{l}\t{%1, %P0|%P0, %1}
1230    mov{l}\t{%1, %a0|%a0, %1}"
1231   [(set_attr "type" "imov")
1232    (set_attr "modrm" "0,*")
1233    (set_attr "length_address" "8,0")
1234    (set_attr "length_immediate" "0,*")
1235    (set_attr "memory" "store")
1236    (set_attr "mode" "SI")])
1237
1238 (define_insn "*movabssi_2_rex64"
1239   [(set (match_operand:SI 0 "register_operand" "=a,r")
1240         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1241   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1242   "@
1243    movabs{l}\t{%P1, %0|%0, %P1}
1244    mov{l}\t{%a1, %0|%0, %a1}"
1245   [(set_attr "type" "imov")
1246    (set_attr "modrm" "0,*")
1247    (set_attr "length_address" "8,0")
1248    (set_attr "length_immediate" "0")
1249    (set_attr "memory" "load")
1250    (set_attr "mode" "SI")])
1251
1252 (define_insn "*swapsi"
1253   [(set (match_operand:SI 0 "register_operand" "+r")
1254         (match_operand:SI 1 "register_operand" "+r"))
1255    (set (match_dup 1)
1256         (match_dup 0))]
1257   ""
1258   "xchg{l}\t%1, %0"
1259   [(set_attr "type" "imov")
1260    (set_attr "mode" "SI")
1261    (set_attr "pent_pair" "np")
1262    (set_attr "athlon_decode" "vector")])
1263
1264 (define_expand "movhi"
1265   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1266         (match_operand:HI 1 "general_operand" ""))]
1267   ""
1268   "ix86_expand_move (HImode, operands); DONE;")
1269
1270 (define_insn "*pushhi2"
1271   [(set (match_operand:HI 0 "push_operand" "=<,<")
1272         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1273   "!TARGET_64BIT"
1274   "@
1275    push{w}\t{|WORD PTR }%1
1276    push{w}\t%1"
1277   [(set_attr "type" "push")
1278    (set_attr "mode" "HI")])
1279
1280 ;; For 64BIT abi we always round up to 8 bytes.
1281 (define_insn "*pushhi2_rex64"
1282   [(set (match_operand:HI 0 "push_operand" "=X")
1283         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1284   "TARGET_64BIT"
1285   "push{q}\t%q1"
1286   [(set_attr "type" "push")
1287    (set_attr "mode" "QI")])
1288
1289 (define_insn "*movhi_1"
1290   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1291         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1292   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1293 {
1294   switch (get_attr_type (insn))
1295     {
1296     case TYPE_IMOVX:
1297       /* movzwl is faster than movw on p2 due to partial word stalls,
1298          though not as fast as an aligned movl.  */
1299       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1300     default:
1301       if (get_attr_mode (insn) == MODE_SI)
1302         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1303       else
1304         return "mov{w}\t{%1, %0|%0, %1}";
1305     }
1306 }
1307   [(set (attr "type")
1308      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1309               (const_string "imov")
1310             (and (eq_attr "alternative" "0")
1311                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1312                           (const_int 0))
1313                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1314                           (const_int 0))))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "1,2")
1317                  (match_operand:HI 1 "aligned_operand" ""))
1318               (const_string "imov")
1319             (and (ne (symbol_ref "TARGET_MOVX")
1320                      (const_int 0))
1321                  (eq_attr "alternative" "0,2"))
1322               (const_string "imovx")
1323            ]
1324            (const_string "imov")))
1325     (set (attr "mode")
1326       (cond [(eq_attr "type" "imovx")
1327                (const_string "SI")
1328              (and (eq_attr "alternative" "1,2")
1329                   (match_operand:HI 1 "aligned_operand" ""))
1330                (const_string "SI")
1331              (and (eq_attr "alternative" "0")
1332                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333                            (const_int 0))
1334                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1335                            (const_int 0))))
1336                (const_string "SI")
1337             ]
1338             (const_string "HI")))])
1339
1340 ;; Stores and loads of ax to arbitrary constant address.
1341 ;; We fake an second form of instruction to force reload to load address
1342 ;; into register when rax is not available
1343 (define_insn "*movabshi_1_rex64"
1344   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1345         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1346   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1347   "@
1348    movabs{w}\t{%1, %P0|%P0, %1}
1349    mov{w}\t{%1, %a0|%a0, %1}"
1350   [(set_attr "type" "imov")
1351    (set_attr "modrm" "0,*")
1352    (set_attr "length_address" "8,0")
1353    (set_attr "length_immediate" "0,*")
1354    (set_attr "memory" "store")
1355    (set_attr "mode" "HI")])
1356
1357 (define_insn "*movabshi_2_rex64"
1358   [(set (match_operand:HI 0 "register_operand" "=a,r")
1359         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1360   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1361   "@
1362    movabs{w}\t{%P1, %0|%0, %P1}
1363    mov{w}\t{%a1, %0|%0, %a1}"
1364   [(set_attr "type" "imov")
1365    (set_attr "modrm" "0,*")
1366    (set_attr "length_address" "8,0")
1367    (set_attr "length_immediate" "0")
1368    (set_attr "memory" "load")
1369    (set_attr "mode" "HI")])
1370
1371 (define_insn "*swaphi_1"
1372   [(set (match_operand:HI 0 "register_operand" "+r")
1373         (match_operand:HI 1 "register_operand" "+r"))
1374    (set (match_dup 1)
1375         (match_dup 0))]
1376   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1377   "xchg{l}\t%k1, %k0"
1378   [(set_attr "type" "imov")
1379    (set_attr "mode" "SI")
1380    (set_attr "pent_pair" "np")
1381    (set_attr "athlon_decode" "vector")])
1382
1383 (define_insn "*swaphi_2"
1384   [(set (match_operand:HI 0 "register_operand" "+r")
1385         (match_operand:HI 1 "register_operand" "+r"))
1386    (set (match_dup 1)
1387         (match_dup 0))]
1388   "TARGET_PARTIAL_REG_STALL"
1389   "xchg{w}\t%1, %0"
1390   [(set_attr "type" "imov")
1391    (set_attr "mode" "HI")
1392    (set_attr "pent_pair" "np")
1393    (set_attr "athlon_decode" "vector")])
1394
1395 (define_expand "movstricthi"
1396   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1397         (match_operand:HI 1 "general_operand" ""))]
1398   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1399 {
1400   /* Don't generate memory->memory moves, go through a register */
1401   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1402     operands[1] = force_reg (HImode, operands[1]);
1403 })
1404
1405 (define_insn "*movstricthi_1"
1406   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1407         (match_operand:HI 1 "general_operand" "rn,m"))]
1408   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1409    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1410   "mov{w}\t{%1, %0|%0, %1}"
1411   [(set_attr "type" "imov")
1412    (set_attr "mode" "HI")])
1413
1414 (define_insn "*movstricthi_xor"
1415   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1416         (match_operand:HI 1 "const0_operand" "i"))
1417    (clobber (reg:CC FLAGS_REG))]
1418   "reload_completed
1419    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1420   "xor{w}\t{%0, %0|%0, %0}"
1421   [(set_attr "type" "alu1")
1422    (set_attr "mode" "HI")
1423    (set_attr "length_immediate" "0")])
1424
1425 (define_expand "movqi"
1426   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1427         (match_operand:QI 1 "general_operand" ""))]
1428   ""
1429   "ix86_expand_move (QImode, operands); DONE;")
1430
1431 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1432 ;; "push a byte".  But actually we use pushw, which has the effect
1433 ;; of rounding the amount pushed up to a halfword.
1434
1435 (define_insn "*pushqi2"
1436   [(set (match_operand:QI 0 "push_operand" "=X,X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1438   "!TARGET_64BIT"
1439   "@
1440    push{w}\t{|word ptr }%1
1441    push{w}\t%w1"
1442   [(set_attr "type" "push")
1443    (set_attr "mode" "HI")])
1444
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushqi2_rex64"
1447   [(set (match_operand:QI 0 "push_operand" "=X")
1448         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1449   "TARGET_64BIT"
1450   "push{q}\t%q1"
1451   [(set_attr "type" "push")
1452    (set_attr "mode" "QI")])
1453
1454 ;; Situation is quite tricky about when to choose full sized (SImode) move
1455 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1456 ;; partial register dependency machines (such as AMD Athlon), where QImode
1457 ;; moves issue extra dependency and for partial register stalls machines
1458 ;; that don't use QImode patterns (and QImode move cause stall on the next
1459 ;; instruction).
1460 ;;
1461 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1462 ;; register stall machines with, where we use QImode instructions, since
1463 ;; partial register stall can be caused there.  Then we use movzx.
1464 (define_insn "*movqi_1"
1465   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1466         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1467   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1468 {
1469   switch (get_attr_type (insn))
1470     {
1471     case TYPE_IMOVX:
1472       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1473       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1474     default:
1475       if (get_attr_mode (insn) == MODE_SI)
1476         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1477       else
1478         return "mov{b}\t{%1, %0|%0, %1}";
1479     }
1480 }
1481   [(set (attr "type")
1482      (cond [(eq_attr "alternative" "5")
1483               (const_string "imovx")
1484             (ne (symbol_ref "optimize_size") (const_int 0))
1485               (const_string "imov")
1486             (and (eq_attr "alternative" "3")
1487                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1488                           (const_int 0))
1489                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1490                           (const_int 0))))
1491               (const_string "imov")
1492             (eq_attr "alternative" "3")
1493               (const_string "imovx")
1494             (and (ne (symbol_ref "TARGET_MOVX")
1495                      (const_int 0))
1496                  (eq_attr "alternative" "2"))
1497               (const_string "imovx")
1498            ]
1499            (const_string "imov")))
1500    (set (attr "mode")
1501       (cond [(eq_attr "alternative" "3,4,5")
1502                (const_string "SI")
1503              (eq_attr "alternative" "6")
1504                (const_string "QI")
1505              (eq_attr "type" "imovx")
1506                (const_string "SI")
1507              (and (eq_attr "type" "imov")
1508                   (and (eq_attr "alternative" "0,1")
1509                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1510                            (const_int 0))))
1511                (const_string "SI")
1512              ;; Avoid partial register stalls when not using QImode arithmetic
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1516                                 (const_int 0))
1517                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1518                                 (const_int 0)))))
1519                (const_string "SI")
1520            ]
1521            (const_string "QI")))])
1522
1523 (define_expand "reload_outqi"
1524   [(parallel [(match_operand:QI 0 "" "=m")
1525               (match_operand:QI 1 "register_operand" "r")
1526               (match_operand:QI 2 "register_operand" "=&q")])]
1527   ""
1528 {
1529   rtx op0, op1, op2;
1530   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1531
1532   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1533   if (! q_regs_operand (op1, QImode))
1534     {
1535       emit_insn (gen_movqi (op2, op1));
1536       op1 = op2;
1537     }
1538   emit_insn (gen_movqi (op0, op1));
1539   DONE;
1540 })
1541
1542 (define_insn "*swapqi_1"
1543   [(set (match_operand:QI 0 "register_operand" "+r")
1544         (match_operand:QI 1 "register_operand" "+r"))
1545    (set (match_dup 1)
1546         (match_dup 0))]
1547   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1548   "xchg{l}\t%k1, %k0"
1549   [(set_attr "type" "imov")
1550    (set_attr "mode" "SI")
1551    (set_attr "pent_pair" "np")
1552    (set_attr "athlon_decode" "vector")])
1553
1554 (define_insn "*swapqi_2"
1555   [(set (match_operand:QI 0 "register_operand" "+q")
1556         (match_operand:QI 1 "register_operand" "+q"))
1557    (set (match_dup 1)
1558         (match_dup 0))]
1559   "TARGET_PARTIAL_REG_STALL"
1560   "xchg{b}\t%1, %0"
1561   [(set_attr "type" "imov")
1562    (set_attr "mode" "QI")
1563    (set_attr "pent_pair" "np")
1564    (set_attr "athlon_decode" "vector")])
1565
1566 (define_expand "movstrictqi"
1567   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1568         (match_operand:QI 1 "general_operand" ""))]
1569   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1570 {
1571   /* Don't generate memory->memory moves, go through a register.  */
1572   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1573     operands[1] = force_reg (QImode, operands[1]);
1574 })
1575
1576 (define_insn "*movstrictqi_1"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1578         (match_operand:QI 1 "general_operand" "*qn,m"))]
1579   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1581   "mov{b}\t{%1, %0|%0, %1}"
1582   [(set_attr "type" "imov")
1583    (set_attr "mode" "QI")])
1584
1585 (define_insn "*movstrictqi_xor"
1586   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1587         (match_operand:QI 1 "const0_operand" "i"))
1588    (clobber (reg:CC FLAGS_REG))]
1589   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1590   "xor{b}\t{%0, %0|%0, %0}"
1591   [(set_attr "type" "alu1")
1592    (set_attr "mode" "QI")
1593    (set_attr "length_immediate" "0")])
1594
1595 (define_insn "*movsi_extv_1"
1596   [(set (match_operand:SI 0 "register_operand" "=R")
1597         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1598                          (const_int 8)
1599                          (const_int 8)))]
1600   ""
1601   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1602   [(set_attr "type" "imovx")
1603    (set_attr "mode" "SI")])
1604
1605 (define_insn "*movhi_extv_1"
1606   [(set (match_operand:HI 0 "register_operand" "=R")
1607         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1614
1615 (define_insn "*movqi_extv_1"
1616   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1617         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   "!TARGET_64BIT"
1621 {
1622   switch (get_attr_type (insn))
1623     {
1624     case TYPE_IMOVX:
1625       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1626     default:
1627       return "mov{b}\t{%h1, %0|%0, %h1}";
1628     }
1629 }
1630   [(set (attr "type")
1631      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1632                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1633                              (ne (symbol_ref "TARGET_MOVX")
1634                                  (const_int 0))))
1635         (const_string "imovx")
1636         (const_string "imov")))
1637    (set (attr "mode")
1638      (if_then_else (eq_attr "type" "imovx")
1639         (const_string "SI")
1640         (const_string "QI")))])
1641
1642 (define_insn "*movqi_extv_1_rex64"
1643   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1644         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1645                          (const_int 8)
1646                          (const_int 8)))]
1647   "TARGET_64BIT"
1648 {
1649   switch (get_attr_type (insn))
1650     {
1651     case TYPE_IMOVX:
1652       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1653     default:
1654       return "mov{b}\t{%h1, %0|%0, %h1}";
1655     }
1656 }
1657   [(set (attr "type")
1658      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1659                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1660                              (ne (symbol_ref "TARGET_MOVX")
1661                                  (const_int 0))))
1662         (const_string "imovx")
1663         (const_string "imov")))
1664    (set (attr "mode")
1665      (if_then_else (eq_attr "type" "imovx")
1666         (const_string "SI")
1667         (const_string "QI")))])
1668
1669 ;; Stores and loads of ax to arbitrary constant address.
1670 ;; We fake an second form of instruction to force reload to load address
1671 ;; into register when rax is not available
1672 (define_insn "*movabsqi_1_rex64"
1673   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1674         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1675   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1676   "@
1677    movabs{b}\t{%1, %P0|%P0, %1}
1678    mov{b}\t{%1, %a0|%a0, %1}"
1679   [(set_attr "type" "imov")
1680    (set_attr "modrm" "0,*")
1681    (set_attr "length_address" "8,0")
1682    (set_attr "length_immediate" "0,*")
1683    (set_attr "memory" "store")
1684    (set_attr "mode" "QI")])
1685
1686 (define_insn "*movabsqi_2_rex64"
1687   [(set (match_operand:QI 0 "register_operand" "=a,r")
1688         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1689   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1690   "@
1691    movabs{b}\t{%P1, %0|%0, %P1}
1692    mov{b}\t{%a1, %0|%0, %a1}"
1693   [(set_attr "type" "imov")
1694    (set_attr "modrm" "0,*")
1695    (set_attr "length_address" "8,0")
1696    (set_attr "length_immediate" "0")
1697    (set_attr "memory" "load")
1698    (set_attr "mode" "QI")])
1699
1700 (define_insn "*movdi_extzv_1"
1701   [(set (match_operand:DI 0 "register_operand" "=R")
1702         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1703                          (const_int 8)
1704                          (const_int 8)))]
1705   "TARGET_64BIT"
1706   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1707   [(set_attr "type" "imovx")
1708    (set_attr "mode" "DI")])
1709
1710 (define_insn "*movsi_extzv_1"
1711   [(set (match_operand:SI 0 "register_operand" "=R")
1712         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   ""
1716   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "SI")])
1719
1720 (define_insn "*movqi_extzv_2"
1721   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1722         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1723                                     (const_int 8)
1724                                     (const_int 8)) 0))]
1725   "!TARGET_64BIT"
1726 {
1727   switch (get_attr_type (insn))
1728     {
1729     case TYPE_IMOVX:
1730       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1731     default:
1732       return "mov{b}\t{%h1, %0|%0, %h1}";
1733     }
1734 }
1735   [(set (attr "type")
1736      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1737                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1738                              (ne (symbol_ref "TARGET_MOVX")
1739                                  (const_int 0))))
1740         (const_string "imovx")
1741         (const_string "imov")))
1742    (set (attr "mode")
1743      (if_then_else (eq_attr "type" "imovx")
1744         (const_string "SI")
1745         (const_string "QI")))])
1746
1747 (define_insn "*movqi_extzv_2_rex64"
1748   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1749         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1750                                     (const_int 8)
1751                                     (const_int 8)) 0))]
1752   "TARGET_64BIT"
1753 {
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_IMOVX:
1757       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1758     default:
1759       return "mov{b}\t{%h1, %0|%0, %h1}";
1760     }
1761 }
1762   [(set (attr "type")
1763      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1764                         (ne (symbol_ref "TARGET_MOVX")
1765                             (const_int 0)))
1766         (const_string "imovx")
1767         (const_string "imov")))
1768    (set (attr "mode")
1769      (if_then_else (eq_attr "type" "imovx")
1770         (const_string "SI")
1771         (const_string "QI")))])
1772
1773 (define_insn "movsi_insv_1"
1774   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1775                          (const_int 8)
1776                          (const_int 8))
1777         (match_operand:SI 1 "general_operand" "Qmn"))]
1778   "!TARGET_64BIT"
1779   "mov{b}\t{%b1, %h0|%h0, %b1}"
1780   [(set_attr "type" "imov")
1781    (set_attr "mode" "QI")])
1782
1783 (define_insn "movdi_insv_1_rex64"
1784   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1788   "TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1792
1793 (define_insn "*movqi_insv_2"
1794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1798                      (const_int 8)))]
1799   ""
1800   "mov{b}\t{%h1, %h0|%h0, %h1}"
1801   [(set_attr "type" "imov")
1802    (set_attr "mode" "QI")])
1803
1804 (define_expand "movdi"
1805   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1806         (match_operand:DI 1 "general_operand" ""))]
1807   ""
1808   "ix86_expand_move (DImode, operands); DONE;")
1809
1810 (define_insn "*pushdi"
1811   [(set (match_operand:DI 0 "push_operand" "=<")
1812         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1813   "!TARGET_64BIT"
1814   "#")
1815
1816 (define_insn "*pushdi2_rex64"
1817   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1818         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1819   "TARGET_64BIT"
1820   "@
1821    push{q}\t%1
1822    #"
1823   [(set_attr "type" "push,multi")
1824    (set_attr "mode" "DI")])
1825
1826 ;; Convert impossible pushes of immediate to existing instructions.
1827 ;; First try to get scratch register and go through it.  In case this
1828 ;; fails, push sign extended lower part first and then overwrite
1829 ;; upper part by 32bit move.
1830 (define_peephole2
1831   [(match_scratch:DI 2 "r")
1832    (set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835    && !x86_64_immediate_operand (operands[1], DImode)"
1836   [(set (match_dup 2) (match_dup 1))
1837    (set (match_dup 0) (match_dup 2))]
1838   "")
1839
1840 ;; We need to define this as both peepholer and splitter for case
1841 ;; peephole2 pass is not run.
1842 ;; "&& 1" is needed to keep it from matching the previous pattern.
1843 (define_peephole2
1844   [(set (match_operand:DI 0 "push_operand" "")
1845         (match_operand:DI 1 "immediate_operand" ""))]
1846   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1847    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1848   [(set (match_dup 0) (match_dup 1))
1849    (set (match_dup 2) (match_dup 3))]
1850   "split_di (operands + 1, 1, operands + 2, operands + 3);
1851    operands[1] = gen_lowpart (DImode, operands[2]);
1852    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1853                                                     GEN_INT (4)));
1854   ")
1855
1856 (define_split
1857   [(set (match_operand:DI 0 "push_operand" "")
1858         (match_operand:DI 1 "immediate_operand" ""))]
1859   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1860    && !symbolic_operand (operands[1], DImode)
1861    && !x86_64_immediate_operand (operands[1], DImode)"
1862   [(set (match_dup 0) (match_dup 1))
1863    (set (match_dup 2) (match_dup 3))]
1864   "split_di (operands + 1, 1, operands + 2, operands + 3);
1865    operands[1] = gen_lowpart (DImode, operands[2]);
1866    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867                                                     GEN_INT (4)));
1868   ")
1869
1870 (define_insn "*pushdi2_prologue_rex64"
1871   [(set (match_operand:DI 0 "push_operand" "=<")
1872         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1873    (clobber (mem:BLK (scratch)))]
1874   "TARGET_64BIT"
1875   "push{q}\t%1"
1876   [(set_attr "type" "push")
1877    (set_attr "mode" "DI")])
1878
1879 (define_insn "*popdi1_epilogue_rex64"
1880   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881         (mem:DI (reg:DI SP_REG)))
1882    (set (reg:DI SP_REG)
1883         (plus:DI (reg:DI SP_REG) (const_int 8)))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "pop{q}\t%0"
1887   [(set_attr "type" "pop")
1888    (set_attr "mode" "DI")])
1889
1890 (define_insn "popdi1"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1899
1900 (define_insn "*movdi_xor_rex64"
1901   [(set (match_operand:DI 0 "register_operand" "=r")
1902         (match_operand:DI 1 "const0_operand" "i"))
1903    (clobber (reg:CC FLAGS_REG))]
1904   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1905    && reload_completed"
1906   "xor{l}\t{%k0, %k0|%k0, %k0}"
1907   [(set_attr "type" "alu1")
1908    (set_attr "mode" "SI")
1909    (set_attr "length_immediate" "0")])
1910
1911 (define_insn "*movdi_or_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const_int_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1916    && reload_completed
1917    && operands[1] == constm1_rtx"
1918 {
1919   operands[1] = constm1_rtx;
1920   return "or{q}\t{%1, %0|%0, %1}";
1921 }
1922   [(set_attr "type" "alu1")
1923    (set_attr "mode" "DI")
1924    (set_attr "length_immediate" "1")])
1925
1926 (define_insn "*movdi_2"
1927   [(set (match_operand:DI 0 "nonimmediate_operand"
1928                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1929         (match_operand:DI 1 "general_operand"
1930                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1931   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932   "@
1933    #
1934    #
1935    pxor\t%0, %0
1936    movq\t{%1, %0|%0, %1}
1937    movq\t{%1, %0|%0, %1}
1938    pxor\t%0, %0
1939    movq\t{%1, %0|%0, %1}
1940    movdqa\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    xorps\t%0, %0
1943    movlps\t{%1, %0|%0, %1}
1944    movaps\t{%1, %0|%0, %1}
1945    movlps\t{%1, %0|%0, %1}"
1946   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1947    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1948
1949 (define_split
1950   [(set (match_operand:DI 0 "push_operand" "")
1951         (match_operand:DI 1 "general_operand" ""))]
1952   "!TARGET_64BIT && reload_completed
1953    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1954   [(const_int 0)]
1955   "ix86_split_long_move (operands); DONE;")
1956
1957 ;; %%% This multiword shite has got to go.
1958 (define_split
1959   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1960         (match_operand:DI 1 "general_operand" ""))]
1961   "!TARGET_64BIT && reload_completed
1962    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1963    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1966
1967 (define_insn "*movdi_1_rex64"
1968   [(set (match_operand:DI 0 "nonimmediate_operand"
1969                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1970         (match_operand:DI 1 "general_operand"
1971                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1972   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1973 {
1974   switch (get_attr_type (insn))
1975     {
1976     case TYPE_SSECVT:
1977       if (which_alternative == 13)
1978         return "movq2dq\t{%1, %0|%0, %1}";
1979       else
1980         return "movdq2q\t{%1, %0|%0, %1}";
1981     case TYPE_SSEMOV:
1982       if (get_attr_mode (insn) == MODE_TI)
1983           return "movdqa\t{%1, %0|%0, %1}";
1984       /* FALLTHRU */
1985     case TYPE_MMXMOV:
1986       /* Moves from and into integer register is done using movd opcode with
1987          REX prefix.  */
1988       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1989           return "movd\t{%1, %0|%0, %1}";
1990       return "movq\t{%1, %0|%0, %1}";
1991     case TYPE_SSELOG1:
1992     case TYPE_MMXADD:
1993       return "pxor\t%0, %0";
1994     case TYPE_MULTI:
1995       return "#";
1996     case TYPE_LEA:
1997       return "lea{q}\t{%a1, %0|%0, %a1}";
1998     default:
1999       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000       if (get_attr_mode (insn) == MODE_SI)
2001         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002       else if (which_alternative == 2)
2003         return "movabs{q}\t{%1, %0|%0, %1}";
2004       else
2005         return "mov{q}\t{%1, %0|%0, %1}";
2006     }
2007 }
2008   [(set (attr "type")
2009      (cond [(eq_attr "alternative" "5")
2010               (const_string "mmx")
2011             (eq_attr "alternative" "6,7,8")
2012               (const_string "mmxmov")
2013             (eq_attr "alternative" "9")
2014               (const_string "sselog1")
2015             (eq_attr "alternative" "10,11,12")
2016               (const_string "ssemov")
2017             (eq_attr "alternative" "13,14")
2018               (const_string "ssecvt")
2019             (eq_attr "alternative" "4")
2020               (const_string "multi")
2021             (match_operand:DI 1 "pic_32bit_operand" "")
2022               (const_string "lea")
2023            ]
2024            (const_string "imov")))
2025    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2026    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2027    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2028
2029 ;; Stores and loads of ax to arbitrary constant address.
2030 ;; We fake an second form of instruction to force reload to load address
2031 ;; into register when rax is not available
2032 (define_insn "*movabsdi_1_rex64"
2033   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2034         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2035   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2036   "@
2037    movabs{q}\t{%1, %P0|%P0, %1}
2038    mov{q}\t{%1, %a0|%a0, %1}"
2039   [(set_attr "type" "imov")
2040    (set_attr "modrm" "0,*")
2041    (set_attr "length_address" "8,0")
2042    (set_attr "length_immediate" "0,*")
2043    (set_attr "memory" "store")
2044    (set_attr "mode" "DI")])
2045
2046 (define_insn "*movabsdi_2_rex64"
2047   [(set (match_operand:DI 0 "register_operand" "=a,r")
2048         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2049   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2050   "@
2051    movabs{q}\t{%P1, %0|%0, %P1}
2052    mov{q}\t{%a1, %0|%0, %a1}"
2053   [(set_attr "type" "imov")
2054    (set_attr "modrm" "0,*")
2055    (set_attr "length_address" "8,0")
2056    (set_attr "length_immediate" "0")
2057    (set_attr "memory" "load")
2058    (set_attr "mode" "DI")])
2059
2060 ;; Convert impossible stores of immediate to existing instructions.
2061 ;; First try to get scratch register and go through it.  In case this
2062 ;; fails, move by 32bit parts.
2063 (define_peephole2
2064   [(match_scratch:DI 2 "r")
2065    (set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "immediate_operand" ""))]
2067   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068    && !x86_64_immediate_operand (operands[1], DImode)"
2069   [(set (match_dup 2) (match_dup 1))
2070    (set (match_dup 0) (match_dup 2))]
2071   "")
2072
2073 ;; We need to define this as both peepholer and splitter for case
2074 ;; peephole2 pass is not run.
2075 ;; "&& 1" is needed to keep it from matching the previous pattern.
2076 (define_peephole2
2077   [(set (match_operand:DI 0 "memory_operand" "")
2078         (match_operand:DI 1 "immediate_operand" ""))]
2079   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2081   [(set (match_dup 2) (match_dup 3))
2082    (set (match_dup 4) (match_dup 5))]
2083   "split_di (operands, 2, operands + 2, operands + 4);")
2084
2085 (define_split
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2089    && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode)"
2091   [(set (match_dup 2) (match_dup 3))
2092    (set (match_dup 4) (match_dup 5))]
2093   "split_di (operands, 2, operands + 2, operands + 4);")
2094
2095 (define_insn "*swapdi_rex64"
2096   [(set (match_operand:DI 0 "register_operand" "+r")
2097         (match_operand:DI 1 "register_operand" "+r"))
2098    (set (match_dup 1)
2099         (match_dup 0))]
2100   "TARGET_64BIT"
2101   "xchg{q}\t%1, %0"
2102   [(set_attr "type" "imov")
2103    (set_attr "mode" "DI")
2104    (set_attr "pent_pair" "np")
2105    (set_attr "athlon_decode" "vector")])
2106
2107 (define_expand "movti"
2108   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2109         (match_operand:TI 1 "nonimmediate_operand" ""))]
2110   "TARGET_SSE || TARGET_64BIT"
2111 {
2112   if (TARGET_64BIT)
2113     ix86_expand_move (TImode, operands);
2114   else
2115     ix86_expand_vector_move (TImode, operands);
2116   DONE;
2117 })
2118
2119 (define_insn "*movti_internal"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2121         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2122   "TARGET_SSE && !TARGET_64BIT
2123    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2124 {
2125   switch (which_alternative)
2126     {
2127     case 0:
2128       if (get_attr_mode (insn) == MODE_V4SF)
2129         return "xorps\t%0, %0";
2130       else
2131         return "pxor\t%0, %0";
2132     case 1:
2133     case 2:
2134       if (get_attr_mode (insn) == MODE_V4SF)
2135         return "movaps\t{%1, %0|%0, %1}";
2136       else
2137         return "movdqa\t{%1, %0|%0, %1}";
2138     default:
2139       gcc_unreachable ();
2140     }
2141 }
2142   [(set_attr "type" "ssemov,ssemov,ssemov")
2143    (set (attr "mode")
2144         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2145                  (const_string "V4SF")
2146
2147                (eq_attr "alternative" "0,1")
2148                  (if_then_else
2149                    (ne (symbol_ref "optimize_size")
2150                        (const_int 0))
2151                    (const_string "V4SF")
2152                    (const_string "TI"))
2153                (eq_attr "alternative" "2")
2154                  (if_then_else
2155                    (ne (symbol_ref "optimize_size")
2156                        (const_int 0))
2157                    (const_string "V4SF")
2158                    (const_string "TI"))]
2159                (const_string "TI")))])
2160
2161 (define_insn "*movti_rex64"
2162   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2163         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2164   "TARGET_64BIT
2165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2166 {
2167   switch (which_alternative)
2168     {
2169     case 0:
2170     case 1:
2171       return "#";
2172     case 2:
2173       if (get_attr_mode (insn) == MODE_V4SF)
2174         return "xorps\t%0, %0";
2175       else
2176         return "pxor\t%0, %0";
2177     case 3:
2178     case 4:
2179       if (get_attr_mode (insn) == MODE_V4SF)
2180         return "movaps\t{%1, %0|%0, %1}";
2181       else
2182         return "movdqa\t{%1, %0|%0, %1}";
2183     default:
2184       gcc_unreachable ();
2185     }
2186 }
2187   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2188    (set (attr "mode")
2189         (cond [(eq_attr "alternative" "2,3")
2190                  (if_then_else
2191                    (ne (symbol_ref "optimize_size")
2192                        (const_int 0))
2193                    (const_string "V4SF")
2194                    (const_string "TI"))
2195                (eq_attr "alternative" "4")
2196                  (if_then_else
2197                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2198                             (const_int 0))
2199                         (ne (symbol_ref "optimize_size")
2200                             (const_int 0)))
2201                    (const_string "V4SF")
2202                    (const_string "TI"))]
2203                (const_string "DI")))])
2204
2205 (define_split
2206   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2207         (match_operand:TI 1 "general_operand" ""))]
2208   "reload_completed && !SSE_REG_P (operands[0])
2209    && !SSE_REG_P (operands[1])"
2210   [(const_int 0)]
2211   "ix86_split_long_move (operands); DONE;")
2212
2213 (define_expand "movsf"
2214   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2215         (match_operand:SF 1 "general_operand" ""))]
2216   ""
2217   "ix86_expand_move (SFmode, operands); DONE;")
2218
2219 (define_insn "*pushsf"
2220   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2221         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2222   "!TARGET_64BIT"
2223 {
2224   /* Anything else should be already split before reg-stack.  */
2225   gcc_assert (which_alternative == 1);
2226   return "push{l}\t%1";
2227 }
2228   [(set_attr "type" "multi,push,multi")
2229    (set_attr "unit" "i387,*,*")
2230    (set_attr "mode" "SF,SI,SF")])
2231
2232 (define_insn "*pushsf_rex64"
2233   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2234         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2235   "TARGET_64BIT"
2236 {
2237   /* Anything else should be already split before reg-stack.  */
2238   gcc_assert (which_alternative == 1);
2239   return "push{q}\t%q1";
2240 }
2241   [(set_attr "type" "multi,push,multi")
2242    (set_attr "unit" "i387,*,*")
2243    (set_attr "mode" "SF,DI,SF")])
2244
2245 (define_split
2246   [(set (match_operand:SF 0 "push_operand" "")
2247         (match_operand:SF 1 "memory_operand" ""))]
2248   "reload_completed
2249    && GET_CODE (operands[1]) == MEM
2250    && constant_pool_reference_p (operands[1])"
2251   [(set (match_dup 0)
2252         (match_dup 1))]
2253   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2254
2255
2256 ;; %%% Kill this when call knows how to work this out.
2257 (define_split
2258   [(set (match_operand:SF 0 "push_operand" "")
2259         (match_operand:SF 1 "any_fp_register_operand" ""))]
2260   "!TARGET_64BIT"
2261   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2262    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2263
2264 (define_split
2265   [(set (match_operand:SF 0 "push_operand" "")
2266         (match_operand:SF 1 "any_fp_register_operand" ""))]
2267   "TARGET_64BIT"
2268   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2269    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2270
2271 (define_insn "*movsf_1"
2272   [(set (match_operand:SF 0 "nonimmediate_operand"
2273           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2274         (match_operand:SF 1 "general_operand"
2275           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2276   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2277    && (reload_in_progress || reload_completed
2278        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2279        || GET_CODE (operands[1]) != CONST_DOUBLE
2280        || memory_operand (operands[0], SFmode))" 
2281 {
2282   switch (which_alternative)
2283     {
2284     case 0:
2285       return output_387_reg_move (insn, operands);
2286
2287     case 1:
2288       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2289         return "fstp%z0\t%y0";
2290       else
2291         return "fst%z0\t%y0";
2292
2293     case 2:
2294       return standard_80387_constant_opcode (operands[1]);
2295
2296     case 3:
2297     case 4:
2298       return "mov{l}\t{%1, %0|%0, %1}";
2299     case 5:
2300       if (get_attr_mode (insn) == MODE_TI)
2301         return "pxor\t%0, %0";
2302       else
2303         return "xorps\t%0, %0";
2304     case 6:
2305       if (get_attr_mode (insn) == MODE_V4SF)
2306         return "movaps\t{%1, %0|%0, %1}";
2307       else
2308         return "movss\t{%1, %0|%0, %1}";
2309     case 7:
2310     case 8:
2311       return "movss\t{%1, %0|%0, %1}";
2312
2313     case 9:
2314     case 10:
2315       return "movd\t{%1, %0|%0, %1}";
2316
2317     case 11:
2318       return "movq\t{%1, %0|%0, %1}";
2319
2320     default:
2321       gcc_unreachable ();
2322     }
2323 }
2324   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2325    (set (attr "mode")
2326         (cond [(eq_attr "alternative" "3,4,9,10")
2327                  (const_string "SI")
2328                (eq_attr "alternative" "5")
2329                  (if_then_else
2330                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2331                                  (const_int 0))
2332                              (ne (symbol_ref "TARGET_SSE2")
2333                                  (const_int 0)))
2334                         (eq (symbol_ref "optimize_size")
2335                             (const_int 0)))
2336                    (const_string "TI")
2337                    (const_string "V4SF"))
2338                /* For architectures resolving dependencies on
2339                   whole SSE registers use APS move to break dependency
2340                   chains, otherwise use short move to avoid extra work. 
2341
2342                   Do the same for architectures resolving dependencies on
2343                   the parts.  While in DF mode it is better to always handle
2344                   just register parts, the SF mode is different due to lack
2345                   of instructions to load just part of the register.  It is
2346                   better to maintain the whole registers in single format
2347                   to avoid problems on using packed logical operations.  */
2348                (eq_attr "alternative" "6")
2349                  (if_then_else
2350                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2351                             (const_int 0))
2352                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2353                             (const_int 0)))
2354                    (const_string "V4SF")
2355                    (const_string "SF"))
2356                (eq_attr "alternative" "11")
2357                  (const_string "DI")]
2358                (const_string "SF")))])
2359
2360 (define_insn "*swapsf"
2361   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2362         (match_operand:SF 1 "fp_register_operand" "+f"))
2363    (set (match_dup 1)
2364         (match_dup 0))]
2365   "reload_completed || TARGET_80387"
2366 {
2367   if (STACK_TOP_P (operands[0]))
2368     return "fxch\t%1";
2369   else
2370     return "fxch\t%0";
2371 }
2372   [(set_attr "type" "fxch")
2373    (set_attr "mode" "SF")])
2374
2375 (define_expand "movdf"
2376   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2377         (match_operand:DF 1 "general_operand" ""))]
2378   ""
2379   "ix86_expand_move (DFmode, operands); DONE;")
2380
2381 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2382 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2383 ;; On the average, pushdf using integers can be still shorter.  Allow this
2384 ;; pattern for optimize_size too.
2385
2386 (define_insn "*pushdf_nointeger"
2387   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2388         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2389   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2390 {
2391   /* This insn should be already split before reg-stack.  */
2392   gcc_unreachable ();
2393 }
2394   [(set_attr "type" "multi")
2395    (set_attr "unit" "i387,*,*,*")
2396    (set_attr "mode" "DF,SI,SI,DF")])
2397
2398 (define_insn "*pushdf_integer"
2399   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2400         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2401   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2402 {
2403   /* This insn should be already split before reg-stack.  */
2404   gcc_unreachable ();
2405 }
2406   [(set_attr "type" "multi")
2407    (set_attr "unit" "i387,*,*")
2408    (set_attr "mode" "DF,SI,DF")])
2409
2410 ;; %%% Kill this when call knows how to work this out.
2411 (define_split
2412   [(set (match_operand:DF 0 "push_operand" "")
2413         (match_operand:DF 1 "any_fp_register_operand" ""))]
2414   "!TARGET_64BIT && reload_completed"
2415   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2416    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2417   "")
2418
2419 (define_split
2420   [(set (match_operand:DF 0 "push_operand" "")
2421         (match_operand:DF 1 "any_fp_register_operand" ""))]
2422   "TARGET_64BIT && reload_completed"
2423   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2424    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2425   "")
2426
2427 (define_split
2428   [(set (match_operand:DF 0 "push_operand" "")
2429         (match_operand:DF 1 "general_operand" ""))]
2430   "reload_completed"
2431   [(const_int 0)]
2432   "ix86_split_long_move (operands); DONE;")
2433
2434 ;; Moving is usually shorter when only FP registers are used. This separate
2435 ;; movdf pattern avoids the use of integer registers for FP operations
2436 ;; when optimizing for size.
2437
2438 (define_insn "*movdf_nointeger"
2439   [(set (match_operand:DF 0 "nonimmediate_operand"
2440                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2441         (match_operand:DF 1 "general_operand"
2442                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2443   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2444    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2445    && (reload_in_progress || reload_completed
2446        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2447        || GET_CODE (operands[1]) != CONST_DOUBLE
2448        || memory_operand (operands[0], DFmode))" 
2449 {
2450   switch (which_alternative)
2451     {
2452     case 0:
2453       return output_387_reg_move (insn, operands);
2454
2455     case 1:
2456       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2457         return "fstp%z0\t%y0";
2458       else
2459         return "fst%z0\t%y0";
2460
2461     case 2:
2462       return standard_80387_constant_opcode (operands[1]);
2463
2464     case 3:
2465     case 4:
2466       return "#";
2467     case 5:
2468       switch (get_attr_mode (insn))
2469         {
2470         case MODE_V4SF:
2471           return "xorps\t%0, %0";
2472         case MODE_V2DF:
2473           return "xorpd\t%0, %0";
2474         case MODE_TI:
2475           return "pxor\t%0, %0";
2476         default:
2477           gcc_unreachable ();
2478         }
2479     case 6:
2480     case 7:
2481     case 8:
2482       switch (get_attr_mode (insn))
2483         {
2484         case MODE_V4SF:
2485           return "movaps\t{%1, %0|%0, %1}";
2486         case MODE_V2DF:
2487           return "movapd\t{%1, %0|%0, %1}";
2488         case MODE_TI:
2489           return "movdqa\t{%1, %0|%0, %1}";
2490         case MODE_DI:
2491           return "movq\t{%1, %0|%0, %1}";
2492         case MODE_DF:
2493           return "movsd\t{%1, %0|%0, %1}";
2494         case MODE_V1DF:
2495           return "movlpd\t{%1, %0|%0, %1}";
2496         case MODE_V2SF:
2497           return "movlps\t{%1, %0|%0, %1}";
2498         default:
2499           gcc_unreachable ();
2500         }
2501
2502     default:
2503       gcc_unreachable ();
2504     }
2505 }
2506   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2507    (set (attr "mode")
2508         (cond [(eq_attr "alternative" "0,1,2")
2509                  (const_string "DF")
2510                (eq_attr "alternative" "3,4")
2511                  (const_string "SI")
2512
2513                /* For SSE1, we have many fewer alternatives.  */
2514                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2515                  (cond [(eq_attr "alternative" "5,6")
2516                           (const_string "V4SF")
2517                        ]
2518                    (const_string "V2SF"))
2519
2520                /* xorps is one byte shorter.  */
2521                (eq_attr "alternative" "5")
2522                  (cond [(ne (symbol_ref "optimize_size")
2523                             (const_int 0))
2524                           (const_string "V4SF")
2525                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2526                             (const_int 0))
2527                           (const_string "TI")
2528                        ]
2529                        (const_string "V2DF"))
2530
2531                /* For architectures resolving dependencies on
2532                   whole SSE registers use APD move to break dependency
2533                   chains, otherwise use short move to avoid extra work.
2534
2535                   movaps encodes one byte shorter.  */
2536                (eq_attr "alternative" "6")
2537                  (cond
2538                    [(ne (symbol_ref "optimize_size")
2539                         (const_int 0))
2540                       (const_string "V4SF")
2541                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2542                         (const_int 0))
2543                       (const_string "V2DF")
2544                    ]
2545                    (const_string "DF"))
2546                /* For architectures resolving dependencies on register
2547                   parts we may avoid extra work to zero out upper part
2548                   of register.  */
2549                (eq_attr "alternative" "7")
2550                  (if_then_else
2551                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2552                        (const_int 0))
2553                    (const_string "V1DF")
2554                    (const_string "DF"))
2555               ]
2556               (const_string "DF")))])
2557
2558 (define_insn "*movdf_integer"
2559   [(set (match_operand:DF 0 "nonimmediate_operand"
2560                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2561         (match_operand:DF 1 "general_operand"
2562                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2563   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2564    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2565    && (reload_in_progress || reload_completed
2566        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2567        || GET_CODE (operands[1]) != CONST_DOUBLE
2568        || memory_operand (operands[0], DFmode))" 
2569 {
2570   switch (which_alternative)
2571     {
2572     case 0:
2573       return output_387_reg_move (insn, operands);
2574
2575     case 1:
2576       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2577         return "fstp%z0\t%y0";
2578       else
2579         return "fst%z0\t%y0";
2580
2581     case 2:
2582       return standard_80387_constant_opcode (operands[1]);
2583
2584     case 3:
2585     case 4:
2586       return "#";
2587
2588     case 5:
2589       switch (get_attr_mode (insn))
2590         {
2591         case MODE_V4SF:
2592           return "xorps\t%0, %0";
2593         case MODE_V2DF:
2594           return "xorpd\t%0, %0";
2595         case MODE_TI:
2596           return "pxor\t%0, %0";
2597         default:
2598           gcc_unreachable ();
2599         }
2600     case 6:
2601     case 7:
2602     case 8:
2603       switch (get_attr_mode (insn))
2604         {
2605         case MODE_V4SF:
2606           return "movaps\t{%1, %0|%0, %1}";
2607         case MODE_V2DF:
2608           return "movapd\t{%1, %0|%0, %1}";
2609         case MODE_TI:
2610           return "movdqa\t{%1, %0|%0, %1}";
2611         case MODE_DI:
2612           return "movq\t{%1, %0|%0, %1}";
2613         case MODE_DF:
2614           return "movsd\t{%1, %0|%0, %1}";
2615         case MODE_V1DF:
2616           return "movlpd\t{%1, %0|%0, %1}";
2617         case MODE_V2SF:
2618           return "movlps\t{%1, %0|%0, %1}";
2619         default:
2620           gcc_unreachable ();
2621         }
2622
2623     default:
2624       gcc_unreachable();
2625     }
2626 }
2627   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2628    (set (attr "mode")
2629         (cond [(eq_attr "alternative" "0,1,2")
2630                  (const_string "DF")
2631                (eq_attr "alternative" "3,4")
2632                  (const_string "SI")
2633
2634                /* For SSE1, we have many fewer alternatives.  */
2635                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636                  (cond [(eq_attr "alternative" "5,6")
2637                           (const_string "V4SF")
2638                        ]
2639                    (const_string "V2SF"))
2640
2641                /* xorps is one byte shorter.  */
2642                (eq_attr "alternative" "5")
2643                  (cond [(ne (symbol_ref "optimize_size")
2644                             (const_int 0))
2645                           (const_string "V4SF")
2646                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647                             (const_int 0))
2648                           (const_string "TI")
2649                        ]
2650                        (const_string "V2DF"))
2651
2652                /* For architectures resolving dependencies on
2653                   whole SSE registers use APD move to break dependency
2654                   chains, otherwise use short move to avoid extra work.
2655
2656                   movaps encodes one byte shorter.  */
2657                (eq_attr "alternative" "6")
2658                  (cond
2659                    [(ne (symbol_ref "optimize_size")
2660                         (const_int 0))
2661                       (const_string "V4SF")
2662                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663                         (const_int 0))
2664                       (const_string "V2DF")
2665                    ]
2666                    (const_string "DF"))
2667                /* For architectures resolving dependencies on register
2668                   parts we may avoid extra work to zero out upper part
2669                   of register.  */
2670                (eq_attr "alternative" "7")
2671                  (if_then_else
2672                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673                        (const_int 0))
2674                    (const_string "V1DF")
2675                    (const_string "DF"))
2676               ]
2677               (const_string "DF")))])
2678
2679 (define_split
2680   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2681         (match_operand:DF 1 "general_operand" ""))]
2682   "reload_completed
2683    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2684    && ! (ANY_FP_REG_P (operands[0]) || 
2685          (GET_CODE (operands[0]) == SUBREG
2686           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2687    && ! (ANY_FP_REG_P (operands[1]) || 
2688          (GET_CODE (operands[1]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2690   [(const_int 0)]
2691   "ix86_split_long_move (operands); DONE;")
2692
2693 (define_insn "*swapdf"
2694   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2695         (match_operand:DF 1 "fp_register_operand" "+f"))
2696    (set (match_dup 1)
2697         (match_dup 0))]
2698   "reload_completed || TARGET_80387"
2699 {
2700   if (STACK_TOP_P (operands[0]))
2701     return "fxch\t%1";
2702   else
2703     return "fxch\t%0";
2704 }
2705   [(set_attr "type" "fxch")
2706    (set_attr "mode" "DF")])
2707
2708 (define_expand "movxf"
2709   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2710         (match_operand:XF 1 "general_operand" ""))]
2711   ""
2712   "ix86_expand_move (XFmode, operands); DONE;")
2713
2714 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2715 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2716 ;; Pushing using integer instructions is longer except for constants
2717 ;; and direct memory references.
2718 ;; (assuming that any given constant is pushed only once, but this ought to be
2719 ;;  handled elsewhere).
2720
2721 (define_insn "*pushxf_nointeger"
2722   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2723         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2724   "optimize_size"
2725 {
2726   /* This insn should be already split before reg-stack.  */
2727   gcc_unreachable ();
2728 }
2729   [(set_attr "type" "multi")
2730    (set_attr "unit" "i387,*,*")
2731    (set_attr "mode" "XF,SI,SI")])
2732
2733 (define_insn "*pushxf_integer"
2734   [(set (match_operand:XF 0 "push_operand" "=<,<")
2735         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2736   "!optimize_size"
2737 {
2738   /* This insn should be already split before reg-stack.  */
2739   gcc_unreachable ();
2740 }
2741   [(set_attr "type" "multi")
2742    (set_attr "unit" "i387,*")
2743    (set_attr "mode" "XF,SI")])
2744
2745 (define_split
2746   [(set (match_operand 0 "push_operand" "")
2747         (match_operand 1 "general_operand" ""))]
2748   "reload_completed
2749    && (GET_MODE (operands[0]) == XFmode
2750        || GET_MODE (operands[0]) == DFmode)
2751    && !ANY_FP_REG_P (operands[1])"
2752   [(const_int 0)]
2753   "ix86_split_long_move (operands); DONE;")
2754
2755 (define_split
2756   [(set (match_operand:XF 0 "push_operand" "")
2757         (match_operand:XF 1 "any_fp_register_operand" ""))]
2758   "!TARGET_64BIT"
2759   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2760    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2762
2763 (define_split
2764   [(set (match_operand:XF 0 "push_operand" "")
2765         (match_operand:XF 1 "any_fp_register_operand" ""))]
2766   "TARGET_64BIT"
2767   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2768    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2769   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2770
2771 ;; Do not use integer registers when optimizing for size
2772 (define_insn "*movxf_nointeger"
2773   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2774         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2775   "optimize_size
2776    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777    && (reload_in_progress || reload_completed
2778        || GET_CODE (operands[1]) != CONST_DOUBLE
2779        || memory_operand (operands[0], XFmode))" 
2780 {
2781   switch (which_alternative)
2782     {
2783     case 0:
2784       return output_387_reg_move (insn, operands);
2785
2786     case 1:
2787       /* There is no non-popping store to memory for XFmode.  So if
2788          we need one, follow the store with a load.  */
2789       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790         return "fstp%z0\t%y0\;fld%z0\t%y0";
2791       else
2792         return "fstp%z0\t%y0";
2793
2794     case 2:
2795       return standard_80387_constant_opcode (operands[1]);
2796
2797     case 3: case 4:
2798       return "#";
2799     default:
2800       gcc_unreachable ();
2801     }
2802 }
2803   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2804    (set_attr "mode" "XF,XF,XF,SI,SI")])
2805
2806 (define_insn "*movxf_integer"
2807   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2808         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2809   "!optimize_size
2810    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2811    && (reload_in_progress || reload_completed
2812        || GET_CODE (operands[1]) != CONST_DOUBLE
2813        || memory_operand (operands[0], XFmode))" 
2814 {
2815   switch (which_alternative)
2816     {
2817     case 0:
2818       return output_387_reg_move (insn, operands);
2819
2820     case 1:
2821       /* There is no non-popping store to memory for XFmode.  So if
2822          we need one, follow the store with a load.  */
2823       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2824         return "fstp%z0\t%y0\;fld%z0\t%y0";
2825       else
2826         return "fstp%z0\t%y0";
2827
2828     case 2:
2829       return standard_80387_constant_opcode (operands[1]);
2830
2831     case 3: case 4:
2832       return "#";
2833
2834     default:
2835       gcc_unreachable ();
2836     }
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2855
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && constant_pool_reference_p (operands[1])"
2864   [(set (match_dup 0) (match_dup 1))]
2865 {
2866   rtx c = avoid_constant_pool_reference (operands[1]);
2867   rtx r = operands[0];
2868
2869   if (GET_CODE (r) == SUBREG)
2870     r = SUBREG_REG (r);
2871
2872   if (SSE_REG_P (r))
2873     {
2874       if (!standard_sse_constant_p (c))
2875         FAIL;
2876     }
2877   else if (FP_REG_P (r))
2878     {
2879       if (!standard_80387_constant_p (c))
2880         FAIL;
2881     }
2882   else if (MMX_REG_P (r))
2883     FAIL;
2884
2885   operands[1] = c;
2886 })
2887
2888 (define_insn "swapxf"
2889   [(set (match_operand:XF 0 "register_operand" "+f")
2890         (match_operand:XF 1 "register_operand" "+f"))
2891    (set (match_dup 1)
2892         (match_dup 0))]
2893   "TARGET_80387"
2894 {
2895   if (STACK_TOP_P (operands[0]))
2896     return "fxch\t%1";
2897   else
2898     return "fxch\t%0";
2899 }
2900   [(set_attr "type" "fxch")
2901    (set_attr "mode" "XF")])
2902
2903 (define_expand "movtf"
2904   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2905         (match_operand:TF 1 "nonimmediate_operand" ""))]
2906   "TARGET_64BIT"
2907 {
2908   ix86_expand_move (TFmode, operands);
2909   DONE;
2910 })
2911
2912 (define_insn "*movtf_internal"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2914         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2915   "TARGET_64BIT
2916    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2917 {
2918   switch (which_alternative)
2919     {
2920     case 0:
2921     case 1:
2922       return "#";
2923     case 2:
2924       if (get_attr_mode (insn) == MODE_V4SF)
2925         return "xorps\t%0, %0";
2926       else
2927         return "pxor\t%0, %0";
2928     case 3:
2929     case 4:
2930       if (get_attr_mode (insn) == MODE_V4SF)
2931         return "movaps\t{%1, %0|%0, %1}";
2932       else
2933         return "movdqa\t{%1, %0|%0, %1}";
2934     default:
2935       gcc_unreachable ();
2936     }
2937 }
2938   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2939    (set (attr "mode")
2940         (cond [(eq_attr "alternative" "2,3")
2941                  (if_then_else
2942                    (ne (symbol_ref "optimize_size")
2943                        (const_int 0))
2944                    (const_string "V4SF")
2945                    (const_string "TI"))
2946                (eq_attr "alternative" "4")
2947                  (if_then_else
2948                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2949                             (const_int 0))
2950                         (ne (symbol_ref "optimize_size")
2951                             (const_int 0)))
2952                    (const_string "V4SF")
2953                    (const_string "TI"))]
2954                (const_string "DI")))])
2955
2956 (define_split
2957   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2958         (match_operand:TF 1 "general_operand" ""))]
2959   "reload_completed && !SSE_REG_P (operands[0])
2960    && !SSE_REG_P (operands[1])"
2961   [(const_int 0)]
2962   "ix86_split_long_move (operands); DONE;")
2963 \f
2964 ;; Zero extension instructions
2965
2966 (define_expand "zero_extendhisi2"
2967   [(set (match_operand:SI 0 "register_operand" "")
2968      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2969   ""
2970 {
2971   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2972     {
2973       operands[1] = force_reg (HImode, operands[1]);
2974       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2975       DONE;
2976     }
2977 })
2978
2979 (define_insn "zero_extendhisi2_and"
2980   [(set (match_operand:SI 0 "register_operand" "=r")
2981      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2982    (clobber (reg:CC FLAGS_REG))]
2983   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2984   "#"
2985   [(set_attr "type" "alu1")
2986    (set_attr "mode" "SI")])
2987
2988 (define_split
2989   [(set (match_operand:SI 0 "register_operand" "")
2990         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2994               (clobber (reg:CC FLAGS_REG))])]
2995   "")
2996
2997 (define_insn "*zero_extendhisi2_movzwl"
2998   [(set (match_operand:SI 0 "register_operand" "=r")
2999      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3000   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3001   "movz{wl|x}\t{%1, %0|%0, %1}"
3002   [(set_attr "type" "imovx")
3003    (set_attr "mode" "SI")])
3004
3005 (define_expand "zero_extendqihi2"
3006   [(parallel
3007     [(set (match_operand:HI 0 "register_operand" "")
3008        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3009      (clobber (reg:CC FLAGS_REG))])]
3010   ""
3011   "")
3012
3013 (define_insn "*zero_extendqihi2_and"
3014   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3015      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018   "#"
3019   [(set_attr "type" "alu1")
3020    (set_attr "mode" "HI")])
3021
3022 (define_insn "*zero_extendqihi2_movzbw_and"
3023   [(set (match_operand:HI 0 "register_operand" "=r,r")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3027   "#"
3028   [(set_attr "type" "imovx,alu1")
3029    (set_attr "mode" "HI")])
3030
3031 (define_insn "*zero_extendqihi2_movzbw"
3032   [(set (match_operand:HI 0 "register_operand" "=r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3034   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3035   "movz{bw|x}\t{%1, %0|%0, %1}"
3036   [(set_attr "type" "imovx")
3037    (set_attr "mode" "HI")])
3038
3039 ;; For the movzbw case strip only the clobber
3040 (define_split
3041   [(set (match_operand:HI 0 "register_operand" "")
3042         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "reload_completed 
3045    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3046    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3047   [(set (match_operand:HI 0 "register_operand" "")
3048         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3049
3050 ;; When source and destination does not overlap, clear destination
3051 ;; first and then do the movb
3052 (define_split
3053   [(set (match_operand:HI 0 "register_operand" "")
3054         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3055    (clobber (reg:CC FLAGS_REG))]
3056   "reload_completed
3057    && ANY_QI_REG_P (operands[0])
3058    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3059    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3060   [(set (match_dup 0) (const_int 0))
3061    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3062   "operands[2] = gen_lowpart (QImode, operands[0]);")
3063
3064 ;; Rest is handled by single and.
3065 (define_split
3066   [(set (match_operand:HI 0 "register_operand" "")
3067         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "reload_completed
3070    && true_regnum (operands[0]) == true_regnum (operands[1])"
3071   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3072               (clobber (reg:CC FLAGS_REG))])]
3073   "")
3074
3075 (define_expand "zero_extendqisi2"
3076   [(parallel
3077     [(set (match_operand:SI 0 "register_operand" "")
3078        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3079      (clobber (reg:CC FLAGS_REG))])]
3080   ""
3081   "")
3082
3083 (define_insn "*zero_extendqisi2_and"
3084   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3086    (clobber (reg:CC FLAGS_REG))]
3087   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3088   "#"
3089   [(set_attr "type" "alu1")
3090    (set_attr "mode" "SI")])
3091
3092 (define_insn "*zero_extendqisi2_movzbw_and"
3093   [(set (match_operand:SI 0 "register_operand" "=r,r")
3094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3097   "#"
3098   [(set_attr "type" "imovx,alu1")
3099    (set_attr "mode" "SI")])
3100
3101 (define_insn "*zero_extendqisi2_movzbw"
3102   [(set (match_operand:SI 0 "register_operand" "=r")
3103      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3104   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3105   "movz{bl|x}\t{%1, %0|%0, %1}"
3106   [(set_attr "type" "imovx")
3107    (set_attr "mode" "SI")])
3108
3109 ;; For the movzbl case strip only the clobber
3110 (define_split
3111   [(set (match_operand:SI 0 "register_operand" "")
3112         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113    (clobber (reg:CC FLAGS_REG))]
3114   "reload_completed 
3115    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3116    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3117   [(set (match_dup 0)
3118         (zero_extend:SI (match_dup 1)))])
3119
3120 ;; When source and destination does not overlap, clear destination
3121 ;; first and then do the movb
3122 (define_split
3123   [(set (match_operand:SI 0 "register_operand" "")
3124         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "reload_completed
3127    && ANY_QI_REG_P (operands[0])
3128    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3129    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3130    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3131   [(set (match_dup 0) (const_int 0))
3132    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3133   "operands[2] = gen_lowpart (QImode, operands[0]);")
3134
3135 ;; Rest is handled by single and.
3136 (define_split
3137   [(set (match_operand:SI 0 "register_operand" "")
3138         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3139    (clobber (reg:CC FLAGS_REG))]
3140   "reload_completed
3141    && true_regnum (operands[0]) == true_regnum (operands[1])"
3142   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3143               (clobber (reg:CC FLAGS_REG))])]
3144   "")
3145
3146 ;; %%% Kill me once multi-word ops are sane.
3147 (define_expand "zero_extendsidi2"
3148   [(set (match_operand:DI 0 "register_operand" "=r")
3149      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3150   ""
3151   "if (!TARGET_64BIT)
3152      {
3153        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3154        DONE;
3155      }
3156   ")
3157
3158 (define_insn "zero_extendsidi2_32"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3160         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3161    (clobber (reg:CC FLAGS_REG))]
3162   "!TARGET_64BIT"
3163   "@
3164    #
3165    #
3166    #
3167    movd\t{%1, %0|%0, %1}
3168    movd\t{%1, %0|%0, %1}"
3169   [(set_attr "mode" "SI,SI,SI,DI,TI")
3170    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3171
3172 (define_insn "zero_extendsidi2_rex64"
3173   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3174      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3175   "TARGET_64BIT"
3176   "@
3177    mov\t{%k1, %k0|%k0, %k1}
3178    #
3179    movd\t{%1, %0|%0, %1}
3180    movd\t{%1, %0|%0, %1}"
3181   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3182    (set_attr "mode" "SI,DI,SI,SI")])
3183
3184 (define_split
3185   [(set (match_operand:DI 0 "memory_operand" "")
3186      (zero_extend:DI (match_dup 0)))]
3187   "TARGET_64BIT"
3188   [(set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190
3191 (define_split 
3192   [(set (match_operand:DI 0 "register_operand" "")
3193         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3194    (clobber (reg:CC FLAGS_REG))]
3195   "!TARGET_64BIT && reload_completed
3196    && true_regnum (operands[0]) == true_regnum (operands[1])"
3197   [(set (match_dup 4) (const_int 0))]
3198   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3199
3200 (define_split 
3201   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3202         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "!TARGET_64BIT && reload_completed
3205    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3206   [(set (match_dup 3) (match_dup 1))
3207    (set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209
3210 (define_insn "zero_extendhidi2"
3211   [(set (match_operand:DI 0 "register_operand" "=r")
3212      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3213   "TARGET_64BIT"
3214   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "DI")])
3217
3218 (define_insn "zero_extendqidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r")
3220      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3221   "TARGET_64BIT"
3222   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3223   [(set_attr "type" "imovx")
3224    (set_attr "mode" "DI")])
3225 \f
3226 ;; Sign extension instructions
3227
3228 (define_expand "extendsidi2"
3229   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3230                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231               (clobber (reg:CC FLAGS_REG))
3232               (clobber (match_scratch:SI 2 ""))])]
3233   ""
3234 {
3235   if (TARGET_64BIT)
3236     {
3237       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3238       DONE;
3239     }
3240 })
3241
3242 (define_insn "*extendsidi2_1"
3243   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3244         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3245    (clobber (reg:CC FLAGS_REG))
3246    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3247   "!TARGET_64BIT"
3248   "#")
3249
3250 (define_insn "extendsidi2_rex64"
3251   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3252         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3253   "TARGET_64BIT"
3254   "@
3255    {cltq|cdqe}
3256    movs{lq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")
3259    (set_attr "prefix_0f" "0")
3260    (set_attr "modrm" "0,1")])
3261
3262 (define_insn "extendhidi2"
3263   [(set (match_operand:DI 0 "register_operand" "=r")
3264         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265   "TARGET_64BIT"
3266   "movs{wq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")])
3269
3270 (define_insn "extendqidi2"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3273   "TARGET_64BIT"
3274   "movs{bq|x}\t{%1,%0|%0, %1}"
3275    [(set_attr "type" "imovx")
3276     (set_attr "mode" "DI")])
3277
3278 ;; Extend to memory case when source register does die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "(reload_completed
3285     && dead_or_set_p (insn, operands[1])
3286     && !reg_mentioned_p (operands[1], operands[0]))"
3287   [(set (match_dup 3) (match_dup 1))
3288    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3289               (clobber (reg:CC FLAGS_REG))])
3290    (set (match_dup 4) (match_dup 1))]
3291   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3292
3293 ;; Extend to memory case when source register does not die.
3294 (define_split 
3295   [(set (match_operand:DI 0 "memory_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_operand:SI 2 "register_operand" ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3301 {
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3303
3304   emit_move_insn (operands[3], operands[1]);
3305
3306   /* Generate a cltd if possible and doing so it profitable.  */
3307   if (true_regnum (operands[1]) == 0
3308       && true_regnum (operands[2]) == 1
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3312     }
3313   else
3314     {
3315       emit_move_insn (operands[2], operands[1]);
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3317     }
3318   emit_move_insn (operands[4], operands[2]);
3319   DONE;
3320 })
3321
3322 ;; Extend to register case.  Optimize case where source and destination
3323 ;; registers match and cases where we can use cltd.
3324 (define_split 
3325   [(set (match_operand:DI 0 "register_operand" "")
3326         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3327    (clobber (reg:CC FLAGS_REG))
3328    (clobber (match_scratch:SI 2 ""))]
3329   "reload_completed"
3330   [(const_int 0)]
3331 {
3332   split_di (&operands[0], 1, &operands[3], &operands[4]);
3333
3334   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3335     emit_move_insn (operands[3], operands[1]);
3336
3337   /* Generate a cltd if possible and doing so it profitable.  */
3338   if (true_regnum (operands[3]) == 0
3339       && (optimize_size || TARGET_USE_CLTD))
3340     {
3341       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3342       DONE;
3343     }
3344
3345   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3346     emit_move_insn (operands[4], operands[1]);
3347
3348   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3349   DONE;
3350 })
3351
3352 (define_insn "extendhisi2"
3353   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3354         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3355   ""
3356 {
3357   switch (get_attr_prefix_0f (insn))
3358     {
3359     case 0:
3360       return "{cwtl|cwde}";
3361     default:
3362       return "movs{wl|x}\t{%1,%0|%0, %1}";
3363     }
3364 }
3365   [(set_attr "type" "imovx")
3366    (set_attr "mode" "SI")
3367    (set (attr "prefix_0f")
3368      ;; movsx is short decodable while cwtl is vector decoded.
3369      (if_then_else (and (eq_attr "cpu" "!k6")
3370                         (eq_attr "alternative" "0"))
3371         (const_string "0")
3372         (const_string "1")))
3373    (set (attr "modrm")
3374      (if_then_else (eq_attr "prefix_0f" "0")
3375         (const_string "0")
3376         (const_string "1")))])
3377
3378 (define_insn "*extendhisi2_zext"
3379   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3380         (zero_extend:DI
3381           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3382   "TARGET_64BIT"
3383 {
3384   switch (get_attr_prefix_0f (insn))
3385     {
3386     case 0:
3387       return "{cwtl|cwde}";
3388     default:
3389       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3390     }
3391 }
3392   [(set_attr "type" "imovx")
3393    (set_attr "mode" "SI")
3394    (set (attr "prefix_0f")
3395      ;; movsx is short decodable while cwtl is vector decoded.
3396      (if_then_else (and (eq_attr "cpu" "!k6")
3397                         (eq_attr "alternative" "0"))
3398         (const_string "0")
3399         (const_string "1")))
3400    (set (attr "modrm")
3401      (if_then_else (eq_attr "prefix_0f" "0")
3402         (const_string "0")
3403         (const_string "1")))])
3404
3405 (define_insn "extendqihi2"
3406   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3407         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3408   ""
3409 {
3410   switch (get_attr_prefix_0f (insn))
3411     {
3412     case 0:
3413       return "{cbtw|cbw}";
3414     default:
3415       return "movs{bw|x}\t{%1,%0|%0, %1}";
3416     }
3417 }
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "HI")
3420    (set (attr "prefix_0f")
3421      ;; movsx is short decodable while cwtl is vector decoded.
3422      (if_then_else (and (eq_attr "cpu" "!k6")
3423                         (eq_attr "alternative" "0"))
3424         (const_string "0")
3425         (const_string "1")))
3426    (set (attr "modrm")
3427      (if_then_else (eq_attr "prefix_0f" "0")
3428         (const_string "0")
3429         (const_string "1")))])
3430
3431 (define_insn "extendqisi2"
3432   [(set (match_operand:SI 0 "register_operand" "=r")
3433         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3434   ""
3435   "movs{bl|x}\t{%1,%0|%0, %1}"
3436    [(set_attr "type" "imovx")
3437     (set_attr "mode" "SI")])
3438
3439 (define_insn "*extendqisi2_zext"
3440   [(set (match_operand:DI 0 "register_operand" "=r")
3441         (zero_extend:DI
3442           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3443   "TARGET_64BIT"
3444   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3445    [(set_attr "type" "imovx")
3446     (set_attr "mode" "SI")])
3447 \f
3448 ;; Conversions between float and double.
3449
3450 ;; These are all no-ops in the model used for the 80387.  So just
3451 ;; emit moves.
3452
3453 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3454 (define_insn "*dummy_extendsfdf2"
3455   [(set (match_operand:DF 0 "push_operand" "=<")
3456         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3457   "0"
3458   "#")
3459
3460 (define_split
3461   [(set (match_operand:DF 0 "push_operand" "")
3462         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463   "!TARGET_64BIT"
3464   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3465    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3466
3467 (define_split
3468   [(set (match_operand:DF 0 "push_operand" "")
3469         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3470   "TARGET_64BIT"
3471   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3472    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3473
3474 (define_insn "*dummy_extendsfxf2"
3475   [(set (match_operand:XF 0 "push_operand" "=<")
3476         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3477   "0"
3478   "#")
3479
3480 (define_split
3481   [(set (match_operand:XF 0 "push_operand" "")
3482         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3483   ""
3484   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3485    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3486   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487
3488 (define_split
3489   [(set (match_operand:XF 0 "push_operand" "")
3490         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3491   "TARGET_64BIT"
3492   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3493    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3494   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495
3496 (define_split
3497   [(set (match_operand:XF 0 "push_operand" "")
3498         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3499   ""
3500   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3501    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3502   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503
3504 (define_split
3505   [(set (match_operand:XF 0 "push_operand" "")
3506         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3507   "TARGET_64BIT"
3508   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3509    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3510   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3511
3512 (define_expand "extendsfdf2"
3513   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3514         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3516 {
3517   /* ??? Needed for compress_float_constant since all fp constants
3518      are LEGITIMATE_CONSTANT_P.  */
3519   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3520     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3522     operands[1] = force_reg (SFmode, operands[1]);
3523 })
3524
3525 (define_insn "*extendsfdf2_mixed"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3527         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3528   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3529    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3530 {
3531   switch (which_alternative)
3532     {
3533     case 0:
3534       return output_387_reg_move (insn, operands);
3535
3536     case 1:
3537       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3538         return "fstp%z0\t%y0";
3539       else
3540         return "fst%z0\t%y0";
3541
3542     case 2:
3543       return "cvtss2sd\t{%1, %0|%0, %1}";
3544
3545     default:
3546       gcc_unreachable ();
3547     }
3548 }
3549   [(set_attr "type" "fmov,fmov,ssecvt")
3550    (set_attr "mode" "SF,XF,DF")])
3551
3552 (define_insn "*extendsfdf2_sse"
3553   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3554         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3555   "TARGET_SSE2 && TARGET_SSE_MATH
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557   "cvtss2sd\t{%1, %0|%0, %1}"
3558   [(set_attr "type" "ssecvt")
3559    (set_attr "mode" "DF")])
3560
3561 (define_insn "*extendsfdf2_i387"
3562   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3563         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3564   "TARGET_80387
3565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3566 {
3567   switch (which_alternative)
3568     {
3569     case 0:
3570       return output_387_reg_move (insn, operands);
3571
3572     case 1:
3573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3574         return "fstp%z0\t%y0";
3575       else
3576         return "fst%z0\t%y0";
3577
3578     default:
3579       gcc_unreachable ();
3580     }
3581 }
3582   [(set_attr "type" "fmov")
3583    (set_attr "mode" "SF,XF")])
3584
3585 (define_expand "extendsfxf2"
3586   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3587         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3588   "TARGET_80387"
3589 {
3590   /* ??? Needed for compress_float_constant since all fp constants
3591      are LEGITIMATE_CONSTANT_P.  */
3592   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3593     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3594   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3595     operands[1] = force_reg (SFmode, operands[1]);
3596 })
3597
3598 (define_insn "*extendsfxf2_i387"
3599   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3600         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3601   "TARGET_80387
3602    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3603 {
3604   switch (which_alternative)
3605     {
3606     case 0:
3607       return output_387_reg_move (insn, operands);
3608
3609     case 1:
3610       /* There is no non-popping store to memory for XFmode.  So if
3611          we need one, follow the store with a load.  */
3612       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3613         return "fstp%z0\t%y0";
3614       else
3615         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3616
3617     default:
3618       gcc_unreachable ();
3619     }
3620 }
3621   [(set_attr "type" "fmov")
3622    (set_attr "mode" "SF,XF")])
3623
3624 (define_expand "extenddfxf2"
3625   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3626         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3627   "TARGET_80387"
3628 {
3629   /* ??? Needed for compress_float_constant since all fp constants
3630      are LEGITIMATE_CONSTANT_P.  */
3631   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3632     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3634     operands[1] = force_reg (DFmode, operands[1]);
3635 })
3636
3637 (define_insn "*extenddfxf2_i387"
3638   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3639         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3640   "TARGET_80387
3641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3642 {
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       return output_387_reg_move (insn, operands);
3647
3648     case 1:
3649       /* There is no non-popping store to memory for XFmode.  So if
3650          we need one, follow the store with a load.  */
3651       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3653       else
3654         return "fstp%z0\t%y0";
3655
3656     default:
3657       gcc_unreachable ();
3658     }
3659 }
3660   [(set_attr "type" "fmov")
3661    (set_attr "mode" "DF,XF")])
3662
3663 ;; %%% This seems bad bad news.
3664 ;; This cannot output into an f-reg because there is no way to be sure
3665 ;; of truncating in that case.  Otherwise this is just like a simple move
3666 ;; insn.  So we pretend we can output to a reg in order to get better
3667 ;; register preferencing, but we really use a stack slot.
3668
3669 ;; Conversion from DFmode to SFmode.
3670
3671 (define_expand "truncdfsf2"
3672   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3673         (float_truncate:SF
3674           (match_operand:DF 1 "nonimmediate_operand" "")))]
3675   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3676 {
3677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3678     operands[1] = force_reg (DFmode, operands[1]);
3679
3680   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3681     ;
3682   else if (flag_unsafe_math_optimizations)
3683     ;
3684   else
3685     {
3686       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3687       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3688       DONE;
3689     }
3690 })
3691
3692 (define_expand "truncdfsf2_with_temp"
3693   [(parallel [(set (match_operand:SF 0 "" "")
3694                    (float_truncate:SF (match_operand:DF 1 "" "")))
3695               (clobber (match_operand:SF 2 "" ""))])]
3696   "")
3697
3698 (define_insn "*truncdfsf_fast_mixed"
3699   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3700         (float_truncate:SF
3701           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3702   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3703 {
3704   switch (which_alternative)
3705     {
3706     case 0:
3707       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708         return "fstp%z0\t%y0";
3709       else
3710         return "fst%z0\t%y0";
3711     case 1:
3712       return output_387_reg_move (insn, operands);
3713     case 2:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     default:
3716       gcc_unreachable ();
3717     }
3718 }
3719   [(set_attr "type" "fmov,fmov,ssecvt")
3720    (set_attr "mode" "SF")])
3721
3722 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3723 ;; because nothing we do here is unsafe.
3724 (define_insn "*truncdfsf_fast_sse"
3725   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3726         (float_truncate:SF
3727           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3728   "TARGET_SSE2 && TARGET_SSE_MATH"
3729   "cvtsd2ss\t{%1, %0|%0, %1}"
3730   [(set_attr "type" "ssecvt")
3731    (set_attr "mode" "SF")])
3732
3733 (define_insn "*truncdfsf_fast_i387"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3737   "TARGET_80387 && flag_unsafe_math_optimizations"
3738   "* return output_387_reg_move (insn, operands);"
3739   [(set_attr "type" "fmov")
3740    (set_attr "mode" "SF")])
3741
3742 (define_insn "*truncdfsf_mixed"
3743   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3744         (float_truncate:SF
3745           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3746    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3747   "TARGET_MIX_SSE_I387"
3748 {
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753         return "fstp%z0\t%y0";
3754       else
3755         return "fst%z0\t%y0";
3756     case 1:
3757       return "#";
3758     case 2:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     default:
3761       gcc_unreachable ();
3762     }
3763 }
3764   [(set_attr "type" "fmov,multi,ssecvt")
3765    (set_attr "unit" "*,i387,*")
3766    (set_attr "mode" "SF")])
3767
3768 (define_insn "*truncdfsf_i387"
3769   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3770         (float_truncate:SF
3771           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3772    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3773   "TARGET_80387"
3774 {
3775   switch (which_alternative)
3776     {
3777     case 0:
3778       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779         return "fstp%z0\t%y0";
3780       else
3781         return "fst%z0\t%y0";
3782     case 1:
3783       return "#";
3784     default:
3785       gcc_unreachable ();
3786     }
3787 }
3788   [(set_attr "type" "fmov,multi")
3789    (set_attr "unit" "*,i387")
3790    (set_attr "mode" "SF")])
3791
3792 (define_insn "*truncdfsf2_i387_1"
3793   [(set (match_operand:SF 0 "memory_operand" "=m")
3794         (float_truncate:SF
3795           (match_operand:DF 1 "register_operand" "f")))]
3796   "TARGET_80387
3797    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3798    && !TARGET_MIX_SSE_I387"
3799 {
3800   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3801     return "fstp%z0\t%y0";
3802   else
3803     return "fst%z0\t%y0";
3804 }
3805   [(set_attr "type" "fmov")
3806    (set_attr "mode" "SF")])
3807
3808 (define_split
3809   [(set (match_operand:SF 0 "register_operand" "")
3810         (float_truncate:SF
3811          (match_operand:DF 1 "fp_register_operand" "")))
3812    (clobber (match_operand 2 "" ""))]
3813   "reload_completed"
3814   [(set (match_dup 2) (match_dup 1))
3815    (set (match_dup 0) (match_dup 2))]
3816 {
3817   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3818 })
3819
3820 ;; Conversion from XFmode to SFmode.
3821
3822 (define_expand "truncxfsf2"
3823   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3824                    (float_truncate:SF
3825                     (match_operand:XF 1 "register_operand" "")))
3826               (clobber (match_dup 2))])]
3827   "TARGET_80387"
3828 {
3829   if (flag_unsafe_math_optimizations)
3830     {
3831       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3832       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3833       if (reg != operands[0])
3834         emit_move_insn (operands[0], reg);
3835       DONE;
3836     }
3837   else
3838     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3839 })
3840
3841 (define_insn "*truncxfsf2_mixed"
3842   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3843         (float_truncate:SF
3844          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3845    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3846   "TARGET_MIX_SSE_I387"
3847 {
3848   gcc_assert (!which_alternative);
3849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850     return "fstp%z0\t%y0";
3851   else
3852     return "fst%z0\t%y0";
3853 }
3854   [(set_attr "type" "fmov,multi,multi,multi")
3855    (set_attr "unit" "*,i387,i387,i387")
3856    (set_attr "mode" "SF")])
3857
3858 (define_insn "truncxfsf2_i387_noop"
3859   [(set (match_operand:SF 0 "register_operand" "=f")
3860         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3861   "TARGET_80387 && flag_unsafe_math_optimizations"
3862 {
3863   return output_387_reg_move (insn, operands);
3864 }
3865   [(set_attr "type" "fmov")
3866    (set_attr "mode" "SF")])
3867
3868 (define_insn "*truncxfsf2_i387"
3869   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3870         (float_truncate:SF
3871          (match_operand:XF 1 "register_operand" "f,f,f")))
3872    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3873   "TARGET_80387"
3874 {
3875   gcc_assert (!which_alternative);
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878    else
3879      return "fst%z0\t%y0";
3880 }
3881   [(set_attr "type" "fmov,multi,multi")
3882    (set_attr "unit" "*,i387,i387")
3883    (set_attr "mode" "SF")])
3884
3885 (define_insn "*truncxfsf2_i387_1"
3886   [(set (match_operand:SF 0 "memory_operand" "=m")
3887         (float_truncate:SF
3888          (match_operand:XF 1 "register_operand" "f")))]
3889   "TARGET_80387"
3890 {
3891   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3892     return "fstp%z0\t%y0";
3893   else
3894     return "fst%z0\t%y0";
3895 }
3896   [(set_attr "type" "fmov")
3897    (set_attr "mode" "SF")])
3898
3899 (define_split
3900   [(set (match_operand:SF 0 "register_operand" "")
3901         (float_truncate:SF
3902          (match_operand:XF 1 "register_operand" "")))
3903    (clobber (match_operand:SF 2 "memory_operand" ""))]
3904   "TARGET_80387 && reload_completed"
3905   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3906    (set (match_dup 0) (match_dup 2))]
3907   "")
3908
3909 (define_split
3910   [(set (match_operand:SF 0 "memory_operand" "")
3911         (float_truncate:SF
3912          (match_operand:XF 1 "register_operand" "")))
3913    (clobber (match_operand:SF 2 "memory_operand" ""))]
3914   "TARGET_80387"
3915   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3916   "")
3917
3918 ;; Conversion from XFmode to DFmode.
3919
3920 (define_expand "truncxfdf2"
3921   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3922                    (float_truncate:DF
3923                     (match_operand:XF 1 "register_operand" "")))
3924               (clobber (match_dup 2))])]
3925   "TARGET_80387"
3926 {
3927   if (flag_unsafe_math_optimizations)
3928     {
3929       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3930       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3931       if (reg != operands[0])
3932         emit_move_insn (operands[0], reg);
3933       DONE;
3934     }
3935   else
3936     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3937 })
3938
3939 (define_insn "*truncxfdf2_mixed"
3940   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3941         (float_truncate:DF
3942          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3943    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3944   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3945 {
3946   gcc_assert (!which_alternative);
3947   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948     return "fstp%z0\t%y0";
3949   else
3950     return "fst%z0\t%y0";
3951 }
3952   [(set_attr "type" "fmov,multi,multi,multi")
3953    (set_attr "unit" "*,i387,i387,i387")
3954    (set_attr "mode" "DF")])
3955
3956 (define_insn "truncxfdf2_i387_noop"
3957   [(set (match_operand:DF 0 "register_operand" "=f")
3958         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959   "TARGET_80387 && flag_unsafe_math_optimizations"
3960 {
3961   return output_387_reg_move (insn, operands);
3962 }
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3965
3966 (define_insn "*truncxfdf2_i387"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3971   "TARGET_80387"
3972 {
3973   gcc_assert (!which_alternative);
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3978 }
3979   [(set_attr "type" "fmov,multi,multi")
3980    (set_attr "unit" "*,i387,i387")
3981    (set_attr "mode" "DF")])
3982
3983 (define_insn "*truncxfdf2_i387_1"
3984   [(set (match_operand:DF 0 "memory_operand" "=m")
3985         (float_truncate:DF
3986           (match_operand:XF 1 "register_operand" "f")))]
3987   "TARGET_80387"
3988 {
3989   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3990     return "fstp%z0\t%y0";
3991   else
3992     return "fst%z0\t%y0";
3993 }
3994   [(set_attr "type" "fmov")
3995    (set_attr "mode" "DF")])
3996
3997 (define_split
3998   [(set (match_operand:DF 0 "register_operand" "")
3999         (float_truncate:DF
4000          (match_operand:XF 1 "register_operand" "")))
4001    (clobber (match_operand:DF 2 "memory_operand" ""))]
4002   "TARGET_80387 && reload_completed"
4003   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4004    (set (match_dup 0) (match_dup 2))]
4005   "")
4006
4007 (define_split
4008   [(set (match_operand:DF 0 "memory_operand" "")
4009         (float_truncate:DF
4010          (match_operand:XF 1 "register_operand" "")))
4011    (clobber (match_operand:DF 2 "memory_operand" ""))]
4012   "TARGET_80387"
4013   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4014   "")
4015 \f
4016 ;; Signed conversion to DImode.
4017
4018 (define_expand "fix_truncxfdi2"
4019   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4021               (clobber (reg:CC FLAGS_REG))])]
4022   "TARGET_80387"
4023 {
4024   if (TARGET_FISTTP)
4025    {
4026      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4027      DONE;
4028    }
4029 })
4030
4031 (define_expand "fix_trunc<mode>di2"
4032   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4034               (clobber (reg:CC FLAGS_REG))])]
4035   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4036 {
4037   if (TARGET_FISTTP
4038       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4039    {
4040      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4041      DONE;
4042    }
4043   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4044    {
4045      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4046      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4047      if (out != operands[0])
4048         emit_move_insn (operands[0], out);
4049      DONE;
4050    }
4051 })
4052
4053 ;; Signed conversion to SImode.
4054
4055 (define_expand "fix_truncxfsi2"
4056   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4057                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4058               (clobber (reg:CC FLAGS_REG))])]
4059   "TARGET_80387"
4060 {
4061   if (TARGET_FISTTP)
4062    {
4063      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4064      DONE;
4065    }
4066 })
4067
4068 (define_expand "fix_trunc<mode>si2"
4069   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4070                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4071               (clobber (reg:CC FLAGS_REG))])]
4072   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4073 {
4074   if (TARGET_FISTTP
4075       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4076    {
4077      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4078      DONE;
4079    }
4080   if (SSE_FLOAT_MODE_P (<MODE>mode))
4081    {
4082      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4083      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4084      if (out != operands[0])
4085         emit_move_insn (operands[0], out);
4086      DONE;
4087    }
4088 })
4089
4090 ;; Signed conversion to HImode.
4091
4092 (define_expand "fix_trunc<mode>hi2"
4093   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4094                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4095               (clobber (reg:CC FLAGS_REG))])]
4096   "TARGET_80387
4097    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4098 {
4099   if (TARGET_FISTTP)
4100    {
4101      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4102      DONE;
4103    }
4104 })
4105
4106 ;; When SSE is available, it is always faster to use it!
4107 (define_insn "fix_truncsfdi_sse"
4108   [(set (match_operand:DI 0 "register_operand" "=r,r")
4109         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4110   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111   "cvttss2si{q}\t{%1, %0|%0, %1}"
4112   [(set_attr "type" "sseicvt")
4113    (set_attr "mode" "SF")
4114    (set_attr "athlon_decode" "double,vector")])
4115
4116 (define_insn "fix_truncdfdi_sse"
4117   [(set (match_operand:DI 0 "register_operand" "=r,r")
4118         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4119   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4121   [(set_attr "type" "sseicvt")
4122    (set_attr "mode" "DF")
4123    (set_attr "athlon_decode" "double,vector")])
4124
4125 (define_insn "fix_truncsfsi_sse"
4126   [(set (match_operand:SI 0 "register_operand" "=r,r")
4127         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4128   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129   "cvttss2si\t{%1, %0|%0, %1}"
4130   [(set_attr "type" "sseicvt")
4131    (set_attr "mode" "DF")
4132    (set_attr "athlon_decode" "double,vector")])
4133
4134 (define_insn "fix_truncdfsi_sse"
4135   [(set (match_operand:SI 0 "register_operand" "=r,r")
4136         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4137   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttsd2si\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "DF")
4141    (set_attr "athlon_decode" "double,vector")])
4142
4143 ;; Avoid vector decoded forms of the instruction.
4144 (define_peephole2
4145   [(match_scratch:DF 2 "Y")
4146    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4148   "TARGET_K8 && !optimize_size"
4149   [(set (match_dup 2) (match_dup 1))
4150    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4151   "")
4152
4153 (define_peephole2
4154   [(match_scratch:SF 2 "x")
4155    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4156         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4157   "TARGET_K8 && !optimize_size"
4158   [(set (match_dup 2) (match_dup 1))
4159    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4160   "")
4161
4162 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4163   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4164         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4165   "TARGET_80387 && TARGET_FISTTP
4166    && FLOAT_MODE_P (GET_MODE (operands[1]))
4167    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4168          && (TARGET_64BIT || <MODE>mode != DImode))
4169         && TARGET_SSE_MATH)
4170    && !(reload_completed || reload_in_progress)"
4171   "#"
4172   "&& 1"
4173   [(const_int 0)]
4174 {
4175   if (memory_operand (operands[0], VOIDmode))
4176     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4177   else
4178     {
4179       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4180       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4181                                                             operands[1],
4182                                                             operands[2]));
4183     }
4184   DONE;
4185 }
4186   [(set_attr "type" "fisttp")
4187    (set_attr "mode" "<MODE>")])
4188
4189 (define_insn "fix_trunc<mode>_i387_fisttp"
4190   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4191         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4192    (clobber (match_scratch:XF 2 "=&1f"))]
4193   "TARGET_80387 && TARGET_FISTTP
4194    && FLOAT_MODE_P (GET_MODE (operands[1]))
4195    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4196          && (TARGET_64BIT || <MODE>mode != DImode))
4197         && TARGET_SSE_MATH)"
4198   "* return output_fix_trunc (insn, operands, 1);"
4199   [(set_attr "type" "fisttp")
4200    (set_attr "mode" "<MODE>")])
4201
4202 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4203   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4205    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4206    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4207   "TARGET_80387 && TARGET_FISTTP
4208    && FLOAT_MODE_P (GET_MODE (operands[1]))
4209    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4210         && (TARGET_64BIT || <MODE>mode != DImode))
4211         && TARGET_SSE_MATH)"
4212   "#"
4213   [(set_attr "type" "fisttp")
4214    (set_attr "mode" "<MODE>")])
4215
4216 (define_split
4217   [(set (match_operand:X87MODEI 0 "register_operand" "")
4218         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4219    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4220    (clobber (match_scratch 3 ""))]
4221   "reload_completed"
4222   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4223               (clobber (match_dup 3))])
4224    (set (match_dup 0) (match_dup 2))]
4225   "")
4226
4227 (define_split
4228   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4229         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4230    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4231    (clobber (match_scratch 3 ""))]
4232   "reload_completed"
4233   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4234               (clobber (match_dup 3))])]
4235   "")
4236
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245    (clobber (reg:CC FLAGS_REG))]
4246   "TARGET_80387 && !TARGET_FISTTP
4247    && FLOAT_MODE_P (GET_MODE (operands[1]))
4248    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249          && (TARGET_64BIT || <MODE>mode != DImode))
4250    && !(reload_completed || reload_in_progress)"
4251   "#"
4252   "&& 1"
4253   [(const_int 0)]
4254 {
4255   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4256
4257   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259   if (memory_operand (operands[0], VOIDmode))
4260     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261                                          operands[2], operands[3]));
4262   else
4263     {
4264       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266                                                      operands[2], operands[3],
4267                                                      operands[4]));
4268     }
4269   DONE;
4270 }
4271   [(set_attr "type" "fistp")
4272    (set_attr "i387_cw" "trunc")
4273    (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_truncdi_i387"
4276   [(set (match_operand:DI 0 "memory_operand" "=m")
4277         (fix:DI (match_operand 1 "register_operand" "f")))
4278    (use (match_operand:HI 2 "memory_operand" "m"))
4279    (use (match_operand:HI 3 "memory_operand" "m"))
4280    (clobber (match_scratch:XF 4 "=&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "* return output_fix_trunc (insn, operands, 0);"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4288
4289 (define_insn "fix_truncdi_i387_with_temp"
4290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291         (fix:DI (match_operand 1 "register_operand" "f,f")))
4292    (use (match_operand:HI 2 "memory_operand" "m,m"))
4293    (use (match_operand:HI 3 "memory_operand" "m,m"))
4294    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4295    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296   "TARGET_80387 && !TARGET_FISTTP
4297    && FLOAT_MODE_P (GET_MODE (operands[1]))
4298    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4299   "#"
4300   [(set_attr "type" "fistp")
4301    (set_attr "i387_cw" "trunc")
4302    (set_attr "mode" "DI")])
4303
4304 (define_split 
4305   [(set (match_operand:DI 0 "register_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])
4316    (set (match_dup 0) (match_dup 4))]
4317   "")
4318
4319 (define_split 
4320   [(set (match_operand:DI 0 "memory_operand" "")
4321         (fix:DI (match_operand 1 "register_operand" "")))
4322    (use (match_operand:HI 2 "memory_operand" ""))
4323    (use (match_operand:HI 3 "memory_operand" ""))
4324    (clobber (match_operand:DI 4 "memory_operand" ""))
4325    (clobber (match_scratch 5 ""))]
4326   "reload_completed"
4327   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4328               (use (match_dup 2))
4329               (use (match_dup 3))
4330               (clobber (match_dup 5))])]
4331   "")
4332
4333 (define_insn "fix_trunc<mode>_i387"
4334   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4335         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4336    (use (match_operand:HI 2 "memory_operand" "m"))
4337    (use (match_operand:HI 3 "memory_operand" "m"))]
4338   "TARGET_80387 && !TARGET_FISTTP
4339    && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341   "* return output_fix_trunc (insn, operands, 0);"
4342   [(set_attr "type" "fistp")
4343    (set_attr "i387_cw" "trunc")
4344    (set_attr "mode" "<MODE>")])
4345
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4348         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4349    (use (match_operand:HI 2 "memory_operand" "m,m"))
4350    (use (match_operand:HI 3 "memory_operand" "m,m"))
4351    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4352   "TARGET_80387 && !TARGET_FISTTP
4353    && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "#"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4359
4360 (define_split 
4361   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4362         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4363    (use (match_operand:HI 2 "memory_operand" ""))
4364    (use (match_operand:HI 3 "memory_operand" ""))
4365    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))])
4370    (set (match_dup 0) (match_dup 4))]
4371   "")
4372
4373 (define_split 
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4376    (use (match_operand:HI 2 "memory_operand" ""))
4377    (use (match_operand:HI 3 "memory_operand" ""))
4378    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4379   "reload_completed"
4380   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4381               (use (match_dup 2))
4382               (use (match_dup 3))])]
4383   "")
4384
4385 (define_insn "x86_fnstcw_1"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4388   "TARGET_80387"
4389   "fnstcw\t%0"
4390   [(set_attr "length" "2")
4391    (set_attr "mode" "HI")
4392    (set_attr "unit" "i387")])
4393
4394 (define_insn "x86_fldcw_1"
4395   [(set (reg:HI FPSR_REG)
4396         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397   "TARGET_80387"
4398   "fldcw\t%0"
4399   [(set_attr "length" "2")
4400    (set_attr "mode" "HI")
4401    (set_attr "unit" "i387")
4402    (set_attr "athlon_decode" "vector")])
4403 \f
4404 ;; Conversion between fixed point and floating point.
4405
4406 ;; Even though we only accept memory inputs, the backend _really_
4407 ;; wants to be able to do this between registers.
4408
4409 (define_expand "floathisf2"
4410   [(set (match_operand:SF 0 "register_operand" "")
4411         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4412   "TARGET_80387 || TARGET_SSE_MATH"
4413 {
4414   if (TARGET_SSE_MATH)
4415     {
4416       emit_insn (gen_floatsisf2 (operands[0],
4417                                  convert_to_mode (SImode, operands[1], 0)));
4418       DONE;
4419     }
4420 })
4421
4422 (define_insn "*floathisf2_i387"
4423   [(set (match_operand:SF 0 "register_operand" "=f,f")
4424         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4425   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4426   "@
4427    fild%z1\t%1
4428    #"
4429   [(set_attr "type" "fmov,multi")
4430    (set_attr "mode" "SF")
4431    (set_attr "unit" "*,i387")
4432    (set_attr "fp_int_src" "true")])
4433
4434 (define_expand "floatsisf2"
4435   [(set (match_operand:SF 0 "register_operand" "")
4436         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4437   "TARGET_80387 || TARGET_SSE_MATH"
4438   "")
4439
4440 (define_insn "*floatsisf2_mixed"
4441   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4442         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4443   "TARGET_MIX_SSE_I387"
4444   "@
4445    fild%z1\t%1
4446    #
4447    cvtsi2ss\t{%1, %0|%0, %1}
4448    cvtsi2ss\t{%1, %0|%0, %1}"
4449   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4450    (set_attr "mode" "SF")
4451    (set_attr "unit" "*,i387,*,*")
4452    (set_attr "athlon_decode" "*,*,vector,double")
4453    (set_attr "fp_int_src" "true")])
4454
4455 (define_insn "*floatsisf2_sse"
4456   [(set (match_operand:SF 0 "register_operand" "=x,x")
4457         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4458   "TARGET_SSE_MATH"
4459   "cvtsi2ss\t{%1, %0|%0, %1}"
4460   [(set_attr "type" "sseicvt")
4461    (set_attr "mode" "SF")
4462    (set_attr "athlon_decode" "vector,double")
4463    (set_attr "fp_int_src" "true")])
4464
4465 (define_insn "*floatsisf2_i387"
4466   [(set (match_operand:SF 0 "register_operand" "=f,f")
4467         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4468   "TARGET_80387"
4469   "@
4470    fild%z1\t%1
4471    #"
4472   [(set_attr "type" "fmov,multi")
4473    (set_attr "mode" "SF")
4474    (set_attr "unit" "*,i387")
4475    (set_attr "fp_int_src" "true")])
4476
4477 (define_expand "floatdisf2"
4478   [(set (match_operand:SF 0 "register_operand" "")
4479         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4480   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4481   "")
4482
4483 (define_insn "*floatdisf2_mixed"
4484   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4487   "@
4488    fild%z1\t%1
4489    #
4490    cvtsi2ss{q}\t{%1, %0|%0, %1}
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493    (set_attr "mode" "SF")
4494    (set_attr "unit" "*,i387,*,*")
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 "unit" "*,i387")
4518    (set_attr "fp_int_src" "true")])
4519
4520 (define_expand "floathidf2"
4521   [(set (match_operand:DF 0 "register_operand" "")
4522         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4523   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524 {
4525   if (TARGET_SSE2 && TARGET_SSE_MATH)
4526     {
4527       emit_insn (gen_floatsidf2 (operands[0],
4528                                  convert_to_mode (SImode, operands[1], 0)));
4529       DONE;
4530     }
4531 })
4532
4533 (define_insn "*floathidf2_i387"
4534   [(set (match_operand:DF 0 "register_operand" "=f,f")
4535         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4536   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4537   "@
4538    fild%z1\t%1
4539    #"
4540   [(set_attr "type" "fmov,multi")
4541    (set_attr "mode" "DF")
4542    (set_attr "unit" "*,i387")
4543    (set_attr "fp_int_src" "true")])
4544
4545 (define_expand "floatsidf2"
4546   [(set (match_operand:DF 0 "register_operand" "")
4547         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4548   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4549   "")
4550
4551 (define_insn "*floatsidf2_mixed"
4552   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4553         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4554   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4555   "@
4556    fild%z1\t%1
4557    #
4558    cvtsi2sd\t{%1, %0|%0, %1}
4559    cvtsi2sd\t{%1, %0|%0, %1}"
4560   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4561    (set_attr "mode" "DF")
4562    (set_attr "unit" "*,i387,*,*")
4563    (set_attr "athlon_decode" "*,*,double,direct")
4564    (set_attr "fp_int_src" "true")])
4565
4566 (define_insn "*floatsidf2_sse"
4567   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4568         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4569   "TARGET_SSE2 && TARGET_SSE_MATH"
4570   "cvtsi2sd\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "mode" "DF")
4573    (set_attr "athlon_decode" "double,direct")
4574    (set_attr "fp_int_src" "true")])
4575
4576 (define_insn "*floatsidf2_i387"
4577   [(set (match_operand:DF 0 "register_operand" "=f,f")
4578         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4579   "TARGET_80387"
4580   "@
4581    fild%z1\t%1
4582    #"
4583   [(set_attr "type" "fmov,multi")
4584    (set_attr "mode" "DF")
4585    (set_attr "unit" "*,i387")
4586    (set_attr "fp_int_src" "true")])
4587
4588 (define_expand "floatdidf2"
4589   [(set (match_operand:DF 0 "register_operand" "")
4590         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4591   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4592   "")
4593
4594 (define_insn "*floatdidf2_mixed"
4595   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598   "@
4599    fild%z1\t%1
4600    #
4601    cvtsi2sd{q}\t{%1, %0|%0, %1}
4602    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "unit" "*,i387,*,*")
4606    (set_attr "athlon_decode" "*,*,double,direct")
4607    (set_attr "fp_int_src" "true")])
4608
4609 (define_insn "*floatdidf2_sse"
4610   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4611         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4612   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4613   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4614   [(set_attr "type" "sseicvt")
4615    (set_attr "mode" "DF")
4616    (set_attr "athlon_decode" "double,direct")
4617    (set_attr "fp_int_src" "true")])
4618
4619 (define_insn "*floatdidf2_i387"
4620   [(set (match_operand:DF 0 "register_operand" "=f,f")
4621         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4622   "TARGET_80387"
4623   "@
4624    fild%z1\t%1
4625    #"
4626   [(set_attr "type" "fmov,multi")
4627    (set_attr "mode" "DF")
4628    (set_attr "unit" "*,i387")
4629    (set_attr "fp_int_src" "true")])
4630
4631 (define_insn "floathixf2"
4632   [(set (match_operand:XF 0 "register_operand" "=f,f")
4633         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4634   "TARGET_80387"
4635   "@
4636    fild%z1\t%1
4637    #"
4638   [(set_attr "type" "fmov,multi")
4639    (set_attr "mode" "XF")
4640    (set_attr "unit" "*,i387")
4641    (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "floatsixf2"
4644   [(set (match_operand:XF 0 "register_operand" "=f,f")
4645         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4646   "TARGET_80387"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "XF")
4652    (set_attr "unit" "*,i387")
4653    (set_attr "fp_int_src" "true")])
4654
4655 (define_insn "floatdixf2"
4656   [(set (match_operand:XF 0 "register_operand" "=f,f")
4657         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4658   "TARGET_80387"
4659   "@
4660    fild%z1\t%1
4661    #"
4662   [(set_attr "type" "fmov,multi")
4663    (set_attr "mode" "XF")
4664    (set_attr "unit" "*,i387")
4665    (set_attr "fp_int_src" "true")])
4666
4667 ;; %%% Kill these when reload knows how to do it.
4668 (define_split
4669   [(set (match_operand 0 "fp_register_operand" "")
4670         (float (match_operand 1 "register_operand" "")))]
4671   "reload_completed
4672    && TARGET_80387
4673    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4674   [(const_int 0)]
4675 {
4676   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4677   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4678   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4679   ix86_free_from_memory (GET_MODE (operands[1]));
4680   DONE;
4681 })
4682
4683 (define_expand "floatunssisf2"
4684   [(use (match_operand:SF 0 "register_operand" ""))
4685    (use (match_operand:SI 1 "register_operand" ""))]
4686   "!TARGET_64BIT && TARGET_SSE_MATH"
4687   "x86_emit_floatuns (operands); DONE;")
4688
4689 (define_expand "floatunsdisf2"
4690   [(use (match_operand:SF 0 "register_operand" ""))
4691    (use (match_operand:DI 1 "register_operand" ""))]
4692   "TARGET_64BIT && TARGET_SSE_MATH"
4693   "x86_emit_floatuns (operands); DONE;")
4694
4695 (define_expand "floatunsdidf2"
4696   [(use (match_operand:DF 0 "register_operand" ""))
4697    (use (match_operand:DI 1 "register_operand" ""))]
4698   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699   "x86_emit_floatuns (operands); DONE;")
4700 \f
4701 ;; SSE extract/set expanders
4702
4703 \f
4704 ;; Add instructions
4705
4706 ;; %%% splits for addditi3
4707
4708 (define_expand "addti3"
4709   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4710         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4711                  (match_operand:TI 2 "x86_64_general_operand" "")))
4712    (clobber (reg:CC FLAGS_REG))]
4713   "TARGET_64BIT"
4714   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4715
4716 (define_insn "*addti3_1"
4717   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4719                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4720    (clobber (reg:CC FLAGS_REG))]
4721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4722   "#")
4723
4724 (define_split
4725   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4727                  (match_operand:TI 2 "general_operand" "")))
4728    (clobber (reg:CC FLAGS_REG))]
4729   "TARGET_64BIT && reload_completed"
4730   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4731                                           UNSPEC_ADD_CARRY))
4732               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4733    (parallel [(set (match_dup 3)
4734                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4735                                      (match_dup 4))
4736                             (match_dup 5)))
4737               (clobber (reg:CC FLAGS_REG))])]
4738   "split_ti (operands+0, 1, operands+0, operands+3);
4739    split_ti (operands+1, 1, operands+1, operands+4);
4740    split_ti (operands+2, 1, operands+2, operands+5);")
4741
4742 ;; %%% splits for addsidi3
4743 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4746
4747 (define_expand "adddi3"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750                  (match_operand:DI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   ""
4753   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4754
4755 (define_insn "*adddi3_1"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4761   "#")
4762
4763 (define_split
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766                  (match_operand:DI 2 "general_operand" "")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "!TARGET_64BIT && reload_completed"
4769   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770                                           UNSPEC_ADD_CARRY))
4771               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_di (operands+0, 1, operands+0, operands+3);
4778    split_di (operands+1, 1, operands+1, operands+4);
4779    split_di (operands+2, 1, operands+2, operands+5);")
4780
4781 (define_insn "adddi3_carry_rex64"
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788   "adc{q}\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")
4790    (set_attr "pent_pair" "pu")
4791    (set_attr "mode" "DI")])
4792
4793 (define_insn "*adddi3_cc_rex64"
4794   [(set (reg:CC FLAGS_REG)
4795         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4797                    UNSPEC_ADD_CARRY))
4798    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799         (plus:DI (match_dup 1) (match_dup 2)))]
4800   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "add{q}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "mode" "DI")])
4804
4805 (define_insn "addqi3_carry"
4806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809                    (match_operand:QI 2 "general_operand" "qi,qm")))
4810    (clobber (reg:CC FLAGS_REG))]
4811   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812   "adc{b}\t{%2, %0|%0, %2}"
4813   [(set_attr "type" "alu")
4814    (set_attr "pent_pair" "pu")
4815    (set_attr "mode" "QI")])
4816
4817 (define_insn "addhi3_carry"
4818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821                    (match_operand:HI 2 "general_operand" "ri,rm")))
4822    (clobber (reg:CC FLAGS_REG))]
4823   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824   "adc{w}\t{%2, %0|%0, %2}"
4825   [(set_attr "type" "alu")
4826    (set_attr "pent_pair" "pu")
4827    (set_attr "mode" "HI")])
4828
4829 (define_insn "addsi3_carry"
4830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:SI 2 "general_operand" "ri,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836   "adc{l}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "SI")])
4840
4841 (define_insn "*addsi3_carry_zext"
4842   [(set (match_operand:DI 0 "register_operand" "=r")
4843           (zero_extend:DI 
4844             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846                      (match_operand:SI 2 "general_operand" "rim"))))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849   "adc{l}\t{%2, %k0|%k0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "pent_pair" "pu")
4852    (set_attr "mode" "SI")])
4853
4854 (define_insn "*addsi3_cc"
4855   [(set (reg:CC FLAGS_REG)
4856         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857                     (match_operand:SI 2 "general_operand" "ri,rm")]
4858                    UNSPEC_ADD_CARRY))
4859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860         (plus:SI (match_dup 1) (match_dup 2)))]
4861   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862   "add{l}\t{%2, %0|%0, %2}"
4863   [(set_attr "type" "alu")
4864    (set_attr "mode" "SI")])
4865
4866 (define_insn "addqi3_cc"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:QI 2 "general_operand" "qi,qm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872         (plus:QI (match_dup 1) (match_dup 2)))]
4873   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874   "add{b}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "QI")])
4877
4878 (define_expand "addsi3"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881                             (match_operand:SI 2 "general_operand" "")))
4882               (clobber (reg:CC FLAGS_REG))])]
4883   ""
4884   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4885
4886 (define_insn "*lea_1"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4889   "!TARGET_64BIT"
4890   "lea{l}\t{%a1, %0|%0, %a1}"
4891   [(set_attr "type" "lea")
4892    (set_attr "mode" "SI")])
4893
4894 (define_insn "*lea_1_rex64"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4897   "TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4901
4902 (define_insn "*lea_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %k0|%k0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4910
4911 (define_insn "*lea_2_rex64"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4914   "TARGET_64BIT"
4915   "lea{q}\t{%a1, %0|%0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "DI")])
4918
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4921
4922 (define_insn_and_split "*lea_general_1"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (plus (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "register_operand" "r"))
4926               (match_operand 3 "immediate_operand" "i")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4937 {
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[2] = gen_lowpart (Pmode, operands[2]);
4942   operands[3] = gen_lowpart (Pmode, operands[3]);
4943   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4944                       operands[3]);
4945   if (Pmode != SImode)
4946     pat = gen_rtx_SUBREG (SImode, pat, 0);
4947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948   DONE;
4949 }
4950   [(set_attr "type" "lea")
4951    (set_attr "mode" "SI")])
4952
4953 (define_insn_and_split "*lea_general_1_zext"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (zero_extend:DI
4956           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957                             (match_operand:SI 2 "register_operand" "r"))
4958                    (match_operand:SI 3 "immediate_operand" "i"))))]
4959   "TARGET_64BIT"
4960   "#"
4961   "&& reload_completed"
4962   [(set (match_dup 0)
4963         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4964                                                      (match_dup 2))
4965                                             (match_dup 3)) 0)))]
4966 {
4967   operands[1] = gen_lowpart (Pmode, operands[1]);
4968   operands[2] = gen_lowpart (Pmode, operands[2]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4970 }
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4973
4974 (define_insn_and_split "*lea_general_2"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (mult (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "const248_operand" "i"))
4978               (match_operand 3 "nonmemory_operand" "ri")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984        || GET_MODE (operands[3]) == VOIDmode)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4988 {
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4994                       operands[3]);
4995   if (Pmode != SImode)
4996     pat = gen_rtx_SUBREG (SImode, pat, 0);
4997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998   DONE;
4999 }
5000   [(set_attr "type" "lea")
5001    (set_attr "mode" "SI")])
5002
5003 (define_insn_and_split "*lea_general_2_zext"
5004   [(set (match_operand:DI 0 "register_operand" "=r")
5005         (zero_extend:DI
5006           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007                             (match_operand:SI 2 "const248_operand" "n"))
5008                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009   "TARGET_64BIT"
5010   "#"
5011   "&& reload_completed"
5012   [(set (match_dup 0)
5013         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5014                                                      (match_dup 2))
5015                                             (match_dup 3)) 0)))]
5016 {
5017   operands[1] = gen_lowpart (Pmode, operands[1]);
5018   operands[3] = gen_lowpart (Pmode, operands[3]);
5019 }
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5022
5023 (define_insn_and_split "*lea_general_3"
5024   [(set (match_operand 0 "register_operand" "=r")
5025         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026                           (match_operand 2 "const248_operand" "i"))
5027                     (match_operand 3 "register_operand" "r"))
5028               (match_operand 4 "immediate_operand" "i")))]
5029   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5034   "#"
5035   "&& reload_completed"
5036   [(const_int 0)]
5037 {
5038   rtx pat;
5039   operands[0] = gen_lowpart (SImode, operands[0]);
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[3] = gen_lowpart (Pmode, operands[3]);
5042   operands[4] = gen_lowpart (Pmode, operands[4]);
5043   pat = gen_rtx_PLUS (Pmode,
5044                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5045                                                          operands[2]),
5046                                     operands[3]),
5047                       operands[4]);
5048   if (Pmode != SImode)
5049     pat = gen_rtx_SUBREG (SImode, pat, 0);
5050   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051   DONE;
5052 }
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5055
5056 (define_insn_and_split "*lea_general_3_zext"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (zero_extend:DI
5059           (plus:SI (plus:SI (mult:SI
5060                               (match_operand:SI 1 "index_register_operand" "l")
5061                               (match_operand:SI 2 "const248_operand" "n"))
5062                             (match_operand:SI 3 "register_operand" "r"))
5063                    (match_operand:SI 4 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069                                                               (match_dup 2))
5070                                                      (match_dup 3))
5071                                             (match_dup 4)) 0)))]
5072 {
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076 }
5077   [(set_attr "type" "lea")
5078    (set_attr "mode" "SI")])
5079
5080 (define_insn "*adddi_1_rex64"
5081   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5086 {
5087   switch (get_attr_type (insn))
5088     {
5089     case TYPE_LEA:
5090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091       return "lea{q}\t{%a2, %0|%0, %a2}";
5092
5093     case TYPE_INCDEC:
5094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5095       if (operands[2] == const1_rtx)
5096         return "inc{q}\t%0";
5097       else
5098         {
5099           gcc_assert (operands[2] == constm1_rtx);
5100           return "dec{q}\t%0";
5101         }
5102
5103     default:
5104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5105
5106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5108       if (GET_CODE (operands[2]) == CONST_INT
5109           /* Avoid overflows.  */
5110           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5111           && (INTVAL (operands[2]) == 128
5112               || (INTVAL (operands[2]) < 0
5113                   && INTVAL (operands[2]) != -128)))
5114         {
5115           operands[2] = GEN_INT (-INTVAL (operands[2]));
5116           return "sub{q}\t{%2, %0|%0, %2}";
5117         }
5118       return "add{q}\t{%2, %0|%0, %2}";
5119     }
5120 }
5121   [(set (attr "type")
5122      (cond [(eq_attr "alternative" "2")
5123               (const_string "lea")
5124             ; Current assemblers are broken and do not allow @GOTOFF in
5125             ; ought but a memory context.
5126             (match_operand:DI 2 "pic_symbolic_operand" "")
5127               (const_string "lea")
5128             (match_operand:DI 2 "incdec_operand" "")
5129               (const_string "incdec")
5130            ]
5131            (const_string "alu")))
5132    (set_attr "mode" "DI")])
5133
5134 ;; Convert lea to the lea pattern to avoid flags dependency.
5135 (define_split
5136   [(set (match_operand:DI 0 "register_operand" "")
5137         (plus:DI (match_operand:DI 1 "register_operand" "")
5138                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5139    (clobber (reg:CC FLAGS_REG))]
5140   "TARGET_64BIT && reload_completed
5141    && true_regnum (operands[0]) != true_regnum (operands[1])"
5142   [(set (match_dup 0)
5143         (plus:DI (match_dup 1)
5144                  (match_dup 2)))]
5145   "")
5146
5147 (define_insn "*adddi_2_rex64"
5148   [(set (reg FLAGS_REG)
5149         (compare
5150           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5151                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5152           (const_int 0)))                       
5153    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5154         (plus:DI (match_dup 1) (match_dup 2)))]
5155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5156    && ix86_binary_operator_ok (PLUS, DImode, operands)
5157    /* Current assemblers are broken and do not allow @GOTOFF in
5158       ought but a memory context.  */
5159    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5160 {
5161   switch (get_attr_type (insn))
5162     {
5163     case TYPE_INCDEC:
5164       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165       if (operands[2] == const1_rtx)
5166         return "inc{q}\t%0";
5167       else
5168         {
5169           gcc_assert (operands[2] == constm1_rtx);
5170           return "dec{q}\t%0";
5171         }
5172
5173     default:
5174       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175       /* ???? We ought to handle there the 32bit case too
5176          - do we need new constraint?  */
5177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5178          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5179       if (GET_CODE (operands[2]) == CONST_INT
5180           /* Avoid overflows.  */
5181           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5182           && (INTVAL (operands[2]) == 128
5183               || (INTVAL (operands[2]) < 0
5184                   && INTVAL (operands[2]) != -128)))
5185         {
5186           operands[2] = GEN_INT (-INTVAL (operands[2]));
5187           return "sub{q}\t{%2, %0|%0, %2}";
5188         }
5189       return "add{q}\t{%2, %0|%0, %2}";
5190     }
5191 }
5192   [(set (attr "type")
5193      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5194         (const_string "incdec")
5195         (const_string "alu")))
5196    (set_attr "mode" "DI")])
5197
5198 (define_insn "*adddi_3_rex64"
5199   [(set (reg FLAGS_REG)
5200         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5201                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5202    (clobber (match_scratch:DI 0 "=r"))]
5203   "TARGET_64BIT
5204    && ix86_match_ccmode (insn, CCZmode)
5205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5206    /* Current assemblers are broken and do not allow @GOTOFF in
5207       ought but a memory context.  */
5208    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5209 {
5210   switch (get_attr_type (insn))
5211     {
5212     case TYPE_INCDEC:
5213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214       if (operands[2] == const1_rtx)
5215         return "inc{q}\t%0";
5216       else
5217         {
5218           gcc_assert (operands[2] == constm1_rtx);
5219           return "dec{q}\t%0";
5220         }
5221
5222     default:
5223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5224       /* ???? We ought to handle there the 32bit case too
5225          - do we need new constraint?  */
5226       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5227          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5228       if (GET_CODE (operands[2]) == CONST_INT
5229           /* Avoid overflows.  */
5230           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5231           && (INTVAL (operands[2]) == 128
5232               || (INTVAL (operands[2]) < 0
5233                   && INTVAL (operands[2]) != -128)))
5234         {
5235           operands[2] = GEN_INT (-INTVAL (operands[2]));
5236           return "sub{q}\t{%2, %0|%0, %2}";
5237         }
5238       return "add{q}\t{%2, %0|%0, %2}";
5239     }
5240 }
5241   [(set (attr "type")
5242      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5243         (const_string "incdec")
5244         (const_string "alu")))
5245    (set_attr "mode" "DI")])
5246
5247 ; For comparisons against 1, -1 and 128, we may generate better code
5248 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5249 ; is matched then.  We can't accept general immediate, because for
5250 ; case of overflows,  the result is messed up.
5251 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5252 ; when negated.
5253 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5254 ; only for comparisons not depending on it.
5255 (define_insn "*adddi_4_rex64"
5256   [(set (reg FLAGS_REG)
5257         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5258                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5259    (clobber (match_scratch:DI 0 "=rm"))]
5260   "TARGET_64BIT
5261    &&  ix86_match_ccmode (insn, CCGCmode)"
5262 {
5263   switch (get_attr_type (insn))
5264     {
5265     case TYPE_INCDEC:
5266       if (operands[2] == constm1_rtx)
5267         return "inc{q}\t%0";
5268       else
5269         {
5270           gcc_assert (operands[2] == const1_rtx);
5271           return "dec{q}\t%0";
5272         }
5273
5274     default:
5275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5277          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5278       if ((INTVAL (operands[2]) == -128
5279            || (INTVAL (operands[2]) > 0
5280                && INTVAL (operands[2]) != 128))
5281           /* Avoid overflows.  */
5282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5283         return "sub{q}\t{%2, %0|%0, %2}";
5284       operands[2] = GEN_INT (-INTVAL (operands[2]));
5285       return "add{q}\t{%2, %0|%0, %2}";
5286     }
5287 }
5288   [(set (attr "type")
5289      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290         (const_string "incdec")
5291         (const_string "alu")))
5292    (set_attr "mode" "DI")])
5293
5294 (define_insn "*adddi_5_rex64"
5295   [(set (reg FLAGS_REG)
5296         (compare
5297           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5298                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5299           (const_int 0)))                       
5300    (clobber (match_scratch:DI 0 "=r"))]
5301   "TARGET_64BIT
5302    && ix86_match_ccmode (insn, CCGOCmode)
5303    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5304    /* Current assemblers are broken and do not allow @GOTOFF in
5305       ought but a memory context.  */
5306    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5307 {
5308   switch (get_attr_type (insn))
5309     {
5310     case TYPE_INCDEC:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else
5315         {
5316           gcc_assert (operands[2] == constm1_rtx);
5317           return "dec{q}\t%0";
5318         }
5319
5320     default:
5321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5324       if (GET_CODE (operands[2]) == CONST_INT
5325           /* Avoid overflows.  */
5326           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327           && (INTVAL (operands[2]) == 128
5328               || (INTVAL (operands[2]) < 0
5329                   && INTVAL (operands[2]) != -128)))
5330         {
5331           operands[2] = GEN_INT (-INTVAL (operands[2]));
5332           return "sub{q}\t{%2, %0|%0, %2}";
5333         }
5334       return "add{q}\t{%2, %0|%0, %2}";
5335     }
5336 }
5337   [(set (attr "type")
5338      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339         (const_string "incdec")
5340         (const_string "alu")))
5341    (set_attr "mode" "DI")])
5342
5343
5344 (define_insn "*addsi_1"
5345   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5348    (clobber (reg:CC FLAGS_REG))]
5349   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355       return "lea{l}\t{%a2, %0|%0, %a2}";
5356
5357     case TYPE_INCDEC:
5358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359       if (operands[2] == const1_rtx)
5360         return "inc{l}\t%0";
5361       else
5362         {
5363           gcc_assert (operands[2] == constm1_rtx);
5364           return "dec{l}\t%0";
5365         }
5366
5367     default:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           && (INTVAL (operands[2]) == 128
5374               || (INTVAL (operands[2]) < 0
5375                   && INTVAL (operands[2]) != -128)))
5376         {
5377           operands[2] = GEN_INT (-INTVAL (operands[2]));
5378           return "sub{l}\t{%2, %0|%0, %2}";
5379         }
5380       return "add{l}\t{%2, %0|%0, %2}";
5381     }
5382 }
5383   [(set (attr "type")
5384      (cond [(eq_attr "alternative" "2")
5385               (const_string "lea")
5386             ; Current assemblers are broken and do not allow @GOTOFF in
5387             ; ought but a memory context.
5388             (match_operand:SI 2 "pic_symbolic_operand" "")
5389               (const_string "lea")
5390             (match_operand:SI 2 "incdec_operand" "")
5391               (const_string "incdec")
5392            ]
5393            (const_string "alu")))
5394    (set_attr "mode" "SI")])
5395
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5397 (define_split
5398   [(set (match_operand 0 "register_operand" "")
5399         (plus (match_operand 1 "register_operand" "")
5400               (match_operand 2 "nonmemory_operand" "")))
5401    (clobber (reg:CC FLAGS_REG))]
5402   "reload_completed
5403    && true_regnum (operands[0]) != true_regnum (operands[1])"
5404   [(const_int 0)]
5405 {
5406   rtx pat;
5407   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5408      may confuse gen_lowpart.  */
5409   if (GET_MODE (operands[0]) != Pmode)
5410     {
5411       operands[1] = gen_lowpart (Pmode, operands[1]);
5412       operands[2] = gen_lowpart (Pmode, operands[2]);
5413     }
5414   operands[0] = gen_lowpart (SImode, operands[0]);
5415   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5416   if (Pmode != SImode)
5417     pat = gen_rtx_SUBREG (SImode, pat, 0);
5418   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5419   DONE;
5420 })
5421
5422 ;; It may seem that nonimmediate operand is proper one for operand 1.
5423 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5424 ;; we take care in ix86_binary_operator_ok to not allow two memory
5425 ;; operands so proper swapping will be done in reload.  This allow
5426 ;; patterns constructed from addsi_1 to match.
5427 (define_insn "addsi_1_zext"
5428   [(set (match_operand:DI 0 "register_operand" "=r,r")
5429         (zero_extend:DI
5430           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5431                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5434 {
5435   switch (get_attr_type (insn))
5436     {
5437     case TYPE_LEA:
5438       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5439       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5440
5441     case TYPE_INCDEC:
5442       if (operands[2] == const1_rtx)
5443         return "inc{l}\t%k0";
5444       else
5445         {
5446           gcc_assert (operands[2] == constm1_rtx);
5447           return "dec{l}\t%k0";
5448         }
5449
5450     default:
5451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5453       if (GET_CODE (operands[2]) == CONST_INT
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{l}\t{%2, %k0|%k0, %2}";
5460         }
5461       return "add{l}\t{%2, %k0|%k0, %2}";
5462     }
5463 }
5464   [(set (attr "type")
5465      (cond [(eq_attr "alternative" "1")
5466               (const_string "lea")
5467             ; Current assemblers are broken and do not allow @GOTOFF in
5468             ; ought but a memory context.
5469             (match_operand:SI 2 "pic_symbolic_operand" "")
5470               (const_string "lea")
5471             (match_operand:SI 2 "incdec_operand" "")
5472               (const_string "incdec")
5473            ]
5474            (const_string "alu")))
5475    (set_attr "mode" "SI")])
5476
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5478 (define_split
5479   [(set (match_operand:DI 0 "register_operand" "")
5480         (zero_extend:DI
5481           (plus:SI (match_operand:SI 1 "register_operand" "")
5482                    (match_operand:SI 2 "nonmemory_operand" ""))))
5483    (clobber (reg:CC FLAGS_REG))]
5484   "TARGET_64BIT && reload_completed
5485    && true_regnum (operands[0]) != true_regnum (operands[1])"
5486   [(set (match_dup 0)
5487         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5488 {
5489   operands[1] = gen_lowpart (Pmode, operands[1]);
5490   operands[2] = gen_lowpart (Pmode, operands[2]);
5491 })
5492
5493 (define_insn "*addsi_2"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5498           (const_int 0)))                       
5499    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:SI (match_dup 1) (match_dup 2)))]
5501   "ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, SImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{l}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{l}\t%0";
5517         }
5518
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5523       if (GET_CODE (operands[2]) == CONST_INT
5524           && (INTVAL (operands[2]) == 128
5525               || (INTVAL (operands[2]) < 0
5526                   && INTVAL (operands[2]) != -128)))
5527         {
5528           operands[2] = GEN_INT (-INTVAL (operands[2]));
5529           return "sub{l}\t{%2, %0|%0, %2}";
5530         }
5531       return "add{l}\t{%2, %0|%0, %2}";
5532     }
5533 }
5534   [(set (attr "type")
5535      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5536         (const_string "incdec")
5537         (const_string "alu")))
5538    (set_attr "mode" "SI")])
5539
5540 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5541 (define_insn "*addsi_2_zext"
5542   [(set (reg FLAGS_REG)
5543         (compare
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5545                    (match_operand:SI 2 "general_operand" "rmni"))
5546           (const_int 0)))                       
5547    (set (match_operand:DI 0 "register_operand" "=r")
5548         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5549   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5550    && ix86_binary_operator_ok (PLUS, SImode, operands)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 {
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       if (operands[2] == const1_rtx)
5559         return "inc{l}\t%k0";
5560       else
5561         {
5562           gcc_assert (operands[2] == constm1_rtx);
5563           return "dec{l}\t%k0";
5564         }
5565
5566     default:
5567       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5569       if (GET_CODE (operands[2]) == CONST_INT
5570           && (INTVAL (operands[2]) == 128
5571               || (INTVAL (operands[2]) < 0
5572                   && INTVAL (operands[2]) != -128)))
5573         {
5574           operands[2] = GEN_INT (-INTVAL (operands[2]));
5575           return "sub{l}\t{%2, %k0|%k0, %2}";
5576         }
5577       return "add{l}\t{%2, %k0|%k0, %2}";
5578     }
5579 }
5580   [(set (attr "type")
5581      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582         (const_string "incdec")
5583         (const_string "alu")))
5584    (set_attr "mode" "SI")])
5585
5586 (define_insn "*addsi_3"
5587   [(set (reg FLAGS_REG)
5588         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590    (clobber (match_scratch:SI 0 "=r"))]
5591   "ix86_match_ccmode (insn, CCZmode)
5592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593    /* Current assemblers are broken and do not allow @GOTOFF in
5594       ought but a memory context.  */
5595    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596 {
5597   switch (get_attr_type (insn))
5598     {
5599     case TYPE_INCDEC:
5600       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5601       if (operands[2] == const1_rtx)
5602         return "inc{l}\t%0";
5603       else
5604         {
5605           gcc_assert (operands[2] == constm1_rtx);
5606           return "dec{l}\t%0";
5607         }
5608
5609     default:
5610       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5613       if (GET_CODE (operands[2]) == CONST_INT
5614           && (INTVAL (operands[2]) == 128
5615               || (INTVAL (operands[2]) < 0
5616                   && INTVAL (operands[2]) != -128)))
5617         {
5618           operands[2] = GEN_INT (-INTVAL (operands[2]));
5619           return "sub{l}\t{%2, %0|%0, %2}";
5620         }
5621       return "add{l}\t{%2, %0|%0, %2}";
5622     }
5623 }
5624   [(set (attr "type")
5625      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5626         (const_string "incdec")
5627         (const_string "alu")))
5628    (set_attr "mode" "SI")])
5629
5630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5631 (define_insn "*addsi_3_zext"
5632   [(set (reg FLAGS_REG)
5633         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5634                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5642 {
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5653
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5673
5674 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5676 ; is matched then.  We can't accept general immediate, because for
5677 ; case of overflows,  the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5679 ; when negated.
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683   [(set (reg FLAGS_REG)
5684         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685                  (match_operand:SI 2 "const_int_operand" "n")))
5686    (clobber (match_scratch:SI 0 "=rm"))]
5687   "ix86_match_ccmode (insn, CCGCmode)
5688    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5689 {
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == constm1_rtx)
5694         return "inc{l}\t%0";
5695       else
5696         {
5697           gcc_assert (operands[2] == const1_rtx);
5698           return "dec{l}\t%0";
5699         }
5700
5701     default:
5702       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if ((INTVAL (operands[2]) == -128
5706            || (INTVAL (operands[2]) > 0
5707                && INTVAL (operands[2]) != 128)))
5708         return "sub{l}\t{%2, %0|%0, %2}";
5709       operands[2] = GEN_INT (-INTVAL (operands[2]));
5710       return "add{l}\t{%2, %0|%0, %2}";
5711     }
5712 }
5713   [(set (attr "type")
5714      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715         (const_string "incdec")
5716         (const_string "alu")))
5717    (set_attr "mode" "SI")])
5718
5719 (define_insn "*addsi_5"
5720   [(set (reg FLAGS_REG)
5721         (compare
5722           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723                    (match_operand:SI 2 "general_operand" "rmni"))
5724           (const_int 0)))                       
5725    (clobber (match_scratch:SI 0 "=r"))]
5726   "ix86_match_ccmode (insn, CCGOCmode)
5727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728    /* Current assemblers are broken and do not allow @GOTOFF in
5729       ought but a memory context.  */
5730    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%0";
5738       else
5739         {
5740           gcc_assert (operands[2] == constm1_rtx);
5741           return "dec{l}\t%0";
5742         }
5743
5744     default:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5748       if (GET_CODE (operands[2]) == CONST_INT
5749           && (INTVAL (operands[2]) == 128
5750               || (INTVAL (operands[2]) < 0
5751                   && INTVAL (operands[2]) != -128)))
5752         {
5753           operands[2] = GEN_INT (-INTVAL (operands[2]));
5754           return "sub{l}\t{%2, %0|%0, %2}";
5755         }
5756       return "add{l}\t{%2, %0|%0, %2}";
5757     }
5758 }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set_attr "mode" "SI")])
5764
5765 (define_expand "addhi3"
5766   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5767                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5768                             (match_operand:HI 2 "general_operand" "")))
5769               (clobber (reg:CC FLAGS_REG))])]
5770   "TARGET_HIMODE_MATH"
5771   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5772
5773 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5774 ;; type optimizations enabled by define-splits.  This is not important
5775 ;; for PII, and in fact harmful because of partial register stalls.
5776
5777 (define_insn "*addhi_1_lea"
5778   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5779         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5780                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5781    (clobber (reg:CC FLAGS_REG))]
5782   "!TARGET_PARTIAL_REG_STALL
5783    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5784 {
5785   switch (get_attr_type (insn))
5786     {
5787     case TYPE_LEA:
5788       return "#";
5789     case TYPE_INCDEC:
5790       if (operands[2] == const1_rtx)
5791         return "inc{w}\t%0";
5792       else
5793         {
5794           gcc_assert (operands[2] == constm1_rtx);
5795           return "dec{w}\t%0";
5796         }
5797
5798     default:
5799       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5800          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5801       if (GET_CODE (operands[2]) == CONST_INT
5802           && (INTVAL (operands[2]) == 128
5803               || (INTVAL (operands[2]) < 0
5804                   && INTVAL (operands[2]) != -128)))
5805         {
5806           operands[2] = GEN_INT (-INTVAL (operands[2]));
5807           return "sub{w}\t{%2, %0|%0, %2}";
5808         }
5809       return "add{w}\t{%2, %0|%0, %2}";
5810     }
5811 }
5812   [(set (attr "type")
5813      (if_then_else (eq_attr "alternative" "2")
5814         (const_string "lea")
5815         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5816            (const_string "incdec")
5817            (const_string "alu"))))
5818    (set_attr "mode" "HI,HI,SI")])
5819
5820 (define_insn "*addhi_1"
5821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5822         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5823                  (match_operand:HI 2 "general_operand" "ri,rm")))
5824    (clobber (reg:CC FLAGS_REG))]
5825   "TARGET_PARTIAL_REG_STALL
5826    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5827 {
5828   switch (get_attr_type (insn))
5829     {
5830     case TYPE_INCDEC:
5831       if (operands[2] == const1_rtx)
5832         return "inc{w}\t%0";
5833       else
5834         {
5835           gcc_assert (operands[2] == constm1_rtx);
5836           return "dec{w}\t%0";
5837         }
5838
5839     default:
5840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5842       if (GET_CODE (operands[2]) == CONST_INT
5843           && (INTVAL (operands[2]) == 128
5844               || (INTVAL (operands[2]) < 0
5845                   && INTVAL (operands[2]) != -128)))
5846         {
5847           operands[2] = GEN_INT (-INTVAL (operands[2]));
5848           return "sub{w}\t{%2, %0|%0, %2}";
5849         }
5850       return "add{w}\t{%2, %0|%0, %2}";
5851     }
5852 }
5853   [(set (attr "type")
5854      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855         (const_string "incdec")
5856         (const_string "alu")))
5857    (set_attr "mode" "HI")])
5858
5859 (define_insn "*addhi_2"
5860   [(set (reg FLAGS_REG)
5861         (compare
5862           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5864           (const_int 0)))                       
5865    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5866         (plus:HI (match_dup 1) (match_dup 2)))]
5867   "ix86_match_ccmode (insn, CCGOCmode)
5868    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5869 {
5870   switch (get_attr_type (insn))
5871     {
5872     case TYPE_INCDEC:
5873       if (operands[2] == const1_rtx)
5874         return "inc{w}\t%0";
5875       else
5876         {
5877           gcc_assert (operands[2] == constm1_rtx);
5878           return "dec{w}\t%0";
5879         }
5880
5881     default:
5882       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5883          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5884       if (GET_CODE (operands[2]) == CONST_INT
5885           && (INTVAL (operands[2]) == 128
5886               || (INTVAL (operands[2]) < 0
5887                   && INTVAL (operands[2]) != -128)))
5888         {
5889           operands[2] = GEN_INT (-INTVAL (operands[2]));
5890           return "sub{w}\t{%2, %0|%0, %2}";
5891         }
5892       return "add{w}\t{%2, %0|%0, %2}";
5893     }
5894 }
5895   [(set (attr "type")
5896      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5897         (const_string "incdec")
5898         (const_string "alu")))
5899    (set_attr "mode" "HI")])
5900
5901 (define_insn "*addhi_3"
5902   [(set (reg FLAGS_REG)
5903         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5904                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5905    (clobber (match_scratch:HI 0 "=r"))]
5906   "ix86_match_ccmode (insn, CCZmode)
5907    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5908 {
5909   switch (get_attr_type (insn))
5910     {
5911     case TYPE_INCDEC:
5912       if (operands[2] == const1_rtx)
5913         return "inc{w}\t%0";
5914       else
5915         {
5916           gcc_assert (operands[2] == constm1_rtx);
5917           return "dec{w}\t%0";
5918         }
5919
5920     default:
5921       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5923       if (GET_CODE (operands[2]) == CONST_INT
5924           && (INTVAL (operands[2]) == 128
5925               || (INTVAL (operands[2]) < 0
5926                   && INTVAL (operands[2]) != -128)))
5927         {
5928           operands[2] = GEN_INT (-INTVAL (operands[2]));
5929           return "sub{w}\t{%2, %0|%0, %2}";
5930         }
5931       return "add{w}\t{%2, %0|%0, %2}";
5932     }
5933 }
5934   [(set (attr "type")
5935      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936         (const_string "incdec")
5937         (const_string "alu")))
5938    (set_attr "mode" "HI")])
5939
5940 ; See comments above addsi_4 for details.
5941 (define_insn "*addhi_4"
5942   [(set (reg FLAGS_REG)
5943         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5944                  (match_operand:HI 2 "const_int_operand" "n")))
5945    (clobber (match_scratch:HI 0 "=rm"))]
5946   "ix86_match_ccmode (insn, CCGCmode)
5947    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5948 {
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       if (operands[2] == constm1_rtx)
5953         return "inc{w}\t%0";
5954       else
5955         {
5956           gcc_assert (operands[2] == const1_rtx);
5957           return "dec{w}\t%0";
5958         }
5959
5960     default:
5961       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5963          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5964       if ((INTVAL (operands[2]) == -128
5965            || (INTVAL (operands[2]) > 0
5966                && INTVAL (operands[2]) != 128)))
5967         return "sub{w}\t{%2, %0|%0, %2}";
5968       operands[2] = GEN_INT (-INTVAL (operands[2]));
5969       return "add{w}\t{%2, %0|%0, %2}";
5970     }
5971 }
5972   [(set (attr "type")
5973      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974         (const_string "incdec")
5975         (const_string "alu")))
5976    (set_attr "mode" "SI")])
5977
5978
5979 (define_insn "*addhi_5"
5980   [(set (reg FLAGS_REG)
5981         (compare
5982           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5983                    (match_operand:HI 2 "general_operand" "rmni"))
5984           (const_int 0)))                       
5985    (clobber (match_scratch:HI 0 "=r"))]
5986   "ix86_match_ccmode (insn, CCGOCmode)
5987    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{w}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{w}\t%0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (GET_CODE (operands[2]) == CONST_INT
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{w}\t{%2, %0|%0, %2}";
6010         }
6011       return "add{w}\t{%2, %0|%0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "HI")])
6019
6020 (define_expand "addqi3"
6021   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6022                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6023                             (match_operand:QI 2 "general_operand" "")))
6024               (clobber (reg:CC FLAGS_REG))])]
6025   "TARGET_QIMODE_MATH"
6026   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6027
6028 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6029 (define_insn "*addqi_1_lea"
6030   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033    (clobber (reg:CC FLAGS_REG))]
6034   "!TARGET_PARTIAL_REG_STALL
6035    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6036 {
6037   int widen = (which_alternative == 2);
6038   switch (get_attr_type (insn))
6039     {
6040     case TYPE_LEA:
6041       return "#";
6042     case TYPE_INCDEC:
6043       if (operands[2] == const1_rtx)
6044         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6045       else
6046         {
6047           gcc_assert (operands[2] == constm1_rtx);
6048           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6049         }
6050
6051     default:
6052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6054       if (GET_CODE (operands[2]) == CONST_INT
6055           && (INTVAL (operands[2]) == 128
6056               || (INTVAL (operands[2]) < 0
6057                   && INTVAL (operands[2]) != -128)))
6058         {
6059           operands[2] = GEN_INT (-INTVAL (operands[2]));
6060           if (widen)
6061             return "sub{l}\t{%2, %k0|%k0, %2}";
6062           else
6063             return "sub{b}\t{%2, %0|%0, %2}";
6064         }
6065       if (widen)
6066         return "add{l}\t{%k2, %k0|%k0, %k2}";
6067       else
6068         return "add{b}\t{%2, %0|%0, %2}";
6069     }
6070 }
6071   [(set (attr "type")
6072      (if_then_else (eq_attr "alternative" "3")
6073         (const_string "lea")
6074         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6075            (const_string "incdec")
6076            (const_string "alu"))))
6077    (set_attr "mode" "QI,QI,SI,SI")])
6078
6079 (define_insn "*addqi_1"
6080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6081         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6082                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6083    (clobber (reg:CC FLAGS_REG))]
6084   "TARGET_PARTIAL_REG_STALL
6085    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6086 {
6087   int widen = (which_alternative == 2);
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097         }
6098
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           if (widen)
6109             return "sub{l}\t{%2, %k0|%k0, %2}";
6110           else
6111             return "sub{b}\t{%2, %0|%0, %2}";
6112         }
6113       if (widen)
6114         return "add{l}\t{%k2, %k0|%k0, %k2}";
6115       else
6116         return "add{b}\t{%2, %0|%0, %2}";
6117     }
6118 }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set_attr "mode" "QI,QI,SI")])
6124
6125 (define_insn "*addqi_1_slp"
6126   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6127         (plus:QI (match_dup 0)
6128                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6129    (clobber (reg:CC FLAGS_REG))]
6130   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6132 {
6133   switch (get_attr_type (insn))
6134     {
6135     case TYPE_INCDEC:
6136       if (operands[1] == const1_rtx)
6137         return "inc{b}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[1] == constm1_rtx);
6141           return "dec{b}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6146       if (GET_CODE (operands[1]) == CONST_INT
6147           && INTVAL (operands[1]) < 0)
6148         {
6149           operands[1] = GEN_INT (-INTVAL (operands[1]));
6150           return "sub{b}\t{%1, %0|%0, %1}";
6151         }
6152       return "add{b}\t{%1, %0|%0, %1}";
6153     }
6154 }
6155   [(set (attr "type")
6156      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6157         (const_string "incdec")
6158         (const_string "alu1")))
6159    (set (attr "memory")
6160      (if_then_else (match_operand 1 "memory_operand" "")
6161         (const_string "load")
6162         (const_string "none")))
6163    (set_attr "mode" "QI")])
6164
6165 (define_insn "*addqi_2"
6166   [(set (reg FLAGS_REG)
6167         (compare
6168           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6169                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6170           (const_int 0)))
6171    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6172         (plus:QI (match_dup 1) (match_dup 2)))]
6173   "ix86_match_ccmode (insn, CCGOCmode)
6174    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175 {
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx
6184                       || (GET_CODE (operands[2]) == CONST_INT
6185                           && INTVAL (operands[2]) == 255));
6186           return "dec{b}\t%0";
6187         }
6188
6189     default:
6190       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6191       if (GET_CODE (operands[2]) == CONST_INT
6192           && INTVAL (operands[2]) < 0)
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{b}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{b}\t{%2, %0|%0, %2}";
6198     }
6199 }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "QI")])
6205
6206 (define_insn "*addqi_3"
6207   [(set (reg FLAGS_REG)
6208         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6209                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6210    (clobber (match_scratch:QI 0 "=q"))]
6211   "ix86_match_ccmode (insn, CCZmode)
6212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6213 {
6214   switch (get_attr_type (insn))
6215     {
6216     case TYPE_INCDEC:
6217       if (operands[2] == const1_rtx)
6218         return "inc{b}\t%0";
6219       else
6220         {
6221           gcc_assert (operands[2] == constm1_rtx
6222                       || (GET_CODE (operands[2]) == CONST_INT
6223                           && INTVAL (operands[2]) == 255));
6224           return "dec{b}\t%0";
6225         }
6226
6227     default:
6228       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6229       if (GET_CODE (operands[2]) == CONST_INT
6230           && INTVAL (operands[2]) < 0)
6231         {
6232           operands[2] = GEN_INT (-INTVAL (operands[2]));
6233           return "sub{b}\t{%2, %0|%0, %2}";
6234         }
6235       return "add{b}\t{%2, %0|%0, %2}";
6236     }
6237 }
6238   [(set (attr "type")
6239      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240         (const_string "incdec")
6241         (const_string "alu")))
6242    (set_attr "mode" "QI")])
6243
6244 ; See comments above addsi_4 for details.
6245 (define_insn "*addqi_4"
6246   [(set (reg FLAGS_REG)
6247         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6248                  (match_operand:QI 2 "const_int_operand" "n")))
6249    (clobber (match_scratch:QI 0 "=qm"))]
6250   "ix86_match_ccmode (insn, CCGCmode)
6251    && (INTVAL (operands[2]) & 0xff) != 0x80"
6252 {
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == constm1_rtx
6257           || (GET_CODE (operands[2]) == CONST_INT
6258               && INTVAL (operands[2]) == 255))
6259         return "inc{b}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == const1_rtx);
6263           return "dec{b}\t%0";
6264         }
6265
6266     default:
6267       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6268       if (INTVAL (operands[2]) < 0)
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           return "add{b}\t{%2, %0|%0, %2}";
6272         }
6273       return "sub{b}\t{%2, %0|%0, %2}";
6274     }
6275 }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set_attr "mode" "QI")])
6281
6282
6283 (define_insn "*addqi_5"
6284   [(set (reg FLAGS_REG)
6285         (compare
6286           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6287                    (match_operand:QI 2 "general_operand" "qmni"))
6288           (const_int 0)))
6289    (clobber (match_scratch:QI 0 "=q"))]
6290   "ix86_match_ccmode (insn, CCGOCmode)
6291    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6292 {
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == const1_rtx)
6297         return "inc{b}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx
6301                       || (GET_CODE (operands[2]) == CONST_INT
6302                           && INTVAL (operands[2]) == 255));
6303           return "dec{b}\t%0";
6304         }
6305
6306     default:
6307       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6308       if (GET_CODE (operands[2]) == CONST_INT
6309           && INTVAL (operands[2]) < 0)
6310         {
6311           operands[2] = GEN_INT (-INTVAL (operands[2]));
6312           return "sub{b}\t{%2, %0|%0, %2}";
6313         }
6314       return "add{b}\t{%2, %0|%0, %2}";
6315     }
6316 }
6317   [(set (attr "type")
6318      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6319         (const_string "incdec")
6320         (const_string "alu")))
6321    (set_attr "mode" "QI")])
6322
6323
6324 (define_insn "addqi_ext_1"
6325   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6326                          (const_int 8)
6327                          (const_int 8))
6328         (plus:SI
6329           (zero_extract:SI
6330             (match_operand 1 "ext_register_operand" "0")
6331             (const_int 8)
6332             (const_int 8))
6333           (match_operand:QI 2 "general_operand" "Qmn")))
6334    (clobber (reg:CC FLAGS_REG))]
6335   "!TARGET_64BIT"
6336 {
6337   switch (get_attr_type (insn))
6338     {
6339     case TYPE_INCDEC:
6340       if (operands[2] == const1_rtx)
6341         return "inc{b}\t%h0";
6342       else
6343         {
6344           gcc_assert (operands[2] == constm1_rtx
6345                       || (GET_CODE (operands[2]) == CONST_INT
6346                           && INTVAL (operands[2]) == 255));
6347           return "dec{b}\t%h0";
6348         }
6349
6350     default:
6351       return "add{b}\t{%2, %h0|%h0, %2}";
6352     }
6353 }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI")])
6359
6360 (define_insn "*addqi_ext_1_rex64"
6361   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6362                          (const_int 8)
6363                          (const_int 8))
6364         (plus:SI
6365           (zero_extract:SI
6366             (match_operand 1 "ext_register_operand" "0")
6367             (const_int 8)
6368             (const_int 8))
6369           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "TARGET_64BIT"
6372 {
6373   switch (get_attr_type (insn))
6374     {
6375     case TYPE_INCDEC:
6376       if (operands[2] == const1_rtx)
6377         return "inc{b}\t%h0";
6378       else
6379         {
6380           gcc_assert (operands[2] == constm1_rtx
6381                       || (GET_CODE (operands[2]) == CONST_INT
6382                           && INTVAL (operands[2]) == 255));
6383           return "dec{b}\t%h0";
6384         }
6385
6386     default:
6387       return "add{b}\t{%2, %h0|%h0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6395
6396 (define_insn "*addqi_ext_2"
6397   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6398                          (const_int 8)
6399                          (const_int 8))
6400         (plus:SI
6401           (zero_extract:SI
6402             (match_operand 1 "ext_register_operand" "%0")
6403             (const_int 8)
6404             (const_int 8))
6405           (zero_extract:SI
6406             (match_operand 2 "ext_register_operand" "Q")
6407             (const_int 8)
6408             (const_int 8))))
6409    (clobber (reg:CC FLAGS_REG))]
6410   ""
6411   "add{b}\t{%h2, %h0|%h0, %h2}"
6412   [(set_attr "type" "alu")
6413    (set_attr "mode" "QI")])
6414
6415 ;; The patterns that match these are at the end of this file.
6416
6417 (define_expand "addxf3"
6418   [(set (match_operand:XF 0 "register_operand" "")
6419         (plus:XF (match_operand:XF 1 "register_operand" "")
6420                  (match_operand:XF 2 "register_operand" "")))]
6421   "TARGET_80387"
6422   "")
6423
6424 (define_expand "adddf3"
6425   [(set (match_operand:DF 0 "register_operand" "")
6426         (plus:DF (match_operand:DF 1 "register_operand" "")
6427                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6428   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6429   "")
6430
6431 (define_expand "addsf3"
6432   [(set (match_operand:SF 0 "register_operand" "")
6433         (plus:SF (match_operand:SF 1 "register_operand" "")
6434                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6435   "TARGET_80387 || TARGET_SSE_MATH"
6436   "")
6437 \f
6438 ;; Subtract instructions
6439
6440 ;; %%% splits for subditi3
6441
6442 (define_expand "subti3"
6443   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6444                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6445                              (match_operand:TI 2 "x86_64_general_operand" "")))
6446               (clobber (reg:CC FLAGS_REG))])]
6447   "TARGET_64BIT"
6448   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6449
6450 (define_insn "*subti3_1"
6451   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6452         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6453                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6454    (clobber (reg:CC FLAGS_REG))]
6455   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6456   "#")
6457
6458 (define_split
6459   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6460         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6461                   (match_operand:TI 2 "general_operand" "")))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "TARGET_64BIT && reload_completed"
6464   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6465               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6466    (parallel [(set (match_dup 3)
6467                    (minus:DI (match_dup 4)
6468                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6469                                       (match_dup 5))))
6470               (clobber (reg:CC FLAGS_REG))])]
6471   "split_ti (operands+0, 1, operands+0, operands+3);
6472    split_ti (operands+1, 1, operands+1, operands+4);
6473    split_ti (operands+2, 1, operands+2, operands+5);")
6474
6475 ;; %%% splits for subsidi3
6476
6477 (define_expand "subdi3"
6478   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6479                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6480                              (match_operand:DI 2 "x86_64_general_operand" "")))
6481               (clobber (reg:CC FLAGS_REG))])]
6482   ""
6483   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6484
6485 (define_insn "*subdi3_1"
6486   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6487         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6488                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6489    (clobber (reg:CC FLAGS_REG))]
6490   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6491   "#")
6492
6493 (define_split
6494   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6495         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6496                   (match_operand:DI 2 "general_operand" "")))
6497    (clobber (reg:CC FLAGS_REG))]
6498   "!TARGET_64BIT && reload_completed"
6499   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6500               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6501    (parallel [(set (match_dup 3)
6502                    (minus:SI (match_dup 4)
6503                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6504                                       (match_dup 5))))
6505               (clobber (reg:CC FLAGS_REG))])]
6506   "split_di (operands+0, 1, operands+0, operands+3);
6507    split_di (operands+1, 1, operands+1, operands+4);
6508    split_di (operands+2, 1, operands+2, operands+5);")
6509
6510 (define_insn "subdi3_carry_rex64"
6511   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6512           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6513             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6514                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6515    (clobber (reg:CC FLAGS_REG))]
6516   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6517   "sbb{q}\t{%2, %0|%0, %2}"
6518   [(set_attr "type" "alu")
6519    (set_attr "pent_pair" "pu")
6520    (set_attr "mode" "DI")])
6521
6522 (define_insn "*subdi_1_rex64"
6523   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6524         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6525                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6526    (clobber (reg:CC FLAGS_REG))]
6527   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6528   "sub{q}\t{%2, %0|%0, %2}"
6529   [(set_attr "type" "alu")
6530    (set_attr "mode" "DI")])
6531
6532 (define_insn "*subdi_2_rex64"
6533   [(set (reg FLAGS_REG)
6534         (compare
6535           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6537           (const_int 0)))
6538    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6539         (minus:DI (match_dup 1) (match_dup 2)))]
6540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6541    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6542   "sub{q}\t{%2, %0|%0, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "DI")])
6545
6546 (define_insn "*subdi_3_rex63"
6547   [(set (reg FLAGS_REG)
6548         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6549                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6550    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551         (minus:DI (match_dup 1) (match_dup 2)))]
6552   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554   "sub{q}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "DI")])
6557
6558 (define_insn "subqi3_carry"
6559   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6560           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6561             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6562                (match_operand:QI 2 "general_operand" "qi,qm"))))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6565   "sbb{b}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "QI")])
6569
6570 (define_insn "subhi3_carry"
6571   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6572           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6573             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6574                (match_operand:HI 2 "general_operand" "ri,rm"))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6577   "sbb{w}\t{%2, %0|%0, %2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "pent_pair" "pu")
6580    (set_attr "mode" "HI")])
6581
6582 (define_insn "subsi3_carry"
6583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6585             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6586                (match_operand:SI 2 "general_operand" "ri,rm"))))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6589   "sbb{l}\t{%2, %0|%0, %2}"
6590   [(set_attr "type" "alu")
6591    (set_attr "pent_pair" "pu")
6592    (set_attr "mode" "SI")])
6593
6594 (define_insn "subsi3_carry_zext"
6595   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6596           (zero_extend:DI
6597             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6598               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6599                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sbb{l}\t{%2, %k0|%k0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "pent_pair" "pu")
6605    (set_attr "mode" "SI")])
6606
6607 (define_expand "subsi3"
6608   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6609                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6610                              (match_operand:SI 2 "general_operand" "")))
6611               (clobber (reg:CC FLAGS_REG))])]
6612   ""
6613   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6614
6615 (define_insn "*subsi_1"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618                   (match_operand:SI 2 "general_operand" "ri,rm")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sub{l}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "mode" "SI")])
6624
6625 (define_insn "*subsi_1_zext"
6626   [(set (match_operand:DI 0 "register_operand" "=r")
6627         (zero_extend:DI
6628           (minus:SI (match_operand:SI 1 "register_operand" "0")
6629                     (match_operand:SI 2 "general_operand" "rim"))))
6630    (clobber (reg:CC FLAGS_REG))]
6631   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632   "sub{l}\t{%2, %k0|%k0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "SI")])
6635
6636 (define_insn "*subsi_2"
6637   [(set (reg FLAGS_REG)
6638         (compare
6639           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6640                     (match_operand:SI 2 "general_operand" "ri,rm"))
6641           (const_int 0)))
6642    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:SI (match_dup 1) (match_dup 2)))]
6644   "ix86_match_ccmode (insn, CCGOCmode)
6645    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6646   "sub{l}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "SI")])
6649
6650 (define_insn "*subsi_2_zext"
6651   [(set (reg FLAGS_REG)
6652         (compare
6653           (minus:SI (match_operand:SI 1 "register_operand" "0")
6654                     (match_operand:SI 2 "general_operand" "rim"))
6655           (const_int 0)))
6656    (set (match_operand:DI 0 "register_operand" "=r")
6657         (zero_extend:DI
6658           (minus:SI (match_dup 1)
6659                     (match_dup 2))))]
6660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6661    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sub{l}\t{%2, %k0|%k0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "mode" "SI")])
6665
6666 (define_insn "*subsi_3"
6667   [(set (reg FLAGS_REG)
6668         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6669                  (match_operand:SI 2 "general_operand" "ri,rm")))
6670    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671         (minus:SI (match_dup 1) (match_dup 2)))]
6672   "ix86_match_ccmode (insn, CCmode)
6673    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sub{l}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "SI")])
6677
6678 (define_insn "*subsi_3_zext"
6679   [(set (reg FLAGS_REG)
6680         (compare (match_operand:SI 1 "register_operand" "0")
6681                  (match_operand:SI 2 "general_operand" "rim")))
6682    (set (match_operand:DI 0 "register_operand" "=r")
6683         (zero_extend:DI
6684           (minus:SI (match_dup 1)
6685                     (match_dup 2))))]
6686   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6687    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688   "sub{q}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "mode" "DI")])
6691
6692 (define_expand "subhi3"
6693   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6694                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6695                              (match_operand:HI 2 "general_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   "TARGET_HIMODE_MATH"
6698   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6699
6700 (define_insn "*subhi_1"
6701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703                   (match_operand:HI 2 "general_operand" "ri,rm")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6706   "sub{w}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "HI")])
6709
6710 (define_insn "*subhi_2"
6711   [(set (reg FLAGS_REG)
6712         (compare
6713           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6714                     (match_operand:HI 2 "general_operand" "ri,rm"))
6715           (const_int 0)))
6716    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6717         (minus:HI (match_dup 1) (match_dup 2)))]
6718   "ix86_match_ccmode (insn, CCGOCmode)
6719    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6720   "sub{w}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "HI")])
6723
6724 (define_insn "*subhi_3"
6725   [(set (reg FLAGS_REG)
6726         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6727                  (match_operand:HI 2 "general_operand" "ri,rm")))
6728    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6729         (minus:HI (match_dup 1) (match_dup 2)))]
6730   "ix86_match_ccmode (insn, CCmode)
6731    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6732   "sub{w}\t{%2, %0|%0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "HI")])
6735
6736 (define_expand "subqi3"
6737   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6738                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6739                              (match_operand:QI 2 "general_operand" "")))
6740               (clobber (reg:CC FLAGS_REG))])]
6741   "TARGET_QIMODE_MATH"
6742   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6743
6744 (define_insn "*subqi_1"
6745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6746         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6747                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6750   "sub{b}\t{%2, %0|%0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "QI")])
6753
6754 (define_insn "*subqi_1_slp"
6755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6756         (minus:QI (match_dup 0)
6757                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6760    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6761   "sub{b}\t{%1, %0|%0, %1}"
6762   [(set_attr "type" "alu1")
6763    (set_attr "mode" "QI")])
6764
6765 (define_insn "*subqi_2"
6766   [(set (reg FLAGS_REG)
6767         (compare
6768           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6769                     (match_operand:QI 2 "general_operand" "qi,qm"))
6770           (const_int 0)))
6771    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6772         (minus:HI (match_dup 1) (match_dup 2)))]
6773   "ix86_match_ccmode (insn, CCGOCmode)
6774    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6775   "sub{b}\t{%2, %0|%0, %2}"
6776   [(set_attr "type" "alu")
6777    (set_attr "mode" "QI")])
6778
6779 (define_insn "*subqi_3"
6780   [(set (reg FLAGS_REG)
6781         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6782                  (match_operand:QI 2 "general_operand" "qi,qm")))
6783    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6784         (minus:HI (match_dup 1) (match_dup 2)))]
6785   "ix86_match_ccmode (insn, CCmode)
6786    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6787   "sub{b}\t{%2, %0|%0, %2}"
6788   [(set_attr "type" "alu")
6789    (set_attr "mode" "QI")])
6790
6791 ;; The patterns that match these are at the end of this file.
6792
6793 (define_expand "subxf3"
6794   [(set (match_operand:XF 0 "register_operand" "")
6795         (minus:XF (match_operand:XF 1 "register_operand" "")
6796                   (match_operand:XF 2 "register_operand" "")))]
6797   "TARGET_80387"
6798   "")
6799
6800 (define_expand "subdf3"
6801   [(set (match_operand:DF 0 "register_operand" "")
6802         (minus:DF (match_operand:DF 1 "register_operand" "")
6803                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6804   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6805   "")
6806
6807 (define_expand "subsf3"
6808   [(set (match_operand:SF 0 "register_operand" "")
6809         (minus:SF (match_operand:SF 1 "register_operand" "")
6810                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6811   "TARGET_80387 || TARGET_SSE_MATH"
6812   "")
6813 \f
6814 ;; Multiply instructions
6815
6816 (define_expand "muldi3"
6817   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6818                    (mult:DI (match_operand:DI 1 "register_operand" "")
6819                             (match_operand:DI 2 "x86_64_general_operand" "")))
6820               (clobber (reg:CC FLAGS_REG))])]
6821   "TARGET_64BIT"
6822   "")
6823
6824 (define_insn "*muldi3_1_rex64"
6825   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6826         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6827                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_64BIT
6830    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6831   "@
6832    imul{q}\t{%2, %1, %0|%0, %1, %2}
6833    imul{q}\t{%2, %1, %0|%0, %1, %2}
6834    imul{q}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1")
6841                   (const_string "vector")
6842                (and (eq_attr "alternative" "2")
6843                     (match_operand 1 "memory_operand" ""))
6844                   (const_string "vector")]
6845               (const_string "direct")))
6846    (set_attr "mode" "DI")])
6847
6848 (define_expand "mulsi3"
6849   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6850                    (mult:SI (match_operand:SI 1 "register_operand" "")
6851                             (match_operand:SI 2 "general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   ""
6854   "")
6855
6856 (define_insn "*mulsi3_1"
6857   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6858         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6862   "@
6863    imul{l}\t{%2, %1, %0|%0, %1, %2}
6864    imul{l}\t{%2, %1, %0|%0, %1, %2}
6865    imul{l}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "imul")
6867    (set_attr "prefix_0f" "0,0,1")
6868    (set (attr "athlon_decode")
6869         (cond [(eq_attr "cpu" "athlon")
6870                   (const_string "vector")
6871                (eq_attr "alternative" "1")
6872                   (const_string "vector")
6873                (and (eq_attr "alternative" "2")
6874                     (match_operand 1 "memory_operand" ""))
6875                   (const_string "vector")]
6876               (const_string "direct")))
6877    (set_attr "mode" "SI")])
6878
6879 (define_insn "*mulsi3_1_zext"
6880   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881         (zero_extend:DI
6882           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6883                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "TARGET_64BIT
6886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6887   "@
6888    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890    imul{l}\t{%2, %k0|%k0, %2}"
6891   [(set_attr "type" "imul")
6892    (set_attr "prefix_0f" "0,0,1")
6893    (set (attr "athlon_decode")
6894         (cond [(eq_attr "cpu" "athlon")
6895                   (const_string "vector")
6896                (eq_attr "alternative" "1")
6897                   (const_string "vector")
6898                (and (eq_attr "alternative" "2")
6899                     (match_operand 1 "memory_operand" ""))
6900                   (const_string "vector")]
6901               (const_string "direct")))
6902    (set_attr "mode" "SI")])
6903
6904 (define_expand "mulhi3"
6905   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6906                    (mult:HI (match_operand:HI 1 "register_operand" "")
6907                             (match_operand:HI 2 "general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_HIMODE_MATH"
6910   "")
6911
6912 (define_insn "*mulhi3_1"
6913   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6914         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6918   "@
6919    imul{w}\t{%2, %1, %0|%0, %1, %2}
6920    imul{w}\t{%2, %1, %0|%0, %1, %2}
6921    imul{w}\t{%2, %0|%0, %2}"
6922   [(set_attr "type" "imul")
6923    (set_attr "prefix_0f" "0,0,1")
6924    (set (attr "athlon_decode")
6925         (cond [(eq_attr "cpu" "athlon")
6926                   (const_string "vector")
6927                (eq_attr "alternative" "1,2")
6928                   (const_string "vector")]
6929               (const_string "direct")))
6930    (set_attr "mode" "HI")])
6931
6932 (define_expand "mulqi3"
6933   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6934                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6935                             (match_operand:QI 2 "register_operand" "")))
6936               (clobber (reg:CC FLAGS_REG))])]
6937   "TARGET_QIMODE_MATH"
6938   "")
6939
6940 (define_insn "*mulqi3_1"
6941   [(set (match_operand:QI 0 "register_operand" "=a")
6942         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6943                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6944    (clobber (reg:CC FLAGS_REG))]
6945   "TARGET_QIMODE_MATH
6946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6947   "mul{b}\t%2"
6948   [(set_attr "type" "imul")
6949    (set_attr "length_immediate" "0")
6950    (set (attr "athlon_decode")
6951      (if_then_else (eq_attr "cpu" "athlon")
6952         (const_string "vector")
6953         (const_string "direct")))
6954    (set_attr "mode" "QI")])
6955
6956 (define_expand "umulqihi3"
6957   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6958                    (mult:HI (zero_extend:HI
6959                               (match_operand:QI 1 "nonimmediate_operand" ""))
6960                             (zero_extend:HI
6961                               (match_operand:QI 2 "register_operand" ""))))
6962               (clobber (reg:CC FLAGS_REG))])]
6963   "TARGET_QIMODE_MATH"
6964   "")
6965
6966 (define_insn "*umulqihi3_1"
6967   [(set (match_operand:HI 0 "register_operand" "=a")
6968         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6969                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970    (clobber (reg:CC FLAGS_REG))]
6971   "TARGET_QIMODE_MATH
6972    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6973   "mul{b}\t%2"
6974   [(set_attr "type" "imul")
6975    (set_attr "length_immediate" "0")
6976    (set (attr "athlon_decode")
6977      (if_then_else (eq_attr "cpu" "athlon")
6978         (const_string "vector")
6979         (const_string "direct")))
6980    (set_attr "mode" "QI")])
6981
6982 (define_expand "mulqihi3"
6983   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6985                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6986               (clobber (reg:CC FLAGS_REG))])]
6987   "TARGET_QIMODE_MATH"
6988   "")
6989
6990 (define_insn "*mulqihi3_insn"
6991   [(set (match_operand:HI 0 "register_operand" "=a")
6992         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6993                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_QIMODE_MATH
6996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997   "imul{b}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "direct")))
7004    (set_attr "mode" "QI")])
7005
7006 (define_expand "umulditi3"
7007   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7008                    (mult:TI (zero_extend:TI
7009                               (match_operand:DI 1 "nonimmediate_operand" ""))
7010                             (zero_extend:TI
7011                               (match_operand:DI 2 "register_operand" ""))))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   "TARGET_64BIT"
7014   "")
7015
7016 (define_insn "*umulditi3_insn"
7017   [(set (match_operand:TI 0 "register_operand" "=A")
7018         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7019                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "TARGET_64BIT
7022    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7023   "mul{q}\t%2"
7024   [(set_attr "type" "imul")
7025    (set_attr "length_immediate" "0")
7026    (set (attr "athlon_decode")
7027      (if_then_else (eq_attr "cpu" "athlon")
7028         (const_string "vector")
7029         (const_string "double")))
7030    (set_attr "mode" "DI")])
7031
7032 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7033 (define_expand "umulsidi3"
7034   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7035                    (mult:DI (zero_extend:DI
7036                               (match_operand:SI 1 "nonimmediate_operand" ""))
7037                             (zero_extend:DI
7038                               (match_operand:SI 2 "register_operand" ""))))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "!TARGET_64BIT"
7041   "")
7042
7043 (define_insn "*umulsidi3_insn"
7044   [(set (match_operand:DI 0 "register_operand" "=A")
7045         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7046                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "!TARGET_64BIT
7049    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7050   "mul{l}\t%2"
7051   [(set_attr "type" "imul")
7052    (set_attr "length_immediate" "0")
7053    (set (attr "athlon_decode")
7054      (if_then_else (eq_attr "cpu" "athlon")
7055         (const_string "vector")
7056         (const_string "double")))
7057    (set_attr "mode" "SI")])
7058
7059 (define_expand "mulditi3"
7060   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7061                    (mult:TI (sign_extend:TI
7062                               (match_operand:DI 1 "nonimmediate_operand" ""))
7063                             (sign_extend:TI
7064                               (match_operand:DI 2 "register_operand" ""))))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   "TARGET_64BIT"
7067   "")
7068
7069 (define_insn "*mulditi3_insn"
7070   [(set (match_operand:TI 0 "register_operand" "=A")
7071         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7072                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7073    (clobber (reg:CC FLAGS_REG))]
7074   "TARGET_64BIT
7075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7076   "imul{q}\t%2"
7077   [(set_attr "type" "imul")
7078    (set_attr "length_immediate" "0")
7079    (set (attr "athlon_decode")
7080      (if_then_else (eq_attr "cpu" "athlon")
7081         (const_string "vector")
7082         (const_string "double")))
7083    (set_attr "mode" "DI")])
7084
7085 (define_expand "mulsidi3"
7086   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7087                    (mult:DI (sign_extend:DI
7088                               (match_operand:SI 1 "nonimmediate_operand" ""))
7089                             (sign_extend:DI
7090                               (match_operand:SI 2 "register_operand" ""))))
7091               (clobber (reg:CC FLAGS_REG))])]
7092   "!TARGET_64BIT"
7093   "")
7094
7095 (define_insn "*mulsidi3_insn"
7096   [(set (match_operand:DI 0 "register_operand" "=A")
7097         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7098                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7099    (clobber (reg:CC FLAGS_REG))]
7100   "!TARGET_64BIT
7101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7102   "imul{l}\t%2"
7103   [(set_attr "type" "imul")
7104    (set_attr "length_immediate" "0")
7105    (set (attr "athlon_decode")
7106      (if_then_else (eq_attr "cpu" "athlon")
7107         (const_string "vector")
7108         (const_string "double")))
7109    (set_attr "mode" "SI")])
7110
7111 (define_expand "umuldi3_highpart"
7112   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7113                    (truncate:DI
7114                      (lshiftrt:TI
7115                        (mult:TI (zero_extend:TI
7116                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7117                                 (zero_extend:TI
7118                                   (match_operand:DI 2 "register_operand" "")))
7119                        (const_int 64))))
7120               (clobber (match_scratch:DI 3 ""))
7121               (clobber (reg:CC FLAGS_REG))])]
7122   "TARGET_64BIT"
7123   "")
7124
7125 (define_insn "*umuldi3_highpart_rex64"
7126   [(set (match_operand:DI 0 "register_operand" "=d")
7127         (truncate:DI
7128           (lshiftrt:TI
7129             (mult:TI (zero_extend:TI
7130                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7131                      (zero_extend:TI
7132                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7133             (const_int 64))))
7134    (clobber (match_scratch:DI 3 "=1"))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "TARGET_64BIT
7137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7138   "mul{q}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "DI")])
7146
7147 (define_expand "umulsi3_highpart"
7148   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7149                    (truncate:SI
7150                      (lshiftrt:DI
7151                        (mult:DI (zero_extend:DI
7152                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7153                                 (zero_extend:DI
7154                                   (match_operand:SI 2 "register_operand" "")))
7155                        (const_int 32))))
7156               (clobber (match_scratch:SI 3 ""))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   ""
7159   "")
7160
7161 (define_insn "*umulsi3_highpart_insn"
7162   [(set (match_operand:SI 0 "register_operand" "=d")
7163         (truncate:SI
7164           (lshiftrt:DI
7165             (mult:DI (zero_extend:DI
7166                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7167                      (zero_extend:DI
7168                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7169             (const_int 32))))
7170    (clobber (match_scratch:SI 3 "=1"))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7173   "mul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set_attr "length_immediate" "0")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "mode" "SI")])
7181
7182 (define_insn "*umulsi3_highpart_zext"
7183   [(set (match_operand:DI 0 "register_operand" "=d")
7184         (zero_extend:DI (truncate:SI
7185           (lshiftrt:DI
7186             (mult:DI (zero_extend:DI
7187                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7188                      (zero_extend:DI
7189                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7190             (const_int 32)))))
7191    (clobber (match_scratch:SI 3 "=1"))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT
7194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195   "mul{l}\t%2"
7196   [(set_attr "type" "imul")
7197    (set_attr "length_immediate" "0")
7198    (set (attr "athlon_decode")
7199      (if_then_else (eq_attr "cpu" "athlon")
7200         (const_string "vector")
7201         (const_string "double")))
7202    (set_attr "mode" "SI")])
7203
7204 (define_expand "smuldi3_highpart"
7205   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7206                    (truncate:DI
7207                      (lshiftrt:TI
7208                        (mult:TI (sign_extend:TI
7209                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7210                                 (sign_extend:TI
7211                                   (match_operand:DI 2 "register_operand" "")))
7212                        (const_int 64))))
7213               (clobber (match_scratch:DI 3 ""))
7214               (clobber (reg:CC FLAGS_REG))])]
7215   "TARGET_64BIT"
7216   "")
7217
7218 (define_insn "*smuldi3_highpart_rex64"
7219   [(set (match_operand:DI 0 "register_operand" "=d")
7220         (truncate:DI
7221           (lshiftrt:TI
7222             (mult:TI (sign_extend:TI
7223                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7224                      (sign_extend:TI
7225                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7226             (const_int 64))))
7227    (clobber (match_scratch:DI 3 "=1"))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_64BIT
7230    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7231   "imul{q}\t%2"
7232   [(set_attr "type" "imul")
7233    (set (attr "athlon_decode")
7234      (if_then_else (eq_attr "cpu" "athlon")
7235         (const_string "vector")
7236         (const_string "double")))
7237    (set_attr "mode" "DI")])
7238
7239 (define_expand "smulsi3_highpart"
7240   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7241                    (truncate:SI
7242                      (lshiftrt:DI
7243                        (mult:DI (sign_extend:DI
7244                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7245                                 (sign_extend:DI
7246                                   (match_operand:SI 2 "register_operand" "")))
7247                        (const_int 32))))
7248               (clobber (match_scratch:SI 3 ""))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   ""
7251   "")
7252
7253 (define_insn "*smulsi3_highpart_insn"
7254   [(set (match_operand:SI 0 "register_operand" "=d")
7255         (truncate:SI
7256           (lshiftrt:DI
7257             (mult:DI (sign_extend:DI
7258                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7259                      (sign_extend:DI
7260                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7261             (const_int 32))))
7262    (clobber (match_scratch:SI 3 "=1"))
7263    (clobber (reg:CC FLAGS_REG))]
7264   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7265   "imul{l}\t%2"
7266   [(set_attr "type" "imul")
7267    (set (attr "athlon_decode")
7268      (if_then_else (eq_attr "cpu" "athlon")
7269         (const_string "vector")
7270         (const_string "double")))
7271    (set_attr "mode" "SI")])
7272
7273 (define_insn "*smulsi3_highpart_zext"
7274   [(set (match_operand:DI 0 "register_operand" "=d")
7275         (zero_extend:DI (truncate:SI
7276           (lshiftrt:DI
7277             (mult:DI (sign_extend:DI
7278                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7279                      (sign_extend:DI
7280                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7281             (const_int 32)))))
7282    (clobber (match_scratch:SI 3 "=1"))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "TARGET_64BIT
7285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7286   "imul{l}\t%2"
7287   [(set_attr "type" "imul")
7288    (set (attr "athlon_decode")
7289      (if_then_else (eq_attr "cpu" "athlon")
7290         (const_string "vector")
7291         (const_string "double")))
7292    (set_attr "mode" "SI")])
7293
7294 ;; The patterns that match these are at the end of this file.
7295
7296 (define_expand "mulxf3"
7297   [(set (match_operand:XF 0 "register_operand" "")
7298         (mult:XF (match_operand:XF 1 "register_operand" "")
7299                  (match_operand:XF 2 "register_operand" "")))]
7300   "TARGET_80387"
7301   "")
7302
7303 (define_expand "muldf3"
7304   [(set (match_operand:DF 0 "register_operand" "")
7305         (mult:DF (match_operand:DF 1 "register_operand" "")
7306                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7307   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7308   "")
7309
7310 (define_expand "mulsf3"
7311   [(set (match_operand:SF 0 "register_operand" "")
7312         (mult:SF (match_operand:SF 1 "register_operand" "")
7313                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7314   "TARGET_80387 || TARGET_SSE_MATH"
7315   "")
7316 \f
7317 ;; Divide instructions
7318
7319 (define_insn "divqi3"
7320   [(set (match_operand:QI 0 "register_operand" "=a")
7321         (div:QI (match_operand:HI 1 "register_operand" "0")
7322                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_QIMODE_MATH"
7325   "idiv{b}\t%2"
7326   [(set_attr "type" "idiv")
7327    (set_attr "mode" "QI")])
7328
7329 (define_insn "udivqi3"
7330   [(set (match_operand:QI 0 "register_operand" "=a")
7331         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7332                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "TARGET_QIMODE_MATH"
7335   "div{b}\t%2"
7336   [(set_attr "type" "idiv")
7337    (set_attr "mode" "QI")])
7338
7339 ;; The patterns that match these are at the end of this file.
7340
7341 (define_expand "divxf3"
7342   [(set (match_operand:XF 0 "register_operand" "")
7343         (div:XF (match_operand:XF 1 "register_operand" "")
7344                 (match_operand:XF 2 "register_operand" "")))]
7345   "TARGET_80387"
7346   "")
7347
7348 (define_expand "divdf3"
7349   [(set (match_operand:DF 0 "register_operand" "")
7350         (div:DF (match_operand:DF 1 "register_operand" "")
7351                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7352    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7353    "")
7354  
7355 (define_expand "divsf3"
7356   [(set (match_operand:SF 0 "register_operand" "")
7357         (div:SF (match_operand:SF 1 "register_operand" "")
7358                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7359   "TARGET_80387 || TARGET_SSE_MATH"
7360   "")
7361 \f
7362 ;; Remainder instructions.
7363
7364 (define_expand "divmoddi4"
7365   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7366                    (div:DI (match_operand:DI 1 "register_operand" "")
7367                            (match_operand:DI 2 "nonimmediate_operand" "")))
7368               (set (match_operand:DI 3 "register_operand" "")
7369                    (mod:DI (match_dup 1) (match_dup 2)))
7370               (clobber (reg:CC FLAGS_REG))])]
7371   "TARGET_64BIT"
7372   "")
7373
7374 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7375 ;; Penalize eax case slightly because it results in worse scheduling
7376 ;; of code.
7377 (define_insn "*divmoddi4_nocltd_rex64"
7378   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7379         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7380                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7381    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7382         (mod:DI (match_dup 2) (match_dup 3)))
7383    (clobber (reg:CC FLAGS_REG))]
7384   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7385   "#"
7386   [(set_attr "type" "multi")])
7387
7388 (define_insn "*divmoddi4_cltd_rex64"
7389   [(set (match_operand:DI 0 "register_operand" "=a")
7390         (div:DI (match_operand:DI 2 "register_operand" "a")
7391                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7392    (set (match_operand:DI 1 "register_operand" "=&d")
7393         (mod:DI (match_dup 2) (match_dup 3)))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7396   "#"
7397   [(set_attr "type" "multi")])
7398
7399 (define_insn "*divmoddi_noext_rex64"
7400   [(set (match_operand:DI 0 "register_operand" "=a")
7401         (div:DI (match_operand:DI 1 "register_operand" "0")
7402                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7403    (set (match_operand:DI 3 "register_operand" "=d")
7404         (mod:DI (match_dup 1) (match_dup 2)))
7405    (use (match_operand:DI 4 "register_operand" "3"))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "TARGET_64BIT"
7408   "idiv{q}\t%2"
7409   [(set_attr "type" "idiv")
7410    (set_attr "mode" "DI")])
7411
7412 (define_split
7413   [(set (match_operand:DI 0 "register_operand" "")
7414         (div:DI (match_operand:DI 1 "register_operand" "")
7415                 (match_operand:DI 2 "nonimmediate_operand" "")))
7416    (set (match_operand:DI 3 "register_operand" "")
7417         (mod:DI (match_dup 1) (match_dup 2)))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_64BIT && reload_completed"
7420   [(parallel [(set (match_dup 3)
7421                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7422               (clobber (reg:CC FLAGS_REG))])
7423    (parallel [(set (match_dup 0)
7424                    (div:DI (reg:DI 0) (match_dup 2)))
7425               (set (match_dup 3)
7426                    (mod:DI (reg:DI 0) (match_dup 2)))
7427               (use (match_dup 3))
7428               (clobber (reg:CC FLAGS_REG))])]
7429 {
7430   /* Avoid use of cltd in favor of a mov+shift.  */
7431   if (!TARGET_USE_CLTD && !optimize_size)
7432     {
7433       if (true_regnum (operands[1]))
7434         emit_move_insn (operands[0], operands[1]);
7435       else
7436         emit_move_insn (operands[3], operands[1]);
7437       operands[4] = operands[3];
7438     }
7439   else
7440     {
7441       gcc_assert (!true_regnum (operands[1]));
7442       operands[4] = operands[1];
7443     }
7444 })
7445
7446
7447 (define_expand "divmodsi4"
7448   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7449                    (div:SI (match_operand:SI 1 "register_operand" "")
7450                            (match_operand:SI 2 "nonimmediate_operand" "")))
7451               (set (match_operand:SI 3 "register_operand" "")
7452                    (mod:SI (match_dup 1) (match_dup 2)))
7453               (clobber (reg:CC FLAGS_REG))])]
7454   ""
7455   "")
7456
7457 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7458 ;; Penalize eax case slightly because it results in worse scheduling
7459 ;; of code.
7460 (define_insn "*divmodsi4_nocltd"
7461   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7462         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7463                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7464    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7465         (mod:SI (match_dup 2) (match_dup 3)))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "!optimize_size && !TARGET_USE_CLTD"
7468   "#"
7469   [(set_attr "type" "multi")])
7470
7471 (define_insn "*divmodsi4_cltd"
7472   [(set (match_operand:SI 0 "register_operand" "=a")
7473         (div:SI (match_operand:SI 2 "register_operand" "a")
7474                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7475    (set (match_operand:SI 1 "register_operand" "=&d")
7476         (mod:SI (match_dup 2) (match_dup 3)))
7477    (clobber (reg:CC FLAGS_REG))]
7478   "optimize_size || TARGET_USE_CLTD"
7479   "#"
7480   [(set_attr "type" "multi")])
7481
7482 (define_insn "*divmodsi_noext"
7483   [(set (match_operand:SI 0 "register_operand" "=a")
7484         (div:SI (match_operand:SI 1 "register_operand" "0")
7485                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486    (set (match_operand:SI 3 "register_operand" "=d")
7487         (mod:SI (match_dup 1) (match_dup 2)))
7488    (use (match_operand:SI 4 "register_operand" "3"))
7489    (clobber (reg:CC FLAGS_REG))]
7490   ""
7491   "idiv{l}\t%2"
7492   [(set_attr "type" "idiv")
7493    (set_attr "mode" "SI")])
7494
7495 (define_split
7496   [(set (match_operand:SI 0 "register_operand" "")
7497         (div:SI (match_operand:SI 1 "register_operand" "")
7498                 (match_operand:SI 2 "nonimmediate_operand" "")))
7499    (set (match_operand:SI 3 "register_operand" "")
7500         (mod:SI (match_dup 1) (match_dup 2)))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "reload_completed"
7503   [(parallel [(set (match_dup 3)
7504                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7505               (clobber (reg:CC FLAGS_REG))])
7506    (parallel [(set (match_dup 0)
7507                    (div:SI (reg:SI 0) (match_dup 2)))
7508               (set (match_dup 3)
7509                    (mod:SI (reg:SI 0) (match_dup 2)))
7510               (use (match_dup 3))
7511               (clobber (reg:CC FLAGS_REG))])]
7512 {
7513   /* Avoid use of cltd in favor of a mov+shift.  */
7514   if (!TARGET_USE_CLTD && !optimize_size)
7515     {
7516       if (true_regnum (operands[1]))
7517         emit_move_insn (operands[0], operands[1]);
7518       else
7519         emit_move_insn (operands[3], operands[1]);
7520       operands[4] = operands[3];
7521     }
7522   else
7523     {
7524       gcc_assert (!true_regnum (operands[1]));
7525       operands[4] = operands[1];
7526     }
7527 })
7528 ;; %%% Split me.
7529 (define_insn "divmodhi4"
7530   [(set (match_operand:HI 0 "register_operand" "=a")
7531         (div:HI (match_operand:HI 1 "register_operand" "0")
7532                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7533    (set (match_operand:HI 3 "register_operand" "=&d")
7534         (mod:HI (match_dup 1) (match_dup 2)))
7535    (clobber (reg:CC FLAGS_REG))]
7536   "TARGET_HIMODE_MATH"
7537   "cwtd\;idiv{w}\t%2"
7538   [(set_attr "type" "multi")
7539    (set_attr "length_immediate" "0")
7540    (set_attr "mode" "SI")])
7541
7542 (define_insn "udivmoddi4"
7543   [(set (match_operand:DI 0 "register_operand" "=a")
7544         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7545                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546    (set (match_operand:DI 3 "register_operand" "=&d")
7547         (umod:DI (match_dup 1) (match_dup 2)))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT"
7550   "xor{q}\t%3, %3\;div{q}\t%2"
7551   [(set_attr "type" "multi")
7552    (set_attr "length_immediate" "0")
7553    (set_attr "mode" "DI")])
7554
7555 (define_insn "*udivmoddi4_noext"
7556   [(set (match_operand:DI 0 "register_operand" "=a")
7557         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7558                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7559    (set (match_operand:DI 3 "register_operand" "=d")
7560         (umod:DI (match_dup 1) (match_dup 2)))
7561    (use (match_dup 3))
7562    (clobber (reg:CC FLAGS_REG))]
7563   "TARGET_64BIT"
7564   "div{q}\t%2"
7565   [(set_attr "type" "idiv")
7566    (set_attr "mode" "DI")])
7567
7568 (define_split
7569   [(set (match_operand:DI 0 "register_operand" "")
7570         (udiv:DI (match_operand:DI 1 "register_operand" "")
7571                  (match_operand:DI 2 "nonimmediate_operand" "")))
7572    (set (match_operand:DI 3 "register_operand" "")
7573         (umod:DI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "TARGET_64BIT && reload_completed"
7576   [(set (match_dup 3) (const_int 0))
7577    (parallel [(set (match_dup 0)
7578                    (udiv:DI (match_dup 1) (match_dup 2)))
7579               (set (match_dup 3)
7580                    (umod:DI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 3))
7582               (clobber (reg:CC FLAGS_REG))])]
7583   "")
7584
7585 (define_insn "udivmodsi4"
7586   [(set (match_operand:SI 0 "register_operand" "=a")
7587         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7588                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7589    (set (match_operand:SI 3 "register_operand" "=&d")
7590         (umod:SI (match_dup 1) (match_dup 2)))
7591    (clobber (reg:CC FLAGS_REG))]
7592   ""
7593   "xor{l}\t%3, %3\;div{l}\t%2"
7594   [(set_attr "type" "multi")
7595    (set_attr "length_immediate" "0")
7596    (set_attr "mode" "SI")])
7597
7598 (define_insn "*udivmodsi4_noext"
7599   [(set (match_operand:SI 0 "register_operand" "=a")
7600         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7601                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7602    (set (match_operand:SI 3 "register_operand" "=d")
7603         (umod:SI (match_dup 1) (match_dup 2)))
7604    (use (match_dup 3))
7605    (clobber (reg:CC FLAGS_REG))]
7606   ""
7607   "div{l}\t%2"
7608   [(set_attr "type" "idiv")
7609    (set_attr "mode" "SI")])
7610
7611 (define_split
7612   [(set (match_operand:SI 0 "register_operand" "")
7613         (udiv:SI (match_operand:SI 1 "register_operand" "")
7614                  (match_operand:SI 2 "nonimmediate_operand" "")))
7615    (set (match_operand:SI 3 "register_operand" "")
7616         (umod:SI (match_dup 1) (match_dup 2)))
7617    (clobber (reg:CC FLAGS_REG))]
7618   "reload_completed"
7619   [(set (match_dup 3) (const_int 0))
7620    (parallel [(set (match_dup 0)
7621                    (udiv:SI (match_dup 1) (match_dup 2)))
7622               (set (match_dup 3)
7623                    (umod:SI (match_dup 1) (match_dup 2)))
7624               (use (match_dup 3))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   "")
7627
7628 (define_expand "udivmodhi4"
7629   [(set (match_dup 4) (const_int 0))
7630    (parallel [(set (match_operand:HI 0 "register_operand" "")
7631                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7632                             (match_operand:HI 2 "nonimmediate_operand" "")))
7633               (set (match_operand:HI 3 "register_operand" "")
7634                    (umod:HI (match_dup 1) (match_dup 2)))
7635               (use (match_dup 4))
7636               (clobber (reg:CC FLAGS_REG))])]
7637   "TARGET_HIMODE_MATH"
7638   "operands[4] = gen_reg_rtx (HImode);")
7639
7640 (define_insn "*udivmodhi_noext"
7641   [(set (match_operand:HI 0 "register_operand" "=a")
7642         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7643                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:HI 3 "register_operand" "=d")
7645         (umod:HI (match_dup 1) (match_dup 2)))
7646    (use (match_operand:HI 4 "register_operand" "3"))
7647    (clobber (reg:CC FLAGS_REG))]
7648   ""
7649   "div{w}\t%2"
7650   [(set_attr "type" "idiv")
7651    (set_attr "mode" "HI")])
7652
7653 ;; We cannot use div/idiv for double division, because it causes
7654 ;; "division by zero" on the overflow and that's not what we expect
7655 ;; from truncate.  Because true (non truncating) double division is
7656 ;; never generated, we can't create this insn anyway.
7657 ;
7658 ;(define_insn ""
7659 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7660 ;       (truncate:SI
7661 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7662 ;                  (zero_extend:DI
7663 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7664 ;   (set (match_operand:SI 3 "register_operand" "=d")
7665 ;       (truncate:SI
7666 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7667 ;   (clobber (reg:CC FLAGS_REG))]
7668 ;  ""
7669 ;  "div{l}\t{%2, %0|%0, %2}"
7670 ;  [(set_attr "type" "idiv")])
7671 \f
7672 ;;- Logical AND instructions
7673
7674 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7675 ;; Note that this excludes ah.
7676
7677 (define_insn "*testdi_1_rex64"
7678   [(set (reg FLAGS_REG)
7679         (compare
7680           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7681                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7682           (const_int 0)))]
7683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7685   "@
7686    test{l}\t{%k1, %k0|%k0, %k1}
7687    test{l}\t{%k1, %k0|%k0, %k1}
7688    test{q}\t{%1, %0|%0, %1}
7689    test{q}\t{%1, %0|%0, %1}
7690    test{q}\t{%1, %0|%0, %1}"
7691   [(set_attr "type" "test")
7692    (set_attr "modrm" "0,1,0,1,1")
7693    (set_attr "mode" "SI,SI,DI,DI,DI")
7694    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7695
7696 (define_insn "testsi_1"
7697   [(set (reg FLAGS_REG)
7698         (compare
7699           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7700                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7701           (const_int 0)))]
7702   "ix86_match_ccmode (insn, CCNOmode)
7703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7704   "test{l}\t{%1, %0|%0, %1}"
7705   [(set_attr "type" "test")
7706    (set_attr "modrm" "0,1,1")
7707    (set_attr "mode" "SI")
7708    (set_attr "pent_pair" "uv,np,uv")])
7709
7710 (define_expand "testsi_ccno_1"
7711   [(set (reg:CCNO FLAGS_REG)
7712         (compare:CCNO
7713           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7714                   (match_operand:SI 1 "nonmemory_operand" ""))
7715           (const_int 0)))]
7716   ""
7717   "")
7718
7719 (define_insn "*testhi_1"
7720   [(set (reg FLAGS_REG)
7721         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7722                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7723                  (const_int 0)))]
7724   "ix86_match_ccmode (insn, CCNOmode)
7725    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7726   "test{w}\t{%1, %0|%0, %1}"
7727   [(set_attr "type" "test")
7728    (set_attr "modrm" "0,1,1")
7729    (set_attr "mode" "HI")
7730    (set_attr "pent_pair" "uv,np,uv")])
7731
7732 (define_expand "testqi_ccz_1"
7733   [(set (reg:CCZ FLAGS_REG)
7734         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7735                              (match_operand:QI 1 "nonmemory_operand" ""))
7736                  (const_int 0)))]
7737   ""
7738   "")
7739
7740 (define_insn "*testqi_1_maybe_si"
7741   [(set (reg FLAGS_REG)
7742         (compare
7743           (and:QI
7744             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7745             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7746           (const_int 0)))]
7747    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7748     && ix86_match_ccmode (insn,
7749                          GET_CODE (operands[1]) == CONST_INT
7750                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7751 {
7752   if (which_alternative == 3)
7753     {
7754       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7755         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7756       return "test{l}\t{%1, %k0|%k0, %1}";
7757     }
7758   return "test{b}\t{%1, %0|%0, %1}";
7759 }
7760   [(set_attr "type" "test")
7761    (set_attr "modrm" "0,1,1,1")
7762    (set_attr "mode" "QI,QI,QI,SI")
7763    (set_attr "pent_pair" "uv,np,uv,np")])
7764
7765 (define_insn "*testqi_1"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:QI
7769             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7770             (match_operand:QI 1 "general_operand" "n,n,qn"))
7771           (const_int 0)))]
7772   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7773    && ix86_match_ccmode (insn, CCNOmode)"
7774   "test{b}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "QI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7779
7780 (define_expand "testqi_ext_ccno_0"
7781   [(set (reg:CCNO FLAGS_REG)
7782         (compare:CCNO
7783           (and:SI
7784             (zero_extract:SI
7785               (match_operand 0 "ext_register_operand" "")
7786               (const_int 8)
7787               (const_int 8))
7788             (match_operand 1 "const_int_operand" ""))
7789           (const_int 0)))]
7790   ""
7791   "")
7792
7793 (define_insn "*testqi_ext_0"
7794   [(set (reg FLAGS_REG)
7795         (compare
7796           (and:SI
7797             (zero_extract:SI
7798               (match_operand 0 "ext_register_operand" "Q")
7799               (const_int 8)
7800               (const_int 8))
7801             (match_operand 1 "const_int_operand" "n"))
7802           (const_int 0)))]
7803   "ix86_match_ccmode (insn, CCNOmode)"
7804   "test{b}\t{%1, %h0|%h0, %1}"
7805   [(set_attr "type" "test")
7806    (set_attr "mode" "QI")
7807    (set_attr "length_immediate" "1")
7808    (set_attr "pent_pair" "np")])
7809
7810 (define_insn "*testqi_ext_1"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (and:SI
7814             (zero_extract:SI
7815               (match_operand 0 "ext_register_operand" "Q")
7816               (const_int 8)
7817               (const_int 8))
7818             (zero_extend:SI
7819               (match_operand:QI 1 "general_operand" "Qm")))
7820           (const_int 0)))]
7821   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823   "test{b}\t{%1, %h0|%h0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "mode" "QI")])
7826
7827 (define_insn "*testqi_ext_1_rex64"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:SI
7831             (zero_extract:SI
7832               (match_operand 0 "ext_register_operand" "Q")
7833               (const_int 8)
7834               (const_int 8))
7835             (zero_extend:SI
7836               (match_operand:QI 1 "register_operand" "Q")))
7837           (const_int 0)))]
7838   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7839   "test{b}\t{%1, %h0|%h0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "mode" "QI")])
7842
7843 (define_insn "*testqi_ext_2"
7844   [(set (reg FLAGS_REG)
7845         (compare
7846           (and:SI
7847             (zero_extract:SI
7848               (match_operand 0 "ext_register_operand" "Q")
7849               (const_int 8)
7850               (const_int 8))
7851             (zero_extract:SI
7852               (match_operand 1 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8)))
7855           (const_int 0)))]
7856   "ix86_match_ccmode (insn, CCNOmode)"
7857   "test{b}\t{%h1, %h0|%h0, %h1}"
7858   [(set_attr "type" "test")
7859    (set_attr "mode" "QI")])
7860
7861 ;; Combine likes to form bit extractions for some tests.  Humor it.
7862 (define_insn "*testqi_ext_3"
7863   [(set (reg FLAGS_REG)
7864         (compare (zero_extract:SI
7865                    (match_operand 0 "nonimmediate_operand" "rm")
7866                    (match_operand:SI 1 "const_int_operand" "")
7867                    (match_operand:SI 2 "const_int_operand" ""))
7868                  (const_int 0)))]
7869   "ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_MODE (operands[0]) == SImode
7871        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7872        || GET_MODE (operands[0]) == HImode
7873        || GET_MODE (operands[0]) == QImode)"
7874   "#")
7875
7876 (define_insn "*testqi_ext_3_rex64"
7877   [(set (reg FLAGS_REG)
7878         (compare (zero_extract:DI
7879                    (match_operand 0 "nonimmediate_operand" "rm")
7880                    (match_operand:DI 1 "const_int_operand" "")
7881                    (match_operand:DI 2 "const_int_operand" ""))
7882                  (const_int 0)))]
7883   "TARGET_64BIT
7884    && ix86_match_ccmode (insn, CCNOmode)
7885    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7886    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7887    /* Ensure that resulting mask is zero or sign extended operand.  */
7888    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7889        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7890            && INTVAL (operands[1]) > 32))
7891    && (GET_MODE (operands[0]) == SImode
7892        || GET_MODE (operands[0]) == DImode
7893        || GET_MODE (operands[0]) == HImode
7894        || GET_MODE (operands[0]) == QImode)"
7895   "#")
7896
7897 (define_split
7898   [(set (match_operand 0 "flags_reg_operand" "")
7899         (match_operator 1 "compare_operator"
7900           [(zero_extract
7901              (match_operand 2 "nonimmediate_operand" "")
7902              (match_operand 3 "const_int_operand" "")
7903              (match_operand 4 "const_int_operand" ""))
7904            (const_int 0)]))]
7905   "ix86_match_ccmode (insn, CCNOmode)"
7906   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7907 {
7908   rtx val = operands[2];
7909   HOST_WIDE_INT len = INTVAL (operands[3]);
7910   HOST_WIDE_INT pos = INTVAL (operands[4]);
7911   HOST_WIDE_INT mask;
7912   enum machine_mode mode, submode;
7913
7914   mode = GET_MODE (val);
7915   if (GET_CODE (val) == MEM)
7916     {
7917       /* ??? Combine likes to put non-volatile mem extractions in QImode
7918          no matter the size of the test.  So find a mode that works.  */
7919       if (! MEM_VOLATILE_P (val))
7920         {
7921           mode = smallest_mode_for_size (pos + len, MODE_INT);
7922           val = adjust_address (val, mode, 0);
7923         }
7924     }
7925   else if (GET_CODE (val) == SUBREG
7926            && (submode = GET_MODE (SUBREG_REG (val)),
7927                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7928            && pos + len <= GET_MODE_BITSIZE (submode))
7929     {
7930       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7931       mode = submode;
7932       val = SUBREG_REG (val);
7933     }
7934   else if (mode == HImode && pos + len <= 8)
7935     {
7936       /* Small HImode tests can be converted to QImode.  */
7937       mode = QImode;
7938       val = gen_lowpart (QImode, val);
7939     }
7940
7941   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7942   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7943
7944   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7945 })
7946
7947 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7948 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7949 ;; this is relatively important trick.
7950 ;; Do the conversion only post-reload to avoid limiting of the register class
7951 ;; to QI regs.
7952 (define_split
7953   [(set (match_operand 0 "flags_reg_operand" "")
7954         (match_operator 1 "compare_operator"
7955           [(and (match_operand 2 "register_operand" "")
7956                 (match_operand 3 "const_int_operand" ""))
7957            (const_int 0)]))]
7958    "reload_completed
7959     && QI_REG_P (operands[2])
7960     && GET_MODE (operands[2]) != QImode
7961     && ((ix86_match_ccmode (insn, CCZmode)
7962          && !(INTVAL (operands[3]) & ~(255 << 8)))
7963         || (ix86_match_ccmode (insn, CCNOmode)
7964             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7965   [(set (match_dup 0)
7966         (match_op_dup 1
7967           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7968                    (match_dup 3))
7969            (const_int 0)]))]
7970   "operands[2] = gen_lowpart (SImode, operands[2]);
7971    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7972
7973 (define_split
7974   [(set (match_operand 0 "flags_reg_operand" "")
7975         (match_operator 1 "compare_operator"
7976           [(and (match_operand 2 "nonimmediate_operand" "")
7977                 (match_operand 3 "const_int_operand" ""))
7978            (const_int 0)]))]
7979    "reload_completed
7980     && GET_MODE (operands[2]) != QImode
7981     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7982     && ((ix86_match_ccmode (insn, CCZmode)
7983          && !(INTVAL (operands[3]) & ~255))
7984         || (ix86_match_ccmode (insn, CCNOmode)
7985             && !(INTVAL (operands[3]) & ~127)))"
7986   [(set (match_dup 0)
7987         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7988                          (const_int 0)]))]
7989   "operands[2] = gen_lowpart (QImode, operands[2]);
7990    operands[3] = gen_lowpart (QImode, operands[3]);")
7991
7992
7993 ;; %%% This used to optimize known byte-wide and operations to memory,
7994 ;; and sometimes to QImode registers.  If this is considered useful,
7995 ;; it should be done with splitters.
7996
7997 (define_expand "anddi3"
7998   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7999         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8000                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "TARGET_64BIT"
8003   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8004
8005 (define_insn "*anddi_1_rex64"
8006   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8007         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8008                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8009    (clobber (reg:CC FLAGS_REG))]
8010   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8011 {
8012   switch (get_attr_type (insn))
8013     {
8014     case TYPE_IMOVX:
8015       {
8016         enum machine_mode mode;
8017
8018         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8019         if (INTVAL (operands[2]) == 0xff)
8020           mode = QImode;
8021         else
8022           {
8023             gcc_assert (INTVAL (operands[2]) == 0xffff);
8024             mode = HImode;
8025           }
8026         
8027         operands[1] = gen_lowpart (mode, operands[1]);
8028         if (mode == QImode)
8029           return "movz{bq|x}\t{%1,%0|%0, %1}";
8030         else
8031           return "movz{wq|x}\t{%1,%0|%0, %1}";
8032       }
8033
8034     default:
8035       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8036       if (get_attr_mode (insn) == MODE_SI)
8037         return "and{l}\t{%k2, %k0|%k0, %k2}";
8038       else
8039         return "and{q}\t{%2, %0|%0, %2}";
8040     }
8041 }
8042   [(set_attr "type" "alu,alu,alu,imovx")
8043    (set_attr "length_immediate" "*,*,*,0")
8044    (set_attr "mode" "SI,DI,DI,DI")])
8045
8046 (define_insn "*anddi_2"
8047   [(set (reg FLAGS_REG)
8048         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8049                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8050                  (const_int 0)))
8051    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8052         (and:DI (match_dup 1) (match_dup 2)))]
8053   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8054    && ix86_binary_operator_ok (AND, DImode, operands)"
8055   "@
8056    and{l}\t{%k2, %k0|%k0, %k2}
8057    and{q}\t{%2, %0|%0, %2}
8058    and{q}\t{%2, %0|%0, %2}"
8059   [(set_attr "type" "alu")
8060    (set_attr "mode" "SI,DI,DI")])
8061
8062 (define_expand "andsi3"
8063   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8064         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8065                 (match_operand:SI 2 "general_operand" "")))
8066    (clobber (reg:CC FLAGS_REG))]
8067   ""
8068   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8069
8070 (define_insn "*andsi_1"
8071   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8072         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8073                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8074    (clobber (reg:CC FLAGS_REG))]
8075   "ix86_binary_operator_ok (AND, SImode, operands)"
8076 {
8077   switch (get_attr_type (insn))
8078     {
8079     case TYPE_IMOVX:
8080       {
8081         enum machine_mode mode;
8082
8083         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8084         if (INTVAL (operands[2]) == 0xff)
8085           mode = QImode;
8086         else
8087           {
8088             gcc_assert (INTVAL (operands[2]) == 0xffff);
8089             mode = HImode;
8090           }
8091         
8092         operands[1] = gen_lowpart (mode, operands[1]);
8093         if (mode == QImode)
8094           return "movz{bl|x}\t{%1,%0|%0, %1}";
8095         else
8096           return "movz{wl|x}\t{%1,%0|%0, %1}";
8097       }
8098
8099     default:
8100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8101       return "and{l}\t{%2, %0|%0, %2}";
8102     }
8103 }
8104   [(set_attr "type" "alu,alu,imovx")
8105    (set_attr "length_immediate" "*,*,0")
8106    (set_attr "mode" "SI")])
8107
8108 (define_split
8109   [(set (match_operand 0 "register_operand" "")
8110         (and (match_dup 0)
8111              (const_int -65536)))
8112    (clobber (reg:CC FLAGS_REG))]
8113   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8114   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8115   "operands[1] = gen_lowpart (HImode, operands[0]);")
8116
8117 (define_split
8118   [(set (match_operand 0 "ext_register_operand" "")
8119         (and (match_dup 0)
8120              (const_int -256)))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8123   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8124   "operands[1] = gen_lowpart (QImode, operands[0]);")
8125
8126 (define_split
8127   [(set (match_operand 0 "ext_register_operand" "")
8128         (and (match_dup 0)
8129              (const_int -65281)))
8130    (clobber (reg:CC FLAGS_REG))]
8131   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8132   [(parallel [(set (zero_extract:SI (match_dup 0)
8133                                     (const_int 8)
8134                                     (const_int 8))
8135                    (xor:SI 
8136                      (zero_extract:SI (match_dup 0)
8137                                       (const_int 8)
8138                                       (const_int 8))
8139                      (zero_extract:SI (match_dup 0)
8140                                       (const_int 8)
8141                                       (const_int 8))))
8142               (clobber (reg:CC FLAGS_REG))])]
8143   "operands[0] = gen_lowpart (SImode, operands[0]);")
8144
8145 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8146 (define_insn "*andsi_1_zext"
8147   [(set (match_operand:DI 0 "register_operand" "=r")
8148         (zero_extend:DI
8149           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8150                   (match_operand:SI 2 "general_operand" "rim"))))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8153   "and{l}\t{%2, %k0|%k0, %2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "SI")])
8156
8157 (define_insn "*andsi_2"
8158   [(set (reg FLAGS_REG)
8159         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8160                          (match_operand:SI 2 "general_operand" "rim,ri"))
8161                  (const_int 0)))
8162    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8163         (and:SI (match_dup 1) (match_dup 2)))]
8164   "ix86_match_ccmode (insn, CCNOmode)
8165    && ix86_binary_operator_ok (AND, SImode, operands)"
8166   "and{l}\t{%2, %0|%0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8169
8170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171 (define_insn "*andsi_2_zext"
8172   [(set (reg FLAGS_REG)
8173         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8174                          (match_operand:SI 2 "general_operand" "rim"))
8175                  (const_int 0)))
8176    (set (match_operand:DI 0 "register_operand" "=r")
8177         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179    && ix86_binary_operator_ok (AND, SImode, operands)"
8180   "and{l}\t{%2, %k0|%k0, %2}"
8181   [(set_attr "type" "alu")
8182    (set_attr "mode" "SI")])
8183
8184 (define_expand "andhi3"
8185   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8186         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8187                 (match_operand:HI 2 "general_operand" "")))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "TARGET_HIMODE_MATH"
8190   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8191
8192 (define_insn "*andhi_1"
8193   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8194         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8195                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8196    (clobber (reg:CC FLAGS_REG))]
8197   "ix86_binary_operator_ok (AND, HImode, operands)"
8198 {
8199   switch (get_attr_type (insn))
8200     {
8201     case TYPE_IMOVX:
8202       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8203       gcc_assert (INTVAL (operands[2]) == 0xff);
8204       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8205
8206     default:
8207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8208
8209       return "and{w}\t{%2, %0|%0, %2}";
8210     }
8211 }
8212   [(set_attr "type" "alu,alu,imovx")
8213    (set_attr "length_immediate" "*,*,0")
8214    (set_attr "mode" "HI,HI,SI")])
8215
8216 (define_insn "*andhi_2"
8217   [(set (reg FLAGS_REG)
8218         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8219                          (match_operand:HI 2 "general_operand" "rim,ri"))
8220                  (const_int 0)))
8221    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8222         (and:HI (match_dup 1) (match_dup 2)))]
8223   "ix86_match_ccmode (insn, CCNOmode)
8224    && ix86_binary_operator_ok (AND, HImode, operands)"
8225   "and{w}\t{%2, %0|%0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "HI")])
8228
8229 (define_expand "andqi3"
8230   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8231         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8232                 (match_operand:QI 2 "general_operand" "")))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "TARGET_QIMODE_MATH"
8235   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8236
8237 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8238 (define_insn "*andqi_1"
8239   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8240         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8241                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "ix86_binary_operator_ok (AND, QImode, operands)"
8244   "@
8245    and{b}\t{%2, %0|%0, %2}
8246    and{b}\t{%2, %0|%0, %2}
8247    and{l}\t{%k2, %k0|%k0, %k2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "QI,QI,SI")])
8250
8251 (define_insn "*andqi_1_slp"
8252   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8253         (and:QI (match_dup 0)
8254                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8255    (clobber (reg:CC FLAGS_REG))]
8256   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8257    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8258   "and{b}\t{%1, %0|%0, %1}"
8259   [(set_attr "type" "alu1")
8260    (set_attr "mode" "QI")])
8261
8262 (define_insn "*andqi_2_maybe_si"
8263   [(set (reg FLAGS_REG)
8264         (compare (and:QI
8265                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8267                  (const_int 0)))
8268    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8269         (and:QI (match_dup 1) (match_dup 2)))]
8270   "ix86_binary_operator_ok (AND, QImode, operands)
8271    && ix86_match_ccmode (insn,
8272                          GET_CODE (operands[2]) == CONST_INT
8273                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8274 {
8275   if (which_alternative == 2)
8276     {
8277       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8278         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8279       return "and{l}\t{%2, %k0|%k0, %2}";
8280     }
8281   return "and{b}\t{%2, %0|%0, %2}";
8282 }
8283   [(set_attr "type" "alu")
8284    (set_attr "mode" "QI,QI,SI")])
8285
8286 (define_insn "*andqi_2"
8287   [(set (reg FLAGS_REG)
8288         (compare (and:QI
8289                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8290                    (match_operand:QI 2 "general_operand" "qim,qi"))
8291                  (const_int 0)))
8292    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8293         (and:QI (match_dup 1) (match_dup 2)))]
8294   "ix86_match_ccmode (insn, CCNOmode)
8295    && ix86_binary_operator_ok (AND, QImode, operands)"
8296   "and{b}\t{%2, %0|%0, %2}"
8297   [(set_attr "type" "alu")
8298    (set_attr "mode" "QI")])
8299
8300 (define_insn "*andqi_2_slp"
8301   [(set (reg FLAGS_REG)
8302         (compare (and:QI
8303                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8304                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8305                  (const_int 0)))
8306    (set (strict_low_part (match_dup 0))
8307         (and:QI (match_dup 0) (match_dup 1)))]
8308   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8309    && ix86_match_ccmode (insn, CCNOmode)
8310    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8311   "and{b}\t{%1, %0|%0, %1}"
8312   [(set_attr "type" "alu1")
8313    (set_attr "mode" "QI")])
8314
8315 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8316 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8317 ;; for a QImode operand, which of course failed.
8318
8319 (define_insn "andqi_ext_0"
8320   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8321                          (const_int 8)
8322                          (const_int 8))
8323         (and:SI 
8324           (zero_extract:SI
8325             (match_operand 1 "ext_register_operand" "0")
8326             (const_int 8)
8327             (const_int 8))
8328           (match_operand 2 "const_int_operand" "n")))
8329    (clobber (reg:CC FLAGS_REG))]
8330   ""
8331   "and{b}\t{%2, %h0|%h0, %2}"
8332   [(set_attr "type" "alu")
8333    (set_attr "length_immediate" "1")
8334    (set_attr "mode" "QI")])
8335
8336 ;; Generated by peephole translating test to and.  This shows up
8337 ;; often in fp comparisons.
8338
8339 (define_insn "*andqi_ext_0_cc"
8340   [(set (reg FLAGS_REG)
8341         (compare
8342           (and:SI
8343             (zero_extract:SI
8344               (match_operand 1 "ext_register_operand" "0")
8345               (const_int 8)
8346               (const_int 8))
8347             (match_operand 2 "const_int_operand" "n"))
8348           (const_int 0)))
8349    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8350                          (const_int 8)
8351                          (const_int 8))
8352         (and:SI 
8353           (zero_extract:SI
8354             (match_dup 1)
8355             (const_int 8)
8356             (const_int 8))
8357           (match_dup 2)))]
8358   "ix86_match_ccmode (insn, CCNOmode)"
8359   "and{b}\t{%2, %h0|%h0, %2}"
8360   [(set_attr "type" "alu")
8361    (set_attr "length_immediate" "1")
8362    (set_attr "mode" "QI")])
8363
8364 (define_insn "*andqi_ext_1"
8365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (and:SI 
8369           (zero_extract:SI
8370             (match_operand 1 "ext_register_operand" "0")
8371             (const_int 8)
8372             (const_int 8))
8373           (zero_extend:SI
8374             (match_operand:QI 2 "general_operand" "Qm"))))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "!TARGET_64BIT"
8377   "and{b}\t{%2, %h0|%h0, %2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "0")
8380    (set_attr "mode" "QI")])
8381
8382 (define_insn "*andqi_ext_1_rex64"
8383   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8384                          (const_int 8)
8385                          (const_int 8))
8386         (and:SI 
8387           (zero_extract:SI
8388             (match_operand 1 "ext_register_operand" "0")
8389             (const_int 8)
8390             (const_int 8))
8391           (zero_extend:SI
8392             (match_operand 2 "ext_register_operand" "Q"))))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "TARGET_64BIT"
8395   "and{b}\t{%2, %h0|%h0, %2}"
8396   [(set_attr "type" "alu")
8397    (set_attr "length_immediate" "0")
8398    (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_ext_2"
8401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8402                          (const_int 8)
8403                          (const_int 8))
8404         (and:SI
8405           (zero_extract:SI
8406             (match_operand 1 "ext_register_operand" "%0")
8407             (const_int 8)
8408             (const_int 8))
8409           (zero_extract:SI
8410             (match_operand 2 "ext_register_operand" "Q")
8411             (const_int 8)
8412             (const_int 8))))
8413    (clobber (reg:CC FLAGS_REG))]
8414   ""
8415   "and{b}\t{%h2, %h0|%h0, %h2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "QI")])
8419
8420 ;; Convert wide AND instructions with immediate operand to shorter QImode
8421 ;; equivalents when possible.
8422 ;; Don't do the splitting with memory operands, since it introduces risk
8423 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8424 ;; for size, but that can (should?) be handled by generic code instead.
8425 (define_split
8426   [(set (match_operand 0 "register_operand" "")
8427         (and (match_operand 1 "register_operand" "")
8428              (match_operand 2 "const_int_operand" "")))
8429    (clobber (reg:CC FLAGS_REG))]
8430    "reload_completed
8431     && QI_REG_P (operands[0])
8432     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8433     && !(~INTVAL (operands[2]) & ~(255 << 8))
8434     && GET_MODE (operands[0]) != QImode"
8435   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8436                    (and:SI (zero_extract:SI (match_dup 1)
8437                                             (const_int 8) (const_int 8))
8438                            (match_dup 2)))
8439               (clobber (reg:CC FLAGS_REG))])]
8440   "operands[0] = gen_lowpart (SImode, operands[0]);
8441    operands[1] = gen_lowpart (SImode, operands[1]);
8442    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8443
8444 ;; Since AND can be encoded with sign extended immediate, this is only
8445 ;; profitable when 7th bit is not set.
8446 (define_split
8447   [(set (match_operand 0 "register_operand" "")
8448         (and (match_operand 1 "general_operand" "")
8449              (match_operand 2 "const_int_operand" "")))
8450    (clobber (reg:CC FLAGS_REG))]
8451    "reload_completed
8452     && ANY_QI_REG_P (operands[0])
8453     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8454     && !(~INTVAL (operands[2]) & ~255)
8455     && !(INTVAL (operands[2]) & 128)
8456     && GET_MODE (operands[0]) != QImode"
8457   [(parallel [(set (strict_low_part (match_dup 0))
8458                    (and:QI (match_dup 1)
8459                            (match_dup 2)))
8460               (clobber (reg:CC FLAGS_REG))])]
8461   "operands[0] = gen_lowpart (QImode, operands[0]);
8462    operands[1] = gen_lowpart (QImode, operands[1]);
8463    operands[2] = gen_lowpart (QImode, operands[2]);")
8464 \f
8465 ;; Logical inclusive OR instructions
8466
8467 ;; %%% This used to optimize known byte-wide and operations to memory.
8468 ;; If this is considered useful, it should be done with splitters.
8469
8470 (define_expand "iordi3"
8471   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8472         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8473                 (match_operand:DI 2 "x86_64_general_operand" "")))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "TARGET_64BIT"
8476   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8477
8478 (define_insn "*iordi_1_rex64"
8479   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8480         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8481                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT
8484    && ix86_binary_operator_ok (IOR, DImode, operands)"
8485   "or{q}\t{%2, %0|%0, %2}"
8486   [(set_attr "type" "alu")
8487    (set_attr "mode" "DI")])
8488
8489 (define_insn "*iordi_2_rex64"
8490   [(set (reg FLAGS_REG)
8491         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8492                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8493                  (const_int 0)))
8494    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8495         (ior:DI (match_dup 1) (match_dup 2)))]
8496   "TARGET_64BIT
8497    && ix86_match_ccmode (insn, CCNOmode)
8498    && ix86_binary_operator_ok (IOR, DImode, operands)"
8499   "or{q}\t{%2, %0|%0, %2}"
8500   [(set_attr "type" "alu")
8501    (set_attr "mode" "DI")])
8502
8503 (define_insn "*iordi_3_rex64"
8504   [(set (reg FLAGS_REG)
8505         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8506                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8507                  (const_int 0)))
8508    (clobber (match_scratch:DI 0 "=r"))]
8509   "TARGET_64BIT
8510    && ix86_match_ccmode (insn, CCNOmode)
8511    && ix86_binary_operator_ok (IOR, DImode, operands)"
8512   "or{q}\t{%2, %0|%0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "DI")])
8515
8516
8517 (define_expand "iorsi3"
8518   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8519         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8520                 (match_operand:SI 2 "general_operand" "")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   ""
8523   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8524
8525 (define_insn "*iorsi_1"
8526   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8527         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8528                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8529    (clobber (reg:CC FLAGS_REG))]
8530   "ix86_binary_operator_ok (IOR, SImode, operands)"
8531   "or{l}\t{%2, %0|%0, %2}"
8532   [(set_attr "type" "alu")
8533    (set_attr "mode" "SI")])
8534
8535 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8536 (define_insn "*iorsi_1_zext"
8537   [(set (match_operand:DI 0 "register_operand" "=rm")
8538         (zero_extend:DI
8539           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8540                   (match_operand:SI 2 "general_operand" "rim"))))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8543   "or{l}\t{%2, %k0|%k0, %2}"
8544   [(set_attr "type" "alu")
8545    (set_attr "mode" "SI")])
8546
8547 (define_insn "*iorsi_1_zext_imm"
8548   [(set (match_operand:DI 0 "register_operand" "=rm")
8549         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8550                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_64BIT"
8553   "or{l}\t{%2, %k0|%k0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "SI")])
8556
8557 (define_insn "*iorsi_2"
8558   [(set (reg FLAGS_REG)
8559         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8560                          (match_operand:SI 2 "general_operand" "rim,ri"))
8561                  (const_int 0)))
8562    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8563         (ior:SI (match_dup 1) (match_dup 2)))]
8564   "ix86_match_ccmode (insn, CCNOmode)
8565    && ix86_binary_operator_ok (IOR, SImode, operands)"
8566   "or{l}\t{%2, %0|%0, %2}"
8567   [(set_attr "type" "alu")
8568    (set_attr "mode" "SI")])
8569
8570 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8571 ;; ??? Special case for immediate operand is missing - it is tricky.
8572 (define_insn "*iorsi_2_zext"
8573   [(set (reg FLAGS_REG)
8574         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8575                          (match_operand:SI 2 "general_operand" "rim"))
8576                  (const_int 0)))
8577    (set (match_operand:DI 0 "register_operand" "=r")
8578         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8579   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8580    && ix86_binary_operator_ok (IOR, SImode, operands)"
8581   "or{l}\t{%2, %k0|%k0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "mode" "SI")])
8584
8585 (define_insn "*iorsi_2_zext_imm"
8586   [(set (reg FLAGS_REG)
8587         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8588                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8589                  (const_int 0)))
8590    (set (match_operand:DI 0 "register_operand" "=r")
8591         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8592   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8593    && ix86_binary_operator_ok (IOR, SImode, operands)"
8594   "or{l}\t{%2, %k0|%k0, %2}"
8595   [(set_attr "type" "alu")
8596    (set_attr "mode" "SI")])
8597
8598 (define_insn "*iorsi_3"
8599   [(set (reg FLAGS_REG)
8600         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8601                          (match_operand:SI 2 "general_operand" "rim"))
8602                  (const_int 0)))
8603    (clobber (match_scratch:SI 0 "=r"))]
8604   "ix86_match_ccmode (insn, CCNOmode)
8605    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8606   "or{l}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "SI")])
8609
8610 (define_expand "iorhi3"
8611   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8612         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8613                 (match_operand:HI 2 "general_operand" "")))
8614    (clobber (reg:CC FLAGS_REG))]
8615   "TARGET_HIMODE_MATH"
8616   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8617
8618 (define_insn "*iorhi_1"
8619   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8620         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8621                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "ix86_binary_operator_ok (IOR, HImode, operands)"
8624   "or{w}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "HI")])
8627
8628 (define_insn "*iorhi_2"
8629   [(set (reg FLAGS_REG)
8630         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8631                          (match_operand:HI 2 "general_operand" "rim,ri"))
8632                  (const_int 0)))
8633    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8634         (ior:HI (match_dup 1) (match_dup 2)))]
8635   "ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (IOR, HImode, operands)"
8637   "or{w}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "HI")])
8640
8641 (define_insn "*iorhi_3"
8642   [(set (reg FLAGS_REG)
8643         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8644                          (match_operand:HI 2 "general_operand" "rim"))
8645                  (const_int 0)))
8646    (clobber (match_scratch:HI 0 "=r"))]
8647   "ix86_match_ccmode (insn, CCNOmode)
8648    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8649   "or{w}\t{%2, %0|%0, %2}"
8650   [(set_attr "type" "alu")
8651    (set_attr "mode" "HI")])
8652
8653 (define_expand "iorqi3"
8654   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8655         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8656                 (match_operand:QI 2 "general_operand" "")))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_QIMODE_MATH"
8659   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8660
8661 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8662 (define_insn "*iorqi_1"
8663   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8664         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8665                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "ix86_binary_operator_ok (IOR, QImode, operands)"
8668   "@
8669    or{b}\t{%2, %0|%0, %2}
8670    or{b}\t{%2, %0|%0, %2}
8671    or{l}\t{%k2, %k0|%k0, %k2}"
8672   [(set_attr "type" "alu")
8673    (set_attr "mode" "QI,QI,SI")])
8674
8675 (define_insn "*iorqi_1_slp"
8676   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8677         (ior:QI (match_dup 0)
8678                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8681    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8682   "or{b}\t{%1, %0|%0, %1}"
8683   [(set_attr "type" "alu1")
8684    (set_attr "mode" "QI")])
8685
8686 (define_insn "*iorqi_2"
8687   [(set (reg FLAGS_REG)
8688         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8689                          (match_operand:QI 2 "general_operand" "qim,qi"))
8690                  (const_int 0)))
8691    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8692         (ior:QI (match_dup 1) (match_dup 2)))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (IOR, QImode, operands)"
8695   "or{b}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "QI")])
8698
8699 (define_insn "*iorqi_2_slp"
8700   [(set (reg FLAGS_REG)
8701         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8702                          (match_operand:QI 1 "general_operand" "qim,qi"))
8703                  (const_int 0)))
8704    (set (strict_low_part (match_dup 0))
8705         (ior:QI (match_dup 0) (match_dup 1)))]
8706   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8707    && ix86_match_ccmode (insn, CCNOmode)
8708    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8709   "or{b}\t{%1, %0|%0, %1}"
8710   [(set_attr "type" "alu1")
8711    (set_attr "mode" "QI")])
8712
8713 (define_insn "*iorqi_3"
8714   [(set (reg FLAGS_REG)
8715         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8716                          (match_operand:QI 2 "general_operand" "qim"))
8717                  (const_int 0)))
8718    (clobber (match_scratch:QI 0 "=q"))]
8719   "ix86_match_ccmode (insn, CCNOmode)
8720    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8721   "or{b}\t{%2, %0|%0, %2}"
8722   [(set_attr "type" "alu")
8723    (set_attr "mode" "QI")])
8724
8725 (define_insn "iorqi_ext_0"
8726   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8727                          (const_int 8)
8728                          (const_int 8))
8729         (ior:SI 
8730           (zero_extract:SI
8731             (match_operand 1 "ext_register_operand" "0")
8732             (const_int 8)
8733             (const_int 8))
8734           (match_operand 2 "const_int_operand" "n")))
8735    (clobber (reg:CC FLAGS_REG))]
8736   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8737   "or{b}\t{%2, %h0|%h0, %2}"
8738   [(set_attr "type" "alu")
8739    (set_attr "length_immediate" "1")
8740    (set_attr "mode" "QI")])
8741
8742 (define_insn "*iorqi_ext_1"
8743   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8744                          (const_int 8)
8745                          (const_int 8))
8746         (ior:SI 
8747           (zero_extract:SI
8748             (match_operand 1 "ext_register_operand" "0")
8749             (const_int 8)
8750             (const_int 8))
8751           (zero_extend:SI
8752             (match_operand:QI 2 "general_operand" "Qm"))))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "!TARGET_64BIT
8755    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8756   "or{b}\t{%2, %h0|%h0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "length_immediate" "0")
8759    (set_attr "mode" "QI")])
8760
8761 (define_insn "*iorqi_ext_1_rex64"
8762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8763                          (const_int 8)
8764                          (const_int 8))
8765         (ior:SI 
8766           (zero_extract:SI
8767             (match_operand 1 "ext_register_operand" "0")
8768             (const_int 8)
8769             (const_int 8))
8770           (zero_extend:SI
8771             (match_operand 2 "ext_register_operand" "Q"))))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_64BIT
8774    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775   "or{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "length_immediate" "0")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_ext_2"
8781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782                          (const_int 8)
8783                          (const_int 8))
8784         (ior:SI 
8785           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8786                            (const_int 8)
8787                            (const_int 8))
8788           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8789                            (const_int 8)
8790                            (const_int 8))))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8793   "ior{b}\t{%h2, %h0|%h0, %h2}"
8794   [(set_attr "type" "alu")
8795    (set_attr "length_immediate" "0")
8796    (set_attr "mode" "QI")])
8797
8798 (define_split
8799   [(set (match_operand 0 "register_operand" "")
8800         (ior (match_operand 1 "register_operand" "")
8801              (match_operand 2 "const_int_operand" "")))
8802    (clobber (reg:CC FLAGS_REG))]
8803    "reload_completed
8804     && QI_REG_P (operands[0])
8805     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8806     && !(INTVAL (operands[2]) & ~(255 << 8))
8807     && GET_MODE (operands[0]) != QImode"
8808   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8809                    (ior:SI (zero_extract:SI (match_dup 1)
8810                                             (const_int 8) (const_int 8))
8811                            (match_dup 2)))
8812               (clobber (reg:CC FLAGS_REG))])]
8813   "operands[0] = gen_lowpart (SImode, operands[0]);
8814    operands[1] = gen_lowpart (SImode, operands[1]);
8815    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8816
8817 ;; Since OR can be encoded with sign extended immediate, this is only
8818 ;; profitable when 7th bit is set.
8819 (define_split
8820   [(set (match_operand 0 "register_operand" "")
8821         (ior (match_operand 1 "general_operand" "")
8822              (match_operand 2 "const_int_operand" "")))
8823    (clobber (reg:CC FLAGS_REG))]
8824    "reload_completed
8825     && ANY_QI_REG_P (operands[0])
8826     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8827     && !(INTVAL (operands[2]) & ~255)
8828     && (INTVAL (operands[2]) & 128)
8829     && GET_MODE (operands[0]) != QImode"
8830   [(parallel [(set (strict_low_part (match_dup 0))
8831                    (ior:QI (match_dup 1)
8832                            (match_dup 2)))
8833               (clobber (reg:CC FLAGS_REG))])]
8834   "operands[0] = gen_lowpart (QImode, operands[0]);
8835    operands[1] = gen_lowpart (QImode, operands[1]);
8836    operands[2] = gen_lowpart (QImode, operands[2]);")
8837 \f
8838 ;; Logical XOR instructions
8839
8840 ;; %%% This used to optimize known byte-wide and operations to memory.
8841 ;; If this is considered useful, it should be done with splitters.
8842
8843 (define_expand "xordi3"
8844   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8845         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8846                 (match_operand:DI 2 "x86_64_general_operand" "")))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "TARGET_64BIT"
8849   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8850
8851 (define_insn "*xordi_1_rex64"
8852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8853         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8854                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "TARGET_64BIT
8857    && ix86_binary_operator_ok (XOR, DImode, operands)"
8858   "@
8859    xor{q}\t{%2, %0|%0, %2}
8860    xor{q}\t{%2, %0|%0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "DI,DI")])
8863
8864 (define_insn "*xordi_2_rex64"
8865   [(set (reg FLAGS_REG)
8866         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8867                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8868                  (const_int 0)))
8869    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8870         (xor:DI (match_dup 1) (match_dup 2)))]
8871   "TARGET_64BIT
8872    && ix86_match_ccmode (insn, CCNOmode)
8873    && ix86_binary_operator_ok (XOR, DImode, operands)"
8874   "@
8875    xor{q}\t{%2, %0|%0, %2}
8876    xor{q}\t{%2, %0|%0, %2}"
8877   [(set_attr "type" "alu")
8878    (set_attr "mode" "DI,DI")])
8879
8880 (define_insn "*xordi_3_rex64"
8881   [(set (reg FLAGS_REG)
8882         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8883                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8884                  (const_int 0)))
8885    (clobber (match_scratch:DI 0 "=r"))]
8886   "TARGET_64BIT
8887    && ix86_match_ccmode (insn, CCNOmode)
8888    && ix86_binary_operator_ok (XOR, DImode, operands)"
8889   "xor{q}\t{%2, %0|%0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "DI")])
8892
8893 (define_expand "xorsi3"
8894   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8895         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8896                 (match_operand:SI 2 "general_operand" "")))
8897    (clobber (reg:CC FLAGS_REG))]
8898   ""
8899   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8900
8901 (define_insn "*xorsi_1"
8902   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8903         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8904                 (match_operand:SI 2 "general_operand" "ri,rm")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "ix86_binary_operator_ok (XOR, SImode, operands)"
8907   "xor{l}\t{%2, %0|%0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "mode" "SI")])
8910
8911 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8912 ;; Add speccase for immediates
8913 (define_insn "*xorsi_1_zext"
8914   [(set (match_operand:DI 0 "register_operand" "=r")
8915         (zero_extend:DI
8916           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8917                   (match_operand:SI 2 "general_operand" "rim"))))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8920   "xor{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8923
8924 (define_insn "*xorsi_1_zext_imm"
8925   [(set (match_operand:DI 0 "register_operand" "=r")
8926         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8927                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8930   "xor{l}\t{%2, %k0|%k0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "SI")])
8933
8934 (define_insn "*xorsi_2"
8935   [(set (reg FLAGS_REG)
8936         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8937                          (match_operand:SI 2 "general_operand" "rim,ri"))
8938                  (const_int 0)))
8939    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8940         (xor:SI (match_dup 1) (match_dup 2)))]
8941   "ix86_match_ccmode (insn, CCNOmode)
8942    && ix86_binary_operator_ok (XOR, SImode, operands)"
8943   "xor{l}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "SI")])
8946
8947 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8948 ;; ??? Special case for immediate operand is missing - it is tricky.
8949 (define_insn "*xorsi_2_zext"
8950   [(set (reg FLAGS_REG)
8951         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8952                          (match_operand:SI 2 "general_operand" "rim"))
8953                  (const_int 0)))
8954    (set (match_operand:DI 0 "register_operand" "=r")
8955         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8956   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8957    && ix86_binary_operator_ok (XOR, SImode, operands)"
8958   "xor{l}\t{%2, %k0|%k0, %2}"
8959   [(set_attr "type" "alu")
8960    (set_attr "mode" "SI")])
8961
8962 (define_insn "*xorsi_2_zext_imm"
8963   [(set (reg FLAGS_REG)
8964         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8965                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8966                  (const_int 0)))
8967    (set (match_operand:DI 0 "register_operand" "=r")
8968         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8969   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8970    && ix86_binary_operator_ok (XOR, SImode, operands)"
8971   "xor{l}\t{%2, %k0|%k0, %2}"
8972   [(set_attr "type" "alu")
8973    (set_attr "mode" "SI")])
8974
8975 (define_insn "*xorsi_3"
8976   [(set (reg FLAGS_REG)
8977         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8978                          (match_operand:SI 2 "general_operand" "rim"))
8979                  (const_int 0)))
8980    (clobber (match_scratch:SI 0 "=r"))]
8981   "ix86_match_ccmode (insn, CCNOmode)
8982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8983   "xor{l}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "SI")])
8986
8987 (define_expand "xorhi3"
8988   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8989         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8990                 (match_operand:HI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "TARGET_HIMODE_MATH"
8993   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8994
8995 (define_insn "*xorhi_1"
8996   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8997         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, HImode, operands)"
9001   "xor{w}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "HI")])
9004
9005 (define_insn "*xorhi_2"
9006   [(set (reg FLAGS_REG)
9007         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9008                          (match_operand:HI 2 "general_operand" "rim,ri"))
9009                  (const_int 0)))
9010    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9011         (xor:HI (match_dup 1) (match_dup 2)))]
9012   "ix86_match_ccmode (insn, CCNOmode)
9013    && ix86_binary_operator_ok (XOR, HImode, operands)"
9014   "xor{w}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "HI")])
9017
9018 (define_insn "*xorhi_3"
9019   [(set (reg FLAGS_REG)
9020         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9021                          (match_operand:HI 2 "general_operand" "rim"))
9022                  (const_int 0)))
9023    (clobber (match_scratch:HI 0 "=r"))]
9024   "ix86_match_ccmode (insn, CCNOmode)
9025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9026   "xor{w}\t{%2, %0|%0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "mode" "HI")])
9029
9030 (define_expand "xorqi3"
9031   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9032         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9033                 (match_operand:QI 2 "general_operand" "")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "TARGET_QIMODE_MATH"
9036   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9037
9038 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9039 (define_insn "*xorqi_1"
9040   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9041         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9042                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "ix86_binary_operator_ok (XOR, QImode, operands)"
9045   "@
9046    xor{b}\t{%2, %0|%0, %2}
9047    xor{b}\t{%2, %0|%0, %2}
9048    xor{l}\t{%k2, %k0|%k0, %k2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "QI,QI,SI")])
9051
9052 (define_insn "*xorqi_1_slp"
9053   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9054         (xor:QI (match_dup 0)
9055                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9058    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9059   "xor{b}\t{%1, %0|%0, %1}"
9060   [(set_attr "type" "alu1")
9061    (set_attr "mode" "QI")])
9062
9063 (define_insn "xorqi_ext_0"
9064   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065                          (const_int 8)
9066                          (const_int 8))
9067         (xor:SI 
9068           (zero_extract:SI
9069             (match_operand 1 "ext_register_operand" "0")
9070             (const_int 8)
9071             (const_int 8))
9072           (match_operand 2 "const_int_operand" "n")))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9075   "xor{b}\t{%2, %h0|%h0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "length_immediate" "1")
9078    (set_attr "mode" "QI")])
9079
9080 (define_insn "*xorqi_ext_1"
9081   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9082                          (const_int 8)
9083                          (const_int 8))
9084         (xor:SI 
9085           (zero_extract:SI
9086             (match_operand 1 "ext_register_operand" "0")
9087             (const_int 8)
9088             (const_int 8))
9089           (zero_extend:SI
9090             (match_operand:QI 2 "general_operand" "Qm"))))
9091    (clobber (reg:CC FLAGS_REG))]
9092   "!TARGET_64BIT
9093    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9094   "xor{b}\t{%2, %h0|%h0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "length_immediate" "0")
9097    (set_attr "mode" "QI")])
9098
9099 (define_insn "*xorqi_ext_1_rex64"
9100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9101                          (const_int 8)
9102                          (const_int 8))
9103         (xor:SI 
9104           (zero_extract:SI
9105             (match_operand 1 "ext_register_operand" "0")
9106             (const_int 8)
9107             (const_int 8))
9108           (zero_extend:SI
9109             (match_operand 2 "ext_register_operand" "Q"))))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "TARGET_64BIT
9112    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113   "xor{b}\t{%2, %h0|%h0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "length_immediate" "0")
9116    (set_attr "mode" "QI")])
9117
9118 (define_insn "*xorqi_ext_2"
9119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120                          (const_int 8)
9121                          (const_int 8))
9122         (xor:SI 
9123           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9124                            (const_int 8)
9125                            (const_int 8))
9126           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9127                            (const_int 8)
9128                            (const_int 8))))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9131   "xor{b}\t{%h2, %h0|%h0, %h2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "length_immediate" "0")
9134    (set_attr "mode" "QI")])
9135
9136 (define_insn "*xorqi_cc_1"
9137   [(set (reg FLAGS_REG)
9138         (compare
9139           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9140                   (match_operand:QI 2 "general_operand" "qim,qi"))
9141           (const_int 0)))
9142    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9143         (xor:QI (match_dup 1) (match_dup 2)))]
9144   "ix86_match_ccmode (insn, CCNOmode)
9145    && ix86_binary_operator_ok (XOR, QImode, operands)"
9146   "xor{b}\t{%2, %0|%0, %2}"
9147   [(set_attr "type" "alu")
9148    (set_attr "mode" "QI")])
9149
9150 (define_insn "*xorqi_2_slp"
9151   [(set (reg FLAGS_REG)
9152         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9153                          (match_operand:QI 1 "general_operand" "qim,qi"))
9154                  (const_int 0)))
9155    (set (strict_low_part (match_dup 0))
9156         (xor:QI (match_dup 0) (match_dup 1)))]
9157   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9158    && ix86_match_ccmode (insn, CCNOmode)
9159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9160   "xor{b}\t{%1, %0|%0, %1}"
9161   [(set_attr "type" "alu1")
9162    (set_attr "mode" "QI")])
9163
9164 (define_insn "*xorqi_cc_2"
9165   [(set (reg FLAGS_REG)
9166         (compare
9167           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9168                   (match_operand:QI 2 "general_operand" "qim"))
9169           (const_int 0)))
9170    (clobber (match_scratch:QI 0 "=q"))]
9171   "ix86_match_ccmode (insn, CCNOmode)
9172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9173   "xor{b}\t{%2, %0|%0, %2}"
9174   [(set_attr "type" "alu")
9175    (set_attr "mode" "QI")])
9176
9177 (define_insn "*xorqi_cc_ext_1"
9178   [(set (reg FLAGS_REG)
9179         (compare
9180           (xor:SI
9181             (zero_extract:SI
9182               (match_operand 1 "ext_register_operand" "0")
9183               (const_int 8)
9184               (const_int 8))
9185             (match_operand:QI 2 "general_operand" "qmn"))
9186           (const_int 0)))
9187    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9188                          (const_int 8)
9189                          (const_int 8))
9190         (xor:SI 
9191           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9192           (match_dup 2)))]
9193   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9194   "xor{b}\t{%2, %h0|%h0, %2}"
9195   [(set_attr "type" "alu")
9196    (set_attr "mode" "QI")])
9197
9198 (define_insn "*xorqi_cc_ext_1_rex64"
9199   [(set (reg FLAGS_REG)
9200         (compare
9201           (xor:SI
9202             (zero_extract:SI
9203               (match_operand 1 "ext_register_operand" "0")
9204               (const_int 8)
9205               (const_int 8))
9206             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9207           (const_int 0)))
9208    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9209                          (const_int 8)
9210                          (const_int 8))
9211         (xor:SI 
9212           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9213           (match_dup 2)))]
9214   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9215   "xor{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "mode" "QI")])
9218
9219 (define_expand "xorqi_cc_ext_1"
9220   [(parallel [
9221      (set (reg:CCNO FLAGS_REG)
9222           (compare:CCNO
9223             (xor:SI
9224               (zero_extract:SI
9225                 (match_operand 1 "ext_register_operand" "")
9226                 (const_int 8)
9227                 (const_int 8))
9228               (match_operand:QI 2 "general_operand" ""))
9229             (const_int 0)))
9230      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9231                            (const_int 8)
9232                            (const_int 8))
9233           (xor:SI 
9234             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9235             (match_dup 2)))])]
9236   ""
9237   "")
9238
9239 (define_split
9240   [(set (match_operand 0 "register_operand" "")
9241         (xor (match_operand 1 "register_operand" "")
9242              (match_operand 2 "const_int_operand" "")))
9243    (clobber (reg:CC FLAGS_REG))]
9244    "reload_completed
9245     && QI_REG_P (operands[0])
9246     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9247     && !(INTVAL (operands[2]) & ~(255 << 8))
9248     && GET_MODE (operands[0]) != QImode"
9249   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9250                    (xor:SI (zero_extract:SI (match_dup 1)
9251                                             (const_int 8) (const_int 8))
9252                            (match_dup 2)))
9253               (clobber (reg:CC FLAGS_REG))])]
9254   "operands[0] = gen_lowpart (SImode, operands[0]);
9255    operands[1] = gen_lowpart (SImode, operands[1]);
9256    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9257
9258 ;; Since XOR can be encoded with sign extended immediate, this is only
9259 ;; profitable when 7th bit is set.
9260 (define_split
9261   [(set (match_operand 0 "register_operand" "")
9262         (xor (match_operand 1 "general_operand" "")
9263              (match_operand 2 "const_int_operand" "")))
9264    (clobber (reg:CC FLAGS_REG))]
9265    "reload_completed
9266     && ANY_QI_REG_P (operands[0])
9267     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9268     && !(INTVAL (operands[2]) & ~255)
9269     && (INTVAL (operands[2]) & 128)
9270     && GET_MODE (operands[0]) != QImode"
9271   [(parallel [(set (strict_low_part (match_dup 0))
9272                    (xor:QI (match_dup 1)
9273                            (match_dup 2)))
9274               (clobber (reg:CC FLAGS_REG))])]
9275   "operands[0] = gen_lowpart (QImode, operands[0]);
9276    operands[1] = gen_lowpart (QImode, operands[1]);
9277    operands[2] = gen_lowpart (QImode, operands[2]);")
9278 \f
9279 ;; Negation instructions
9280
9281 (define_expand "negti2"
9282   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9283                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9284               (clobber (reg:CC FLAGS_REG))])]
9285   "TARGET_64BIT"
9286   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9287
9288 (define_insn "*negti2_1"
9289   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9290         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "TARGET_64BIT
9293    && ix86_unary_operator_ok (NEG, TImode, operands)"
9294   "#")
9295
9296 (define_split
9297   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9298         (neg:TI (match_operand:TI 1 "general_operand" "")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   "TARGET_64BIT && reload_completed"
9301   [(parallel
9302     [(set (reg:CCZ FLAGS_REG)
9303           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9304      (set (match_dup 0) (neg:DI (match_dup 2)))])
9305    (parallel
9306     [(set (match_dup 1)
9307           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9308                             (match_dup 3))
9309                    (const_int 0)))
9310      (clobber (reg:CC FLAGS_REG))])
9311    (parallel
9312     [(set (match_dup 1)
9313           (neg:DI (match_dup 1)))
9314      (clobber (reg:CC FLAGS_REG))])]
9315   "split_ti (operands+1, 1, operands+2, operands+3);
9316    split_ti (operands+0, 1, operands+0, operands+1);")
9317
9318 (define_expand "negdi2"
9319   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9320                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9321               (clobber (reg:CC FLAGS_REG))])]
9322   ""
9323   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9324
9325 (define_insn "*negdi2_1"
9326   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9327         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9328    (clobber (reg:CC FLAGS_REG))]
9329   "!TARGET_64BIT
9330    && ix86_unary_operator_ok (NEG, DImode, operands)"
9331   "#")
9332
9333 (define_split
9334   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9335         (neg:DI (match_operand:DI 1 "general_operand" "")))
9336    (clobber (reg:CC FLAGS_REG))]
9337   "!TARGET_64BIT && reload_completed"
9338   [(parallel
9339     [(set (reg:CCZ FLAGS_REG)
9340           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9341      (set (match_dup 0) (neg:SI (match_dup 2)))])
9342    (parallel
9343     [(set (match_dup 1)
9344           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9345                             (match_dup 3))
9346                    (const_int 0)))
9347      (clobber (reg:CC FLAGS_REG))])
9348    (parallel
9349     [(set (match_dup 1)
9350           (neg:SI (match_dup 1)))
9351      (clobber (reg:CC FLAGS_REG))])]
9352   "split_di (operands+1, 1, operands+2, operands+3);
9353    split_di (operands+0, 1, operands+0, operands+1);")
9354
9355 (define_insn "*negdi2_1_rex64"
9356   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9357         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9360   "neg{q}\t%0"
9361   [(set_attr "type" "negnot")
9362    (set_attr "mode" "DI")])
9363
9364 ;; The problem with neg is that it does not perform (compare x 0),
9365 ;; it really performs (compare 0 x), which leaves us with the zero
9366 ;; flag being the only useful item.
9367
9368 (define_insn "*negdi2_cmpz_rex64"
9369   [(set (reg:CCZ FLAGS_REG)
9370         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9371                      (const_int 0)))
9372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9373         (neg:DI (match_dup 1)))]
9374   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9375   "neg{q}\t%0"
9376   [(set_attr "type" "negnot")
9377    (set_attr "mode" "DI")])
9378
9379
9380 (define_expand "negsi2"
9381   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9382                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9383               (clobber (reg:CC FLAGS_REG))])]
9384   ""
9385   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9386
9387 (define_insn "*negsi2_1"
9388   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9389         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "ix86_unary_operator_ok (NEG, SImode, operands)"
9392   "neg{l}\t%0"
9393   [(set_attr "type" "negnot")
9394    (set_attr "mode" "SI")])
9395
9396 ;; Combine is quite creative about this pattern.
9397 (define_insn "*negsi2_1_zext"
9398   [(set (match_operand:DI 0 "register_operand" "=r")
9399         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9400                                         (const_int 32)))
9401                      (const_int 32)))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9404   "neg{l}\t%k0"
9405   [(set_attr "type" "negnot")
9406    (set_attr "mode" "SI")])
9407
9408 ;; The problem with neg is that it does not perform (compare x 0),
9409 ;; it really performs (compare 0 x), which leaves us with the zero
9410 ;; flag being the only useful item.
9411
9412 (define_insn "*negsi2_cmpz"
9413   [(set (reg:CCZ FLAGS_REG)
9414         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9415                      (const_int 0)))
9416    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9417         (neg:SI (match_dup 1)))]
9418   "ix86_unary_operator_ok (NEG, SImode, operands)"
9419   "neg{l}\t%0"
9420   [(set_attr "type" "negnot")
9421    (set_attr "mode" "SI")])
9422
9423 (define_insn "*negsi2_cmpz_zext"
9424   [(set (reg:CCZ FLAGS_REG)
9425         (compare:CCZ (lshiftrt:DI
9426                        (neg:DI (ashift:DI
9427                                  (match_operand:DI 1 "register_operand" "0")
9428                                  (const_int 32)))
9429                        (const_int 32))
9430                      (const_int 0)))
9431    (set (match_operand:DI 0 "register_operand" "=r")
9432         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9433                                         (const_int 32)))
9434                      (const_int 32)))]
9435   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9436   "neg{l}\t%k0"
9437   [(set_attr "type" "negnot")
9438    (set_attr "mode" "SI")])
9439
9440 (define_expand "neghi2"
9441   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9442                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9443               (clobber (reg:CC FLAGS_REG))])]
9444   "TARGET_HIMODE_MATH"
9445   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9446
9447 (define_insn "*neghi2_1"
9448   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9449         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "ix86_unary_operator_ok (NEG, HImode, operands)"
9452   "neg{w}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "HI")])
9455
9456 (define_insn "*neghi2_cmpz"
9457   [(set (reg:CCZ FLAGS_REG)
9458         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9459                      (const_int 0)))
9460    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9461         (neg:HI (match_dup 1)))]
9462   "ix86_unary_operator_ok (NEG, HImode, operands)"
9463   "neg{w}\t%0"
9464   [(set_attr "type" "negnot")
9465    (set_attr "mode" "HI")])
9466
9467 (define_expand "negqi2"
9468   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9469                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9470               (clobber (reg:CC FLAGS_REG))])]
9471   "TARGET_QIMODE_MATH"
9472   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9473
9474 (define_insn "*negqi2_1"
9475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9476         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9477    (clobber (reg:CC FLAGS_REG))]
9478   "ix86_unary_operator_ok (NEG, QImode, operands)"
9479   "neg{b}\t%0"
9480   [(set_attr "type" "negnot")
9481    (set_attr "mode" "QI")])
9482
9483 (define_insn "*negqi2_cmpz"
9484   [(set (reg:CCZ FLAGS_REG)
9485         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9486                      (const_int 0)))
9487    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9488         (neg:QI (match_dup 1)))]
9489   "ix86_unary_operator_ok (NEG, QImode, operands)"
9490   "neg{b}\t%0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "QI")])
9493
9494 ;; Changing of sign for FP values is doable using integer unit too.
9495
9496 (define_expand "negsf2"
9497   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9498         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9499   "TARGET_80387 || TARGET_SSE_MATH"
9500   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9501
9502 (define_expand "abssf2"
9503   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9504         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9505   "TARGET_80387 || TARGET_SSE_MATH"
9506   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9507
9508 (define_insn "*absnegsf2_mixed"
9509   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9510         (match_operator:SF 3 "absneg_operator"
9511           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9512    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9515    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9516   "#")
9517
9518 (define_insn "*absnegsf2_sse"
9519   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9520         (match_operator:SF 3 "absneg_operator"
9521           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9522    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "TARGET_SSE_MATH
9525    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526   "#")
9527
9528 (define_insn "*absnegsf2_i387"
9529   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9530         (match_operator:SF 3 "absneg_operator"
9531           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9532    (use (match_operand 2 "" ""))
9533    (clobber (reg:CC FLAGS_REG))]
9534   "TARGET_80387 && !TARGET_SSE_MATH
9535    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536   "#")
9537
9538 (define_expand "copysignsf3"
9539   [(match_operand:SF 0 "register_operand" "")
9540    (match_operand:SF 1 "nonmemory_operand" "")
9541    (match_operand:SF 2 "register_operand" "")]
9542   "TARGET_SSE_MATH"
9543 {
9544   ix86_expand_copysign (operands);
9545   DONE;
9546 })
9547
9548 (define_insn_and_split "copysignsf3_const"
9549   [(set (match_operand:SF 0 "register_operand"          "=x")
9550         (unspec:SF
9551           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9552            (match_operand:SF 2 "register_operand"       "0")
9553            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9554           UNSPEC_COPYSIGN))]
9555   "TARGET_SSE_MATH"
9556   "#"
9557   "&& reload_completed"
9558   [(const_int 0)]
9559 {
9560   ix86_split_copysign_const (operands);
9561   DONE;
9562 })
9563
9564 (define_insn "copysignsf3_var"
9565   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9566         (unspec:SF
9567           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9568            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9569            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9570            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9571           UNSPEC_COPYSIGN))
9572    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9573   "TARGET_SSE_MATH"
9574   "#")
9575
9576 (define_split
9577   [(set (match_operand:SF 0 "register_operand" "")
9578         (unspec:SF
9579           [(match_operand:SF 2 "register_operand" "")
9580            (match_operand:SF 3 "register_operand" "")
9581            (match_operand:V4SF 4 "" "")
9582            (match_operand:V4SF 5 "" "")]
9583           UNSPEC_COPYSIGN))
9584    (clobber (match_scratch:V4SF 1 ""))]
9585   "TARGET_SSE_MATH && reload_completed"
9586   [(const_int 0)]
9587 {
9588   ix86_split_copysign_var (operands);
9589   DONE;
9590 })
9591
9592 (define_expand "negdf2"
9593   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9594         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9595   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9596   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9597
9598 (define_expand "absdf2"
9599   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9600         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9601   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9602   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9603
9604 (define_insn "*absnegdf2_mixed"
9605   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9606         (match_operator:DF 3 "absneg_operator"
9607           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9608    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9609    (clobber (reg:CC FLAGS_REG))]
9610   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9611    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9612   "#")
9613
9614 (define_insn "*absnegdf2_sse"
9615   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9616         (match_operator:DF 3 "absneg_operator"
9617           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9618    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "TARGET_SSE2 && TARGET_SSE_MATH
9621    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622   "#")
9623
9624 (define_insn "*absnegdf2_i387"
9625   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9626         (match_operator:DF 3 "absneg_operator"
9627           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9628    (use (match_operand 2 "" ""))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9631    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632   "#")
9633
9634 (define_expand "copysigndf3"
9635   [(match_operand:DF 0 "register_operand" "")
9636    (match_operand:DF 1 "nonmemory_operand" "")
9637    (match_operand:DF 2 "register_operand" "")]
9638   "TARGET_SSE2 && TARGET_SSE_MATH"
9639 {
9640   ix86_expand_copysign (operands);
9641   DONE;
9642 })
9643
9644 (define_insn_and_split "copysigndf3_const"
9645   [(set (match_operand:DF 0 "register_operand"          "=x")
9646         (unspec:DF
9647           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9648            (match_operand:DF 2 "register_operand"       "0")
9649            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9650           UNSPEC_COPYSIGN))]
9651   "TARGET_SSE2 && TARGET_SSE_MATH"
9652   "#"
9653   "&& reload_completed"
9654   [(const_int 0)]
9655 {
9656   ix86_split_copysign_const (operands);
9657   DONE;
9658 })
9659
9660 (define_insn "copysigndf3_var"
9661   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9662         (unspec:DF
9663           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9664            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9665            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9666            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9667           UNSPEC_COPYSIGN))
9668    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9669   "TARGET_SSE2 && TARGET_SSE_MATH"
9670   "#")
9671
9672 (define_split
9673   [(set (match_operand:DF 0 "register_operand" "")
9674         (unspec:DF
9675           [(match_operand:DF 2 "register_operand" "")
9676            (match_operand:DF 3 "register_operand" "")
9677            (match_operand:V2DF 4 "" "")
9678            (match_operand:V2DF 5 "" "")]
9679           UNSPEC_COPYSIGN))
9680    (clobber (match_scratch:V2DF 1 ""))]
9681   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9682   [(const_int 0)]
9683 {
9684   ix86_split_copysign_var (operands);
9685   DONE;
9686 })
9687
9688 (define_expand "negxf2"
9689   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9690         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9691   "TARGET_80387"
9692   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9693
9694 (define_expand "absxf2"
9695   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9696         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9697   "TARGET_80387"
9698   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9699
9700 (define_insn "*absnegxf2_i387"
9701   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9702         (match_operator:XF 3 "absneg_operator"
9703           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9704    (use (match_operand 2 "" ""))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "TARGET_80387
9707    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9708   "#")
9709
9710 ;; Splitters for fp abs and neg.
9711
9712 (define_split
9713   [(set (match_operand 0 "fp_register_operand" "")
9714         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9715    (use (match_operand 2 "" ""))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "reload_completed"
9718   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9719
9720 (define_split
9721   [(set (match_operand 0 "register_operand" "")
9722         (match_operator 3 "absneg_operator"
9723           [(match_operand 1 "register_operand" "")]))
9724    (use (match_operand 2 "nonimmediate_operand" ""))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "reload_completed && SSE_REG_P (operands[0])"
9727   [(set (match_dup 0) (match_dup 3))]
9728 {
9729   enum machine_mode mode = GET_MODE (operands[0]);
9730   enum machine_mode vmode = GET_MODE (operands[2]);
9731   rtx tmp;
9732   
9733   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9734   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9735   if (operands_match_p (operands[0], operands[2]))
9736     {
9737       tmp = operands[1];
9738       operands[1] = operands[2];
9739       operands[2] = tmp;
9740     }
9741   if (GET_CODE (operands[3]) == ABS)
9742     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9743   else
9744     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9745   operands[3] = tmp;
9746 })
9747
9748 (define_split
9749   [(set (match_operand:SF 0 "register_operand" "")
9750         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9751    (use (match_operand:V4SF 2 "" ""))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "reload_completed"
9754   [(parallel [(set (match_dup 0) (match_dup 1))
9755               (clobber (reg:CC FLAGS_REG))])]
9756
9757   rtx tmp;
9758   operands[0] = gen_lowpart (SImode, operands[0]);
9759   if (GET_CODE (operands[1]) == ABS)
9760     {
9761       tmp = gen_int_mode (0x7fffffff, SImode);
9762       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9763     }
9764   else
9765     {
9766       tmp = gen_int_mode (0x80000000, SImode);
9767       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9768     }
9769   operands[1] = tmp;
9770 })
9771
9772 (define_split
9773   [(set (match_operand:DF 0 "register_operand" "")
9774         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9775    (use (match_operand 2 "" ""))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "reload_completed"
9778   [(parallel [(set (match_dup 0) (match_dup 1))
9779               (clobber (reg:CC FLAGS_REG))])]
9780 {
9781   rtx tmp;
9782   if (TARGET_64BIT)
9783     {
9784       tmp = gen_lowpart (DImode, operands[0]);
9785       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9786       operands[0] = tmp;
9787
9788       if (GET_CODE (operands[1]) == ABS)
9789         tmp = const0_rtx;
9790       else
9791         tmp = gen_rtx_NOT (DImode, tmp);
9792     }
9793   else
9794     {
9795       operands[0] = gen_highpart (SImode, operands[0]);
9796       if (GET_CODE (operands[1]) == ABS)
9797         {
9798           tmp = gen_int_mode (0x7fffffff, SImode);
9799           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9800         }
9801       else
9802         {
9803           tmp = gen_int_mode (0x80000000, SImode);
9804           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9805         }
9806     }
9807   operands[1] = tmp;
9808 })
9809
9810 (define_split
9811   [(set (match_operand:XF 0 "register_operand" "")
9812         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9813    (use (match_operand 2 "" ""))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "reload_completed"
9816   [(parallel [(set (match_dup 0) (match_dup 1))
9817               (clobber (reg:CC FLAGS_REG))])]
9818 {
9819   rtx tmp;
9820   operands[0] = gen_rtx_REG (SImode,
9821                              true_regnum (operands[0])
9822                              + (TARGET_64BIT ? 1 : 2));
9823   if (GET_CODE (operands[1]) == ABS)
9824     {
9825       tmp = GEN_INT (0x7fff);
9826       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9827     }
9828   else
9829     {
9830       tmp = GEN_INT (0x8000);
9831       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9832     }
9833   operands[1] = tmp;
9834 })
9835
9836 (define_split
9837   [(set (match_operand 0 "memory_operand" "")
9838         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9839    (use (match_operand 2 "" ""))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "reload_completed"
9842   [(parallel [(set (match_dup 0) (match_dup 1))
9843               (clobber (reg:CC FLAGS_REG))])]
9844 {
9845   enum machine_mode mode = GET_MODE (operands[0]);
9846   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9847   rtx tmp;
9848
9849   operands[0] = adjust_address (operands[0], QImode, size - 1);
9850   if (GET_CODE (operands[1]) == ABS)
9851     {
9852       tmp = gen_int_mode (0x7f, QImode);
9853       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9854     }
9855   else
9856     {
9857       tmp = gen_int_mode (0x80, QImode);
9858       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9859     }
9860   operands[1] = tmp;
9861 })
9862
9863 ;; Conditionalize these after reload. If they match before reload, we 
9864 ;; lose the clobber and ability to use integer instructions.
9865
9866 (define_insn "*negsf2_1"
9867   [(set (match_operand:SF 0 "register_operand" "=f")
9868         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9869   "TARGET_80387 && reload_completed"
9870   "fchs"
9871   [(set_attr "type" "fsgn")
9872    (set_attr "mode" "SF")])
9873
9874 (define_insn "*negdf2_1"
9875   [(set (match_operand:DF 0 "register_operand" "=f")
9876         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9877   "TARGET_80387 && reload_completed"
9878   "fchs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "DF")])
9881
9882 (define_insn "*negxf2_1"
9883   [(set (match_operand:XF 0 "register_operand" "=f")
9884         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9885   "TARGET_80387 && reload_completed"
9886   "fchs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "XF")])
9889
9890 (define_insn "*abssf2_1"
9891   [(set (match_operand:SF 0 "register_operand" "=f")
9892         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9893   "TARGET_80387 && reload_completed"
9894   "fabs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "SF")])
9897
9898 (define_insn "*absdf2_1"
9899   [(set (match_operand:DF 0 "register_operand" "=f")
9900         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9901   "TARGET_80387 && reload_completed"
9902   "fabs"
9903   [(set_attr "type" "fsgn")
9904    (set_attr "mode" "DF")])
9905
9906 (define_insn "*absxf2_1"
9907   [(set (match_operand:XF 0 "register_operand" "=f")
9908         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9909   "TARGET_80387 && reload_completed"
9910   "fabs"
9911   [(set_attr "type" "fsgn")
9912    (set_attr "mode" "DF")])
9913
9914 (define_insn "*negextendsfdf2"
9915   [(set (match_operand:DF 0 "register_operand" "=f")
9916         (neg:DF (float_extend:DF
9917                   (match_operand:SF 1 "register_operand" "0"))))]
9918   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9919   "fchs"
9920   [(set_attr "type" "fsgn")
9921    (set_attr "mode" "DF")])
9922
9923 (define_insn "*negextenddfxf2"
9924   [(set (match_operand:XF 0 "register_operand" "=f")
9925         (neg:XF (float_extend:XF
9926                   (match_operand:DF 1 "register_operand" "0"))))]
9927   "TARGET_80387"
9928   "fchs"
9929   [(set_attr "type" "fsgn")
9930    (set_attr "mode" "XF")])
9931
9932 (define_insn "*negextendsfxf2"
9933   [(set (match_operand:XF 0 "register_operand" "=f")
9934         (neg:XF (float_extend:XF
9935                   (match_operand:SF 1 "register_operand" "0"))))]
9936   "TARGET_80387"
9937   "fchs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "XF")])
9940
9941 (define_insn "*absextendsfdf2"
9942   [(set (match_operand:DF 0 "register_operand" "=f")
9943         (abs:DF (float_extend:DF
9944                   (match_operand:SF 1 "register_operand" "0"))))]
9945   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9946   "fabs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "DF")])
9949
9950 (define_insn "*absextenddfxf2"
9951   [(set (match_operand:XF 0 "register_operand" "=f")
9952         (abs:XF (float_extend:XF
9953           (match_operand:DF 1 "register_operand" "0"))))]
9954   "TARGET_80387"
9955   "fabs"
9956   [(set_attr "type" "fsgn")
9957    (set_attr "mode" "XF")])
9958
9959 (define_insn "*absextendsfxf2"
9960   [(set (match_operand:XF 0 "register_operand" "=f")
9961         (abs:XF (float_extend:XF
9962           (match_operand:SF 1 "register_operand" "0"))))]
9963   "TARGET_80387"
9964   "fabs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "XF")])
9967 \f
9968 ;; One complement instructions
9969
9970 (define_expand "one_cmpldi2"
9971   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9972         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9973   "TARGET_64BIT"
9974   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9975
9976 (define_insn "*one_cmpldi2_1_rex64"
9977   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9978         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9979   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9980   "not{q}\t%0"
9981   [(set_attr "type" "negnot")
9982    (set_attr "mode" "DI")])
9983
9984 (define_insn "*one_cmpldi2_2_rex64"
9985   [(set (reg FLAGS_REG)
9986         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9987                  (const_int 0)))
9988    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9989         (not:DI (match_dup 1)))]
9990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9991    && ix86_unary_operator_ok (NOT, DImode, operands)"
9992   "#"
9993   [(set_attr "type" "alu1")
9994    (set_attr "mode" "DI")])
9995
9996 (define_split
9997   [(set (match_operand 0 "flags_reg_operand" "")
9998         (match_operator 2 "compare_operator"
9999           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10000            (const_int 0)]))
10001    (set (match_operand:DI 1 "nonimmediate_operand" "")
10002         (not:DI (match_dup 3)))]
10003   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10004   [(parallel [(set (match_dup 0)
10005                    (match_op_dup 2
10006                      [(xor:DI (match_dup 3) (const_int -1))
10007                       (const_int 0)]))
10008               (set (match_dup 1)
10009                    (xor:DI (match_dup 3) (const_int -1)))])]
10010   "")
10011
10012 (define_expand "one_cmplsi2"
10013   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10014         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10015   ""
10016   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10017
10018 (define_insn "*one_cmplsi2_1"
10019   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10020         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10021   "ix86_unary_operator_ok (NOT, SImode, operands)"
10022   "not{l}\t%0"
10023   [(set_attr "type" "negnot")
10024    (set_attr "mode" "SI")])
10025
10026 ;; ??? Currently never generated - xor is used instead.
10027 (define_insn "*one_cmplsi2_1_zext"
10028   [(set (match_operand:DI 0 "register_operand" "=r")
10029         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10030   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10031   "not{l}\t%k0"
10032   [(set_attr "type" "negnot")
10033    (set_attr "mode" "SI")])
10034
10035 (define_insn "*one_cmplsi2_2"
10036   [(set (reg FLAGS_REG)
10037         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10038                  (const_int 0)))
10039    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10040         (not:SI (match_dup 1)))]
10041   "ix86_match_ccmode (insn, CCNOmode)
10042    && ix86_unary_operator_ok (NOT, SImode, operands)"
10043   "#"
10044   [(set_attr "type" "alu1")
10045    (set_attr "mode" "SI")])
10046
10047 (define_split
10048   [(set (match_operand 0 "flags_reg_operand" "")
10049         (match_operator 2 "compare_operator"
10050           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10051            (const_int 0)]))
10052    (set (match_operand:SI 1 "nonimmediate_operand" "")
10053         (not:SI (match_dup 3)))]
10054   "ix86_match_ccmode (insn, CCNOmode)"
10055   [(parallel [(set (match_dup 0)
10056                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057                                     (const_int 0)]))
10058               (set (match_dup 1)
10059                    (xor:SI (match_dup 3) (const_int -1)))])]
10060   "")
10061
10062 ;; ??? Currently never generated - xor is used instead.
10063 (define_insn "*one_cmplsi2_2_zext"
10064   [(set (reg FLAGS_REG)
10065         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10066                  (const_int 0)))
10067    (set (match_operand:DI 0 "register_operand" "=r")
10068         (zero_extend:DI (not:SI (match_dup 1))))]
10069   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10070    && ix86_unary_operator_ok (NOT, SImode, operands)"
10071   "#"
10072   [(set_attr "type" "alu1")
10073    (set_attr "mode" "SI")])
10074
10075 (define_split
10076   [(set (match_operand 0 "flags_reg_operand" "")
10077         (match_operator 2 "compare_operator"
10078           [(not:SI (match_operand:SI 3 "register_operand" ""))
10079            (const_int 0)]))
10080    (set (match_operand:DI 1 "register_operand" "")
10081         (zero_extend:DI (not:SI (match_dup 3))))]
10082   "ix86_match_ccmode (insn, CCNOmode)"
10083   [(parallel [(set (match_dup 0)
10084                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10085                                     (const_int 0)]))
10086               (set (match_dup 1)
10087                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10088   "")
10089
10090 (define_expand "one_cmplhi2"
10091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10092         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10093   "TARGET_HIMODE_MATH"
10094   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10095
10096 (define_insn "*one_cmplhi2_1"
10097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10098         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10099   "ix86_unary_operator_ok (NOT, HImode, operands)"
10100   "not{w}\t%0"
10101   [(set_attr "type" "negnot")
10102    (set_attr "mode" "HI")])
10103
10104 (define_insn "*one_cmplhi2_2"
10105   [(set (reg FLAGS_REG)
10106         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10107                  (const_int 0)))
10108    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10109         (not:HI (match_dup 1)))]
10110   "ix86_match_ccmode (insn, CCNOmode)
10111    && ix86_unary_operator_ok (NEG, HImode, operands)"
10112   "#"
10113   [(set_attr "type" "alu1")
10114    (set_attr "mode" "HI")])
10115
10116 (define_split
10117   [(set (match_operand 0 "flags_reg_operand" "")
10118         (match_operator 2 "compare_operator"
10119           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10120            (const_int 0)]))
10121    (set (match_operand:HI 1 "nonimmediate_operand" "")
10122         (not:HI (match_dup 3)))]
10123   "ix86_match_ccmode (insn, CCNOmode)"
10124   [(parallel [(set (match_dup 0)
10125                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10126                                     (const_int 0)]))
10127               (set (match_dup 1)
10128                    (xor:HI (match_dup 3) (const_int -1)))])]
10129   "")
10130
10131 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10132 (define_expand "one_cmplqi2"
10133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10134         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10135   "TARGET_QIMODE_MATH"
10136   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10137
10138 (define_insn "*one_cmplqi2_1"
10139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10140         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10141   "ix86_unary_operator_ok (NOT, QImode, operands)"
10142   "@
10143    not{b}\t%0
10144    not{l}\t%k0"
10145   [(set_attr "type" "negnot")
10146    (set_attr "mode" "QI,SI")])
10147
10148 (define_insn "*one_cmplqi2_2"
10149   [(set (reg FLAGS_REG)
10150         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10151                  (const_int 0)))
10152    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10153         (not:QI (match_dup 1)))]
10154   "ix86_match_ccmode (insn, CCNOmode)
10155    && ix86_unary_operator_ok (NOT, QImode, operands)"
10156   "#"
10157   [(set_attr "type" "alu1")
10158    (set_attr "mode" "QI")])
10159
10160 (define_split
10161   [(set (match_operand 0 "flags_reg_operand" "")
10162         (match_operator 2 "compare_operator"
10163           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10164            (const_int 0)]))
10165    (set (match_operand:QI 1 "nonimmediate_operand" "")
10166         (not:QI (match_dup 3)))]
10167   "ix86_match_ccmode (insn, CCNOmode)"
10168   [(parallel [(set (match_dup 0)
10169                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10170                                     (const_int 0)]))
10171               (set (match_dup 1)
10172                    (xor:QI (match_dup 3) (const_int -1)))])]
10173   "")
10174 \f
10175 ;; Arithmetic shift instructions
10176
10177 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10178 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10179 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10180 ;; from the assembler input.
10181 ;;
10182 ;; This instruction shifts the target reg/mem as usual, but instead of
10183 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10184 ;; is a left shift double, bits are taken from the high order bits of
10185 ;; reg, else if the insn is a shift right double, bits are taken from the
10186 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10187 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10188 ;;
10189 ;; Since sh[lr]d does not change the `reg' operand, that is done
10190 ;; separately, making all shifts emit pairs of shift double and normal
10191 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10192 ;; support a 63 bit shift, each shift where the count is in a reg expands
10193 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10194 ;;
10195 ;; If the shift count is a constant, we need never emit more than one
10196 ;; shift pair, instead using moves and sign extension for counts greater
10197 ;; than 31.
10198
10199 (define_expand "ashlti3"
10200   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10201                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10202                               (match_operand:QI 2 "nonmemory_operand" "")))
10203               (clobber (reg:CC FLAGS_REG))])]
10204   "TARGET_64BIT"
10205 {
10206   if (! immediate_operand (operands[2], QImode))
10207     {
10208       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10209       DONE;
10210     }
10211   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10212   DONE;
10213 })
10214
10215 (define_insn "ashlti3_1"
10216   [(set (match_operand:TI 0 "register_operand" "=r")
10217         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10218                    (match_operand:QI 2 "register_operand" "c")))
10219    (clobber (match_scratch:DI 3 "=&r"))
10220    (clobber (reg:CC FLAGS_REG))]
10221   "TARGET_64BIT"
10222   "#"
10223   [(set_attr "type" "multi")])
10224
10225 (define_insn "*ashlti3_2"
10226   [(set (match_operand:TI 0 "register_operand" "=r")
10227         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10228                    (match_operand:QI 2 "immediate_operand" "O")))
10229    (clobber (reg:CC FLAGS_REG))]
10230   "TARGET_64BIT"
10231   "#"
10232   [(set_attr "type" "multi")])
10233
10234 (define_split
10235   [(set (match_operand:TI 0 "register_operand" "")
10236         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10237                    (match_operand:QI 2 "register_operand" "")))
10238    (clobber (match_scratch:DI 3 ""))
10239    (clobber (reg:CC FLAGS_REG))]
10240   "TARGET_64BIT && reload_completed"
10241   [(const_int 0)]
10242   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10243
10244 (define_split
10245   [(set (match_operand:TI 0 "register_operand" "")
10246         (ashift:TI (match_operand:TI 1 "register_operand" "")
10247                    (match_operand:QI 2 "immediate_operand" "")))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "TARGET_64BIT && reload_completed"
10250   [(const_int 0)]
10251   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10252
10253 (define_insn "x86_64_shld"
10254   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10255         (ior:DI (ashift:DI (match_dup 0)
10256                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10257                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10258                   (minus:QI (const_int 64) (match_dup 2)))))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_64BIT"
10261   "@
10262    shld{q}\t{%2, %1, %0|%0, %1, %2}
10263    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10264   [(set_attr "type" "ishift")
10265    (set_attr "prefix_0f" "1")
10266    (set_attr "mode" "DI")
10267    (set_attr "athlon_decode" "vector")])
10268
10269 (define_expand "x86_64_shift_adj"
10270   [(set (reg:CCZ FLAGS_REG)
10271         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10272                              (const_int 64))
10273                      (const_int 0)))
10274    (set (match_operand:DI 0 "register_operand" "")
10275         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10276                          (match_operand:DI 1 "register_operand" "")
10277                          (match_dup 0)))
10278    (set (match_dup 1)
10279         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280                          (match_operand:DI 3 "register_operand" "r")
10281                          (match_dup 1)))]
10282   "TARGET_64BIT"
10283   "")
10284
10285 (define_expand "ashldi3"
10286   [(set (match_operand:DI 0 "shiftdi_operand" "")
10287         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10288                    (match_operand:QI 2 "nonmemory_operand" "")))]
10289   ""
10290   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10291
10292 (define_insn "*ashldi3_1_rex64"
10293   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10294         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10295                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10298 {
10299   switch (get_attr_type (insn))
10300     {
10301     case TYPE_ALU:
10302       gcc_assert (operands[2] == const1_rtx);
10303       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10304       return "add{q}\t{%0, %0|%0, %0}";
10305
10306     case TYPE_LEA:
10307       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10308       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10309       operands[1] = gen_rtx_MULT (DImode, operands[1],
10310                                   GEN_INT (1 << INTVAL (operands[2])));
10311       return "lea{q}\t{%a1, %0|%0, %a1}";
10312
10313     default:
10314       if (REG_P (operands[2]))
10315         return "sal{q}\t{%b2, %0|%0, %b2}";
10316       else if (operands[2] == const1_rtx
10317                && (TARGET_SHIFT1 || optimize_size))
10318         return "sal{q}\t%0";
10319       else
10320         return "sal{q}\t{%2, %0|%0, %2}";
10321     }
10322 }
10323   [(set (attr "type")
10324      (cond [(eq_attr "alternative" "1")
10325               (const_string "lea")
10326             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10327                           (const_int 0))
10328                       (match_operand 0 "register_operand" ""))
10329                  (match_operand 2 "const1_operand" ""))
10330               (const_string "alu")
10331            ]
10332            (const_string "ishift")))
10333    (set_attr "mode" "DI")])
10334
10335 ;; Convert lea to the lea pattern to avoid flags dependency.
10336 (define_split
10337   [(set (match_operand:DI 0 "register_operand" "")
10338         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10339                    (match_operand:QI 2 "immediate_operand" "")))
10340    (clobber (reg:CC FLAGS_REG))]
10341   "TARGET_64BIT && reload_completed
10342    && true_regnum (operands[0]) != true_regnum (operands[1])"
10343   [(set (match_dup 0)
10344         (mult:DI (match_dup 1)
10345                  (match_dup 2)))]
10346   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10347
10348 ;; This pattern can't accept a variable shift count, since shifts by
10349 ;; zero don't affect the flags.  We assume that shifts by constant
10350 ;; zero are optimized away.
10351 (define_insn "*ashldi3_cmp_rex64"
10352   [(set (reg FLAGS_REG)
10353         (compare
10354           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10355                      (match_operand:QI 2 "immediate_operand" "e"))
10356           (const_int 0)))
10357    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10358         (ashift:DI (match_dup 1) (match_dup 2)))]
10359   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10360    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10361 {
10362   switch (get_attr_type (insn))
10363     {
10364     case TYPE_ALU:
10365       gcc_assert (operands[2] == const1_rtx);
10366       return "add{q}\t{%0, %0|%0, %0}";
10367
10368     default:
10369       if (REG_P (operands[2]))
10370         return "sal{q}\t{%b2, %0|%0, %b2}";
10371       else if (operands[2] == const1_rtx
10372                && (TARGET_SHIFT1 || optimize_size))
10373         return "sal{q}\t%0";
10374       else
10375         return "sal{q}\t{%2, %0|%0, %2}";
10376     }
10377 }
10378   [(set (attr "type")
10379      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10380                           (const_int 0))
10381                       (match_operand 0 "register_operand" ""))
10382                  (match_operand 2 "const1_operand" ""))
10383               (const_string "alu")
10384            ]
10385            (const_string "ishift")))
10386    (set_attr "mode" "DI")])
10387
10388 (define_insn "*ashldi3_1"
10389   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10390         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10391                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "!TARGET_64BIT"
10394   "#"
10395   [(set_attr "type" "multi")])
10396
10397 ;; By default we don't ask for a scratch register, because when DImode
10398 ;; values are manipulated, registers are already at a premium.  But if
10399 ;; we have one handy, we won't turn it away.
10400 (define_peephole2
10401   [(match_scratch:SI 3 "r")
10402    (parallel [(set (match_operand:DI 0 "register_operand" "")
10403                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10404                               (match_operand:QI 2 "nonmemory_operand" "")))
10405               (clobber (reg:CC FLAGS_REG))])
10406    (match_dup 3)]
10407   "!TARGET_64BIT && TARGET_CMOVE"
10408   [(const_int 0)]
10409   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10410
10411 (define_split
10412   [(set (match_operand:DI 0 "register_operand" "")
10413         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10414                    (match_operand:QI 2 "nonmemory_operand" "")))
10415    (clobber (reg:CC FLAGS_REG))]
10416   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10417   [(const_int 0)]
10418   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10419
10420 (define_insn "x86_shld_1"
10421   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10422         (ior:SI (ashift:SI (match_dup 0)
10423                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10424                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10425                   (minus:QI (const_int 32) (match_dup 2)))))
10426    (clobber (reg:CC FLAGS_REG))]
10427   ""
10428   "@
10429    shld{l}\t{%2, %1, %0|%0, %1, %2}
10430    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10431   [(set_attr "type" "ishift")
10432    (set_attr "prefix_0f" "1")
10433    (set_attr "mode" "SI")
10434    (set_attr "pent_pair" "np")
10435    (set_attr "athlon_decode" "vector")])
10436
10437 (define_expand "x86_shift_adj_1"
10438   [(set (reg:CCZ FLAGS_REG)
10439         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10440                              (const_int 32))
10441                      (const_int 0)))
10442    (set (match_operand:SI 0 "register_operand" "")
10443         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10444                          (match_operand:SI 1 "register_operand" "")
10445                          (match_dup 0)))
10446    (set (match_dup 1)
10447         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10448                          (match_operand:SI 3 "register_operand" "r")
10449                          (match_dup 1)))]
10450   "TARGET_CMOVE"
10451   "")
10452
10453 (define_expand "x86_shift_adj_2"
10454   [(use (match_operand:SI 0 "register_operand" ""))
10455    (use (match_operand:SI 1 "register_operand" ""))
10456    (use (match_operand:QI 2 "register_operand" ""))]
10457   ""
10458 {
10459   rtx label = gen_label_rtx ();
10460   rtx tmp;
10461
10462   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10463
10464   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10465   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10466   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10467                               gen_rtx_LABEL_REF (VOIDmode, label),
10468                               pc_rtx);
10469   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10470   JUMP_LABEL (tmp) = label;
10471
10472   emit_move_insn (operands[0], operands[1]);
10473   ix86_expand_clear (operands[1]);
10474
10475   emit_label (label);
10476   LABEL_NUSES (label) = 1;
10477
10478   DONE;
10479 })
10480
10481 (define_expand "ashlsi3"
10482   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10483         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10484                    (match_operand:QI 2 "nonmemory_operand" "")))
10485    (clobber (reg:CC FLAGS_REG))]
10486   ""
10487   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10488
10489 (define_insn "*ashlsi3_1"
10490   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10491         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10492                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10495 {
10496   switch (get_attr_type (insn))
10497     {
10498     case TYPE_ALU:
10499       gcc_assert (operands[2] == const1_rtx);
10500       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10501       return "add{l}\t{%0, %0|%0, %0}";
10502
10503     case TYPE_LEA:
10504       return "#";
10505
10506     default:
10507       if (REG_P (operands[2]))
10508         return "sal{l}\t{%b2, %0|%0, %b2}";
10509       else if (operands[2] == const1_rtx
10510                && (TARGET_SHIFT1 || optimize_size))
10511         return "sal{l}\t%0";
10512       else
10513         return "sal{l}\t{%2, %0|%0, %2}";
10514     }
10515 }
10516   [(set (attr "type")
10517      (cond [(eq_attr "alternative" "1")
10518               (const_string "lea")
10519             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520                           (const_int 0))
10521                       (match_operand 0 "register_operand" ""))
10522                  (match_operand 2 "const1_operand" ""))
10523               (const_string "alu")
10524            ]
10525            (const_string "ishift")))
10526    (set_attr "mode" "SI")])
10527
10528 ;; Convert lea to the lea pattern to avoid flags dependency.
10529 (define_split
10530   [(set (match_operand 0 "register_operand" "")
10531         (ashift (match_operand 1 "index_register_operand" "")
10532                 (match_operand:QI 2 "const_int_operand" "")))
10533    (clobber (reg:CC FLAGS_REG))]
10534   "reload_completed
10535    && true_regnum (operands[0]) != true_regnum (operands[1])
10536    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10537   [(const_int 0)]
10538 {
10539   rtx pat;
10540   enum machine_mode mode = GET_MODE (operands[0]);
10541
10542   if (GET_MODE_SIZE (mode) < 4)
10543     operands[0] = gen_lowpart (SImode, operands[0]);
10544   if (mode != Pmode)
10545     operands[1] = gen_lowpart (Pmode, operands[1]);
10546   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10547
10548   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10549   if (Pmode != SImode)
10550     pat = gen_rtx_SUBREG (SImode, pat, 0);
10551   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10552   DONE;
10553 })
10554
10555 ;; Rare case of shifting RSP is handled by generating move and shift
10556 (define_split
10557   [(set (match_operand 0 "register_operand" "")
10558         (ashift (match_operand 1 "register_operand" "")
10559                 (match_operand:QI 2 "const_int_operand" "")))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "reload_completed
10562    && true_regnum (operands[0]) != true_regnum (operands[1])"
10563   [(const_int 0)]
10564 {
10565   rtx pat, clob;
10566   emit_move_insn (operands[1], operands[0]);
10567   pat = gen_rtx_SET (VOIDmode, operands[0],
10568                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10569                                      operands[0], operands[2]));
10570   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10571   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10572   DONE;
10573 })
10574
10575 (define_insn "*ashlsi3_1_zext"
10576   [(set (match_operand:DI 0 "register_operand" "=r,r")
10577         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10578                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10581 {
10582   switch (get_attr_type (insn))
10583     {
10584     case TYPE_ALU:
10585       gcc_assert (operands[2] == const1_rtx);
10586       return "add{l}\t{%k0, %k0|%k0, %k0}";
10587
10588     case TYPE_LEA:
10589       return "#";
10590
10591     default:
10592       if (REG_P (operands[2]))
10593         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10594       else if (operands[2] == const1_rtx
10595                && (TARGET_SHIFT1 || optimize_size))
10596         return "sal{l}\t%k0";
10597       else
10598         return "sal{l}\t{%2, %k0|%k0, %2}";
10599     }
10600 }
10601   [(set (attr "type")
10602      (cond [(eq_attr "alternative" "1")
10603               (const_string "lea")
10604             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10605                      (const_int 0))
10606                  (match_operand 2 "const1_operand" ""))
10607               (const_string "alu")
10608            ]
10609            (const_string "ishift")))
10610    (set_attr "mode" "SI")])
10611
10612 ;; Convert lea to the lea pattern to avoid flags dependency.
10613 (define_split
10614   [(set (match_operand:DI 0 "register_operand" "")
10615         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10616                                 (match_operand:QI 2 "const_int_operand" ""))))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "TARGET_64BIT && reload_completed
10619    && true_regnum (operands[0]) != true_regnum (operands[1])"
10620   [(set (match_dup 0) (zero_extend:DI
10621                         (subreg:SI (mult:SI (match_dup 1)
10622                                             (match_dup 2)) 0)))]
10623 {
10624   operands[1] = gen_lowpart (Pmode, operands[1]);
10625   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10626 })
10627
10628 ;; This pattern can't accept a variable shift count, since shifts by
10629 ;; zero don't affect the flags.  We assume that shifts by constant
10630 ;; zero are optimized away.
10631 (define_insn "*ashlsi3_cmp"
10632   [(set (reg FLAGS_REG)
10633         (compare
10634           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10635                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10636           (const_int 0)))
10637    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10638         (ashift:SI (match_dup 1) (match_dup 2)))]
10639   "ix86_match_ccmode (insn, CCGOCmode)
10640    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10641 {
10642   switch (get_attr_type (insn))
10643     {
10644     case TYPE_ALU:
10645       gcc_assert (operands[2] == const1_rtx);
10646       return "add{l}\t{%0, %0|%0, %0}";
10647
10648     default:
10649       if (REG_P (operands[2]))
10650         return "sal{l}\t{%b2, %0|%0, %b2}";
10651       else if (operands[2] == const1_rtx
10652                && (TARGET_SHIFT1 || optimize_size))
10653         return "sal{l}\t%0";
10654       else
10655         return "sal{l}\t{%2, %0|%0, %2}";
10656     }
10657 }
10658   [(set (attr "type")
10659      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10660                           (const_int 0))
10661                       (match_operand 0 "register_operand" ""))
10662                  (match_operand 2 "const1_operand" ""))
10663               (const_string "alu")
10664            ]
10665            (const_string "ishift")))
10666    (set_attr "mode" "SI")])
10667
10668 (define_insn "*ashlsi3_cmp_zext"
10669   [(set (reg FLAGS_REG)
10670         (compare
10671           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10672                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10673           (const_int 0)))
10674    (set (match_operand:DI 0 "register_operand" "=r")
10675         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10677    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10678 {
10679   switch (get_attr_type (insn))
10680     {
10681     case TYPE_ALU:
10682       gcc_assert (operands[2] == const1_rtx);
10683       return "add{l}\t{%k0, %k0|%k0, %k0}";
10684
10685     default:
10686       if (REG_P (operands[2]))
10687         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10688       else if (operands[2] == const1_rtx
10689                && (TARGET_SHIFT1 || optimize_size))
10690         return "sal{l}\t%k0";
10691       else
10692         return "sal{l}\t{%2, %k0|%k0, %2}";
10693     }
10694 }
10695   [(set (attr "type")
10696      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697                      (const_int 0))
10698                  (match_operand 2 "const1_operand" ""))
10699               (const_string "alu")
10700            ]
10701            (const_string "ishift")))
10702    (set_attr "mode" "SI")])
10703
10704 (define_expand "ashlhi3"
10705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10706         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10707                    (match_operand:QI 2 "nonmemory_operand" "")))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_HIMODE_MATH"
10710   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10711
10712 (define_insn "*ashlhi3_1_lea"
10713   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10714         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10715                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10716    (clobber (reg:CC FLAGS_REG))]
10717   "!TARGET_PARTIAL_REG_STALL
10718    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10719 {
10720   switch (get_attr_type (insn))
10721     {
10722     case TYPE_LEA:
10723       return "#";
10724     case TYPE_ALU:
10725       gcc_assert (operands[2] == const1_rtx);
10726       return "add{w}\t{%0, %0|%0, %0}";
10727
10728     default:
10729       if (REG_P (operands[2]))
10730         return "sal{w}\t{%b2, %0|%0, %b2}";
10731       else if (operands[2] == const1_rtx
10732                && (TARGET_SHIFT1 || optimize_size))
10733         return "sal{w}\t%0";
10734       else
10735         return "sal{w}\t{%2, %0|%0, %2}";
10736     }
10737 }
10738   [(set (attr "type")
10739      (cond [(eq_attr "alternative" "1")
10740               (const_string "lea")
10741             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10742                           (const_int 0))
10743                       (match_operand 0 "register_operand" ""))
10744                  (match_operand 2 "const1_operand" ""))
10745               (const_string "alu")
10746            ]
10747            (const_string "ishift")))
10748    (set_attr "mode" "HI,SI")])
10749
10750 (define_insn "*ashlhi3_1"
10751   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10752         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10753                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10754    (clobber (reg:CC FLAGS_REG))]
10755   "TARGET_PARTIAL_REG_STALL
10756    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10757 {
10758   switch (get_attr_type (insn))
10759     {
10760     case TYPE_ALU:
10761       gcc_assert (operands[2] == const1_rtx);
10762       return "add{w}\t{%0, %0|%0, %0}";
10763
10764     default:
10765       if (REG_P (operands[2]))
10766         return "sal{w}\t{%b2, %0|%0, %b2}";
10767       else if (operands[2] == const1_rtx
10768                && (TARGET_SHIFT1 || optimize_size))
10769         return "sal{w}\t%0";
10770       else
10771         return "sal{w}\t{%2, %0|%0, %2}";
10772     }
10773 }
10774   [(set (attr "type")
10775      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10776                           (const_int 0))
10777                       (match_operand 0 "register_operand" ""))
10778                  (match_operand 2 "const1_operand" ""))
10779               (const_string "alu")
10780            ]
10781            (const_string "ishift")))
10782    (set_attr "mode" "HI")])
10783
10784 ;; This pattern can't accept a variable shift count, since shifts by
10785 ;; zero don't affect the flags.  We assume that shifts by constant
10786 ;; zero are optimized away.
10787 (define_insn "*ashlhi3_cmp"
10788   [(set (reg FLAGS_REG)
10789         (compare
10790           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10791                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10792           (const_int 0)))
10793    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10794         (ashift:HI (match_dup 1) (match_dup 2)))]
10795   "ix86_match_ccmode (insn, CCGOCmode)
10796    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797 {
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       gcc_assert (operands[2] == const1_rtx);
10802       return "add{w}\t{%0, %0|%0, %0}";
10803
10804     default:
10805       if (REG_P (operands[2]))
10806         return "sal{w}\t{%b2, %0|%0, %b2}";
10807       else if (operands[2] == const1_rtx
10808                && (TARGET_SHIFT1 || optimize_size))
10809         return "sal{w}\t%0";
10810       else
10811         return "sal{w}\t{%2, %0|%0, %2}";
10812     }
10813 }
10814   [(set (attr "type")
10815      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "HI")])
10823
10824 (define_expand "ashlqi3"
10825   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10826         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10827                    (match_operand:QI 2 "nonmemory_operand" "")))
10828    (clobber (reg:CC FLAGS_REG))]
10829   "TARGET_QIMODE_MATH"
10830   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10831
10832 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10833
10834 (define_insn "*ashlqi3_1_lea"
10835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10836         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10837                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "!TARGET_PARTIAL_REG_STALL
10840    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10841 {
10842   switch (get_attr_type (insn))
10843     {
10844     case TYPE_LEA:
10845       return "#";
10846     case TYPE_ALU:
10847       gcc_assert (operands[2] == const1_rtx);
10848       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10849         return "add{l}\t{%k0, %k0|%k0, %k0}";
10850       else
10851         return "add{b}\t{%0, %0|%0, %0}";
10852
10853     default:
10854       if (REG_P (operands[2]))
10855         {
10856           if (get_attr_mode (insn) == MODE_SI)
10857             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10858           else
10859             return "sal{b}\t{%b2, %0|%0, %b2}";
10860         }
10861       else if (operands[2] == const1_rtx
10862                && (TARGET_SHIFT1 || optimize_size))
10863         {
10864           if (get_attr_mode (insn) == MODE_SI)
10865             return "sal{l}\t%0";
10866           else
10867             return "sal{b}\t%0";
10868         }
10869       else
10870         {
10871           if (get_attr_mode (insn) == MODE_SI)
10872             return "sal{l}\t{%2, %k0|%k0, %2}";
10873           else
10874             return "sal{b}\t{%2, %0|%0, %2}";
10875         }
10876     }
10877 }
10878   [(set (attr "type")
10879      (cond [(eq_attr "alternative" "2")
10880               (const_string "lea")
10881             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10882                           (const_int 0))
10883                       (match_operand 0 "register_operand" ""))
10884                  (match_operand 2 "const1_operand" ""))
10885               (const_string "alu")
10886            ]
10887            (const_string "ishift")))
10888    (set_attr "mode" "QI,SI,SI")])
10889
10890 (define_insn "*ashlqi3_1"
10891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10892         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10893                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_PARTIAL_REG_STALL
10896    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10897 {
10898   switch (get_attr_type (insn))
10899     {
10900     case TYPE_ALU:
10901       gcc_assert (operands[2] == const1_rtx);
10902       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10903         return "add{l}\t{%k0, %k0|%k0, %k0}";
10904       else
10905         return "add{b}\t{%0, %0|%0, %0}";
10906
10907     default:
10908       if (REG_P (operands[2]))
10909         {
10910           if (get_attr_mode (insn) == MODE_SI)
10911             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10912           else
10913             return "sal{b}\t{%b2, %0|%0, %b2}";
10914         }
10915       else if (operands[2] == const1_rtx
10916                && (TARGET_SHIFT1 || optimize_size))
10917         {
10918           if (get_attr_mode (insn) == MODE_SI)
10919             return "sal{l}\t%0";
10920           else
10921             return "sal{b}\t%0";
10922         }
10923       else
10924         {
10925           if (get_attr_mode (insn) == MODE_SI)
10926             return "sal{l}\t{%2, %k0|%k0, %2}";
10927           else
10928             return "sal{b}\t{%2, %0|%0, %2}";
10929         }
10930     }
10931 }
10932   [(set (attr "type")
10933      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934                           (const_int 0))
10935                       (match_operand 0 "register_operand" ""))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "QI,SI")])
10941
10942 ;; This pattern can't accept a variable shift count, since shifts by
10943 ;; zero don't affect the flags.  We assume that shifts by constant
10944 ;; zero are optimized away.
10945 (define_insn "*ashlqi3_cmp"
10946   [(set (reg FLAGS_REG)
10947         (compare
10948           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10949                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10950           (const_int 0)))
10951    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10952         (ashift:QI (match_dup 1) (match_dup 2)))]
10953   "ix86_match_ccmode (insn, CCGOCmode)
10954    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10955 {
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       return "add{b}\t{%0, %0|%0, %0}";
10961
10962     default:
10963       if (REG_P (operands[2]))
10964         return "sal{b}\t{%b2, %0|%0, %b2}";
10965       else if (operands[2] == const1_rtx
10966                && (TARGET_SHIFT1 || optimize_size))
10967         return "sal{b}\t%0";
10968       else
10969         return "sal{b}\t{%2, %0|%0, %2}";
10970     }
10971 }
10972   [(set (attr "type")
10973      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974                           (const_int 0))
10975                       (match_operand 0 "register_operand" ""))
10976                  (match_operand 2 "const1_operand" ""))
10977               (const_string "alu")
10978            ]
10979            (const_string "ishift")))
10980    (set_attr "mode" "QI")])
10981
10982 ;; See comment above `ashldi3' about how this works.
10983
10984 (define_expand "ashrti3"
10985   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10986                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10987                                 (match_operand:QI 2 "nonmemory_operand" "")))
10988               (clobber (reg:CC FLAGS_REG))])]
10989   "TARGET_64BIT"
10990 {
10991   if (! immediate_operand (operands[2], QImode))
10992     {
10993       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10994       DONE;
10995     }
10996   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
10997   DONE;
10998 })
10999
11000 (define_insn "ashrti3_1"
11001   [(set (match_operand:TI 0 "register_operand" "=r")
11002         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11003                      (match_operand:QI 2 "register_operand" "c")))
11004    (clobber (match_scratch:DI 3 "=&r"))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "TARGET_64BIT"
11007   "#"
11008   [(set_attr "type" "multi")])
11009
11010 (define_insn "*ashrti3_2"
11011   [(set (match_operand:TI 0 "register_operand" "=r")
11012         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11013                      (match_operand:QI 2 "immediate_operand" "O")))
11014    (clobber (reg:CC FLAGS_REG))]
11015   "TARGET_64BIT"
11016   "#"
11017   [(set_attr "type" "multi")])
11018
11019 (define_split
11020   [(set (match_operand:TI 0 "register_operand" "")
11021         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11022                      (match_operand:QI 2 "register_operand" "")))
11023    (clobber (match_scratch:DI 3 ""))
11024    (clobber (reg:CC FLAGS_REG))]
11025   "TARGET_64BIT && reload_completed"
11026   [(const_int 0)]
11027   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11028
11029 (define_split
11030   [(set (match_operand:TI 0 "register_operand" "")
11031         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11032                      (match_operand:QI 2 "immediate_operand" "")))
11033    (clobber (reg:CC FLAGS_REG))]
11034   "TARGET_64BIT && reload_completed"
11035   [(const_int 0)]
11036   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11037
11038 (define_insn "x86_64_shrd"
11039   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11040         (ior:DI (ashiftrt:DI (match_dup 0)
11041                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11042                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11043                   (minus:QI (const_int 64) (match_dup 2)))))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT"
11046   "@
11047    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11048    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11049   [(set_attr "type" "ishift")
11050    (set_attr "prefix_0f" "1")
11051    (set_attr "mode" "DI")
11052    (set_attr "athlon_decode" "vector")])
11053
11054 (define_expand "ashrdi3"
11055   [(set (match_operand:DI 0 "shiftdi_operand" "")
11056         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11057                      (match_operand:QI 2 "nonmemory_operand" "")))]
11058   ""
11059   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11060
11061 (define_insn "*ashrdi3_63_rex64"
11062   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11063         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11064                      (match_operand:DI 2 "const_int_operand" "i,i")))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "TARGET_64BIT && INTVAL (operands[2]) == 63
11067    && (TARGET_USE_CLTD || optimize_size)
11068    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11069   "@
11070    {cqto|cqo}
11071    sar{q}\t{%2, %0|%0, %2}"
11072   [(set_attr "type" "imovx,ishift")
11073    (set_attr "prefix_0f" "0,*")
11074    (set_attr "length_immediate" "0,*")
11075    (set_attr "modrm" "0,1")
11076    (set_attr "mode" "DI")])
11077
11078 (define_insn "*ashrdi3_1_one_bit_rex64"
11079   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11080         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11081                      (match_operand:QI 2 "const1_operand" "")))
11082    (clobber (reg:CC FLAGS_REG))]
11083   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11084    && (TARGET_SHIFT1 || optimize_size)"
11085   "sar{q}\t%0"
11086   [(set_attr "type" "ishift")
11087    (set (attr "length") 
11088      (if_then_else (match_operand:DI 0 "register_operand" "") 
11089         (const_string "2")
11090         (const_string "*")))])
11091
11092 (define_insn "*ashrdi3_1_rex64"
11093   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11094         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11095                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11098   "@
11099    sar{q}\t{%2, %0|%0, %2}
11100    sar{q}\t{%b2, %0|%0, %b2}"
11101   [(set_attr "type" "ishift")
11102    (set_attr "mode" "DI")])
11103
11104 ;; This pattern can't accept a variable shift count, since shifts by
11105 ;; zero don't affect the flags.  We assume that shifts by constant
11106 ;; zero are optimized away.
11107 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11108   [(set (reg FLAGS_REG)
11109         (compare
11110           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11111                        (match_operand:QI 2 "const1_operand" ""))
11112           (const_int 0)))
11113    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11114         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11115   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11116    && (TARGET_SHIFT1 || optimize_size)
11117    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11118   "sar{q}\t%0"
11119   [(set_attr "type" "ishift")
11120    (set (attr "length") 
11121      (if_then_else (match_operand:DI 0 "register_operand" "") 
11122         (const_string "2")
11123         (const_string "*")))])
11124
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags.  We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashrdi3_cmp_rex64"
11129   [(set (reg FLAGS_REG)
11130         (compare
11131           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11132                        (match_operand:QI 2 "const_int_operand" "n"))
11133           (const_int 0)))
11134    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11135         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11136   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11137    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138   "sar{q}\t{%2, %0|%0, %2}"
11139   [(set_attr "type" "ishift")
11140    (set_attr "mode" "DI")])
11141
11142 (define_insn "*ashrdi3_1"
11143   [(set (match_operand:DI 0 "register_operand" "=r")
11144         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11145                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11146    (clobber (reg:CC FLAGS_REG))]
11147   "!TARGET_64BIT"
11148   "#"
11149   [(set_attr "type" "multi")])
11150
11151 ;; By default we don't ask for a scratch register, because when DImode
11152 ;; values are manipulated, registers are already at a premium.  But if
11153 ;; we have one handy, we won't turn it away.
11154 (define_peephole2
11155   [(match_scratch:SI 3 "r")
11156    (parallel [(set (match_operand:DI 0 "register_operand" "")
11157                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11158                                 (match_operand:QI 2 "nonmemory_operand" "")))
11159               (clobber (reg:CC FLAGS_REG))])
11160    (match_dup 3)]
11161   "!TARGET_64BIT && TARGET_CMOVE"
11162   [(const_int 0)]
11163   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11164
11165 (define_split
11166   [(set (match_operand:DI 0 "register_operand" "")
11167         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11168                      (match_operand:QI 2 "nonmemory_operand" "")))
11169    (clobber (reg:CC FLAGS_REG))]
11170   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11171   [(const_int 0)]
11172   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11173
11174 (define_insn "x86_shrd_1"
11175   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176         (ior:SI (ashiftrt:SI (match_dup 0)
11177                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11179                   (minus:QI (const_int 32) (match_dup 2)))))
11180    (clobber (reg:CC FLAGS_REG))]
11181   ""
11182   "@
11183    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11184    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11185   [(set_attr "type" "ishift")
11186    (set_attr "prefix_0f" "1")
11187    (set_attr "pent_pair" "np")
11188    (set_attr "mode" "SI")])
11189
11190 (define_expand "x86_shift_adj_3"
11191   [(use (match_operand:SI 0 "register_operand" ""))
11192    (use (match_operand:SI 1 "register_operand" ""))
11193    (use (match_operand:QI 2 "register_operand" ""))]
11194   ""
11195 {
11196   rtx label = gen_label_rtx ();
11197   rtx tmp;
11198
11199   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11200
11201   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11202   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11203   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11204                               gen_rtx_LABEL_REF (VOIDmode, label),
11205                               pc_rtx);
11206   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11207   JUMP_LABEL (tmp) = label;
11208
11209   emit_move_insn (operands[0], operands[1]);
11210   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11211
11212   emit_label (label);
11213   LABEL_NUSES (label) = 1;
11214
11215   DONE;
11216 })
11217
11218 (define_insn "ashrsi3_31"
11219   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11220         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11221                      (match_operand:SI 2 "const_int_operand" "i,i")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11224    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11225   "@
11226    {cltd|cdq}
11227    sar{l}\t{%2, %0|%0, %2}"
11228   [(set_attr "type" "imovx,ishift")
11229    (set_attr "prefix_0f" "0,*")
11230    (set_attr "length_immediate" "0,*")
11231    (set_attr "modrm" "0,1")
11232    (set_attr "mode" "SI")])
11233
11234 (define_insn "*ashrsi3_31_zext"
11235   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11236         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11237                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11240    && INTVAL (operands[2]) == 31
11241    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11242   "@
11243    {cltd|cdq}
11244    sar{l}\t{%2, %k0|%k0, %2}"
11245   [(set_attr "type" "imovx,ishift")
11246    (set_attr "prefix_0f" "0,*")
11247    (set_attr "length_immediate" "0,*")
11248    (set_attr "modrm" "0,1")
11249    (set_attr "mode" "SI")])
11250
11251 (define_expand "ashrsi3"
11252   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11253         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11254                      (match_operand:QI 2 "nonmemory_operand" "")))
11255    (clobber (reg:CC FLAGS_REG))]
11256   ""
11257   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11258
11259 (define_insn "*ashrsi3_1_one_bit"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11262                      (match_operand:QI 2 "const1_operand" "")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11265    && (TARGET_SHIFT1 || optimize_size)"
11266   "sar{l}\t%0"
11267   [(set_attr "type" "ishift")
11268    (set (attr "length") 
11269      (if_then_else (match_operand:SI 0 "register_operand" "") 
11270         (const_string "2")
11271         (const_string "*")))])
11272
11273 (define_insn "*ashrsi3_1_one_bit_zext"
11274   [(set (match_operand:DI 0 "register_operand" "=r")
11275         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11276                                      (match_operand:QI 2 "const1_operand" ""))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11279    && (TARGET_SHIFT1 || optimize_size)"
11280   "sar{l}\t%k0"
11281   [(set_attr "type" "ishift")
11282    (set_attr "length" "2")])
11283
11284 (define_insn "*ashrsi3_1"
11285   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11286         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11287                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11290   "@
11291    sar{l}\t{%2, %0|%0, %2}
11292    sar{l}\t{%b2, %0|%0, %b2}"
11293   [(set_attr "type" "ishift")
11294    (set_attr "mode" "SI")])
11295
11296 (define_insn "*ashrsi3_1_zext"
11297   [(set (match_operand:DI 0 "register_operand" "=r,r")
11298         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11299                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11302   "@
11303    sar{l}\t{%2, %k0|%k0, %2}
11304    sar{l}\t{%b2, %k0|%k0, %b2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "SI")])
11307
11308 ;; This pattern can't accept a variable shift count, since shifts by
11309 ;; zero don't affect the flags.  We assume that shifts by constant
11310 ;; zero are optimized away.
11311 (define_insn "*ashrsi3_one_bit_cmp"
11312   [(set (reg FLAGS_REG)
11313         (compare
11314           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11315                        (match_operand:QI 2 "const1_operand" ""))
11316           (const_int 0)))
11317    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11318         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11319   "ix86_match_ccmode (insn, CCGOCmode)
11320    && (TARGET_SHIFT1 || optimize_size)
11321    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11322   "sar{l}\t%0"
11323   [(set_attr "type" "ishift")
11324    (set (attr "length") 
11325      (if_then_else (match_operand:SI 0 "register_operand" "") 
11326         (const_string "2")
11327         (const_string "*")))])
11328
11329 (define_insn "*ashrsi3_one_bit_cmp_zext"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11333                        (match_operand:QI 2 "const1_operand" ""))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "register_operand" "=r")
11336         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11338    && (TARGET_SHIFT1 || optimize_size)
11339    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11340   "sar{l}\t%k0"
11341   [(set_attr "type" "ishift")
11342    (set_attr "length" "2")])
11343
11344 ;; This pattern can't accept a variable shift count, since shifts by
11345 ;; zero don't affect the flags.  We assume that shifts by constant
11346 ;; zero are optimized away.
11347 (define_insn "*ashrsi3_cmp"
11348   [(set (reg FLAGS_REG)
11349         (compare
11350           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11351                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11352           (const_int 0)))
11353    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11354         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11355   "ix86_match_ccmode (insn, CCGOCmode)
11356    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11357   "sar{l}\t{%2, %0|%0, %2}"
11358   [(set_attr "type" "ishift")
11359    (set_attr "mode" "SI")])
11360
11361 (define_insn "*ashrsi3_cmp_zext"
11362   [(set (reg FLAGS_REG)
11363         (compare
11364           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11365                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11366           (const_int 0)))
11367    (set (match_operand:DI 0 "register_operand" "=r")
11368         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11369   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11370    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11371   "sar{l}\t{%2, %k0|%k0, %2}"
11372   [(set_attr "type" "ishift")
11373    (set_attr "mode" "SI")])
11374
11375 (define_expand "ashrhi3"
11376   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11377         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_HIMODE_MATH"
11381   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11382
11383 (define_insn "*ashrhi3_1_one_bit"
11384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "sar{w}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11396
11397 (define_insn "*ashrhi3_1"
11398   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11399         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11400                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11403   "@
11404    sar{w}\t{%2, %0|%0, %2}
11405    sar{w}\t{%b2, %0|%0, %b2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "HI")])
11408
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags.  We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrhi3_one_bit_cmp"
11413   [(set (reg FLAGS_REG)
11414         (compare
11415           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11416                        (match_operand:QI 2 "const1_operand" ""))
11417           (const_int 0)))
11418    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11419         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11420   "ix86_match_ccmode (insn, CCGOCmode)
11421    && (TARGET_SHIFT1 || optimize_size)
11422    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11423   "sar{w}\t%0"
11424   [(set_attr "type" "ishift")
11425    (set (attr "length") 
11426      (if_then_else (match_operand 0 "register_operand" "") 
11427         (const_string "2")
11428         (const_string "*")))])
11429
11430 ;; This pattern can't accept a variable shift count, since shifts by
11431 ;; zero don't affect the flags.  We assume that shifts by constant
11432 ;; zero are optimized away.
11433 (define_insn "*ashrhi3_cmp"
11434   [(set (reg FLAGS_REG)
11435         (compare
11436           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11437                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11438           (const_int 0)))
11439    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11440         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11441   "ix86_match_ccmode (insn, CCGOCmode)
11442    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443   "sar{w}\t{%2, %0|%0, %2}"
11444   [(set_attr "type" "ishift")
11445    (set_attr "mode" "HI")])
11446
11447 (define_expand "ashrqi3"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11449         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11450                      (match_operand:QI 2 "nonmemory_operand" "")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_QIMODE_MATH"
11453   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11454
11455 (define_insn "*ashrqi3_1_one_bit"
11456   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11457         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11458                      (match_operand:QI 2 "const1_operand" "")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11461    && (TARGET_SHIFT1 || optimize_size)"
11462   "sar{b}\t%0"
11463   [(set_attr "type" "ishift")
11464    (set (attr "length") 
11465      (if_then_else (match_operand 0 "register_operand" "") 
11466         (const_string "2")
11467         (const_string "*")))])
11468
11469 (define_insn "*ashrqi3_1_one_bit_slp"
11470   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11471         (ashiftrt:QI (match_dup 0)
11472                      (match_operand:QI 1 "const1_operand" "")))
11473    (clobber (reg:CC FLAGS_REG))]
11474   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11475    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11476    && (TARGET_SHIFT1 || optimize_size)"
11477   "sar{b}\t%0"
11478   [(set_attr "type" "ishift1")
11479    (set (attr "length") 
11480      (if_then_else (match_operand 0 "register_operand" "") 
11481         (const_string "2")
11482         (const_string "*")))])
11483
11484 (define_insn "*ashrqi3_1"
11485   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11486         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11487                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11490   "@
11491    sar{b}\t{%2, %0|%0, %2}
11492    sar{b}\t{%b2, %0|%0, %b2}"
11493   [(set_attr "type" "ishift")
11494    (set_attr "mode" "QI")])
11495
11496 (define_insn "*ashrqi3_1_slp"
11497   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11498         (ashiftrt:QI (match_dup 0)
11499                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11502    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11503   "@
11504    sar{b}\t{%1, %0|%0, %1}
11505    sar{b}\t{%b1, %0|%0, %b1}"
11506   [(set_attr "type" "ishift1")
11507    (set_attr "mode" "QI")])
11508
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags.  We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*ashrqi3_one_bit_cmp"
11513   [(set (reg FLAGS_REG)
11514         (compare
11515           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11516                        (match_operand:QI 2 "const1_operand" "I"))
11517           (const_int 0)))
11518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11519         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11520   "ix86_match_ccmode (insn, CCGOCmode)
11521    && (TARGET_SHIFT1 || optimize_size)
11522    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11523   "sar{b}\t%0"
11524   [(set_attr "type" "ishift")
11525    (set (attr "length") 
11526      (if_then_else (match_operand 0 "register_operand" "") 
11527         (const_string "2")
11528         (const_string "*")))])
11529
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags.  We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*ashrqi3_cmp"
11534   [(set (reg FLAGS_REG)
11535         (compare
11536           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11537                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11538           (const_int 0)))
11539    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11540         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11541   "ix86_match_ccmode (insn, CCGOCmode)
11542    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11543   "sar{b}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "ishift")
11545    (set_attr "mode" "QI")])
11546 \f
11547 ;; Logical shift instructions
11548
11549 ;; See comment above `ashldi3' about how this works.
11550
11551 (define_expand "lshrti3"
11552   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11553                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11554                                 (match_operand:QI 2 "nonmemory_operand" "")))
11555               (clobber (reg:CC FLAGS_REG))])]
11556   "TARGET_64BIT"
11557 {
11558   if (! immediate_operand (operands[2], QImode))
11559     {
11560       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11561       DONE;
11562     }
11563   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11564   DONE;
11565 })
11566
11567 (define_insn "lshrti3_1"
11568   [(set (match_operand:TI 0 "register_operand" "=r")
11569         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11570                      (match_operand:QI 2 "register_operand" "c")))
11571    (clobber (match_scratch:DI 3 "=&r"))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "TARGET_64BIT"
11574   "#"
11575   [(set_attr "type" "multi")])
11576
11577 (define_insn "*lshrti3_2"
11578   [(set (match_operand:TI 0 "register_operand" "=r")
11579         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580                      (match_operand:QI 2 "immediate_operand" "O")))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11585
11586 (define_split 
11587   [(set (match_operand:TI 0 "register_operand" "")
11588         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11589                      (match_operand:QI 2 "register_operand" "")))
11590    (clobber (match_scratch:DI 3 ""))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT && reload_completed"
11593   [(const_int 0)]
11594   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11595
11596 (define_split 
11597   [(set (match_operand:TI 0 "register_operand" "")
11598         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599                      (match_operand:QI 2 "immediate_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11604
11605 (define_expand "lshrdi3"
11606   [(set (match_operand:DI 0 "shiftdi_operand" "")
11607         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11608                      (match_operand:QI 2 "nonmemory_operand" "")))]
11609   ""
11610   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11611
11612 (define_insn "*lshrdi3_1_one_bit_rex64"
11613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11614         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11615                      (match_operand:QI 2 "const1_operand" "")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11618    && (TARGET_SHIFT1 || optimize_size)"
11619   "shr{q}\t%0"
11620   [(set_attr "type" "ishift")
11621    (set (attr "length") 
11622      (if_then_else (match_operand:DI 0 "register_operand" "") 
11623         (const_string "2")
11624         (const_string "*")))])
11625
11626 (define_insn "*lshrdi3_1_rex64"
11627   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11628         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11629                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11632   "@
11633    shr{q}\t{%2, %0|%0, %2}
11634    shr{q}\t{%b2, %0|%0, %b2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "DI")])
11637
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags.  We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11642   [(set (reg FLAGS_REG)
11643         (compare
11644           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11645                        (match_operand:QI 2 "const1_operand" ""))
11646           (const_int 0)))
11647    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11648         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11649   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650    && (TARGET_SHIFT1 || optimize_size)
11651    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11652   "shr{q}\t%0"
11653   [(set_attr "type" "ishift")
11654    (set (attr "length") 
11655      (if_then_else (match_operand:DI 0 "register_operand" "") 
11656         (const_string "2")
11657         (const_string "*")))])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*lshrdi3_cmp_rex64"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_int_operand" "e"))
11667           (const_int 0)))
11668    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672   "shr{q}\t{%2, %0|%0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "DI")])
11675
11676 (define_insn "*lshrdi3_1"
11677   [(set (match_operand:DI 0 "register_operand" "=r")
11678         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11679                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "!TARGET_64BIT"
11682   "#"
11683   [(set_attr "type" "multi")])
11684
11685 ;; By default we don't ask for a scratch register, because when DImode
11686 ;; values are manipulated, registers are already at a premium.  But if
11687 ;; we have one handy, we won't turn it away.
11688 (define_peephole2
11689   [(match_scratch:SI 3 "r")
11690    (parallel [(set (match_operand:DI 0 "register_operand" "")
11691                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11692                                 (match_operand:QI 2 "nonmemory_operand" "")))
11693               (clobber (reg:CC FLAGS_REG))])
11694    (match_dup 3)]
11695   "!TARGET_64BIT && TARGET_CMOVE"
11696   [(const_int 0)]
11697   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11698
11699 (define_split 
11700   [(set (match_operand:DI 0 "register_operand" "")
11701         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702                      (match_operand:QI 2 "nonmemory_operand" "")))
11703    (clobber (reg:CC FLAGS_REG))]
11704   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11705   [(const_int 0)]
11706   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11707
11708 (define_expand "lshrsi3"
11709   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11710         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11711                      (match_operand:QI 2 "nonmemory_operand" "")))
11712    (clobber (reg:CC FLAGS_REG))]
11713   ""
11714   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11715
11716 (define_insn "*lshrsi3_1_one_bit"
11717   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11718         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11719                      (match_operand:QI 2 "const1_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11722    && (TARGET_SHIFT1 || optimize_size)"
11723   "shr{l}\t%0"
11724   [(set_attr "type" "ishift")
11725    (set (attr "length") 
11726      (if_then_else (match_operand:SI 0 "register_operand" "") 
11727         (const_string "2")
11728         (const_string "*")))])
11729
11730 (define_insn "*lshrsi3_1_one_bit_zext"
11731   [(set (match_operand:DI 0 "register_operand" "=r")
11732         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11733                      (match_operand:QI 2 "const1_operand" "")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "shr{l}\t%k0"
11738   [(set_attr "type" "ishift")
11739    (set_attr "length" "2")])
11740
11741 (define_insn "*lshrsi3_1"
11742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11743         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11744                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11747   "@
11748    shr{l}\t{%2, %0|%0, %2}
11749    shr{l}\t{%b2, %0|%0, %b2}"
11750   [(set_attr "type" "ishift")
11751    (set_attr "mode" "SI")])
11752
11753 (define_insn "*lshrsi3_1_zext"
11754   [(set (match_operand:DI 0 "register_operand" "=r,r")
11755         (zero_extend:DI
11756           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11757                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11760   "@
11761    shr{l}\t{%2, %k0|%k0, %2}
11762    shr{l}\t{%b2, %k0|%k0, %b2}"
11763   [(set_attr "type" "ishift")
11764    (set_attr "mode" "SI")])
11765
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags.  We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*lshrsi3_one_bit_cmp"
11770   [(set (reg FLAGS_REG)
11771         (compare
11772           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11773                        (match_operand:QI 2 "const1_operand" ""))
11774           (const_int 0)))
11775    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11776         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11777   "ix86_match_ccmode (insn, CCGOCmode)
11778    && (TARGET_SHIFT1 || optimize_size)
11779    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11780   "shr{l}\t%0"
11781   [(set_attr "type" "ishift")
11782    (set (attr "length") 
11783      (if_then_else (match_operand:SI 0 "register_operand" "") 
11784         (const_string "2")
11785         (const_string "*")))])
11786
11787 (define_insn "*lshrsi3_cmp_one_bit_zext"
11788   [(set (reg FLAGS_REG)
11789         (compare
11790           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11791                        (match_operand:QI 2 "const1_operand" ""))
11792           (const_int 0)))
11793    (set (match_operand:DI 0 "register_operand" "=r")
11794         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11795   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11796    && (TARGET_SHIFT1 || optimize_size)
11797    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11798   "shr{l}\t%k0"
11799   [(set_attr "type" "ishift")
11800    (set_attr "length" "2")])
11801
11802 ;; This pattern can't accept a variable shift count, since shifts by
11803 ;; zero don't affect the flags.  We assume that shifts by constant
11804 ;; zero are optimized away.
11805 (define_insn "*lshrsi3_cmp"
11806   [(set (reg FLAGS_REG)
11807         (compare
11808           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11809                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810           (const_int 0)))
11811    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11812         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11813   "ix86_match_ccmode (insn, CCGOCmode)
11814    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11815   "shr{l}\t{%2, %0|%0, %2}"
11816   [(set_attr "type" "ishift")
11817    (set_attr "mode" "SI")])
11818
11819 (define_insn "*lshrsi3_cmp_zext"
11820   [(set (reg FLAGS_REG)
11821         (compare
11822           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11823                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11824           (const_int 0)))
11825    (set (match_operand:DI 0 "register_operand" "=r")
11826         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11827   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11828    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11829   "shr{l}\t{%2, %k0|%k0, %2}"
11830   [(set_attr "type" "ishift")
11831    (set_attr "mode" "SI")])
11832
11833 (define_expand "lshrhi3"
11834   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11835         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11836                      (match_operand:QI 2 "nonmemory_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "TARGET_HIMODE_MATH"
11839   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11840
11841 (define_insn "*lshrhi3_1_one_bit"
11842   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11843         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11844                      (match_operand:QI 2 "const1_operand" "")))
11845    (clobber (reg:CC FLAGS_REG))]
11846   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11847    && (TARGET_SHIFT1 || optimize_size)"
11848   "shr{w}\t%0"
11849   [(set_attr "type" "ishift")
11850    (set (attr "length") 
11851      (if_then_else (match_operand 0 "register_operand" "") 
11852         (const_string "2")
11853         (const_string "*")))])
11854
11855 (define_insn "*lshrhi3_1"
11856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11857         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11858                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11861   "@
11862    shr{w}\t{%2, %0|%0, %2}
11863    shr{w}\t{%b2, %0|%0, %b2}"
11864   [(set_attr "type" "ishift")
11865    (set_attr "mode" "HI")])
11866
11867 ;; This pattern can't accept a variable shift count, since shifts by
11868 ;; zero don't affect the flags.  We assume that shifts by constant
11869 ;; zero are optimized away.
11870 (define_insn "*lshrhi3_one_bit_cmp"
11871   [(set (reg FLAGS_REG)
11872         (compare
11873           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11874                        (match_operand:QI 2 "const1_operand" ""))
11875           (const_int 0)))
11876    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11877         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11878   "ix86_match_ccmode (insn, CCGOCmode)
11879    && (TARGET_SHIFT1 || optimize_size)
11880    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11881   "shr{w}\t%0"
11882   [(set_attr "type" "ishift")
11883    (set (attr "length") 
11884      (if_then_else (match_operand:SI 0 "register_operand" "") 
11885         (const_string "2")
11886         (const_string "*")))])
11887
11888 ;; This pattern can't accept a variable shift count, since shifts by
11889 ;; zero don't affect the flags.  We assume that shifts by constant
11890 ;; zero are optimized away.
11891 (define_insn "*lshrhi3_cmp"
11892   [(set (reg FLAGS_REG)
11893         (compare
11894           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11895                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11896           (const_int 0)))
11897    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11899   "ix86_match_ccmode (insn, CCGOCmode)
11900    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11901   "shr{w}\t{%2, %0|%0, %2}"
11902   [(set_attr "type" "ishift")
11903    (set_attr "mode" "HI")])
11904
11905 (define_expand "lshrqi3"
11906   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11907         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11908                      (match_operand:QI 2 "nonmemory_operand" "")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_QIMODE_MATH"
11911   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11912
11913 (define_insn "*lshrqi3_1_one_bit"
11914   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11915         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11916                      (match_operand:QI 2 "const1_operand" "")))
11917    (clobber (reg:CC FLAGS_REG))]
11918   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11919    && (TARGET_SHIFT1 || optimize_size)"
11920   "shr{b}\t%0"
11921   [(set_attr "type" "ishift")
11922    (set (attr "length") 
11923      (if_then_else (match_operand 0 "register_operand" "") 
11924         (const_string "2")
11925         (const_string "*")))])
11926
11927 (define_insn "*lshrqi3_1_one_bit_slp"
11928   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11929         (lshiftrt:QI (match_dup 0)
11930                      (match_operand:QI 1 "const1_operand" "")))
11931    (clobber (reg:CC FLAGS_REG))]
11932   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11933    && (TARGET_SHIFT1 || optimize_size)"
11934   "shr{b}\t%0"
11935   [(set_attr "type" "ishift1")
11936    (set (attr "length") 
11937      (if_then_else (match_operand 0 "register_operand" "") 
11938         (const_string "2")
11939         (const_string "*")))])
11940
11941 (define_insn "*lshrqi3_1"
11942   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11943         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11944                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11947   "@
11948    shr{b}\t{%2, %0|%0, %2}
11949    shr{b}\t{%b2, %0|%0, %b2}"
11950   [(set_attr "type" "ishift")
11951    (set_attr "mode" "QI")])
11952
11953 (define_insn "*lshrqi3_1_slp"
11954   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11955         (lshiftrt:QI (match_dup 0)
11956                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11959    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11960   "@
11961    shr{b}\t{%1, %0|%0, %1}
11962    shr{b}\t{%b1, %0|%0, %b1}"
11963   [(set_attr "type" "ishift1")
11964    (set_attr "mode" "QI")])
11965
11966 ;; This pattern can't accept a variable shift count, since shifts by
11967 ;; zero don't affect the flags.  We assume that shifts by constant
11968 ;; zero are optimized away.
11969 (define_insn "*lshrqi2_one_bit_cmp"
11970   [(set (reg FLAGS_REG)
11971         (compare
11972           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11973                        (match_operand:QI 2 "const1_operand" ""))
11974           (const_int 0)))
11975    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11976         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11977   "ix86_match_ccmode (insn, CCGOCmode)
11978    && (TARGET_SHIFT1 || optimize_size)
11979    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11980   "shr{b}\t%0"
11981   [(set_attr "type" "ishift")
11982    (set (attr "length") 
11983      (if_then_else (match_operand:SI 0 "register_operand" "") 
11984         (const_string "2")
11985         (const_string "*")))])
11986
11987 ;; This pattern can't accept a variable shift count, since shifts by
11988 ;; zero don't affect the flags.  We assume that shifts by constant
11989 ;; zero are optimized away.
11990 (define_insn "*lshrqi2_cmp"
11991   [(set (reg FLAGS_REG)
11992         (compare
11993           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995           (const_int 0)))
11996    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11997         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11998   "ix86_match_ccmode (insn, CCGOCmode)
11999    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12000   "shr{b}\t{%2, %0|%0, %2}"
12001   [(set_attr "type" "ishift")
12002    (set_attr "mode" "QI")])
12003 \f
12004 ;; Rotate instructions
12005
12006 (define_expand "rotldi3"
12007   [(set (match_operand:DI 0 "shiftdi_operand" "")
12008         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12009                    (match_operand:QI 2 "nonmemory_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011  ""
12012 {
12013   if (TARGET_64BIT)
12014     {
12015       ix86_expand_binary_operator (ROTATE, DImode, operands);
12016       DONE;
12017     }
12018   if (!const_1_to_31_operand (operands[2], VOIDmode))
12019     FAIL;
12020   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12021   DONE;
12022 })
12023
12024 ;; Implement rotation using two double-precision shift instructions
12025 ;; and a scratch register.   
12026 (define_insn_and_split "ix86_rotldi3"
12027  [(set (match_operand:DI 0 "register_operand" "=r")
12028        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12029                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12030   (clobber (reg:CC FLAGS_REG))
12031   (clobber (match_scratch:SI 3 "=&r"))]
12032  "!TARGET_64BIT"
12033  "" 
12034  "&& reload_completed"
12035  [(set (match_dup 3) (match_dup 4))
12036   (parallel
12037    [(set (match_dup 4)
12038          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12039                  (lshiftrt:SI (match_dup 5)
12040                               (minus:QI (const_int 32) (match_dup 2)))))
12041     (clobber (reg:CC FLAGS_REG))])
12042   (parallel
12043    [(set (match_dup 5)
12044          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12045                  (lshiftrt:SI (match_dup 3)
12046                               (minus:QI (const_int 32) (match_dup 2)))))
12047     (clobber (reg:CC FLAGS_REG))])]
12048  "split_di (operands, 1, operands + 4, operands + 5);")
12049  
12050 (define_insn "*rotlsi3_1_one_bit_rex64"
12051   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12052         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12053                    (match_operand:QI 2 "const1_operand" "")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12056    && (TARGET_SHIFT1 || optimize_size)"
12057   "rol{q}\t%0"
12058   [(set_attr "type" "rotate")
12059    (set (attr "length") 
12060      (if_then_else (match_operand:DI 0 "register_operand" "") 
12061         (const_string "2")
12062         (const_string "*")))])
12063
12064 (define_insn "*rotldi3_1_rex64"
12065   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12066         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12067                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12070   "@
12071    rol{q}\t{%2, %0|%0, %2}
12072    rol{q}\t{%b2, %0|%0, %b2}"
12073   [(set_attr "type" "rotate")
12074    (set_attr "mode" "DI")])
12075
12076 (define_expand "rotlsi3"
12077   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12078         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12079                    (match_operand:QI 2 "nonmemory_operand" "")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   ""
12082   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12083
12084 (define_insn "*rotlsi3_1_one_bit"
12085   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12086         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12087                    (match_operand:QI 2 "const1_operand" "")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12090    && (TARGET_SHIFT1 || optimize_size)"
12091   "rol{l}\t%0"
12092   [(set_attr "type" "rotate")
12093    (set (attr "length") 
12094      (if_then_else (match_operand:SI 0 "register_operand" "") 
12095         (const_string "2")
12096         (const_string "*")))])
12097
12098 (define_insn "*rotlsi3_1_one_bit_zext"
12099   [(set (match_operand:DI 0 "register_operand" "=r")
12100         (zero_extend:DI
12101           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12102                      (match_operand:QI 2 "const1_operand" ""))))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12105    && (TARGET_SHIFT1 || optimize_size)"
12106   "rol{l}\t%k0"
12107   [(set_attr "type" "rotate")
12108    (set_attr "length" "2")])
12109
12110 (define_insn "*rotlsi3_1"
12111   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12112         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12113                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12114    (clobber (reg:CC FLAGS_REG))]
12115   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12116   "@
12117    rol{l}\t{%2, %0|%0, %2}
12118    rol{l}\t{%b2, %0|%0, %b2}"
12119   [(set_attr "type" "rotate")
12120    (set_attr "mode" "SI")])
12121
12122 (define_insn "*rotlsi3_1_zext"
12123   [(set (match_operand:DI 0 "register_operand" "=r,r")
12124         (zero_extend:DI
12125           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12126                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12129   "@
12130    rol{l}\t{%2, %k0|%k0, %2}
12131    rol{l}\t{%b2, %k0|%k0, %b2}"
12132   [(set_attr "type" "rotate")
12133    (set_attr "mode" "SI")])
12134
12135 (define_expand "rotlhi3"
12136   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12137         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12138                    (match_operand:QI 2 "nonmemory_operand" "")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "TARGET_HIMODE_MATH"
12141   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12142
12143 (define_insn "*rotlhi3_1_one_bit"
12144   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12145         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12146                    (match_operand:QI 2 "const1_operand" "")))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12149    && (TARGET_SHIFT1 || optimize_size)"
12150   "rol{w}\t%0"
12151   [(set_attr "type" "rotate")
12152    (set (attr "length") 
12153      (if_then_else (match_operand 0 "register_operand" "") 
12154         (const_string "2")
12155         (const_string "*")))])
12156
12157 (define_insn "*rotlhi3_1"
12158   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12159         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12160                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161    (clobber (reg:CC FLAGS_REG))]
12162   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12163   "@
12164    rol{w}\t{%2, %0|%0, %2}
12165    rol{w}\t{%b2, %0|%0, %b2}"
12166   [(set_attr "type" "rotate")
12167    (set_attr "mode" "HI")])
12168
12169 (define_expand "rotlqi3"
12170   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12171         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12172                    (match_operand:QI 2 "nonmemory_operand" "")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "TARGET_QIMODE_MATH"
12175   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12176
12177 (define_insn "*rotlqi3_1_one_bit_slp"
12178   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12179         (rotate:QI (match_dup 0)
12180                    (match_operand:QI 1 "const1_operand" "")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12183    && (TARGET_SHIFT1 || optimize_size)"
12184   "rol{b}\t%0"
12185   [(set_attr "type" "rotate1")
12186    (set (attr "length") 
12187      (if_then_else (match_operand 0 "register_operand" "") 
12188         (const_string "2")
12189         (const_string "*")))])
12190
12191 (define_insn "*rotlqi3_1_one_bit"
12192   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12193         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12194                    (match_operand:QI 2 "const1_operand" "")))
12195    (clobber (reg:CC FLAGS_REG))]
12196   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12197    && (TARGET_SHIFT1 || optimize_size)"
12198   "rol{b}\t%0"
12199   [(set_attr "type" "rotate")
12200    (set (attr "length") 
12201      (if_then_else (match_operand 0 "register_operand" "") 
12202         (const_string "2")
12203         (const_string "*")))])
12204
12205 (define_insn "*rotlqi3_1_slp"
12206   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12207         (rotate:QI (match_dup 0)
12208                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12209    (clobber (reg:CC FLAGS_REG))]
12210   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12211    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12212   "@
12213    rol{b}\t{%1, %0|%0, %1}
12214    rol{b}\t{%b1, %0|%0, %b1}"
12215   [(set_attr "type" "rotate1")
12216    (set_attr "mode" "QI")])
12217
12218 (define_insn "*rotlqi3_1"
12219   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12220         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12221                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12224   "@
12225    rol{b}\t{%2, %0|%0, %2}
12226    rol{b}\t{%b2, %0|%0, %b2}"
12227   [(set_attr "type" "rotate")
12228    (set_attr "mode" "QI")])
12229
12230 (define_expand "rotrdi3"
12231   [(set (match_operand:DI 0 "shiftdi_operand" "")
12232         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12233                    (match_operand:QI 2 "nonmemory_operand" "")))
12234    (clobber (reg:CC FLAGS_REG))]
12235  ""
12236 {
12237   if (TARGET_64BIT)
12238     {
12239       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12240       DONE;
12241     }
12242   if (!const_1_to_31_operand (operands[2], VOIDmode))
12243     FAIL;
12244   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12245   DONE;
12246 })
12247   
12248 ;; Implement rotation using two double-precision shift instructions
12249 ;; and a scratch register.   
12250 (define_insn_and_split "ix86_rotrdi3"
12251  [(set (match_operand:DI 0 "register_operand" "=r")
12252        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12253                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12254   (clobber (reg:CC FLAGS_REG))
12255   (clobber (match_scratch:SI 3 "=&r"))]
12256  "!TARGET_64BIT"
12257  ""
12258  "&& reload_completed"
12259  [(set (match_dup 3) (match_dup 4))
12260   (parallel
12261    [(set (match_dup 4)
12262          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12263                  (ashift:SI (match_dup 5)
12264                             (minus:QI (const_int 32) (match_dup 2)))))
12265     (clobber (reg:CC FLAGS_REG))])
12266   (parallel
12267    [(set (match_dup 5)
12268          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12269                  (ashift:SI (match_dup 3)
12270                             (minus:QI (const_int 32) (match_dup 2)))))
12271     (clobber (reg:CC FLAGS_REG))])]
12272  "split_di (operands, 1, operands + 4, operands + 5);")
12273
12274 (define_insn "*rotrdi3_1_one_bit_rex64"
12275   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12276         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12277                      (match_operand:QI 2 "const1_operand" "")))
12278    (clobber (reg:CC FLAGS_REG))]
12279   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12280    && (TARGET_SHIFT1 || optimize_size)"
12281   "ror{q}\t%0"
12282   [(set_attr "type" "rotate")
12283    (set (attr "length") 
12284      (if_then_else (match_operand:DI 0 "register_operand" "") 
12285         (const_string "2")
12286         (const_string "*")))])
12287
12288 (define_insn "*rotrdi3_1_rex64"
12289   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12290         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12291                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12292    (clobber (reg:CC FLAGS_REG))]
12293   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12294   "@
12295    ror{q}\t{%2, %0|%0, %2}
12296    ror{q}\t{%b2, %0|%0, %b2}"
12297   [(set_attr "type" "rotate")
12298    (set_attr "mode" "DI")])
12299
12300 (define_expand "rotrsi3"
12301   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12302         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12303                      (match_operand:QI 2 "nonmemory_operand" "")))
12304    (clobber (reg:CC FLAGS_REG))]
12305   ""
12306   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12307
12308 (define_insn "*rotrsi3_1_one_bit"
12309   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12310         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12311                      (match_operand:QI 2 "const1_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12314    && (TARGET_SHIFT1 || optimize_size)"
12315   "ror{l}\t%0"
12316   [(set_attr "type" "rotate")
12317    (set (attr "length") 
12318      (if_then_else (match_operand:SI 0 "register_operand" "") 
12319         (const_string "2")
12320         (const_string "*")))])
12321
12322 (define_insn "*rotrsi3_1_one_bit_zext"
12323   [(set (match_operand:DI 0 "register_operand" "=r")
12324         (zero_extend:DI
12325           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12326                        (match_operand:QI 2 "const1_operand" ""))))
12327    (clobber (reg:CC FLAGS_REG))]
12328   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12329    && (TARGET_SHIFT1 || optimize_size)"
12330   "ror{l}\t%k0"
12331   [(set_attr "type" "rotate")
12332    (set (attr "length") 
12333      (if_then_else (match_operand:SI 0 "register_operand" "") 
12334         (const_string "2")
12335         (const_string "*")))])
12336
12337 (define_insn "*rotrsi3_1"
12338   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12339         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12340                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12341    (clobber (reg:CC FLAGS_REG))]
12342   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12343   "@
12344    ror{l}\t{%2, %0|%0, %2}
12345    ror{l}\t{%b2, %0|%0, %b2}"
12346   [(set_attr "type" "rotate")
12347    (set_attr "mode" "SI")])
12348
12349 (define_insn "*rotrsi3_1_zext"
12350   [(set (match_operand:DI 0 "register_operand" "=r,r")
12351         (zero_extend:DI
12352           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12353                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12356   "@
12357    ror{l}\t{%2, %k0|%k0, %2}
12358    ror{l}\t{%b2, %k0|%k0, %b2}"
12359   [(set_attr "type" "rotate")
12360    (set_attr "mode" "SI")])
12361
12362 (define_expand "rotrhi3"
12363   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12364         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12365                      (match_operand:QI 2 "nonmemory_operand" "")))
12366    (clobber (reg:CC FLAGS_REG))]
12367   "TARGET_HIMODE_MATH"
12368   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12369
12370 (define_insn "*rotrhi3_one_bit"
12371   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12372         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12373                      (match_operand:QI 2 "const1_operand" "")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12376    && (TARGET_SHIFT1 || optimize_size)"
12377   "ror{w}\t%0"
12378   [(set_attr "type" "rotate")
12379    (set (attr "length") 
12380      (if_then_else (match_operand 0 "register_operand" "") 
12381         (const_string "2")
12382         (const_string "*")))])
12383
12384 (define_insn "*rotrhi3"
12385   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12386         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12387                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12388    (clobber (reg:CC FLAGS_REG))]
12389   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12390   "@
12391    ror{w}\t{%2, %0|%0, %2}
12392    ror{w}\t{%b2, %0|%0, %b2}"
12393   [(set_attr "type" "rotate")
12394    (set_attr "mode" "HI")])
12395
12396 (define_expand "rotrqi3"
12397   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12398         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12399                      (match_operand:QI 2 "nonmemory_operand" "")))
12400    (clobber (reg:CC FLAGS_REG))]
12401   "TARGET_QIMODE_MATH"
12402   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12403
12404 (define_insn "*rotrqi3_1_one_bit"
12405   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12406         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12407                      (match_operand:QI 2 "const1_operand" "")))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12410    && (TARGET_SHIFT1 || optimize_size)"
12411   "ror{b}\t%0"
12412   [(set_attr "type" "rotate")
12413    (set (attr "length") 
12414      (if_then_else (match_operand 0 "register_operand" "") 
12415         (const_string "2")
12416         (const_string "*")))])
12417
12418 (define_insn "*rotrqi3_1_one_bit_slp"
12419   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12420         (rotatert:QI (match_dup 0)
12421                      (match_operand:QI 1 "const1_operand" "")))
12422    (clobber (reg:CC FLAGS_REG))]
12423   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12424    && (TARGET_SHIFT1 || optimize_size)"
12425   "ror{b}\t%0"
12426   [(set_attr "type" "rotate1")
12427    (set (attr "length") 
12428      (if_then_else (match_operand 0 "register_operand" "") 
12429         (const_string "2")
12430         (const_string "*")))])
12431
12432 (define_insn "*rotrqi3_1"
12433   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12434         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12435                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12436    (clobber (reg:CC FLAGS_REG))]
12437   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12438   "@
12439    ror{b}\t{%2, %0|%0, %2}
12440    ror{b}\t{%b2, %0|%0, %b2}"
12441   [(set_attr "type" "rotate")
12442    (set_attr "mode" "QI")])
12443
12444 (define_insn "*rotrqi3_1_slp"
12445   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12446         (rotatert:QI (match_dup 0)
12447                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12448    (clobber (reg:CC FLAGS_REG))]
12449   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12450    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12451   "@
12452    ror{b}\t{%1, %0|%0, %1}
12453    ror{b}\t{%b1, %0|%0, %b1}"
12454   [(set_attr "type" "rotate1")
12455    (set_attr "mode" "QI")])
12456 \f
12457 ;; Bit set / bit test instructions
12458
12459 (define_expand "extv"
12460   [(set (match_operand:SI 0 "register_operand" "")
12461         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12462                          (match_operand:SI 2 "immediate_operand" "")
12463                          (match_operand:SI 3 "immediate_operand" "")))]
12464   ""
12465 {
12466   /* Handle extractions from %ah et al.  */
12467   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12468     FAIL;
12469
12470   /* From mips.md: extract_bit_field doesn't verify that our source
12471      matches the predicate, so check it again here.  */
12472   if (! ext_register_operand (operands[1], VOIDmode))
12473     FAIL;
12474 })
12475
12476 (define_expand "extzv"
12477   [(set (match_operand:SI 0 "register_operand" "")
12478         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12479                          (match_operand:SI 2 "immediate_operand" "")
12480                          (match_operand:SI 3 "immediate_operand" "")))]
12481   ""
12482 {
12483   /* Handle extractions from %ah et al.  */
12484   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12485     FAIL;
12486
12487   /* From mips.md: extract_bit_field doesn't verify that our source
12488      matches the predicate, so check it again here.  */
12489   if (! ext_register_operand (operands[1], VOIDmode))
12490     FAIL;
12491 })
12492
12493 (define_expand "insv"
12494   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12495                       (match_operand 1 "immediate_operand" "")
12496                       (match_operand 2 "immediate_operand" ""))
12497         (match_operand 3 "register_operand" ""))]
12498   ""
12499 {
12500   /* Handle extractions from %ah et al.  */
12501   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12502     FAIL;
12503
12504   /* From mips.md: insert_bit_field doesn't verify that our source
12505      matches the predicate, so check it again here.  */
12506   if (! ext_register_operand (operands[0], VOIDmode))
12507     FAIL;
12508
12509   if (TARGET_64BIT)
12510     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12511   else
12512     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12513
12514   DONE;
12515 })
12516
12517 ;; %%% bts, btr, btc, bt.
12518 ;; In general these instructions are *slow* when applied to memory,
12519 ;; since they enforce atomic operation.  When applied to registers,
12520 ;; it depends on the cpu implementation.  They're never faster than
12521 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12522 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12523 ;; within the instruction itself, so operating on bits in the high
12524 ;; 32-bits of a register becomes easier.
12525 ;;
12526 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12527 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12528 ;; negdf respectively, so they can never be disabled entirely.
12529
12530 (define_insn "*btsq"
12531   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12532                          (const_int 1)
12533                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12534         (const_int 1))
12535    (clobber (reg:CC FLAGS_REG))]
12536   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12537   "bts{q} %1,%0"
12538   [(set_attr "type" "alu1")])
12539
12540 (define_insn "*btrq"
12541   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12542                          (const_int 1)
12543                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12544         (const_int 0))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12547   "btr{q} %1,%0"
12548   [(set_attr "type" "alu1")])
12549
12550 (define_insn "*btcq"
12551   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12552                          (const_int 1)
12553                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12554         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12555    (clobber (reg:CC FLAGS_REG))]
12556   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12557   "btc{q} %1,%0"
12558   [(set_attr "type" "alu1")])
12559
12560 ;; Allow Nocona to avoid these instructions if a register is available.
12561
12562 (define_peephole2
12563   [(match_scratch:DI 2 "r")
12564    (parallel [(set (zero_extract:DI
12565                      (match_operand:DI 0 "register_operand" "")
12566                      (const_int 1)
12567                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12568                    (const_int 1))
12569               (clobber (reg:CC FLAGS_REG))])]
12570   "TARGET_64BIT && !TARGET_USE_BT"
12571   [(const_int 0)]
12572 {
12573   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12574   rtx op1;
12575
12576   if (HOST_BITS_PER_WIDE_INT >= 64)
12577     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12578   else if (i < HOST_BITS_PER_WIDE_INT)
12579     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12580   else
12581     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12582
12583   op1 = immed_double_const (lo, hi, DImode);
12584   if (i >= 31)
12585     {
12586       emit_move_insn (operands[2], op1);
12587       op1 = operands[2];
12588     }
12589
12590   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12591   DONE;
12592 })
12593
12594 (define_peephole2
12595   [(match_scratch:DI 2 "r")
12596    (parallel [(set (zero_extract:DI
12597                      (match_operand:DI 0 "register_operand" "")
12598                      (const_int 1)
12599                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12600                    (const_int 0))
12601               (clobber (reg:CC FLAGS_REG))])]
12602   "TARGET_64BIT && !TARGET_USE_BT"
12603   [(const_int 0)]
12604 {
12605   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12606   rtx op1;
12607
12608   if (HOST_BITS_PER_WIDE_INT >= 64)
12609     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12610   else if (i < HOST_BITS_PER_WIDE_INT)
12611     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12612   else
12613     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12614
12615   op1 = immed_double_const (~lo, ~hi, DImode);
12616   if (i >= 32)
12617     {
12618       emit_move_insn (operands[2], op1);
12619       op1 = operands[2];
12620     }
12621
12622   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12623   DONE;
12624 })
12625
12626 (define_peephole2
12627   [(match_scratch:DI 2 "r")
12628    (parallel [(set (zero_extract:DI
12629                      (match_operand:DI 0 "register_operand" "")
12630                      (const_int 1)
12631                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12632               (not:DI (zero_extract:DI
12633                         (match_dup 0) (const_int 1) (match_dup 1))))
12634               (clobber (reg:CC FLAGS_REG))])]
12635   "TARGET_64BIT && !TARGET_USE_BT"
12636   [(const_int 0)]
12637 {
12638   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12639   rtx op1;
12640
12641   if (HOST_BITS_PER_WIDE_INT >= 64)
12642     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12643   else if (i < HOST_BITS_PER_WIDE_INT)
12644     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12645   else
12646     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12647
12648   op1 = immed_double_const (lo, hi, DImode);
12649   if (i >= 31)
12650     {
12651       emit_move_insn (operands[2], op1);
12652       op1 = operands[2];
12653     }
12654
12655   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12656   DONE;
12657 })
12658 \f
12659 ;; Store-flag instructions.
12660
12661 ;; For all sCOND expanders, also expand the compare or test insn that
12662 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12663
12664 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12665 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12666 ;; way, which can later delete the movzx if only QImode is needed.
12667
12668 (define_expand "seq"
12669   [(set (match_operand:QI 0 "register_operand" "")
12670         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12671   ""
12672   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12673
12674 (define_expand "sne"
12675   [(set (match_operand:QI 0 "register_operand" "")
12676         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12677   ""
12678   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12679
12680 (define_expand "sgt"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   ""
12684   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "sgtu"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   ""
12690   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "slt"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   ""
12696   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sltu"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   ""
12702   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "sge"
12705   [(set (match_operand:QI 0 "register_operand" "")
12706         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12707   ""
12708   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "sgeu"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sle"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sleu"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   ""
12726   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sunordered"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   "TARGET_80387 || TARGET_SSE"
12732   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sordered"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   "TARGET_80387"
12738   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "suneq"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   "TARGET_80387 || TARGET_SSE"
12744   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sunge"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   "TARGET_80387 || TARGET_SSE"
12750   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "sungt"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   "TARGET_80387 || TARGET_SSE"
12756   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sunle"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   "TARGET_80387 || TARGET_SSE"
12762   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "sunlt"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   "TARGET_80387 || TARGET_SSE"
12768   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sltgt"
12771   [(set (match_operand:QI 0 "register_operand" "")
12772         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773   "TARGET_80387 || TARGET_SSE"
12774   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12775
12776 (define_insn "*setcc_1"
12777   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12778         (match_operator:QI 1 "ix86_comparison_operator"
12779           [(reg FLAGS_REG) (const_int 0)]))]
12780   ""
12781   "set%C1\t%0"
12782   [(set_attr "type" "setcc")
12783    (set_attr "mode" "QI")])
12784
12785 (define_insn "*setcc_2"
12786   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12787         (match_operator:QI 1 "ix86_comparison_operator"
12788           [(reg FLAGS_REG) (const_int 0)]))]
12789   ""
12790   "set%C1\t%0"
12791   [(set_attr "type" "setcc")
12792    (set_attr "mode" "QI")])
12793
12794 ;; In general it is not safe to assume too much about CCmode registers,
12795 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12796 ;; conditions this is safe on x86, so help combine not create
12797 ;;
12798 ;;      seta    %al
12799 ;;      testb   %al, %al
12800 ;;      sete    %al
12801
12802 (define_split 
12803   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12804         (ne:QI (match_operator 1 "ix86_comparison_operator"
12805                  [(reg FLAGS_REG) (const_int 0)])
12806             (const_int 0)))]
12807   ""
12808   [(set (match_dup 0) (match_dup 1))]
12809 {
12810   PUT_MODE (operands[1], QImode);
12811 })
12812
12813 (define_split 
12814   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12815         (ne:QI (match_operator 1 "ix86_comparison_operator"
12816                  [(reg FLAGS_REG) (const_int 0)])
12817             (const_int 0)))]
12818   ""
12819   [(set (match_dup 0) (match_dup 1))]
12820 {
12821   PUT_MODE (operands[1], QImode);
12822 })
12823
12824 (define_split 
12825   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12826         (eq:QI (match_operator 1 "ix86_comparison_operator"
12827                  [(reg FLAGS_REG) (const_int 0)])
12828             (const_int 0)))]
12829   ""
12830   [(set (match_dup 0) (match_dup 1))]
12831 {
12832   rtx new_op1 = copy_rtx (operands[1]);
12833   operands[1] = new_op1;
12834   PUT_MODE (new_op1, QImode);
12835   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12836                                              GET_MODE (XEXP (new_op1, 0))));
12837
12838   /* Make sure that (a) the CCmode we have for the flags is strong
12839      enough for the reversed compare or (b) we have a valid FP compare.  */
12840   if (! ix86_comparison_operator (new_op1, VOIDmode))
12841     FAIL;
12842 })
12843
12844 (define_split 
12845   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12846         (eq:QI (match_operator 1 "ix86_comparison_operator"
12847                  [(reg FLAGS_REG) (const_int 0)])
12848             (const_int 0)))]
12849   ""
12850   [(set (match_dup 0) (match_dup 1))]
12851 {
12852   rtx new_op1 = copy_rtx (operands[1]);
12853   operands[1] = new_op1;
12854   PUT_MODE (new_op1, QImode);
12855   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12856                                              GET_MODE (XEXP (new_op1, 0))));
12857
12858   /* Make sure that (a) the CCmode we have for the flags is strong
12859      enough for the reversed compare or (b) we have a valid FP compare.  */
12860   if (! ix86_comparison_operator (new_op1, VOIDmode))
12861     FAIL;
12862 })
12863
12864 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12865 ;; subsequent logical operations are used to imitate conditional moves.
12866 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12867 ;; it directly.
12868
12869 (define_insn "*sse_setccsf"
12870   [(set (match_operand:SF 0 "register_operand" "=x")
12871         (match_operator:SF 1 "sse_comparison_operator"
12872           [(match_operand:SF 2 "register_operand" "0")
12873            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12874   "TARGET_SSE"
12875   "cmp%D1ss\t{%3, %0|%0, %3}"
12876   [(set_attr "type" "ssecmp")
12877    (set_attr "mode" "SF")])
12878
12879 (define_insn "*sse_setccdf"
12880   [(set (match_operand:DF 0 "register_operand" "=Y")
12881         (match_operator:DF 1 "sse_comparison_operator"
12882           [(match_operand:DF 2 "register_operand" "0")
12883            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12884   "TARGET_SSE2"
12885   "cmp%D1sd\t{%3, %0|%0, %3}"
12886   [(set_attr "type" "ssecmp")
12887    (set_attr "mode" "DF")])
12888 \f
12889 ;; Basic conditional jump instructions.
12890 ;; We ignore the overflow flag for signed branch instructions.
12891
12892 ;; For all bCOND expanders, also expand the compare or test insn that
12893 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12894
12895 (define_expand "beq"
12896   [(set (pc)
12897         (if_then_else (match_dup 1)
12898                       (label_ref (match_operand 0 "" ""))
12899                       (pc)))]
12900   ""
12901   "ix86_expand_branch (EQ, operands[0]); DONE;")
12902
12903 (define_expand "bne"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   ""
12909   "ix86_expand_branch (NE, operands[0]); DONE;")
12910
12911 (define_expand "bgt"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   ""
12917   "ix86_expand_branch (GT, operands[0]); DONE;")
12918
12919 (define_expand "bgtu"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   ""
12925   "ix86_expand_branch (GTU, operands[0]); DONE;")
12926
12927 (define_expand "blt"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   ""
12933   "ix86_expand_branch (LT, operands[0]); DONE;")
12934
12935 (define_expand "bltu"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (LTU, operands[0]); DONE;")
12942
12943 (define_expand "bge"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (GE, operands[0]); DONE;")
12950
12951 (define_expand "bgeu"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (GEU, operands[0]); DONE;")
12958
12959 (define_expand "ble"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (LE, operands[0]); DONE;")
12966
12967 (define_expand "bleu"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (LEU, operands[0]); DONE;")
12974
12975 (define_expand "bunordered"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   "TARGET_80387 || TARGET_SSE_MATH"
12981   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12982
12983 (define_expand "bordered"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   "TARGET_80387 || TARGET_SSE_MATH"
12989   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12990
12991 (define_expand "buneq"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   "TARGET_80387 || TARGET_SSE_MATH"
12997   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12998
12999 (define_expand "bunge"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   "TARGET_80387 || TARGET_SSE_MATH"
13005   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13006
13007 (define_expand "bungt"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   "TARGET_80387 || TARGET_SSE_MATH"
13013   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13014
13015 (define_expand "bunle"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE_MATH"
13021   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13022
13023 (define_expand "bunlt"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE_MATH"
13029   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13030
13031 (define_expand "bltgt"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE_MATH"
13037   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13038
13039 (define_insn "*jcc_1"
13040   [(set (pc)
13041         (if_then_else (match_operator 1 "ix86_comparison_operator"
13042                                       [(reg FLAGS_REG) (const_int 0)])
13043                       (label_ref (match_operand 0 "" ""))
13044                       (pc)))]
13045   ""
13046   "%+j%C1\t%l0"
13047   [(set_attr "type" "ibr")
13048    (set_attr "modrm" "0")
13049    (set (attr "length")
13050            (if_then_else (and (ge (minus (match_dup 0) (pc))
13051                                   (const_int -126))
13052                               (lt (minus (match_dup 0) (pc))
13053                                   (const_int 128)))
13054              (const_int 2)
13055              (const_int 6)))])
13056
13057 (define_insn "*jcc_2"
13058   [(set (pc)
13059         (if_then_else (match_operator 1 "ix86_comparison_operator"
13060                                       [(reg FLAGS_REG) (const_int 0)])
13061                       (pc)
13062                       (label_ref (match_operand 0 "" ""))))]
13063   ""
13064   "%+j%c1\t%l0"
13065   [(set_attr "type" "ibr")
13066    (set_attr "modrm" "0")
13067    (set (attr "length")
13068            (if_then_else (and (ge (minus (match_dup 0) (pc))
13069                                   (const_int -126))
13070                               (lt (minus (match_dup 0) (pc))
13071                                   (const_int 128)))
13072              (const_int 2)
13073              (const_int 6)))])
13074
13075 ;; In general it is not safe to assume too much about CCmode registers,
13076 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13077 ;; conditions this is safe on x86, so help combine not create
13078 ;;
13079 ;;      seta    %al
13080 ;;      testb   %al, %al
13081 ;;      je      Lfoo
13082
13083 (define_split 
13084   [(set (pc)
13085         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13086                                       [(reg FLAGS_REG) (const_int 0)])
13087                           (const_int 0))
13088                       (label_ref (match_operand 1 "" ""))
13089                       (pc)))]
13090   ""
13091   [(set (pc)
13092         (if_then_else (match_dup 0)
13093                       (label_ref (match_dup 1))
13094                       (pc)))]
13095 {
13096   PUT_MODE (operands[0], VOIDmode);
13097 })
13098   
13099 (define_split 
13100   [(set (pc)
13101         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13102                                       [(reg FLAGS_REG) (const_int 0)])
13103                           (const_int 0))
13104                       (label_ref (match_operand 1 "" ""))
13105                       (pc)))]
13106   ""
13107   [(set (pc)
13108         (if_then_else (match_dup 0)
13109                       (label_ref (match_dup 1))
13110                       (pc)))]
13111 {
13112   rtx new_op0 = copy_rtx (operands[0]);
13113   operands[0] = new_op0;
13114   PUT_MODE (new_op0, VOIDmode);
13115   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13116                                              GET_MODE (XEXP (new_op0, 0))));
13117
13118   /* Make sure that (a) the CCmode we have for the flags is strong
13119      enough for the reversed compare or (b) we have a valid FP compare.  */
13120   if (! ix86_comparison_operator (new_op0, VOIDmode))
13121     FAIL;
13122 })
13123
13124 ;; Define combination compare-and-branch fp compare instructions to use
13125 ;; during early optimization.  Splitting the operation apart early makes
13126 ;; for bad code when we want to reverse the operation.
13127
13128 (define_insn "*fp_jcc_1_mixed"
13129   [(set (pc)
13130         (if_then_else (match_operator 0 "comparison_operator"
13131                         [(match_operand 1 "register_operand" "f#x,x#f")
13132                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13133           (label_ref (match_operand 3 "" ""))
13134           (pc)))
13135    (clobber (reg:CCFP FPSR_REG))
13136    (clobber (reg:CCFP FLAGS_REG))]
13137   "TARGET_MIX_SSE_I387
13138    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13139    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13140    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13141   "#")
13142
13143 (define_insn "*fp_jcc_1_sse"
13144   [(set (pc)
13145         (if_then_else (match_operator 0 "comparison_operator"
13146                         [(match_operand 1 "register_operand" "x")
13147                          (match_operand 2 "nonimmediate_operand" "xm")])
13148           (label_ref (match_operand 3 "" ""))
13149           (pc)))
13150    (clobber (reg:CCFP FPSR_REG))
13151    (clobber (reg:CCFP FLAGS_REG))]
13152   "TARGET_SSE_MATH
13153    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13154    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13155    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13156   "#")
13157
13158 (define_insn "*fp_jcc_1_387"
13159   [(set (pc)
13160         (if_then_else (match_operator 0 "comparison_operator"
13161                         [(match_operand 1 "register_operand" "f")
13162                          (match_operand 2 "register_operand" "f")])
13163           (label_ref (match_operand 3 "" ""))
13164           (pc)))
13165    (clobber (reg:CCFP FPSR_REG))
13166    (clobber (reg:CCFP FLAGS_REG))]
13167   "TARGET_CMOVE && TARGET_80387
13168    && FLOAT_MODE_P (GET_MODE (operands[1]))
13169    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13170    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13171   "#")
13172
13173 (define_insn "*fp_jcc_2_mixed"
13174   [(set (pc)
13175         (if_then_else (match_operator 0 "comparison_operator"
13176                         [(match_operand 1 "register_operand" "f#x,x#f")
13177                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13178           (pc)
13179           (label_ref (match_operand 3 "" ""))))
13180    (clobber (reg:CCFP FPSR_REG))
13181    (clobber (reg:CCFP FLAGS_REG))]
13182   "TARGET_MIX_SSE_I387
13183    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13184    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13185    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186   "#")
13187
13188 (define_insn "*fp_jcc_2_sse"
13189   [(set (pc)
13190         (if_then_else (match_operator 0 "comparison_operator"
13191                         [(match_operand 1 "register_operand" "x")
13192                          (match_operand 2 "nonimmediate_operand" "xm")])
13193           (pc)
13194           (label_ref (match_operand 3 "" ""))))
13195    (clobber (reg:CCFP FPSR_REG))
13196    (clobber (reg:CCFP FLAGS_REG))]
13197   "TARGET_SSE_MATH
13198    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13199    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13200    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13201   "#")
13202
13203 (define_insn "*fp_jcc_2_387"
13204   [(set (pc)
13205         (if_then_else (match_operator 0 "comparison_operator"
13206                         [(match_operand 1 "register_operand" "f")
13207                          (match_operand 2 "register_operand" "f")])
13208           (pc)
13209           (label_ref (match_operand 3 "" ""))))
13210    (clobber (reg:CCFP FPSR_REG))
13211    (clobber (reg:CCFP FLAGS_REG))]
13212   "TARGET_CMOVE && TARGET_80387
13213    && FLOAT_MODE_P (GET_MODE (operands[1]))
13214    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13215    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13216   "#")
13217
13218 (define_insn "*fp_jcc_3_387"
13219   [(set (pc)
13220         (if_then_else (match_operator 0 "comparison_operator"
13221                         [(match_operand 1 "register_operand" "f")
13222                          (match_operand 2 "nonimmediate_operand" "fm")])
13223           (label_ref (match_operand 3 "" ""))
13224           (pc)))
13225    (clobber (reg:CCFP FPSR_REG))
13226    (clobber (reg:CCFP FLAGS_REG))
13227    (clobber (match_scratch:HI 4 "=a"))]
13228   "TARGET_80387
13229    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13230    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13231    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13232    && SELECT_CC_MODE (GET_CODE (operands[0]),
13233                       operands[1], operands[2]) == CCFPmode
13234    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13235   "#")
13236
13237 (define_insn "*fp_jcc_4_387"
13238   [(set (pc)
13239         (if_then_else (match_operator 0 "comparison_operator"
13240                         [(match_operand 1 "register_operand" "f")
13241                          (match_operand 2 "nonimmediate_operand" "fm")])
13242           (pc)
13243           (label_ref (match_operand 3 "" ""))))
13244    (clobber (reg:CCFP FPSR_REG))
13245    (clobber (reg:CCFP FLAGS_REG))
13246    (clobber (match_scratch:HI 4 "=a"))]
13247   "TARGET_80387
13248    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13249    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13250    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13251    && SELECT_CC_MODE (GET_CODE (operands[0]),
13252                       operands[1], operands[2]) == CCFPmode
13253    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13254   "#")
13255
13256 (define_insn "*fp_jcc_5_387"
13257   [(set (pc)
13258         (if_then_else (match_operator 0 "comparison_operator"
13259                         [(match_operand 1 "register_operand" "f")
13260                          (match_operand 2 "register_operand" "f")])
13261           (label_ref (match_operand 3 "" ""))
13262           (pc)))
13263    (clobber (reg:CCFP FPSR_REG))
13264    (clobber (reg:CCFP FLAGS_REG))
13265    (clobber (match_scratch:HI 4 "=a"))]
13266   "TARGET_80387
13267    && FLOAT_MODE_P (GET_MODE (operands[1]))
13268    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13269    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13270   "#")
13271
13272 (define_insn "*fp_jcc_6_387"
13273   [(set (pc)
13274         (if_then_else (match_operator 0 "comparison_operator"
13275                         [(match_operand 1 "register_operand" "f")
13276                          (match_operand 2 "register_operand" "f")])
13277           (pc)
13278           (label_ref (match_operand 3 "" ""))))
13279    (clobber (reg:CCFP FPSR_REG))
13280    (clobber (reg:CCFP FLAGS_REG))
13281    (clobber (match_scratch:HI 4 "=a"))]
13282   "TARGET_80387
13283    && FLOAT_MODE_P (GET_MODE (operands[1]))
13284    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13285    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13286   "#")
13287
13288 (define_insn "*fp_jcc_7_387"
13289   [(set (pc)
13290         (if_then_else (match_operator 0 "comparison_operator"
13291                         [(match_operand 1 "register_operand" "f")
13292                          (match_operand 2 "const0_operand" "X")])
13293           (label_ref (match_operand 3 "" ""))
13294           (pc)))
13295    (clobber (reg:CCFP FPSR_REG))
13296    (clobber (reg:CCFP FLAGS_REG))
13297    (clobber (match_scratch:HI 4 "=a"))]
13298   "TARGET_80387
13299    && FLOAT_MODE_P (GET_MODE (operands[1]))
13300    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13301    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13302    && SELECT_CC_MODE (GET_CODE (operands[0]),
13303                       operands[1], operands[2]) == CCFPmode
13304    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13305   "#")
13306
13307 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13308 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13309 ;; with a precedence over other operators and is always put in the first
13310 ;; place. Swap condition and operands to match ficom instruction.
13311
13312 (define_insn "*fp_jcc_8<mode>_387"
13313   [(set (pc)
13314         (if_then_else (match_operator 0 "comparison_operator"
13315                         [(match_operator 1 "float_operator"
13316                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13317                            (match_operand 3 "register_operand" "f,f")])
13318           (label_ref (match_operand 4 "" ""))
13319           (pc)))
13320    (clobber (reg:CCFP FPSR_REG))
13321    (clobber (reg:CCFP FLAGS_REG))
13322    (clobber (match_scratch:HI 5 "=a,a"))]
13323   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13324    && FLOAT_MODE_P (GET_MODE (operands[3]))
13325    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13326    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13327    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13328    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13329   "#")
13330
13331 (define_split
13332   [(set (pc)
13333         (if_then_else (match_operator 0 "comparison_operator"
13334                         [(match_operand 1 "register_operand" "")
13335                          (match_operand 2 "nonimmediate_operand" "")])
13336           (match_operand 3 "" "")
13337           (match_operand 4 "" "")))
13338    (clobber (reg:CCFP FPSR_REG))
13339    (clobber (reg:CCFP FLAGS_REG))]
13340   "reload_completed"
13341   [(const_int 0)]
13342 {
13343   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13344                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13345   DONE;
13346 })
13347
13348 (define_split
13349   [(set (pc)
13350         (if_then_else (match_operator 0 "comparison_operator"
13351                         [(match_operand 1 "register_operand" "")
13352                          (match_operand 2 "general_operand" "")])
13353           (match_operand 3 "" "")
13354           (match_operand 4 "" "")))
13355    (clobber (reg:CCFP FPSR_REG))
13356    (clobber (reg:CCFP FLAGS_REG))
13357    (clobber (match_scratch:HI 5 "=a"))]
13358   "reload_completed"
13359   [(const_int 0)]
13360 {
13361   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13362                         operands[3], operands[4], operands[5], NULL_RTX);
13363   DONE;
13364 })
13365
13366 (define_split
13367   [(set (pc)
13368         (if_then_else (match_operator 0 "comparison_operator"
13369                         [(match_operator 1 "float_operator"
13370                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13371                            (match_operand 3 "register_operand" "")])
13372           (match_operand 4 "" "")
13373           (match_operand 5 "" "")))
13374    (clobber (reg:CCFP FPSR_REG))
13375    (clobber (reg:CCFP FLAGS_REG))
13376    (clobber (match_scratch:HI 6 "=a"))]
13377   "reload_completed"
13378   [(const_int 0)]
13379 {
13380   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13381   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13382                         operands[3], operands[7],
13383                         operands[4], operands[5], operands[6], NULL_RTX);
13384   DONE;
13385 })
13386
13387 ;; %%% Kill this when reload knows how to do it.
13388 (define_split
13389   [(set (pc)
13390         (if_then_else (match_operator 0 "comparison_operator"
13391                         [(match_operator 1 "float_operator"
13392                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13393                            (match_operand 3 "register_operand" "")])
13394           (match_operand 4 "" "")
13395           (match_operand 5 "" "")))
13396    (clobber (reg:CCFP FPSR_REG))
13397    (clobber (reg:CCFP FLAGS_REG))
13398    (clobber (match_scratch:HI 6 "=a"))]
13399   "reload_completed"
13400   [(const_int 0)]
13401 {
13402   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13403   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13404   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13405                         operands[3], operands[7],
13406                         operands[4], operands[5], operands[6], operands[2]);
13407   DONE;
13408 })
13409 \f
13410 ;; Unconditional and other jump instructions
13411
13412 (define_insn "jump"
13413   [(set (pc)
13414         (label_ref (match_operand 0 "" "")))]
13415   ""
13416   "jmp\t%l0"
13417   [(set_attr "type" "ibr")
13418    (set (attr "length")
13419            (if_then_else (and (ge (minus (match_dup 0) (pc))
13420                                   (const_int -126))
13421                               (lt (minus (match_dup 0) (pc))
13422                                   (const_int 128)))
13423              (const_int 2)
13424              (const_int 5)))
13425    (set_attr "modrm" "0")])
13426
13427 (define_expand "indirect_jump"
13428   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13429   ""
13430   "")
13431
13432 (define_insn "*indirect_jump"
13433   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13434   "!TARGET_64BIT"
13435   "jmp\t%A0"
13436   [(set_attr "type" "ibr")
13437    (set_attr "length_immediate" "0")])
13438
13439 (define_insn "*indirect_jump_rtx64"
13440   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13441   "TARGET_64BIT"
13442   "jmp\t%A0"
13443   [(set_attr "type" "ibr")
13444    (set_attr "length_immediate" "0")])
13445
13446 (define_expand "tablejump"
13447   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13448               (use (label_ref (match_operand 1 "" "")))])]
13449   ""
13450 {
13451   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13452      relative.  Convert the relative address to an absolute address.  */
13453   if (flag_pic)
13454     {
13455       rtx op0, op1;
13456       enum rtx_code code;
13457
13458       if (TARGET_64BIT)
13459         {
13460           code = PLUS;
13461           op0 = operands[0];
13462           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13463         }
13464       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13465         {
13466           code = PLUS;
13467           op0 = operands[0];
13468           op1 = pic_offset_table_rtx;
13469         }
13470       else
13471         {
13472           code = MINUS;
13473           op0 = pic_offset_table_rtx;
13474           op1 = operands[0];
13475         }
13476
13477       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13478                                          OPTAB_DIRECT);
13479     }
13480 })
13481
13482 (define_insn "*tablejump_1"
13483   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13484    (use (label_ref (match_operand 1 "" "")))]
13485   "!TARGET_64BIT"
13486   "jmp\t%A0"
13487   [(set_attr "type" "ibr")
13488    (set_attr "length_immediate" "0")])
13489
13490 (define_insn "*tablejump_1_rtx64"
13491   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13492    (use (label_ref (match_operand 1 "" "")))]
13493   "TARGET_64BIT"
13494   "jmp\t%A0"
13495   [(set_attr "type" "ibr")
13496    (set_attr "length_immediate" "0")])
13497 \f
13498 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13499
13500 (define_peephole2
13501   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13502    (set (match_operand:QI 1 "register_operand" "")
13503         (match_operator:QI 2 "ix86_comparison_operator"
13504           [(reg FLAGS_REG) (const_int 0)]))
13505    (set (match_operand 3 "q_regs_operand" "")
13506         (zero_extend (match_dup 1)))]
13507   "(peep2_reg_dead_p (3, operands[1])
13508     || operands_match_p (operands[1], operands[3]))
13509    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13510   [(set (match_dup 4) (match_dup 0))
13511    (set (strict_low_part (match_dup 5))
13512         (match_dup 2))]
13513 {
13514   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13515   operands[5] = gen_lowpart (QImode, operands[3]);
13516   ix86_expand_clear (operands[3]);
13517 })
13518
13519 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13520
13521 (define_peephole2
13522   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13523    (set (match_operand:QI 1 "register_operand" "")
13524         (match_operator:QI 2 "ix86_comparison_operator"
13525           [(reg FLAGS_REG) (const_int 0)]))
13526    (parallel [(set (match_operand 3 "q_regs_operand" "")
13527                    (zero_extend (match_dup 1)))
13528               (clobber (reg:CC FLAGS_REG))])]
13529   "(peep2_reg_dead_p (3, operands[1])
13530     || operands_match_p (operands[1], operands[3]))
13531    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13532   [(set (match_dup 4) (match_dup 0))
13533    (set (strict_low_part (match_dup 5))
13534         (match_dup 2))]
13535 {
13536   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13537   operands[5] = gen_lowpart (QImode, operands[3]);
13538   ix86_expand_clear (operands[3]);
13539 })
13540 \f
13541 ;; Call instructions.
13542
13543 ;; The predicates normally associated with named expanders are not properly
13544 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13545 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13546
13547 ;; Call subroutine returning no value.
13548
13549 (define_expand "call_pop"
13550   [(parallel [(call (match_operand:QI 0 "" "")
13551                     (match_operand:SI 1 "" ""))
13552               (set (reg:SI SP_REG)
13553                    (plus:SI (reg:SI SP_REG)
13554                             (match_operand:SI 3 "" "")))])]
13555   "!TARGET_64BIT"
13556 {
13557   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13558   DONE;
13559 })
13560
13561 (define_insn "*call_pop_0"
13562   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13563          (match_operand:SI 1 "" ""))
13564    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13565                             (match_operand:SI 2 "immediate_operand" "")))]
13566   "!TARGET_64BIT"
13567 {
13568   if (SIBLING_CALL_P (insn))
13569     return "jmp\t%P0";
13570   else
13571     return "call\t%P0";
13572 }
13573   [(set_attr "type" "call")])
13574   
13575 (define_insn "*call_pop_1"
13576   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13577          (match_operand:SI 1 "" ""))
13578    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13579                             (match_operand:SI 2 "immediate_operand" "i")))]
13580   "!TARGET_64BIT"
13581 {
13582   if (constant_call_address_operand (operands[0], Pmode))
13583     {
13584       if (SIBLING_CALL_P (insn))
13585         return "jmp\t%P0";
13586       else
13587         return "call\t%P0";
13588     }
13589   if (SIBLING_CALL_P (insn))
13590     return "jmp\t%A0";
13591   else
13592     return "call\t%A0";
13593 }
13594   [(set_attr "type" "call")])
13595
13596 (define_expand "call"
13597   [(call (match_operand:QI 0 "" "")
13598          (match_operand 1 "" ""))
13599    (use (match_operand 2 "" ""))]
13600   ""
13601 {
13602   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13603   DONE;
13604 })
13605
13606 (define_expand "sibcall"
13607   [(call (match_operand:QI 0 "" "")
13608          (match_operand 1 "" ""))
13609    (use (match_operand 2 "" ""))]
13610   ""
13611 {
13612   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13613   DONE;
13614 })
13615
13616 (define_insn "*call_0"
13617   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13618          (match_operand 1 "" ""))]
13619   ""
13620 {
13621   if (SIBLING_CALL_P (insn))
13622     return "jmp\t%P0";
13623   else
13624     return "call\t%P0";
13625 }
13626   [(set_attr "type" "call")])
13627
13628 (define_insn "*call_1"
13629   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13630          (match_operand 1 "" ""))]
13631   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13632 {
13633   if (constant_call_address_operand (operands[0], Pmode))
13634     return "call\t%P0";
13635   return "call\t%A0";
13636 }
13637   [(set_attr "type" "call")])
13638
13639 (define_insn "*sibcall_1"
13640   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13641          (match_operand 1 "" ""))]
13642   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13643 {
13644   if (constant_call_address_operand (operands[0], Pmode))
13645     return "jmp\t%P0";
13646   return "jmp\t%A0";
13647 }
13648   [(set_attr "type" "call")])
13649
13650 (define_insn "*call_1_rex64"
13651   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13652          (match_operand 1 "" ""))]
13653   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13654 {
13655   if (constant_call_address_operand (operands[0], Pmode))
13656     return "call\t%P0";
13657   return "call\t%A0";
13658 }
13659   [(set_attr "type" "call")])
13660
13661 (define_insn "*sibcall_1_rex64"
13662   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13663          (match_operand 1 "" ""))]
13664   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13665   "jmp\t%P0"
13666   [(set_attr "type" "call")])
13667
13668 (define_insn "*sibcall_1_rex64_v"
13669   [(call (mem:QI (reg:DI 40))
13670          (match_operand 0 "" ""))]
13671   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13672   "jmp\t*%%r11"
13673   [(set_attr "type" "call")])
13674
13675
13676 ;; Call subroutine, returning value in operand 0
13677
13678 (define_expand "call_value_pop"
13679   [(parallel [(set (match_operand 0 "" "")
13680                    (call (match_operand:QI 1 "" "")
13681                          (match_operand:SI 2 "" "")))
13682               (set (reg:SI SP_REG)
13683                    (plus:SI (reg:SI SP_REG)
13684                             (match_operand:SI 4 "" "")))])]
13685   "!TARGET_64BIT"
13686 {
13687   ix86_expand_call (operands[0], operands[1], operands[2],
13688                     operands[3], operands[4], 0);
13689   DONE;
13690 })
13691
13692 (define_expand "call_value"
13693   [(set (match_operand 0 "" "")
13694         (call (match_operand:QI 1 "" "")
13695               (match_operand:SI 2 "" "")))
13696    (use (match_operand:SI 3 "" ""))]
13697   ;; Operand 2 not used on the i386.
13698   ""
13699 {
13700   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13701   DONE;
13702 })
13703
13704 (define_expand "sibcall_value"
13705   [(set (match_operand 0 "" "")
13706         (call (match_operand:QI 1 "" "")
13707               (match_operand:SI 2 "" "")))
13708    (use (match_operand:SI 3 "" ""))]
13709   ;; Operand 2 not used on the i386.
13710   ""
13711 {
13712   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13713   DONE;
13714 })
13715
13716 ;; Call subroutine returning any type.
13717
13718 (define_expand "untyped_call"
13719   [(parallel [(call (match_operand 0 "" "")
13720                     (const_int 0))
13721               (match_operand 1 "" "")
13722               (match_operand 2 "" "")])]
13723   ""
13724 {
13725   int i;
13726
13727   /* In order to give reg-stack an easier job in validating two
13728      coprocessor registers as containing a possible return value,
13729      simply pretend the untyped call returns a complex long double
13730      value.  */
13731
13732   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13733                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13734                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13735                     NULL, 0);
13736
13737   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13738     {
13739       rtx set = XVECEXP (operands[2], 0, i);
13740       emit_move_insn (SET_DEST (set), SET_SRC (set));
13741     }
13742
13743   /* The optimizer does not know that the call sets the function value
13744      registers we stored in the result block.  We avoid problems by
13745      claiming that all hard registers are used and clobbered at this
13746      point.  */
13747   emit_insn (gen_blockage (const0_rtx));
13748
13749   DONE;
13750 })
13751 \f
13752 ;; Prologue and epilogue instructions
13753
13754 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13755 ;; all of memory.  This blocks insns from being moved across this point.
13756
13757 (define_insn "blockage"
13758   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13759   ""
13760   ""
13761   [(set_attr "length" "0")])
13762
13763 ;; Insn emitted into the body of a function to return from a function.
13764 ;; This is only done if the function's epilogue is known to be simple.
13765 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13766
13767 (define_expand "return"
13768   [(return)]
13769   "ix86_can_use_return_insn_p ()"
13770 {
13771   if (current_function_pops_args)
13772     {
13773       rtx popc = GEN_INT (current_function_pops_args);
13774       emit_jump_insn (gen_return_pop_internal (popc));
13775       DONE;
13776     }
13777 })
13778
13779 (define_insn "return_internal"
13780   [(return)]
13781   "reload_completed"
13782   "ret"
13783   [(set_attr "length" "1")
13784    (set_attr "length_immediate" "0")
13785    (set_attr "modrm" "0")])
13786
13787 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13788 ;; instruction Athlon and K8 have.
13789
13790 (define_insn "return_internal_long"
13791   [(return)
13792    (unspec [(const_int 0)] UNSPEC_REP)]
13793   "reload_completed"
13794   "rep {;} ret"
13795   [(set_attr "length" "1")
13796    (set_attr "length_immediate" "0")
13797    (set_attr "prefix_rep" "1")
13798    (set_attr "modrm" "0")])
13799
13800 (define_insn "return_pop_internal"
13801   [(return)
13802    (use (match_operand:SI 0 "const_int_operand" ""))]
13803   "reload_completed"
13804   "ret\t%0"
13805   [(set_attr "length" "3")
13806    (set_attr "length_immediate" "2")
13807    (set_attr "modrm" "0")])
13808
13809 (define_insn "return_indirect_internal"
13810   [(return)
13811    (use (match_operand:SI 0 "register_operand" "r"))]
13812   "reload_completed"
13813   "jmp\t%A0"
13814   [(set_attr "type" "ibr")
13815    (set_attr "length_immediate" "0")])
13816
13817 (define_insn "nop"
13818   [(const_int 0)]
13819   ""
13820   "nop"
13821   [(set_attr "length" "1")
13822    (set_attr "length_immediate" "0")
13823    (set_attr "modrm" "0")])
13824
13825 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13826 ;; branch prediction penalty for the third jump in a 16-byte
13827 ;; block on K8.
13828
13829 (define_insn "align"
13830   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13831   ""
13832 {
13833 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13834   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13835 #else
13836   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13837      The align insn is used to avoid 3 jump instructions in the row to improve
13838      branch prediction and the benefits hardly outweight the cost of extra 8
13839      nops on the average inserted by full alignment pseudo operation.  */
13840 #endif
13841   return "";
13842 }
13843   [(set_attr "length" "16")])
13844
13845 (define_expand "prologue"
13846   [(const_int 1)]
13847   ""
13848   "ix86_expand_prologue (); DONE;")
13849
13850 (define_insn "set_got"
13851   [(set (match_operand:SI 0 "register_operand" "=r")
13852         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13853    (clobber (reg:CC FLAGS_REG))]
13854   "!TARGET_64BIT"
13855   { return output_set_got (operands[0]); }
13856   [(set_attr "type" "multi")
13857    (set_attr "length" "12")])
13858
13859 (define_insn "set_got_rex64"
13860   [(set (match_operand:DI 0 "register_operand" "=r")
13861         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13862   "TARGET_64BIT"
13863   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13864   [(set_attr "type" "lea")
13865    (set_attr "length" "6")])
13866
13867 (define_expand "epilogue"
13868   [(const_int 1)]
13869   ""
13870   "ix86_expand_epilogue (1); DONE;")
13871
13872 (define_expand "sibcall_epilogue"
13873   [(const_int 1)]
13874   ""
13875   "ix86_expand_epilogue (0); DONE;")
13876
13877 (define_expand "eh_return"
13878   [(use (match_operand 0 "register_operand" ""))]
13879   ""
13880 {
13881   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13882
13883   /* Tricky bit: we write the address of the handler to which we will
13884      be returning into someone else's stack frame, one word below the
13885      stack address we wish to restore.  */
13886   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13887   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13888   tmp = gen_rtx_MEM (Pmode, tmp);
13889   emit_move_insn (tmp, ra);
13890
13891   if (Pmode == SImode)
13892     emit_jump_insn (gen_eh_return_si (sa));
13893   else
13894     emit_jump_insn (gen_eh_return_di (sa));
13895   emit_barrier ();
13896   DONE;
13897 })
13898
13899 (define_insn_and_split "eh_return_si"
13900   [(set (pc) 
13901         (unspec [(match_operand:SI 0 "register_operand" "c")]
13902                  UNSPEC_EH_RETURN))]
13903   "!TARGET_64BIT"
13904   "#"
13905   "reload_completed"
13906   [(const_int 1)]
13907   "ix86_expand_epilogue (2); DONE;")
13908
13909 (define_insn_and_split "eh_return_di"
13910   [(set (pc) 
13911         (unspec [(match_operand:DI 0 "register_operand" "c")]
13912                  UNSPEC_EH_RETURN))]
13913   "TARGET_64BIT"
13914   "#"
13915   "reload_completed"
13916   [(const_int 1)]
13917   "ix86_expand_epilogue (2); DONE;")
13918
13919 (define_insn "leave"
13920   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13921    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13922    (clobber (mem:BLK (scratch)))]
13923   "!TARGET_64BIT"
13924   "leave"
13925   [(set_attr "type" "leave")])
13926
13927 (define_insn "leave_rex64"
13928   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13929    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13930    (clobber (mem:BLK (scratch)))]
13931   "TARGET_64BIT"
13932   "leave"
13933   [(set_attr "type" "leave")])
13934 \f
13935 (define_expand "ffssi2"
13936   [(parallel
13937      [(set (match_operand:SI 0 "register_operand" "") 
13938            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13939       (clobber (match_scratch:SI 2 ""))
13940       (clobber (reg:CC FLAGS_REG))])]
13941   ""
13942   "")
13943
13944 (define_insn_and_split "*ffs_cmove"
13945   [(set (match_operand:SI 0 "register_operand" "=r") 
13946         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13947    (clobber (match_scratch:SI 2 "=&r"))
13948    (clobber (reg:CC FLAGS_REG))]
13949   "TARGET_CMOVE"
13950   "#"
13951   "&& reload_completed"
13952   [(set (match_dup 2) (const_int -1))
13953    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13954               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13955    (set (match_dup 0) (if_then_else:SI
13956                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13957                         (match_dup 2)
13958                         (match_dup 0)))
13959    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13960               (clobber (reg:CC FLAGS_REG))])]
13961   "")
13962
13963 (define_insn_and_split "*ffs_no_cmove"
13964   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13965         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13966    (clobber (match_scratch:SI 2 "=&q"))
13967    (clobber (reg:CC FLAGS_REG))]
13968   ""
13969   "#"
13970   "reload_completed"
13971   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13972               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13973    (set (strict_low_part (match_dup 3))
13974         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13975    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13976               (clobber (reg:CC FLAGS_REG))])
13977    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13978               (clobber (reg:CC FLAGS_REG))])
13979    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13980               (clobber (reg:CC FLAGS_REG))])]
13981 {
13982   operands[3] = gen_lowpart (QImode, operands[2]);
13983   ix86_expand_clear (operands[2]);
13984 })
13985
13986 (define_insn "*ffssi_1"
13987   [(set (reg:CCZ FLAGS_REG)
13988         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13989                      (const_int 0)))
13990    (set (match_operand:SI 0 "register_operand" "=r")
13991         (ctz:SI (match_dup 1)))]
13992   ""
13993   "bsf{l}\t{%1, %0|%0, %1}"
13994   [(set_attr "prefix_0f" "1")])
13995
13996 (define_expand "ffsdi2"
13997   [(parallel
13998      [(set (match_operand:DI 0 "register_operand" "") 
13999            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14000       (clobber (match_scratch:DI 2 ""))
14001       (clobber (reg:CC FLAGS_REG))])]
14002   "TARGET_64BIT && TARGET_CMOVE"
14003   "")
14004
14005 (define_insn_and_split "*ffs_rex64"
14006   [(set (match_operand:DI 0 "register_operand" "=r") 
14007         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14008    (clobber (match_scratch:DI 2 "=&r"))
14009    (clobber (reg:CC FLAGS_REG))]
14010   "TARGET_64BIT && TARGET_CMOVE"
14011   "#"
14012   "&& reload_completed"
14013   [(set (match_dup 2) (const_int -1))
14014    (parallel [(set (reg:CCZ FLAGS_REG)
14015                    (compare:CCZ (match_dup 1) (const_int 0)))
14016               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14017    (set (match_dup 0) (if_then_else:DI
14018                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14019                         (match_dup 2)
14020                         (match_dup 0)))
14021    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14022               (clobber (reg:CC FLAGS_REG))])]
14023   "")
14024
14025 (define_insn "*ffsdi_1"
14026   [(set (reg:CCZ FLAGS_REG)
14027         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14028                      (const_int 0)))
14029    (set (match_operand:DI 0 "register_operand" "=r")
14030         (ctz:DI (match_dup 1)))]
14031   "TARGET_64BIT"
14032   "bsf{q}\t{%1, %0|%0, %1}"
14033   [(set_attr "prefix_0f" "1")])
14034
14035 (define_insn "ctzsi2"
14036   [(set (match_operand:SI 0 "register_operand" "=r")
14037         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14038    (clobber (reg:CC FLAGS_REG))]
14039   ""
14040   "bsf{l}\t{%1, %0|%0, %1}"
14041   [(set_attr "prefix_0f" "1")])
14042
14043 (define_insn "ctzdi2"
14044   [(set (match_operand:DI 0 "register_operand" "=r")
14045         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14046    (clobber (reg:CC FLAGS_REG))]
14047   "TARGET_64BIT"
14048   "bsf{q}\t{%1, %0|%0, %1}"
14049   [(set_attr "prefix_0f" "1")])
14050
14051 (define_expand "clzsi2"
14052   [(parallel
14053      [(set (match_operand:SI 0 "register_operand" "")
14054            (minus:SI (const_int 31)
14055                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14056       (clobber (reg:CC FLAGS_REG))])
14057    (parallel
14058      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14059       (clobber (reg:CC FLAGS_REG))])]
14060   ""
14061   "")
14062
14063 (define_insn "*bsr"
14064   [(set (match_operand:SI 0 "register_operand" "=r")
14065         (minus:SI (const_int 31)
14066                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14067    (clobber (reg:CC FLAGS_REG))]
14068   ""
14069   "bsr{l}\t{%1, %0|%0, %1}"
14070   [(set_attr "prefix_0f" "1")])
14071
14072 (define_expand "clzdi2"
14073   [(parallel
14074      [(set (match_operand:DI 0 "register_operand" "")
14075            (minus:DI (const_int 63)
14076                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14077       (clobber (reg:CC FLAGS_REG))])
14078    (parallel
14079      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14080       (clobber (reg:CC FLAGS_REG))])]
14081   "TARGET_64BIT"
14082   "")
14083
14084 (define_insn "*bsr_rex64"
14085   [(set (match_operand:DI 0 "register_operand" "=r")
14086         (minus:DI (const_int 63)
14087                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14088    (clobber (reg:CC FLAGS_REG))]
14089   "TARGET_64BIT"
14090   "bsr{q}\t{%1, %0|%0, %1}"
14091   [(set_attr "prefix_0f" "1")])
14092 \f
14093 ;; Thread-local storage patterns for ELF.
14094 ;;
14095 ;; Note that these code sequences must appear exactly as shown
14096 ;; in order to allow linker relaxation.
14097
14098 (define_insn "*tls_global_dynamic_32_gnu"
14099   [(set (match_operand:SI 0 "register_operand" "=a")
14100         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14101                     (match_operand:SI 2 "tls_symbolic_operand" "")
14102                     (match_operand:SI 3 "call_insn_operand" "")]
14103                     UNSPEC_TLS_GD))
14104    (clobber (match_scratch:SI 4 "=d"))
14105    (clobber (match_scratch:SI 5 "=c"))
14106    (clobber (reg:CC FLAGS_REG))]
14107   "!TARGET_64BIT && TARGET_GNU_TLS"
14108   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14109   [(set_attr "type" "multi")
14110    (set_attr "length" "12")])
14111
14112 (define_insn "*tls_global_dynamic_32_sun"
14113   [(set (match_operand:SI 0 "register_operand" "=a")
14114         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14115                     (match_operand:SI 2 "tls_symbolic_operand" "")
14116                     (match_operand:SI 3 "call_insn_operand" "")]
14117                     UNSPEC_TLS_GD))
14118    (clobber (match_scratch:SI 4 "=d"))
14119    (clobber (match_scratch:SI 5 "=c"))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "!TARGET_64BIT && TARGET_SUN_TLS"
14122   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14123         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14124   [(set_attr "type" "multi")
14125    (set_attr "length" "14")])
14126
14127 (define_expand "tls_global_dynamic_32"
14128   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14129                    (unspec:SI
14130                     [(match_dup 2)
14131                      (match_operand:SI 1 "tls_symbolic_operand" "")
14132                      (match_dup 3)]
14133                     UNSPEC_TLS_GD))
14134               (clobber (match_scratch:SI 4 ""))
14135               (clobber (match_scratch:SI 5 ""))
14136               (clobber (reg:CC FLAGS_REG))])]
14137   ""
14138 {
14139   if (flag_pic)
14140     operands[2] = pic_offset_table_rtx;
14141   else
14142     {
14143       operands[2] = gen_reg_rtx (Pmode);
14144       emit_insn (gen_set_got (operands[2]));
14145     }
14146   operands[3] = ix86_tls_get_addr ();
14147 })
14148
14149 (define_insn "*tls_global_dynamic_64"
14150   [(set (match_operand:DI 0 "register_operand" "=a")
14151         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14152                  (match_operand:DI 3 "" "")))
14153    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14154               UNSPEC_TLS_GD)]
14155   "TARGET_64BIT"
14156   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14157   [(set_attr "type" "multi")
14158    (set_attr "length" "16")])
14159
14160 (define_expand "tls_global_dynamic_64"
14161   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14162                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14163               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14164                          UNSPEC_TLS_GD)])]
14165   ""
14166 {
14167   operands[2] = ix86_tls_get_addr ();
14168 })
14169
14170 (define_insn "*tls_local_dynamic_base_32_gnu"
14171   [(set (match_operand:SI 0 "register_operand" "=a")
14172         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14173                     (match_operand:SI 2 "call_insn_operand" "")]
14174                    UNSPEC_TLS_LD_BASE))
14175    (clobber (match_scratch:SI 3 "=d"))
14176    (clobber (match_scratch:SI 4 "=c"))
14177    (clobber (reg:CC FLAGS_REG))]
14178   "!TARGET_64BIT && TARGET_GNU_TLS"
14179   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14180   [(set_attr "type" "multi")
14181    (set_attr "length" "11")])
14182
14183 (define_insn "*tls_local_dynamic_base_32_sun"
14184   [(set (match_operand:SI 0 "register_operand" "=a")
14185         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14186                     (match_operand:SI 2 "call_insn_operand" "")]
14187                    UNSPEC_TLS_LD_BASE))
14188    (clobber (match_scratch:SI 3 "=d"))
14189    (clobber (match_scratch:SI 4 "=c"))
14190    (clobber (reg:CC FLAGS_REG))]
14191   "!TARGET_64BIT && TARGET_SUN_TLS"
14192   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14193         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14194   [(set_attr "type" "multi")
14195    (set_attr "length" "13")])
14196
14197 (define_expand "tls_local_dynamic_base_32"
14198   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14199                    (unspec:SI [(match_dup 1) (match_dup 2)]
14200                               UNSPEC_TLS_LD_BASE))
14201               (clobber (match_scratch:SI 3 ""))
14202               (clobber (match_scratch:SI 4 ""))
14203               (clobber (reg:CC FLAGS_REG))])]
14204   ""
14205 {
14206   if (flag_pic)
14207     operands[1] = pic_offset_table_rtx;
14208   else
14209     {
14210       operands[1] = gen_reg_rtx (Pmode);
14211       emit_insn (gen_set_got (operands[1]));
14212     }
14213   operands[2] = ix86_tls_get_addr ();
14214 })
14215
14216 (define_insn "*tls_local_dynamic_base_64"
14217   [(set (match_operand:DI 0 "register_operand" "=a")
14218         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14219                  (match_operand:DI 2 "" "")))
14220    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14221   "TARGET_64BIT"
14222   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14223   [(set_attr "type" "multi")
14224    (set_attr "length" "12")])
14225
14226 (define_expand "tls_local_dynamic_base_64"
14227   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14228                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14229               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14230   ""
14231 {
14232   operands[1] = ix86_tls_get_addr ();
14233 })
14234
14235 ;; Local dynamic of a single variable is a lose.  Show combine how
14236 ;; to convert that back to global dynamic.
14237
14238 (define_insn_and_split "*tls_local_dynamic_32_once"
14239   [(set (match_operand:SI 0 "register_operand" "=a")
14240         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14241                              (match_operand:SI 2 "call_insn_operand" "")]
14242                             UNSPEC_TLS_LD_BASE)
14243                  (const:SI (unspec:SI
14244                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14245                             UNSPEC_DTPOFF))))
14246    (clobber (match_scratch:SI 4 "=d"))
14247    (clobber (match_scratch:SI 5 "=c"))
14248    (clobber (reg:CC FLAGS_REG))]
14249   ""
14250   "#"
14251   ""
14252   [(parallel [(set (match_dup 0)
14253                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14254                               UNSPEC_TLS_GD))
14255               (clobber (match_dup 4))
14256               (clobber (match_dup 5))
14257               (clobber (reg:CC FLAGS_REG))])]
14258   "")
14259
14260 ;; Load and add the thread base pointer from %gs:0.
14261
14262 (define_insn "*load_tp_si"
14263   [(set (match_operand:SI 0 "register_operand" "=r")
14264         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14265   "!TARGET_64BIT"
14266   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14267   [(set_attr "type" "imov")
14268    (set_attr "modrm" "0")
14269    (set_attr "length" "7")
14270    (set_attr "memory" "load")
14271    (set_attr "imm_disp" "false")])
14272
14273 (define_insn "*add_tp_si"
14274   [(set (match_operand:SI 0 "register_operand" "=r")
14275         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14276                  (match_operand:SI 1 "register_operand" "0")))
14277    (clobber (reg:CC FLAGS_REG))]
14278   "!TARGET_64BIT"
14279   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14280   [(set_attr "type" "alu")
14281    (set_attr "modrm" "0")
14282    (set_attr "length" "7")
14283    (set_attr "memory" "load")
14284    (set_attr "imm_disp" "false")])
14285
14286 (define_insn "*load_tp_di"
14287   [(set (match_operand:DI 0 "register_operand" "=r")
14288         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14289   "TARGET_64BIT"
14290   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14291   [(set_attr "type" "imov")
14292    (set_attr "modrm" "0")
14293    (set_attr "length" "7")
14294    (set_attr "memory" "load")
14295    (set_attr "imm_disp" "false")])
14296
14297 (define_insn "*add_tp_di"
14298   [(set (match_operand:DI 0 "register_operand" "=r")
14299         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14300                  (match_operand:DI 1 "register_operand" "0")))
14301    (clobber (reg:CC FLAGS_REG))]
14302   "TARGET_64BIT"
14303   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14304   [(set_attr "type" "alu")
14305    (set_attr "modrm" "0")
14306    (set_attr "length" "7")
14307    (set_attr "memory" "load")
14308    (set_attr "imm_disp" "false")])
14309 \f
14310 ;; These patterns match the binary 387 instructions for addM3, subM3,
14311 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14312 ;; SFmode.  The first is the normal insn, the second the same insn but
14313 ;; with one operand a conversion, and the third the same insn but with
14314 ;; the other operand a conversion.  The conversion may be SFmode or
14315 ;; SImode if the target mode DFmode, but only SImode if the target mode
14316 ;; is SFmode.
14317
14318 ;; Gcc is slightly more smart about handling normal two address instructions
14319 ;; so use special patterns for add and mull.
14320
14321 (define_insn "*fop_sf_comm_mixed"
14322   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14323         (match_operator:SF 3 "binary_fp_operator"
14324                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14325                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14326   "TARGET_MIX_SSE_I387
14327    && COMMUTATIVE_ARITH_P (operands[3])
14328    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14329   "* return output_387_binary_op (insn, operands);"
14330   [(set (attr "type") 
14331         (if_then_else (eq_attr "alternative" "1")
14332            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14333               (const_string "ssemul")
14334               (const_string "sseadd"))
14335            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14336               (const_string "fmul")
14337               (const_string "fop"))))
14338    (set_attr "mode" "SF")])
14339
14340 (define_insn "*fop_sf_comm_sse"
14341   [(set (match_operand:SF 0 "register_operand" "=x")
14342         (match_operator:SF 3 "binary_fp_operator"
14343                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14344                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14345   "TARGET_SSE_MATH
14346    && COMMUTATIVE_ARITH_P (operands[3])
14347    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14348   "* return output_387_binary_op (insn, operands);"
14349   [(set (attr "type") 
14350         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14351            (const_string "ssemul")
14352            (const_string "sseadd")))
14353    (set_attr "mode" "SF")])
14354
14355 (define_insn "*fop_sf_comm_i387"
14356   [(set (match_operand:SF 0 "register_operand" "=f")
14357         (match_operator:SF 3 "binary_fp_operator"
14358                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14359                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14360   "TARGET_80387
14361    && COMMUTATIVE_ARITH_P (operands[3])
14362    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14363   "* return output_387_binary_op (insn, operands);"
14364   [(set (attr "type") 
14365         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14366            (const_string "fmul")
14367            (const_string "fop")))
14368    (set_attr "mode" "SF")])
14369
14370 (define_insn "*fop_sf_1_mixed"
14371   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14372         (match_operator:SF 3 "binary_fp_operator"
14373                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14374                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14375   "TARGET_MIX_SSE_I387
14376    && !COMMUTATIVE_ARITH_P (operands[3])
14377    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14378   "* return output_387_binary_op (insn, operands);"
14379   [(set (attr "type") 
14380         (cond [(and (eq_attr "alternative" "2")
14381                     (match_operand:SF 3 "mult_operator" ""))
14382                  (const_string "ssemul")
14383                (and (eq_attr "alternative" "2")
14384                     (match_operand:SF 3 "div_operator" ""))
14385                  (const_string "ssediv")
14386                (eq_attr "alternative" "2")
14387                  (const_string "sseadd")
14388                (match_operand:SF 3 "mult_operator" "") 
14389                  (const_string "fmul")
14390                (match_operand:SF 3 "div_operator" "") 
14391                  (const_string "fdiv")
14392               ]
14393               (const_string "fop")))
14394    (set_attr "mode" "SF")])
14395
14396 (define_insn "*fop_sf_1_sse"
14397   [(set (match_operand:SF 0 "register_operand" "=x")
14398         (match_operator:SF 3 "binary_fp_operator"
14399                         [(match_operand:SF 1 "register_operand" "0")
14400                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14401   "TARGET_SSE_MATH
14402    && !COMMUTATIVE_ARITH_P (operands[3])"
14403   "* return output_387_binary_op (insn, operands);"
14404   [(set (attr "type") 
14405         (cond [(match_operand:SF 3 "mult_operator" "")
14406                  (const_string "ssemul")
14407                (match_operand:SF 3 "div_operator" "")
14408                  (const_string "ssediv")
14409               ]
14410               (const_string "sseadd")))
14411    (set_attr "mode" "SF")])
14412
14413 ;; This pattern is not fully shadowed by the pattern above.
14414 (define_insn "*fop_sf_1_i387"
14415   [(set (match_operand:SF 0 "register_operand" "=f,f")
14416         (match_operator:SF 3 "binary_fp_operator"
14417                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14418                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14419   "TARGET_80387 && !TARGET_SSE_MATH
14420    && !COMMUTATIVE_ARITH_P (operands[3])
14421    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422   "* return output_387_binary_op (insn, operands);"
14423   [(set (attr "type") 
14424         (cond [(match_operand:SF 3 "mult_operator" "") 
14425                  (const_string "fmul")
14426                (match_operand:SF 3 "div_operator" "") 
14427                  (const_string "fdiv")
14428               ]
14429               (const_string "fop")))
14430    (set_attr "mode" "SF")])
14431
14432 ;; ??? Add SSE splitters for these!
14433 (define_insn "*fop_sf_2<mode>_i387"
14434   [(set (match_operand:SF 0 "register_operand" "=f,f")
14435         (match_operator:SF 3 "binary_fp_operator"
14436           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14437            (match_operand:SF 2 "register_operand" "0,0")]))]
14438   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14439   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14440   [(set (attr "type") 
14441         (cond [(match_operand:SF 3 "mult_operator" "") 
14442                  (const_string "fmul")
14443                (match_operand:SF 3 "div_operator" "") 
14444                  (const_string "fdiv")
14445               ]
14446               (const_string "fop")))
14447    (set_attr "fp_int_src" "true")
14448    (set_attr "mode" "<MODE>")])
14449
14450 (define_insn "*fop_sf_3<mode>_i387"
14451   [(set (match_operand:SF 0 "register_operand" "=f,f")
14452         (match_operator:SF 3 "binary_fp_operator"
14453           [(match_operand:SF 1 "register_operand" "0,0")
14454            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14455   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14456   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14457   [(set (attr "type") 
14458         (cond [(match_operand:SF 3 "mult_operator" "") 
14459                  (const_string "fmul")
14460                (match_operand:SF 3 "div_operator" "") 
14461                  (const_string "fdiv")
14462               ]
14463               (const_string "fop")))
14464    (set_attr "fp_int_src" "true")
14465    (set_attr "mode" "<MODE>")])
14466
14467 (define_insn "*fop_df_comm_mixed"
14468   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14469         (match_operator:DF 3 "binary_fp_operator"
14470                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14471                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14472   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14473    && COMMUTATIVE_ARITH_P (operands[3])
14474    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14475   "* return output_387_binary_op (insn, operands);"
14476   [(set (attr "type") 
14477         (if_then_else (eq_attr "alternative" "1")
14478            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14479               (const_string "ssemul")
14480               (const_string "sseadd"))
14481            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14482               (const_string "fmul")
14483               (const_string "fop"))))
14484    (set_attr "mode" "DF")])
14485
14486 (define_insn "*fop_df_comm_sse"
14487   [(set (match_operand:DF 0 "register_operand" "=Y")
14488         (match_operator:DF 3 "binary_fp_operator"
14489                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14490                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14491   "TARGET_SSE2 && TARGET_SSE_MATH
14492    && COMMUTATIVE_ARITH_P (operands[3])
14493    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14494   "* return output_387_binary_op (insn, operands);"
14495   [(set (attr "type") 
14496         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14497            (const_string "ssemul")
14498            (const_string "sseadd")))
14499    (set_attr "mode" "DF")])
14500
14501 (define_insn "*fop_df_comm_i387"
14502   [(set (match_operand:DF 0 "register_operand" "=f")
14503         (match_operator:DF 3 "binary_fp_operator"
14504                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14505                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14506   "TARGET_80387
14507    && COMMUTATIVE_ARITH_P (operands[3])
14508    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14509   "* return output_387_binary_op (insn, operands);"
14510   [(set (attr "type") 
14511         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14512            (const_string "fmul")
14513            (const_string "fop")))
14514    (set_attr "mode" "DF")])
14515
14516 (define_insn "*fop_df_1_mixed"
14517   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14518         (match_operator:DF 3 "binary_fp_operator"
14519                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14520                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14521   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14522    && !COMMUTATIVE_ARITH_P (operands[3])
14523    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14524   "* return output_387_binary_op (insn, operands);"
14525   [(set (attr "type") 
14526         (cond [(and (eq_attr "alternative" "2")
14527                     (match_operand:SF 3 "mult_operator" ""))
14528                  (const_string "ssemul")
14529                (and (eq_attr "alternative" "2")
14530                     (match_operand:SF 3 "div_operator" ""))
14531                  (const_string "ssediv")
14532                (eq_attr "alternative" "2")
14533                  (const_string "sseadd")
14534                (match_operand:DF 3 "mult_operator" "") 
14535                  (const_string "fmul")
14536                (match_operand:DF 3 "div_operator" "") 
14537                  (const_string "fdiv")
14538               ]
14539               (const_string "fop")))
14540    (set_attr "mode" "DF")])
14541
14542 (define_insn "*fop_df_1_sse"
14543   [(set (match_operand:DF 0 "register_operand" "=Y")
14544         (match_operator:DF 3 "binary_fp_operator"
14545                         [(match_operand:DF 1 "register_operand" "0")
14546                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14547   "TARGET_SSE2 && TARGET_SSE_MATH
14548    && !COMMUTATIVE_ARITH_P (operands[3])"
14549   "* return output_387_binary_op (insn, operands);"
14550   [(set_attr "mode" "DF")
14551    (set (attr "type") 
14552         (cond [(match_operand:SF 3 "mult_operator" "")
14553                  (const_string "ssemul")
14554                (match_operand:SF 3 "div_operator" "")
14555                  (const_string "ssediv")
14556               ]
14557               (const_string "sseadd")))])
14558
14559 ;; This pattern is not fully shadowed by the pattern above.
14560 (define_insn "*fop_df_1_i387"
14561   [(set (match_operand:DF 0 "register_operand" "=f,f")
14562         (match_operator:DF 3 "binary_fp_operator"
14563                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14564                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14565   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14566    && !COMMUTATIVE_ARITH_P (operands[3])
14567    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14568   "* return output_387_binary_op (insn, operands);"
14569   [(set (attr "type") 
14570         (cond [(match_operand:DF 3 "mult_operator" "") 
14571                  (const_string "fmul")
14572                (match_operand:DF 3 "div_operator" "")
14573                  (const_string "fdiv")
14574               ]
14575               (const_string "fop")))
14576    (set_attr "mode" "DF")])
14577
14578 ;; ??? Add SSE splitters for these!
14579 (define_insn "*fop_df_2<mode>_i387"
14580   [(set (match_operand:DF 0 "register_operand" "=f,f")
14581         (match_operator:DF 3 "binary_fp_operator"
14582            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14583             (match_operand:DF 2 "register_operand" "0,0")]))]
14584   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14585    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14586   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14587   [(set (attr "type") 
14588         (cond [(match_operand:DF 3 "mult_operator" "") 
14589                  (const_string "fmul")
14590                (match_operand:DF 3 "div_operator" "") 
14591                  (const_string "fdiv")
14592               ]
14593               (const_string "fop")))
14594    (set_attr "fp_int_src" "true")
14595    (set_attr "mode" "<MODE>")])
14596
14597 (define_insn "*fop_df_3<mode>_i387"
14598   [(set (match_operand:DF 0 "register_operand" "=f,f")
14599         (match_operator:DF 3 "binary_fp_operator"
14600            [(match_operand:DF 1 "register_operand" "0,0")
14601             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14602   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14603    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14604   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14605   [(set (attr "type") 
14606         (cond [(match_operand:DF 3 "mult_operator" "") 
14607                  (const_string "fmul")
14608                (match_operand:DF 3 "div_operator" "") 
14609                  (const_string "fdiv")
14610               ]
14611               (const_string "fop")))
14612    (set_attr "fp_int_src" "true")
14613    (set_attr "mode" "<MODE>")])
14614
14615 (define_insn "*fop_df_4_i387"
14616   [(set (match_operand:DF 0 "register_operand" "=f,f")
14617         (match_operator:DF 3 "binary_fp_operator"
14618            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14619             (match_operand:DF 2 "register_operand" "0,f")]))]
14620   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14621    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14622   "* return output_387_binary_op (insn, operands);"
14623   [(set (attr "type") 
14624         (cond [(match_operand:DF 3 "mult_operator" "") 
14625                  (const_string "fmul")
14626                (match_operand:DF 3 "div_operator" "") 
14627                  (const_string "fdiv")
14628               ]
14629               (const_string "fop")))
14630    (set_attr "mode" "SF")])
14631
14632 (define_insn "*fop_df_5_i387"
14633   [(set (match_operand:DF 0 "register_operand" "=f,f")
14634         (match_operator:DF 3 "binary_fp_operator"
14635           [(match_operand:DF 1 "register_operand" "0,f")
14636            (float_extend:DF
14637             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14638   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14639   "* return output_387_binary_op (insn, operands);"
14640   [(set (attr "type") 
14641         (cond [(match_operand:DF 3 "mult_operator" "") 
14642                  (const_string "fmul")
14643                (match_operand:DF 3 "div_operator" "") 
14644                  (const_string "fdiv")
14645               ]
14646               (const_string "fop")))
14647    (set_attr "mode" "SF")])
14648
14649 (define_insn "*fop_df_6_i387"
14650   [(set (match_operand:DF 0 "register_operand" "=f,f")
14651         (match_operator:DF 3 "binary_fp_operator"
14652           [(float_extend:DF
14653             (match_operand:SF 1 "register_operand" "0,f"))
14654            (float_extend:DF
14655             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14656   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14657   "* return output_387_binary_op (insn, operands);"
14658   [(set (attr "type") 
14659         (cond [(match_operand:DF 3 "mult_operator" "") 
14660                  (const_string "fmul")
14661                (match_operand:DF 3 "div_operator" "") 
14662                  (const_string "fdiv")
14663               ]
14664               (const_string "fop")))
14665    (set_attr "mode" "SF")])
14666
14667 (define_insn "*fop_xf_comm_i387"
14668   [(set (match_operand:XF 0 "register_operand" "=f")
14669         (match_operator:XF 3 "binary_fp_operator"
14670                         [(match_operand:XF 1 "register_operand" "%0")
14671                          (match_operand:XF 2 "register_operand" "f")]))]
14672   "TARGET_80387
14673    && COMMUTATIVE_ARITH_P (operands[3])"
14674   "* return output_387_binary_op (insn, operands);"
14675   [(set (attr "type") 
14676         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14677            (const_string "fmul")
14678            (const_string "fop")))
14679    (set_attr "mode" "XF")])
14680
14681 (define_insn "*fop_xf_1_i387"
14682   [(set (match_operand:XF 0 "register_operand" "=f,f")
14683         (match_operator:XF 3 "binary_fp_operator"
14684                         [(match_operand:XF 1 "register_operand" "0,f")
14685                          (match_operand:XF 2 "register_operand" "f,0")]))]
14686   "TARGET_80387
14687    && !COMMUTATIVE_ARITH_P (operands[3])"
14688   "* return output_387_binary_op (insn, operands);"
14689   [(set (attr "type") 
14690         (cond [(match_operand:XF 3 "mult_operator" "") 
14691                  (const_string "fmul")
14692                (match_operand:XF 3 "div_operator" "") 
14693                  (const_string "fdiv")
14694               ]
14695               (const_string "fop")))
14696    (set_attr "mode" "XF")])
14697
14698 (define_insn "*fop_xf_2<mode>_i387"
14699   [(set (match_operand:XF 0 "register_operand" "=f,f")
14700         (match_operator:XF 3 "binary_fp_operator"
14701            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14702             (match_operand:XF 2 "register_operand" "0,0")]))]
14703   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14704   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14705   [(set (attr "type") 
14706         (cond [(match_operand:XF 3 "mult_operator" "") 
14707                  (const_string "fmul")
14708                (match_operand:XF 3 "div_operator" "") 
14709                  (const_string "fdiv")
14710               ]
14711               (const_string "fop")))
14712    (set_attr "fp_int_src" "true")
14713    (set_attr "mode" "<MODE>")])
14714
14715 (define_insn "*fop_xf_3<mode>_i387"
14716   [(set (match_operand:XF 0 "register_operand" "=f,f")
14717         (match_operator:XF 3 "binary_fp_operator"
14718           [(match_operand:XF 1 "register_operand" "0,0")
14719            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14720   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14721   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14722   [(set (attr "type") 
14723         (cond [(match_operand:XF 3 "mult_operator" "") 
14724                  (const_string "fmul")
14725                (match_operand:XF 3 "div_operator" "") 
14726                  (const_string "fdiv")
14727               ]
14728               (const_string "fop")))
14729    (set_attr "fp_int_src" "true")
14730    (set_attr "mode" "<MODE>")])
14731
14732 (define_insn "*fop_xf_4_i387"
14733   [(set (match_operand:XF 0 "register_operand" "=f,f")
14734         (match_operator:XF 3 "binary_fp_operator"
14735            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14736             (match_operand:XF 2 "register_operand" "0,f")]))]
14737   "TARGET_80387"
14738   "* return output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(match_operand:XF 3 "mult_operator" "") 
14741                  (const_string "fmul")
14742                (match_operand:XF 3 "div_operator" "") 
14743                  (const_string "fdiv")
14744               ]
14745               (const_string "fop")))
14746    (set_attr "mode" "SF")])
14747
14748 (define_insn "*fop_xf_5_i387"
14749   [(set (match_operand:XF 0 "register_operand" "=f,f")
14750         (match_operator:XF 3 "binary_fp_operator"
14751           [(match_operand:XF 1 "register_operand" "0,f")
14752            (float_extend:XF
14753             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14754   "TARGET_80387"
14755   "* return output_387_binary_op (insn, operands);"
14756   [(set (attr "type") 
14757         (cond [(match_operand:XF 3 "mult_operator" "") 
14758                  (const_string "fmul")
14759                (match_operand:XF 3 "div_operator" "") 
14760                  (const_string "fdiv")
14761               ]
14762               (const_string "fop")))
14763    (set_attr "mode" "SF")])
14764
14765 (define_insn "*fop_xf_6_i387"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768           [(float_extend:XF
14769             (match_operand 1 "register_operand" "0,f"))
14770            (float_extend:XF
14771             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14772   "TARGET_80387"
14773   "* return output_387_binary_op (insn, operands);"
14774   [(set (attr "type") 
14775         (cond [(match_operand:XF 3 "mult_operator" "") 
14776                  (const_string "fmul")
14777                (match_operand:XF 3 "div_operator" "") 
14778                  (const_string "fdiv")
14779               ]
14780               (const_string "fop")))
14781    (set_attr "mode" "SF")])
14782
14783 (define_split
14784   [(set (match_operand 0 "register_operand" "")
14785         (match_operator 3 "binary_fp_operator"
14786            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14787             (match_operand 2 "register_operand" "")]))]
14788   "TARGET_80387 && reload_completed
14789    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14790   [(const_int 0)]
14791
14792   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14793   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14794   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14795                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14796                                           GET_MODE (operands[3]),
14797                                           operands[4],
14798                                           operands[2])));
14799   ix86_free_from_memory (GET_MODE (operands[1]));
14800   DONE;
14801 })
14802
14803 (define_split
14804   [(set (match_operand 0 "register_operand" "")
14805         (match_operator 3 "binary_fp_operator"
14806            [(match_operand 1 "register_operand" "")
14807             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14808   "TARGET_80387 && reload_completed
14809    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14810   [(const_int 0)]
14811 {
14812   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14813   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14814   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14815                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14816                                           GET_MODE (operands[3]),
14817                                           operands[1],
14818                                           operands[4])));
14819   ix86_free_from_memory (GET_MODE (operands[2]));
14820   DONE;
14821 })
14822 \f
14823 ;; FPU special functions.
14824
14825 (define_expand "sqrtsf2"
14826   [(set (match_operand:SF 0 "register_operand" "")
14827         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14828   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14829 {
14830   if (!TARGET_SSE_MATH)
14831     operands[1] = force_reg (SFmode, operands[1]);
14832 })
14833
14834 (define_insn "*sqrtsf2_mixed"
14835   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14836         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14837   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14838   "@
14839    fsqrt
14840    sqrtss\t{%1, %0|%0, %1}"
14841   [(set_attr "type" "fpspc,sse")
14842    (set_attr "mode" "SF,SF")
14843    (set_attr "athlon_decode" "direct,*")])
14844
14845 (define_insn "*sqrtsf2_sse"
14846   [(set (match_operand:SF 0 "register_operand" "=x")
14847         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14848   "TARGET_SSE_MATH"
14849   "sqrtss\t{%1, %0|%0, %1}"
14850   [(set_attr "type" "sse")
14851    (set_attr "mode" "SF")
14852    (set_attr "athlon_decode" "*")])
14853
14854 (define_insn "*sqrtsf2_i387"
14855   [(set (match_operand:SF 0 "register_operand" "=f")
14856         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14857   "TARGET_USE_FANCY_MATH_387"
14858   "fsqrt"
14859   [(set_attr "type" "fpspc")
14860    (set_attr "mode" "SF")
14861    (set_attr "athlon_decode" "direct")])
14862
14863 (define_expand "sqrtdf2"
14864   [(set (match_operand:DF 0 "register_operand" "")
14865         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14866   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14867 {
14868   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14869     operands[1] = force_reg (DFmode, operands[1]);
14870 })
14871
14872 (define_insn "*sqrtdf2_mixed"
14873   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14874         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14875   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14876   "@
14877    fsqrt
14878    sqrtsd\t{%1, %0|%0, %1}"
14879   [(set_attr "type" "fpspc,sse")
14880    (set_attr "mode" "DF,DF")
14881    (set_attr "athlon_decode" "direct,*")])
14882
14883 (define_insn "*sqrtdf2_sse"
14884   [(set (match_operand:DF 0 "register_operand" "=Y")
14885         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14886   "TARGET_SSE2 && TARGET_SSE_MATH"
14887   "sqrtsd\t{%1, %0|%0, %1}"
14888   [(set_attr "type" "sse")
14889    (set_attr "mode" "DF")
14890    (set_attr "athlon_decode" "*")])
14891
14892 (define_insn "*sqrtdf2_i387"
14893   [(set (match_operand:DF 0 "register_operand" "=f")
14894         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14895   "TARGET_USE_FANCY_MATH_387"
14896   "fsqrt"
14897   [(set_attr "type" "fpspc")
14898    (set_attr "mode" "DF")
14899    (set_attr "athlon_decode" "direct")])
14900
14901 (define_insn "*sqrtextendsfdf2_i387"
14902   [(set (match_operand:DF 0 "register_operand" "=f")
14903         (sqrt:DF (float_extend:DF
14904                   (match_operand:SF 1 "register_operand" "0"))))]
14905   "TARGET_USE_FANCY_MATH_387
14906    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14907   "fsqrt"
14908   [(set_attr "type" "fpspc")
14909    (set_attr "mode" "DF")
14910    (set_attr "athlon_decode" "direct")])
14911
14912 (define_insn "sqrtxf2"
14913   [(set (match_operand:XF 0 "register_operand" "=f")
14914         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14915   "TARGET_USE_FANCY_MATH_387 
14916    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14917   "fsqrt"
14918   [(set_attr "type" "fpspc")
14919    (set_attr "mode" "XF")
14920    (set_attr "athlon_decode" "direct")])
14921
14922 (define_insn "*sqrtextendsfxf2_i387"
14923   [(set (match_operand:XF 0 "register_operand" "=f")
14924         (sqrt:XF (float_extend:XF
14925                   (match_operand:SF 1 "register_operand" "0"))))]
14926   "TARGET_USE_FANCY_MATH_387"
14927   "fsqrt"
14928   [(set_attr "type" "fpspc")
14929    (set_attr "mode" "XF")
14930    (set_attr "athlon_decode" "direct")])
14931
14932 (define_insn "*sqrtextenddfxf2_i387"
14933   [(set (match_operand:XF 0 "register_operand" "=f")
14934         (sqrt:XF (float_extend:XF
14935                   (match_operand:DF 1 "register_operand" "0"))))]
14936   "TARGET_USE_FANCY_MATH_387"
14937   "fsqrt"
14938   [(set_attr "type" "fpspc")
14939    (set_attr "mode" "XF")
14940    (set_attr "athlon_decode" "direct")])
14941
14942 (define_insn "fpremxf4"
14943   [(set (match_operand:XF 0 "register_operand" "=f")
14944         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14945                     (match_operand:XF 3 "register_operand" "1")]
14946                    UNSPEC_FPREM_F))
14947    (set (match_operand:XF 1 "register_operand" "=u")
14948         (unspec:XF [(match_dup 2) (match_dup 3)]
14949                    UNSPEC_FPREM_U))
14950    (set (reg:CCFP FPSR_REG)
14951         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14952   "TARGET_USE_FANCY_MATH_387
14953    && flag_unsafe_math_optimizations"
14954   "fprem"
14955   [(set_attr "type" "fpspc")
14956    (set_attr "mode" "XF")])
14957
14958 (define_expand "fmodsf3"
14959   [(use (match_operand:SF 0 "register_operand" ""))
14960    (use (match_operand:SF 1 "register_operand" ""))
14961    (use (match_operand:SF 2 "register_operand" ""))]
14962   "TARGET_USE_FANCY_MATH_387
14963    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14964    && flag_unsafe_math_optimizations"
14965 {
14966   rtx label = gen_label_rtx ();
14967
14968   rtx op1 = gen_reg_rtx (XFmode);
14969   rtx op2 = gen_reg_rtx (XFmode);
14970
14971   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14972   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14973
14974   emit_label (label);
14975
14976   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14977   ix86_emit_fp_unordered_jump (label);
14978
14979   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14980   DONE;
14981 })
14982
14983 (define_expand "fmoddf3"
14984   [(use (match_operand:DF 0 "register_operand" ""))
14985    (use (match_operand:DF 1 "register_operand" ""))
14986    (use (match_operand:DF 2 "register_operand" ""))]
14987   "TARGET_USE_FANCY_MATH_387
14988    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14989    && flag_unsafe_math_optimizations"
14990 {
14991   rtx label = gen_label_rtx ();
14992
14993   rtx op1 = gen_reg_rtx (XFmode);
14994   rtx op2 = gen_reg_rtx (XFmode);
14995
14996   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14997   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14998
14999   emit_label (label);
15000
15001   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15002   ix86_emit_fp_unordered_jump (label);
15003
15004   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15005   DONE;
15006 })
15007
15008 (define_expand "fmodxf3"
15009   [(use (match_operand:XF 0 "register_operand" ""))
15010    (use (match_operand:XF 1 "register_operand" ""))
15011    (use (match_operand:XF 2 "register_operand" ""))]
15012   "TARGET_USE_FANCY_MATH_387
15013    && flag_unsafe_math_optimizations"
15014 {
15015   rtx label = gen_label_rtx ();
15016
15017   emit_label (label);
15018
15019   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15020                            operands[1], operands[2]));
15021   ix86_emit_fp_unordered_jump (label);
15022
15023   emit_move_insn (operands[0], operands[1]);
15024   DONE;
15025 })
15026
15027 (define_insn "fprem1xf4"
15028   [(set (match_operand:XF 0 "register_operand" "=f")
15029         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15030                     (match_operand:XF 3 "register_operand" "1")]
15031                    UNSPEC_FPREM1_F))
15032    (set (match_operand:XF 1 "register_operand" "=u")
15033         (unspec:XF [(match_dup 2) (match_dup 3)]
15034                    UNSPEC_FPREM1_U))
15035    (set (reg:CCFP FPSR_REG)
15036         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && flag_unsafe_math_optimizations"
15039   "fprem1"
15040   [(set_attr "type" "fpspc")
15041    (set_attr "mode" "XF")])
15042
15043 (define_expand "dremsf3"
15044   [(use (match_operand:SF 0 "register_operand" ""))
15045    (use (match_operand:SF 1 "register_operand" ""))
15046    (use (match_operand:SF 2 "register_operand" ""))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15049    && flag_unsafe_math_optimizations"
15050 {
15051   rtx label = gen_label_rtx ();
15052
15053   rtx op1 = gen_reg_rtx (XFmode);
15054   rtx op2 = gen_reg_rtx (XFmode);
15055
15056   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15057   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15058
15059   emit_label (label);
15060
15061   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15062   ix86_emit_fp_unordered_jump (label);
15063
15064   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15065   DONE;
15066 })
15067
15068 (define_expand "dremdf3"
15069   [(use (match_operand:DF 0 "register_operand" ""))
15070    (use (match_operand:DF 1 "register_operand" ""))
15071    (use (match_operand:DF 2 "register_operand" ""))]
15072   "TARGET_USE_FANCY_MATH_387
15073    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15074    && flag_unsafe_math_optimizations"
15075 {
15076   rtx label = gen_label_rtx ();
15077
15078   rtx op1 = gen_reg_rtx (XFmode);
15079   rtx op2 = gen_reg_rtx (XFmode);
15080
15081   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15082   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15083
15084   emit_label (label);
15085
15086   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15087   ix86_emit_fp_unordered_jump (label);
15088
15089   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15090   DONE;
15091 })
15092
15093 (define_expand "dremxf3"
15094   [(use (match_operand:XF 0 "register_operand" ""))
15095    (use (match_operand:XF 1 "register_operand" ""))
15096    (use (match_operand:XF 2 "register_operand" ""))]
15097   "TARGET_USE_FANCY_MATH_387
15098    && flag_unsafe_math_optimizations"
15099 {
15100   rtx label = gen_label_rtx ();
15101
15102   emit_label (label);
15103
15104   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15105                             operands[1], operands[2]));
15106   ix86_emit_fp_unordered_jump (label);
15107
15108   emit_move_insn (operands[0], operands[1]);
15109   DONE;
15110 })
15111
15112 (define_insn "*sindf2"
15113   [(set (match_operand:DF 0 "register_operand" "=f")
15114         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15115   "TARGET_USE_FANCY_MATH_387
15116    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15117    && flag_unsafe_math_optimizations"
15118   "fsin"
15119   [(set_attr "type" "fpspc")
15120    (set_attr "mode" "DF")])
15121
15122 (define_insn "*sinsf2"
15123   [(set (match_operand:SF 0 "register_operand" "=f")
15124         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15125   "TARGET_USE_FANCY_MATH_387
15126    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15127    && flag_unsafe_math_optimizations"
15128   "fsin"
15129   [(set_attr "type" "fpspc")
15130    (set_attr "mode" "SF")])
15131
15132 (define_insn "*sinextendsfdf2"
15133   [(set (match_operand:DF 0 "register_operand" "=f")
15134         (unspec:DF [(float_extend:DF
15135                      (match_operand:SF 1 "register_operand" "0"))]
15136                    UNSPEC_SIN))]
15137   "TARGET_USE_FANCY_MATH_387
15138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15139    && flag_unsafe_math_optimizations"
15140   "fsin"
15141   [(set_attr "type" "fpspc")
15142    (set_attr "mode" "DF")])
15143
15144 (define_insn "*sinxf2"
15145   [(set (match_operand:XF 0 "register_operand" "=f")
15146         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15147   "TARGET_USE_FANCY_MATH_387
15148    && flag_unsafe_math_optimizations"
15149   "fsin"
15150   [(set_attr "type" "fpspc")
15151    (set_attr "mode" "XF")])
15152
15153 (define_insn "*cosdf2"
15154   [(set (match_operand:DF 0 "register_operand" "=f")
15155         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15156   "TARGET_USE_FANCY_MATH_387
15157    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15158    && flag_unsafe_math_optimizations"
15159   "fcos"
15160   [(set_attr "type" "fpspc")
15161    (set_attr "mode" "DF")])
15162
15163 (define_insn "*cossf2"
15164   [(set (match_operand:SF 0 "register_operand" "=f")
15165         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15166   "TARGET_USE_FANCY_MATH_387
15167    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15168    && flag_unsafe_math_optimizations"
15169   "fcos"
15170   [(set_attr "type" "fpspc")
15171    (set_attr "mode" "SF")])
15172
15173 (define_insn "*cosextendsfdf2"
15174   [(set (match_operand:DF 0 "register_operand" "=f")
15175         (unspec:DF [(float_extend:DF
15176                      (match_operand:SF 1 "register_operand" "0"))]
15177                    UNSPEC_COS))]
15178   "TARGET_USE_FANCY_MATH_387
15179    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15180    && flag_unsafe_math_optimizations"
15181   "fcos"
15182   [(set_attr "type" "fpspc")
15183    (set_attr "mode" "DF")])
15184
15185 (define_insn "*cosxf2"
15186   [(set (match_operand:XF 0 "register_operand" "=f")
15187         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15188   "TARGET_USE_FANCY_MATH_387
15189    && flag_unsafe_math_optimizations"
15190   "fcos"
15191   [(set_attr "type" "fpspc")
15192    (set_attr "mode" "XF")])
15193
15194 ;; With sincos pattern defined, sin and cos builtin function will be
15195 ;; expanded to sincos pattern with one of its outputs left unused. 
15196 ;; Cse pass  will detected, if two sincos patterns can be combined,
15197 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15198 ;; depending on the unused output.
15199
15200 (define_insn "sincosdf3"
15201   [(set (match_operand:DF 0 "register_operand" "=f")
15202         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15203                    UNSPEC_SINCOS_COS))
15204    (set (match_operand:DF 1 "register_operand" "=u")
15205         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15206   "TARGET_USE_FANCY_MATH_387
15207    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15208    && flag_unsafe_math_optimizations"
15209   "fsincos"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "DF")])
15212
15213 (define_split
15214   [(set (match_operand:DF 0 "register_operand" "")
15215         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15216                    UNSPEC_SINCOS_COS))
15217    (set (match_operand:DF 1 "register_operand" "")
15218         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15219   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15220    && !reload_completed && !reload_in_progress"
15221   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15222   "")
15223
15224 (define_split
15225   [(set (match_operand:DF 0 "register_operand" "")
15226         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227                    UNSPEC_SINCOS_COS))
15228    (set (match_operand:DF 1 "register_operand" "")
15229         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15231    && !reload_completed && !reload_in_progress"
15232   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15233   "")
15234
15235 (define_insn "sincossf3"
15236   [(set (match_operand:SF 0 "register_operand" "=f")
15237         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15238                    UNSPEC_SINCOS_COS))
15239    (set (match_operand:SF 1 "register_operand" "=u")
15240         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241   "TARGET_USE_FANCY_MATH_387
15242    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15243    && flag_unsafe_math_optimizations"
15244   "fsincos"
15245   [(set_attr "type" "fpspc")
15246    (set_attr "mode" "SF")])
15247
15248 (define_split
15249   [(set (match_operand:SF 0 "register_operand" "")
15250         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15251                    UNSPEC_SINCOS_COS))
15252    (set (match_operand:SF 1 "register_operand" "")
15253         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15254   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15255    && !reload_completed && !reload_in_progress"
15256   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15257   "")
15258
15259 (define_split
15260   [(set (match_operand:SF 0 "register_operand" "")
15261         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15262                    UNSPEC_SINCOS_COS))
15263    (set (match_operand:SF 1 "register_operand" "")
15264         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15265   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15266    && !reload_completed && !reload_in_progress"
15267   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15268   "")
15269
15270 (define_insn "*sincosextendsfdf3"
15271   [(set (match_operand:DF 0 "register_operand" "=f")
15272         (unspec:DF [(float_extend:DF
15273                      (match_operand:SF 2 "register_operand" "0"))]
15274                    UNSPEC_SINCOS_COS))
15275    (set (match_operand:DF 1 "register_operand" "=u")
15276         (unspec:DF [(float_extend:DF
15277                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15278   "TARGET_USE_FANCY_MATH_387
15279    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15280    && flag_unsafe_math_optimizations"
15281   "fsincos"
15282   [(set_attr "type" "fpspc")
15283    (set_attr "mode" "DF")])
15284
15285 (define_split
15286   [(set (match_operand:DF 0 "register_operand" "")
15287         (unspec:DF [(float_extend:DF
15288                      (match_operand:SF 2 "register_operand" ""))]
15289                    UNSPEC_SINCOS_COS))
15290    (set (match_operand:DF 1 "register_operand" "")
15291         (unspec:DF [(float_extend:DF
15292                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15293   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15294    && !reload_completed && !reload_in_progress"
15295   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15296                                    (match_dup 2))] UNSPEC_SIN))]
15297   "")
15298
15299 (define_split
15300   [(set (match_operand:DF 0 "register_operand" "")
15301         (unspec:DF [(float_extend:DF
15302                      (match_operand:SF 2 "register_operand" ""))]
15303                    UNSPEC_SINCOS_COS))
15304    (set (match_operand:DF 1 "register_operand" "")
15305         (unspec:DF [(float_extend:DF
15306                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15307   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15308    && !reload_completed && !reload_in_progress"
15309   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15310                                    (match_dup 2))] UNSPEC_COS))]
15311   "")
15312
15313 (define_insn "sincosxf3"
15314   [(set (match_operand:XF 0 "register_operand" "=f")
15315         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15316                    UNSPEC_SINCOS_COS))
15317    (set (match_operand:XF 1 "register_operand" "=u")
15318         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15319   "TARGET_USE_FANCY_MATH_387
15320    && flag_unsafe_math_optimizations"
15321   "fsincos"
15322   [(set_attr "type" "fpspc")
15323    (set_attr "mode" "XF")])
15324
15325 (define_split
15326   [(set (match_operand:XF 0 "register_operand" "")
15327         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15328                    UNSPEC_SINCOS_COS))
15329    (set (match_operand:XF 1 "register_operand" "")
15330         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15331   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15332    && !reload_completed && !reload_in_progress"
15333   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15334   "")
15335
15336 (define_split
15337   [(set (match_operand:XF 0 "register_operand" "")
15338         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15339                    UNSPEC_SINCOS_COS))
15340    (set (match_operand:XF 1 "register_operand" "")
15341         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15342   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15343    && !reload_completed && !reload_in_progress"
15344   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15345   "")
15346
15347 (define_insn "*tandf3_1"
15348   [(set (match_operand:DF 0 "register_operand" "=f")
15349         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15350                    UNSPEC_TAN_ONE))
15351    (set (match_operand:DF 1 "register_operand" "=u")
15352         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15353   "TARGET_USE_FANCY_MATH_387
15354    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15355    && flag_unsafe_math_optimizations"
15356   "fptan"
15357   [(set_attr "type" "fpspc")
15358    (set_attr "mode" "DF")])
15359
15360 ;; optimize sequence: fptan
15361 ;;                    fstp    %st(0)
15362 ;;                    fld1
15363 ;; into fptan insn.
15364
15365 (define_peephole2
15366   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15367                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15368                              UNSPEC_TAN_ONE))
15369              (set (match_operand:DF 1 "register_operand" "")
15370                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15371    (set (match_dup 0)
15372         (match_operand:DF 3 "immediate_operand" ""))]
15373   "standard_80387_constant_p (operands[3]) == 2"
15374   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15375              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15376   "")
15377
15378 (define_expand "tandf2"
15379   [(parallel [(set (match_dup 2)
15380                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15381                               UNSPEC_TAN_ONE))
15382               (set (match_operand:DF 0 "register_operand" "")
15383                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15384   "TARGET_USE_FANCY_MATH_387
15385    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15386    && flag_unsafe_math_optimizations"
15387 {
15388   operands[2] = gen_reg_rtx (DFmode);
15389 })
15390
15391 (define_insn "*tansf3_1"
15392   [(set (match_operand:SF 0 "register_operand" "=f")
15393         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15394                    UNSPEC_TAN_ONE))
15395    (set (match_operand:SF 1 "register_operand" "=u")
15396         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15397   "TARGET_USE_FANCY_MATH_387
15398    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15399    && flag_unsafe_math_optimizations"
15400   "fptan"
15401   [(set_attr "type" "fpspc")
15402    (set_attr "mode" "SF")])
15403
15404 ;; optimize sequence: fptan
15405 ;;                    fstp    %st(0)
15406 ;;                    fld1
15407 ;; into fptan insn.
15408
15409 (define_peephole2
15410   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15411                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15412                              UNSPEC_TAN_ONE))
15413              (set (match_operand:SF 1 "register_operand" "")
15414                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15415    (set (match_dup 0)
15416         (match_operand:SF 3 "immediate_operand" ""))]
15417   "standard_80387_constant_p (operands[3]) == 2"
15418   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15419              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15420   "")
15421
15422 (define_expand "tansf2"
15423   [(parallel [(set (match_dup 2)
15424                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15425                               UNSPEC_TAN_ONE))
15426               (set (match_operand:SF 0 "register_operand" "")
15427                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15428   "TARGET_USE_FANCY_MATH_387
15429    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15430    && flag_unsafe_math_optimizations"
15431 {
15432   operands[2] = gen_reg_rtx (SFmode);
15433 })
15434
15435 (define_insn "*tanxf3_1"
15436   [(set (match_operand:XF 0 "register_operand" "=f")
15437         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15438                    UNSPEC_TAN_ONE))
15439    (set (match_operand:XF 1 "register_operand" "=u")
15440         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15441   "TARGET_USE_FANCY_MATH_387
15442    && flag_unsafe_math_optimizations"
15443   "fptan"
15444   [(set_attr "type" "fpspc")
15445    (set_attr "mode" "XF")])
15446
15447 ;; optimize sequence: fptan
15448 ;;                    fstp    %st(0)
15449 ;;                    fld1
15450 ;; into fptan insn.
15451
15452 (define_peephole2
15453   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15454                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15455                              UNSPEC_TAN_ONE))
15456              (set (match_operand:XF 1 "register_operand" "")
15457                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15458    (set (match_dup 0)
15459         (match_operand:XF 3 "immediate_operand" ""))]
15460   "standard_80387_constant_p (operands[3]) == 2"
15461   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15462              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15463   "")
15464
15465 (define_expand "tanxf2"
15466   [(parallel [(set (match_dup 2)
15467                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15468                               UNSPEC_TAN_ONE))
15469               (set (match_operand:XF 0 "register_operand" "")
15470                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15471   "TARGET_USE_FANCY_MATH_387
15472    && flag_unsafe_math_optimizations"
15473 {
15474   operands[2] = gen_reg_rtx (XFmode);
15475 })
15476
15477 (define_insn "atan2df3_1"
15478   [(set (match_operand:DF 0 "register_operand" "=f")
15479         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15480                     (match_operand:DF 1 "register_operand" "u")]
15481                    UNSPEC_FPATAN))
15482    (clobber (match_scratch:DF 3 "=1"))]
15483   "TARGET_USE_FANCY_MATH_387
15484    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15485    && flag_unsafe_math_optimizations"
15486   "fpatan"
15487   [(set_attr "type" "fpspc")
15488    (set_attr "mode" "DF")])
15489
15490 (define_expand "atan2df3"
15491   [(use (match_operand:DF 0 "register_operand" ""))
15492    (use (match_operand:DF 2 "register_operand" ""))
15493    (use (match_operand:DF 1 "register_operand" ""))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496    && flag_unsafe_math_optimizations"
15497 {
15498   rtx copy = gen_reg_rtx (DFmode);
15499   emit_move_insn (copy, operands[1]);
15500   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15501   DONE;
15502 })
15503
15504 (define_expand "atandf2"
15505   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15506                    (unspec:DF [(match_dup 2)
15507                                (match_operand:DF 1 "register_operand" "")]
15508                     UNSPEC_FPATAN))
15509               (clobber (match_scratch:DF 3 ""))])]
15510   "TARGET_USE_FANCY_MATH_387
15511    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15512    && flag_unsafe_math_optimizations"
15513 {
15514   operands[2] = gen_reg_rtx (DFmode);
15515   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15516 })
15517
15518 (define_insn "atan2sf3_1"
15519   [(set (match_operand:SF 0 "register_operand" "=f")
15520         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15521                     (match_operand:SF 1 "register_operand" "u")]
15522                    UNSPEC_FPATAN))
15523    (clobber (match_scratch:SF 3 "=1"))]
15524   "TARGET_USE_FANCY_MATH_387
15525    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15526    && flag_unsafe_math_optimizations"
15527   "fpatan"
15528   [(set_attr "type" "fpspc")
15529    (set_attr "mode" "SF")])
15530
15531 (define_expand "atan2sf3"
15532   [(use (match_operand:SF 0 "register_operand" ""))
15533    (use (match_operand:SF 2 "register_operand" ""))
15534    (use (match_operand:SF 1 "register_operand" ""))]
15535   "TARGET_USE_FANCY_MATH_387
15536    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15537    && flag_unsafe_math_optimizations"
15538 {
15539   rtx copy = gen_reg_rtx (SFmode);
15540   emit_move_insn (copy, operands[1]);
15541   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15542   DONE;
15543 })
15544
15545 (define_expand "atansf2"
15546   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15547                    (unspec:SF [(match_dup 2)
15548                                (match_operand:SF 1 "register_operand" "")]
15549                     UNSPEC_FPATAN))
15550               (clobber (match_scratch:SF 3 ""))])]
15551   "TARGET_USE_FANCY_MATH_387
15552    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15553    && flag_unsafe_math_optimizations"
15554 {
15555   operands[2] = gen_reg_rtx (SFmode);
15556   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15557 })
15558
15559 (define_insn "atan2xf3_1"
15560   [(set (match_operand:XF 0 "register_operand" "=f")
15561         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15562                     (match_operand:XF 1 "register_operand" "u")]
15563                    UNSPEC_FPATAN))
15564    (clobber (match_scratch:XF 3 "=1"))]
15565   "TARGET_USE_FANCY_MATH_387
15566    && flag_unsafe_math_optimizations"
15567   "fpatan"
15568   [(set_attr "type" "fpspc")
15569    (set_attr "mode" "XF")])
15570
15571 (define_expand "atan2xf3"
15572   [(use (match_operand:XF 0 "register_operand" ""))
15573    (use (match_operand:XF 2 "register_operand" ""))
15574    (use (match_operand:XF 1 "register_operand" ""))]
15575   "TARGET_USE_FANCY_MATH_387
15576    && flag_unsafe_math_optimizations"
15577 {
15578   rtx copy = gen_reg_rtx (XFmode);
15579   emit_move_insn (copy, operands[1]);
15580   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15581   DONE;
15582 })
15583
15584 (define_expand "atanxf2"
15585   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15586                    (unspec:XF [(match_dup 2)
15587                                (match_operand:XF 1 "register_operand" "")]
15588                     UNSPEC_FPATAN))
15589               (clobber (match_scratch:XF 3 ""))])]
15590   "TARGET_USE_FANCY_MATH_387
15591    && flag_unsafe_math_optimizations"
15592 {
15593   operands[2] = gen_reg_rtx (XFmode);
15594   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15595 })
15596
15597 (define_expand "asindf2"
15598   [(set (match_dup 2)
15599         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15600    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15601    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15602    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15603    (parallel [(set (match_dup 7)
15604                    (unspec:XF [(match_dup 6) (match_dup 2)]
15605                               UNSPEC_FPATAN))
15606               (clobber (match_scratch:XF 8 ""))])
15607    (set (match_operand:DF 0 "register_operand" "")
15608         (float_truncate:DF (match_dup 7)))]
15609   "TARGET_USE_FANCY_MATH_387
15610    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15611    && flag_unsafe_math_optimizations"
15612 {
15613   int i;
15614
15615   for (i=2; i<8; i++)
15616     operands[i] = gen_reg_rtx (XFmode);
15617
15618   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15619 })
15620
15621 (define_expand "asinsf2"
15622   [(set (match_dup 2)
15623         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15624    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15625    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15626    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15627    (parallel [(set (match_dup 7)
15628                    (unspec:XF [(match_dup 6) (match_dup 2)]
15629                               UNSPEC_FPATAN))
15630               (clobber (match_scratch:XF 8 ""))])
15631    (set (match_operand:SF 0 "register_operand" "")
15632         (float_truncate:SF (match_dup 7)))]
15633   "TARGET_USE_FANCY_MATH_387
15634    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15635    && flag_unsafe_math_optimizations"
15636 {
15637   int i;
15638
15639   for (i=2; i<8; i++)
15640     operands[i] = gen_reg_rtx (XFmode);
15641
15642   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15643 })
15644
15645 (define_expand "asinxf2"
15646   [(set (match_dup 2)
15647         (mult:XF (match_operand:XF 1 "register_operand" "")
15648                  (match_dup 1)))
15649    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15650    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15651    (parallel [(set (match_operand:XF 0 "register_operand" "")
15652                    (unspec:XF [(match_dup 5) (match_dup 1)]
15653                               UNSPEC_FPATAN))
15654               (clobber (match_scratch:XF 6 ""))])]
15655   "TARGET_USE_FANCY_MATH_387
15656    && flag_unsafe_math_optimizations"
15657 {
15658   int i;
15659
15660   for (i=2; i<6; i++)
15661     operands[i] = gen_reg_rtx (XFmode);
15662
15663   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15664 })
15665
15666 (define_expand "acosdf2"
15667   [(set (match_dup 2)
15668         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15669    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15670    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15671    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15672    (parallel [(set (match_dup 7)
15673                    (unspec:XF [(match_dup 2) (match_dup 6)]
15674                               UNSPEC_FPATAN))
15675               (clobber (match_scratch:XF 8 ""))])
15676    (set (match_operand:DF 0 "register_operand" "")
15677         (float_truncate:DF (match_dup 7)))]
15678   "TARGET_USE_FANCY_MATH_387
15679    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15680    && flag_unsafe_math_optimizations"
15681 {
15682   int i;
15683
15684   for (i=2; i<8; i++)
15685     operands[i] = gen_reg_rtx (XFmode);
15686
15687   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15688 })
15689
15690 (define_expand "acossf2"
15691   [(set (match_dup 2)
15692         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15693    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15694    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15695    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15696    (parallel [(set (match_dup 7)
15697                    (unspec:XF [(match_dup 2) (match_dup 6)]
15698                               UNSPEC_FPATAN))
15699               (clobber (match_scratch:XF 8 ""))])
15700    (set (match_operand:SF 0 "register_operand" "")
15701         (float_truncate:SF (match_dup 7)))]
15702   "TARGET_USE_FANCY_MATH_387
15703    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15704    && flag_unsafe_math_optimizations"
15705 {
15706   int i;
15707
15708   for (i=2; i<8; i++)
15709     operands[i] = gen_reg_rtx (XFmode);
15710
15711   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15712 })
15713
15714 (define_expand "acosxf2"
15715   [(set (match_dup 2)
15716         (mult:XF (match_operand:XF 1 "register_operand" "")
15717                  (match_dup 1)))
15718    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15719    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15720    (parallel [(set (match_operand:XF 0 "register_operand" "")
15721                    (unspec:XF [(match_dup 1) (match_dup 5)]
15722                               UNSPEC_FPATAN))
15723               (clobber (match_scratch:XF 6 ""))])]
15724   "TARGET_USE_FANCY_MATH_387
15725    && flag_unsafe_math_optimizations"
15726 {
15727   int i;
15728
15729   for (i=2; i<6; i++)
15730     operands[i] = gen_reg_rtx (XFmode);
15731
15732   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15733 })
15734
15735 (define_insn "fyl2x_xf3"
15736   [(set (match_operand:XF 0 "register_operand" "=f")
15737         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15738                     (match_operand:XF 1 "register_operand" "u")]
15739                    UNSPEC_FYL2X))
15740    (clobber (match_scratch:XF 3 "=1"))]
15741   "TARGET_USE_FANCY_MATH_387
15742    && flag_unsafe_math_optimizations"
15743   "fyl2x"
15744   [(set_attr "type" "fpspc")
15745    (set_attr "mode" "XF")])
15746
15747 (define_expand "logsf2"
15748   [(set (match_dup 2)
15749         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15750    (parallel [(set (match_dup 4)
15751                    (unspec:XF [(match_dup 2)
15752                                (match_dup 3)] UNSPEC_FYL2X))
15753               (clobber (match_scratch:XF 5 ""))])
15754    (set (match_operand:SF 0 "register_operand" "")
15755         (float_truncate:SF (match_dup 4)))]
15756   "TARGET_USE_FANCY_MATH_387
15757    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15758    && flag_unsafe_math_optimizations"
15759 {
15760   rtx temp;
15761
15762   operands[2] = gen_reg_rtx (XFmode);
15763   operands[3] = gen_reg_rtx (XFmode);
15764   operands[4] = gen_reg_rtx (XFmode);
15765
15766   temp = standard_80387_constant_rtx (4); /* fldln2 */
15767   emit_move_insn (operands[3], temp);
15768 })
15769
15770 (define_expand "logdf2"
15771   [(set (match_dup 2)
15772         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15773    (parallel [(set (match_dup 4)
15774                    (unspec:XF [(match_dup 2)
15775                                (match_dup 3)] UNSPEC_FYL2X))
15776               (clobber (match_scratch:XF 5 ""))])
15777    (set (match_operand:DF 0 "register_operand" "")
15778         (float_truncate:DF (match_dup 4)))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations"
15782 {
15783   rtx temp;
15784
15785   operands[2] = gen_reg_rtx (XFmode);
15786   operands[3] = gen_reg_rtx (XFmode);
15787   operands[4] = gen_reg_rtx (XFmode);
15788
15789   temp = standard_80387_constant_rtx (4); /* fldln2 */
15790   emit_move_insn (operands[3], temp);
15791 })
15792
15793 (define_expand "logxf2"
15794   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15795                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15796                                (match_dup 2)] UNSPEC_FYL2X))
15797               (clobber (match_scratch:XF 3 ""))])]
15798   "TARGET_USE_FANCY_MATH_387
15799    && flag_unsafe_math_optimizations"
15800 {
15801   rtx temp;
15802
15803   operands[2] = gen_reg_rtx (XFmode);
15804   temp = standard_80387_constant_rtx (4); /* fldln2 */
15805   emit_move_insn (operands[2], temp);
15806 })
15807
15808 (define_expand "log10sf2"
15809   [(set (match_dup 2)
15810         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15811    (parallel [(set (match_dup 4)
15812                    (unspec:XF [(match_dup 2)
15813                                (match_dup 3)] UNSPEC_FYL2X))
15814               (clobber (match_scratch:XF 5 ""))])
15815    (set (match_operand:SF 0 "register_operand" "")
15816         (float_truncate:SF (match_dup 4)))]
15817   "TARGET_USE_FANCY_MATH_387
15818    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15819    && flag_unsafe_math_optimizations"
15820 {
15821   rtx temp;
15822
15823   operands[2] = gen_reg_rtx (XFmode);
15824   operands[3] = gen_reg_rtx (XFmode);
15825   operands[4] = gen_reg_rtx (XFmode);
15826
15827   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15828   emit_move_insn (operands[3], temp);
15829 })
15830
15831 (define_expand "log10df2"
15832   [(set (match_dup 2)
15833         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15834    (parallel [(set (match_dup 4)
15835                    (unspec:XF [(match_dup 2)
15836                                (match_dup 3)] UNSPEC_FYL2X))
15837               (clobber (match_scratch:XF 5 ""))])
15838    (set (match_operand:DF 0 "register_operand" "")
15839         (float_truncate:DF (match_dup 4)))]
15840   "TARGET_USE_FANCY_MATH_387
15841    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15842    && flag_unsafe_math_optimizations"
15843 {
15844   rtx temp;
15845
15846   operands[2] = gen_reg_rtx (XFmode);
15847   operands[3] = gen_reg_rtx (XFmode);
15848   operands[4] = gen_reg_rtx (XFmode);
15849
15850   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15851   emit_move_insn (operands[3], temp);
15852 })
15853
15854 (define_expand "log10xf2"
15855   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15856                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15857                                (match_dup 2)] UNSPEC_FYL2X))
15858               (clobber (match_scratch:XF 3 ""))])]
15859   "TARGET_USE_FANCY_MATH_387
15860    && flag_unsafe_math_optimizations"
15861 {
15862   rtx temp;
15863
15864   operands[2] = gen_reg_rtx (XFmode);
15865   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15866   emit_move_insn (operands[2], temp);
15867 })
15868
15869 (define_expand "log2sf2"
15870   [(set (match_dup 2)
15871         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15872    (parallel [(set (match_dup 4)
15873                    (unspec:XF [(match_dup 2)
15874                                (match_dup 3)] UNSPEC_FYL2X))
15875               (clobber (match_scratch:XF 5 ""))])
15876    (set (match_operand:SF 0 "register_operand" "")
15877         (float_truncate:SF (match_dup 4)))]
15878   "TARGET_USE_FANCY_MATH_387
15879    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15880    && flag_unsafe_math_optimizations"
15881 {
15882   operands[2] = gen_reg_rtx (XFmode);
15883   operands[3] = gen_reg_rtx (XFmode);
15884   operands[4] = gen_reg_rtx (XFmode);
15885
15886   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15887 })
15888
15889 (define_expand "log2df2"
15890   [(set (match_dup 2)
15891         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15892    (parallel [(set (match_dup 4)
15893                    (unspec:XF [(match_dup 2)
15894                                (match_dup 3)] UNSPEC_FYL2X))
15895               (clobber (match_scratch:XF 5 ""))])
15896    (set (match_operand:DF 0 "register_operand" "")
15897         (float_truncate:DF (match_dup 4)))]
15898   "TARGET_USE_FANCY_MATH_387
15899    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15900    && flag_unsafe_math_optimizations"
15901 {
15902   operands[2] = gen_reg_rtx (XFmode);
15903   operands[3] = gen_reg_rtx (XFmode);
15904   operands[4] = gen_reg_rtx (XFmode);
15905
15906   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15907 })
15908
15909 (define_expand "log2xf2"
15910   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15911                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15912                                (match_dup 2)] UNSPEC_FYL2X))
15913               (clobber (match_scratch:XF 3 ""))])]
15914   "TARGET_USE_FANCY_MATH_387
15915    && flag_unsafe_math_optimizations"
15916 {
15917   operands[2] = gen_reg_rtx (XFmode);
15918   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15919 })
15920
15921 (define_insn "fyl2xp1_xf3"
15922   [(set (match_operand:XF 0 "register_operand" "=f")
15923         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15924                     (match_operand:XF 1 "register_operand" "u")]
15925                    UNSPEC_FYL2XP1))
15926    (clobber (match_scratch:XF 3 "=1"))]
15927   "TARGET_USE_FANCY_MATH_387
15928    && flag_unsafe_math_optimizations"
15929   "fyl2xp1"
15930   [(set_attr "type" "fpspc")
15931    (set_attr "mode" "XF")])
15932
15933 (define_expand "log1psf2"
15934   [(use (match_operand:SF 0 "register_operand" ""))
15935    (use (match_operand:SF 1 "register_operand" ""))]
15936   "TARGET_USE_FANCY_MATH_387
15937    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15938    && flag_unsafe_math_optimizations"
15939 {
15940   rtx op0 = gen_reg_rtx (XFmode);
15941   rtx op1 = gen_reg_rtx (XFmode);
15942
15943   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15944   ix86_emit_i387_log1p (op0, op1);
15945   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15946   DONE;
15947 })
15948
15949 (define_expand "log1pdf2"
15950   [(use (match_operand:DF 0 "register_operand" ""))
15951    (use (match_operand:DF 1 "register_operand" ""))]
15952   "TARGET_USE_FANCY_MATH_387
15953    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15954    && flag_unsafe_math_optimizations"
15955 {
15956   rtx op0 = gen_reg_rtx (XFmode);
15957   rtx op1 = gen_reg_rtx (XFmode);
15958
15959   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15960   ix86_emit_i387_log1p (op0, op1);
15961   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15962   DONE;
15963 })
15964
15965 (define_expand "log1pxf2"
15966   [(use (match_operand:XF 0 "register_operand" ""))
15967    (use (match_operand:XF 1 "register_operand" ""))]
15968   "TARGET_USE_FANCY_MATH_387
15969    && flag_unsafe_math_optimizations"
15970 {
15971   ix86_emit_i387_log1p (operands[0], operands[1]);
15972   DONE;
15973 })
15974
15975 (define_insn "*fxtractxf3"
15976   [(set (match_operand:XF 0 "register_operand" "=f")
15977         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15978                    UNSPEC_XTRACT_FRACT))
15979    (set (match_operand:XF 1 "register_operand" "=u")
15980         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15981   "TARGET_USE_FANCY_MATH_387
15982    && flag_unsafe_math_optimizations"
15983   "fxtract"
15984   [(set_attr "type" "fpspc")
15985    (set_attr "mode" "XF")])
15986
15987 (define_expand "logbsf2"
15988   [(set (match_dup 2)
15989         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15990    (parallel [(set (match_dup 3)
15991                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15992               (set (match_dup 4)
15993                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15994    (set (match_operand:SF 0 "register_operand" "")
15995         (float_truncate:SF (match_dup 4)))]
15996   "TARGET_USE_FANCY_MATH_387
15997    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15998    && flag_unsafe_math_optimizations"
15999 {
16000   operands[2] = gen_reg_rtx (XFmode);
16001   operands[3] = gen_reg_rtx (XFmode);
16002   operands[4] = gen_reg_rtx (XFmode);
16003 })
16004
16005 (define_expand "logbdf2"
16006   [(set (match_dup 2)
16007         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16008    (parallel [(set (match_dup 3)
16009                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16010               (set (match_dup 4)
16011                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16012    (set (match_operand:DF 0 "register_operand" "")
16013         (float_truncate:DF (match_dup 4)))]
16014   "TARGET_USE_FANCY_MATH_387
16015    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16016    && flag_unsafe_math_optimizations"
16017 {
16018   operands[2] = gen_reg_rtx (XFmode);
16019   operands[3] = gen_reg_rtx (XFmode);
16020   operands[4] = gen_reg_rtx (XFmode);
16021 })
16022
16023 (define_expand "logbxf2"
16024   [(parallel [(set (match_dup 2)
16025                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16026                               UNSPEC_XTRACT_FRACT))
16027               (set (match_operand:XF 0 "register_operand" "")
16028                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16029   "TARGET_USE_FANCY_MATH_387
16030    && flag_unsafe_math_optimizations"
16031 {
16032   operands[2] = gen_reg_rtx (XFmode);
16033 })
16034
16035 (define_expand "ilogbsi2"
16036   [(parallel [(set (match_dup 2)
16037                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16038                               UNSPEC_XTRACT_FRACT))
16039               (set (match_operand:XF 3 "register_operand" "")
16040                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16041    (parallel [(set (match_operand:SI 0 "register_operand" "")
16042                    (fix:SI (match_dup 3)))
16043               (clobber (reg:CC FLAGS_REG))])]
16044   "TARGET_USE_FANCY_MATH_387
16045    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16046    && flag_unsafe_math_optimizations"
16047 {
16048   operands[2] = gen_reg_rtx (XFmode);
16049   operands[3] = gen_reg_rtx (XFmode);
16050 })
16051
16052 (define_insn "*f2xm1xf2"
16053   [(set (match_operand:XF 0 "register_operand" "=f")
16054         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16055          UNSPEC_F2XM1))]
16056   "TARGET_USE_FANCY_MATH_387
16057    && flag_unsafe_math_optimizations"
16058   "f2xm1"
16059   [(set_attr "type" "fpspc")
16060    (set_attr "mode" "XF")])
16061
16062 (define_insn "*fscalexf4"
16063   [(set (match_operand:XF 0 "register_operand" "=f")
16064         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16065                     (match_operand:XF 3 "register_operand" "1")]
16066                    UNSPEC_FSCALE_FRACT))
16067    (set (match_operand:XF 1 "register_operand" "=u")
16068         (unspec:XF [(match_dup 2) (match_dup 3)]
16069                    UNSPEC_FSCALE_EXP))]
16070   "TARGET_USE_FANCY_MATH_387
16071    && flag_unsafe_math_optimizations"
16072   "fscale"
16073   [(set_attr "type" "fpspc")
16074    (set_attr "mode" "XF")])
16075
16076 (define_expand "expsf2"
16077   [(set (match_dup 2)
16078         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16079    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16080    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16081    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16082    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16083    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16084    (parallel [(set (match_dup 10)
16085                    (unspec:XF [(match_dup 9) (match_dup 5)]
16086                               UNSPEC_FSCALE_FRACT))
16087               (set (match_dup 11)
16088                    (unspec:XF [(match_dup 9) (match_dup 5)]
16089                               UNSPEC_FSCALE_EXP))])
16090    (set (match_operand:SF 0 "register_operand" "")
16091         (float_truncate:SF (match_dup 10)))]
16092   "TARGET_USE_FANCY_MATH_387
16093    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16094    && flag_unsafe_math_optimizations"
16095 {
16096   rtx temp;
16097   int i;
16098
16099   for (i=2; i<12; i++)
16100     operands[i] = gen_reg_rtx (XFmode);
16101   temp = standard_80387_constant_rtx (5); /* fldl2e */
16102   emit_move_insn (operands[3], temp);
16103   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16104 })
16105
16106 (define_expand "expdf2"
16107   [(set (match_dup 2)
16108         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16109    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16110    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16111    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16112    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16113    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16114    (parallel [(set (match_dup 10)
16115                    (unspec:XF [(match_dup 9) (match_dup 5)]
16116                               UNSPEC_FSCALE_FRACT))
16117               (set (match_dup 11)
16118                    (unspec:XF [(match_dup 9) (match_dup 5)]
16119                               UNSPEC_FSCALE_EXP))])
16120    (set (match_operand:DF 0 "register_operand" "")
16121         (float_truncate:DF (match_dup 10)))]
16122   "TARGET_USE_FANCY_MATH_387
16123    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16124    && flag_unsafe_math_optimizations"
16125 {
16126   rtx temp;
16127   int i;
16128
16129   for (i=2; i<12; i++)
16130     operands[i] = gen_reg_rtx (XFmode);
16131   temp = standard_80387_constant_rtx (5); /* fldl2e */
16132   emit_move_insn (operands[3], temp);
16133   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16134 })
16135
16136 (define_expand "expxf2"
16137   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16138                                (match_dup 2)))
16139    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16140    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16141    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16142    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16143    (parallel [(set (match_operand:XF 0 "register_operand" "")
16144                    (unspec:XF [(match_dup 8) (match_dup 4)]
16145                               UNSPEC_FSCALE_FRACT))
16146               (set (match_dup 9)
16147                    (unspec:XF [(match_dup 8) (match_dup 4)]
16148                               UNSPEC_FSCALE_EXP))])]
16149   "TARGET_USE_FANCY_MATH_387
16150    && flag_unsafe_math_optimizations"
16151 {
16152   rtx temp;
16153   int i;
16154
16155   for (i=2; i<10; i++)
16156     operands[i] = gen_reg_rtx (XFmode);
16157   temp = standard_80387_constant_rtx (5); /* fldl2e */
16158   emit_move_insn (operands[2], temp);
16159   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16160 })
16161
16162 (define_expand "exp10sf2"
16163   [(set (match_dup 2)
16164         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16165    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16166    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16167    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16168    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16169    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16170    (parallel [(set (match_dup 10)
16171                    (unspec:XF [(match_dup 9) (match_dup 5)]
16172                               UNSPEC_FSCALE_FRACT))
16173               (set (match_dup 11)
16174                    (unspec:XF [(match_dup 9) (match_dup 5)]
16175                               UNSPEC_FSCALE_EXP))])
16176    (set (match_operand:SF 0 "register_operand" "")
16177         (float_truncate:SF (match_dup 10)))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180    && flag_unsafe_math_optimizations"
16181 {
16182   rtx temp;
16183   int i;
16184
16185   for (i=2; i<12; i++)
16186     operands[i] = gen_reg_rtx (XFmode);
16187   temp = standard_80387_constant_rtx (6); /* fldl2t */
16188   emit_move_insn (operands[3], temp);
16189   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16190 })
16191
16192 (define_expand "exp10df2"
16193   [(set (match_dup 2)
16194         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16195    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16196    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16197    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16198    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16199    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16200    (parallel [(set (match_dup 10)
16201                    (unspec:XF [(match_dup 9) (match_dup 5)]
16202                               UNSPEC_FSCALE_FRACT))
16203               (set (match_dup 11)
16204                    (unspec:XF [(match_dup 9) (match_dup 5)]
16205                               UNSPEC_FSCALE_EXP))])
16206    (set (match_operand:DF 0 "register_operand" "")
16207         (float_truncate:DF (match_dup 10)))]
16208   "TARGET_USE_FANCY_MATH_387
16209    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16210    && flag_unsafe_math_optimizations"
16211 {
16212   rtx temp;
16213   int i;
16214
16215   for (i=2; i<12; i++)
16216     operands[i] = gen_reg_rtx (XFmode);
16217   temp = standard_80387_constant_rtx (6); /* fldl2t */
16218   emit_move_insn (operands[3], temp);
16219   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16220 })
16221
16222 (define_expand "exp10xf2"
16223   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16224                                (match_dup 2)))
16225    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16226    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16227    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16228    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16229    (parallel [(set (match_operand:XF 0 "register_operand" "")
16230                    (unspec:XF [(match_dup 8) (match_dup 4)]
16231                               UNSPEC_FSCALE_FRACT))
16232               (set (match_dup 9)
16233                    (unspec:XF [(match_dup 8) (match_dup 4)]
16234                               UNSPEC_FSCALE_EXP))])]
16235   "TARGET_USE_FANCY_MATH_387
16236    && flag_unsafe_math_optimizations"
16237 {
16238   rtx temp;
16239   int i;
16240
16241   for (i=2; i<10; i++)
16242     operands[i] = gen_reg_rtx (XFmode);
16243   temp = standard_80387_constant_rtx (6); /* fldl2t */
16244   emit_move_insn (operands[2], temp);
16245   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16246 })
16247
16248 (define_expand "exp2sf2"
16249   [(set (match_dup 2)
16250         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16251    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16252    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16253    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16254    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16255    (parallel [(set (match_dup 8)
16256                    (unspec:XF [(match_dup 7) (match_dup 3)]
16257                               UNSPEC_FSCALE_FRACT))
16258               (set (match_dup 9)
16259                    (unspec:XF [(match_dup 7) (match_dup 3)]
16260                               UNSPEC_FSCALE_EXP))])
16261    (set (match_operand:SF 0 "register_operand" "")
16262         (float_truncate:SF (match_dup 8)))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16266 {
16267   int i;
16268
16269   for (i=2; i<10; i++)
16270     operands[i] = gen_reg_rtx (XFmode);
16271   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16272 })
16273
16274 (define_expand "exp2df2"
16275   [(set (match_dup 2)
16276         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16277    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16278    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16279    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16280    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16281    (parallel [(set (match_dup 8)
16282                    (unspec:XF [(match_dup 7) (match_dup 3)]
16283                               UNSPEC_FSCALE_FRACT))
16284               (set (match_dup 9)
16285                    (unspec:XF [(match_dup 7) (match_dup 3)]
16286                               UNSPEC_FSCALE_EXP))])
16287    (set (match_operand:DF 0 "register_operand" "")
16288         (float_truncate:DF (match_dup 8)))]
16289   "TARGET_USE_FANCY_MATH_387
16290    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16291    && flag_unsafe_math_optimizations"
16292 {
16293   int i;
16294
16295   for (i=2; i<10; i++)
16296     operands[i] = gen_reg_rtx (XFmode);
16297   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16298 })
16299
16300 (define_expand "exp2xf2"
16301   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16302    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16303    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16304    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16305    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16306    (parallel [(set (match_operand:XF 0 "register_operand" "")
16307                    (unspec:XF [(match_dup 7) (match_dup 3)]
16308                               UNSPEC_FSCALE_FRACT))
16309               (set (match_dup 8)
16310                    (unspec:XF [(match_dup 7) (match_dup 3)]
16311                               UNSPEC_FSCALE_EXP))])]
16312   "TARGET_USE_FANCY_MATH_387
16313    && flag_unsafe_math_optimizations"
16314 {
16315   int i;
16316
16317   for (i=2; i<9; i++)
16318     operands[i] = gen_reg_rtx (XFmode);
16319   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16320 })
16321
16322 (define_expand "expm1df2"
16323   [(set (match_dup 2)
16324         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16326    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16327    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16328    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16329    (parallel [(set (match_dup 8)
16330                    (unspec:XF [(match_dup 7) (match_dup 5)]
16331                               UNSPEC_FSCALE_FRACT))
16332                    (set (match_dup 9)
16333                    (unspec:XF [(match_dup 7) (match_dup 5)]
16334                               UNSPEC_FSCALE_EXP))])
16335    (parallel [(set (match_dup 11)
16336                    (unspec:XF [(match_dup 10) (match_dup 9)]
16337                               UNSPEC_FSCALE_FRACT))
16338               (set (match_dup 12)
16339                    (unspec:XF [(match_dup 10) (match_dup 9)]
16340                               UNSPEC_FSCALE_EXP))])
16341    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16342    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16343    (set (match_operand:DF 0 "register_operand" "")
16344         (float_truncate:DF (match_dup 14)))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16347    && flag_unsafe_math_optimizations"
16348 {
16349   rtx temp;
16350   int i;
16351
16352   for (i=2; i<15; i++)
16353     operands[i] = gen_reg_rtx (XFmode);
16354   temp = standard_80387_constant_rtx (5); /* fldl2e */
16355   emit_move_insn (operands[3], temp);
16356   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16357 })
16358
16359 (define_expand "expm1sf2"
16360   [(set (match_dup 2)
16361         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16362    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16363    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16364    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16365    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16366    (parallel [(set (match_dup 8)
16367                    (unspec:XF [(match_dup 7) (match_dup 5)]
16368                               UNSPEC_FSCALE_FRACT))
16369                    (set (match_dup 9)
16370                    (unspec:XF [(match_dup 7) (match_dup 5)]
16371                               UNSPEC_FSCALE_EXP))])
16372    (parallel [(set (match_dup 11)
16373                    (unspec:XF [(match_dup 10) (match_dup 9)]
16374                               UNSPEC_FSCALE_FRACT))
16375               (set (match_dup 12)
16376                    (unspec:XF [(match_dup 10) (match_dup 9)]
16377                               UNSPEC_FSCALE_EXP))])
16378    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16379    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16380    (set (match_operand:SF 0 "register_operand" "")
16381         (float_truncate:SF (match_dup 14)))]
16382   "TARGET_USE_FANCY_MATH_387
16383    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16384    && flag_unsafe_math_optimizations"
16385 {
16386   rtx temp;
16387   int i;
16388
16389   for (i=2; i<15; i++)
16390     operands[i] = gen_reg_rtx (XFmode);
16391   temp = standard_80387_constant_rtx (5); /* fldl2e */
16392   emit_move_insn (operands[3], temp);
16393   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16394 })
16395
16396 (define_expand "expm1xf2"
16397   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16398                                (match_dup 2)))
16399    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16400    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16401    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16402    (parallel [(set (match_dup 7)
16403                    (unspec:XF [(match_dup 6) (match_dup 4)]
16404                               UNSPEC_FSCALE_FRACT))
16405                    (set (match_dup 8)
16406                    (unspec:XF [(match_dup 6) (match_dup 4)]
16407                               UNSPEC_FSCALE_EXP))])
16408    (parallel [(set (match_dup 10)
16409                    (unspec:XF [(match_dup 9) (match_dup 8)]
16410                               UNSPEC_FSCALE_FRACT))
16411               (set (match_dup 11)
16412                    (unspec:XF [(match_dup 9) (match_dup 8)]
16413                               UNSPEC_FSCALE_EXP))])
16414    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16415    (set (match_operand:XF 0 "register_operand" "")
16416         (plus:XF (match_dup 12) (match_dup 7)))]
16417   "TARGET_USE_FANCY_MATH_387
16418    && flag_unsafe_math_optimizations"
16419 {
16420   rtx temp;
16421   int i;
16422
16423   for (i=2; i<13; i++)
16424     operands[i] = gen_reg_rtx (XFmode);
16425   temp = standard_80387_constant_rtx (5); /* fldl2e */
16426   emit_move_insn (operands[2], temp);
16427   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16428 })
16429
16430 (define_expand "ldexpdf3"
16431   [(set (match_dup 3)
16432         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16433    (set (match_dup 4)
16434         (float:XF (match_operand:SI 2 "register_operand" "")))
16435    (parallel [(set (match_dup 5)
16436                    (unspec:XF [(match_dup 3) (match_dup 4)]
16437                               UNSPEC_FSCALE_FRACT))
16438               (set (match_dup 6)
16439                    (unspec:XF [(match_dup 3) (match_dup 4)]
16440                               UNSPEC_FSCALE_EXP))])
16441    (set (match_operand:DF 0 "register_operand" "")
16442         (float_truncate:DF (match_dup 5)))]
16443   "TARGET_USE_FANCY_MATH_387
16444    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16445    && flag_unsafe_math_optimizations"
16446 {
16447   int i;
16448
16449   for (i=3; i<7; i++)
16450     operands[i] = gen_reg_rtx (XFmode);
16451 })
16452
16453 (define_expand "ldexpsf3"
16454   [(set (match_dup 3)
16455         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16456    (set (match_dup 4)
16457         (float:XF (match_operand:SI 2 "register_operand" "")))
16458    (parallel [(set (match_dup 5)
16459                    (unspec:XF [(match_dup 3) (match_dup 4)]
16460                               UNSPEC_FSCALE_FRACT))
16461               (set (match_dup 6)
16462                    (unspec:XF [(match_dup 3) (match_dup 4)]
16463                               UNSPEC_FSCALE_EXP))])
16464    (set (match_operand:SF 0 "register_operand" "")
16465         (float_truncate:SF (match_dup 5)))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16468    && flag_unsafe_math_optimizations"
16469 {
16470   int i;
16471
16472   for (i=3; i<7; i++)
16473     operands[i] = gen_reg_rtx (XFmode);
16474 })
16475
16476 (define_expand "ldexpxf3"
16477   [(set (match_dup 3)
16478         (float:XF (match_operand:SI 2 "register_operand" "")))
16479    (parallel [(set (match_operand:XF 0 " register_operand" "")
16480                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16481                                (match_dup 3)]
16482                               UNSPEC_FSCALE_FRACT))
16483               (set (match_dup 4)
16484                    (unspec:XF [(match_dup 1) (match_dup 3)]
16485                               UNSPEC_FSCALE_EXP))])]
16486   "TARGET_USE_FANCY_MATH_387
16487    && flag_unsafe_math_optimizations"
16488 {
16489   int i;
16490
16491   for (i=3; i<5; i++)
16492     operands[i] = gen_reg_rtx (XFmode);
16493 })
16494 \f
16495
16496 (define_insn "frndintxf2"
16497   [(set (match_operand:XF 0 "register_operand" "=f")
16498         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16499          UNSPEC_FRNDINT))]
16500   "TARGET_USE_FANCY_MATH_387
16501    && flag_unsafe_math_optimizations"
16502   "frndint"
16503   [(set_attr "type" "fpspc")
16504    (set_attr "mode" "XF")])
16505
16506 (define_expand "rintdf2"
16507   [(use (match_operand:DF 0 "register_operand" ""))
16508    (use (match_operand:DF 1 "register_operand" ""))]
16509   "TARGET_USE_FANCY_MATH_387
16510    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16511    && flag_unsafe_math_optimizations"
16512 {
16513   rtx op0 = gen_reg_rtx (XFmode);
16514   rtx op1 = gen_reg_rtx (XFmode);
16515
16516   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16517   emit_insn (gen_frndintxf2 (op0, op1));
16518
16519   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16520   DONE;
16521 })
16522
16523 (define_expand "rintsf2"
16524   [(use (match_operand:SF 0 "register_operand" ""))
16525    (use (match_operand:SF 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16528    && flag_unsafe_math_optimizations"
16529 {
16530   rtx op0 = gen_reg_rtx (XFmode);
16531   rtx op1 = gen_reg_rtx (XFmode);
16532
16533   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16534   emit_insn (gen_frndintxf2 (op0, op1));
16535
16536   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16537   DONE;
16538 })
16539
16540 (define_expand "rintxf2"
16541   [(use (match_operand:XF 0 "register_operand" ""))
16542    (use (match_operand:XF 1 "register_operand" ""))]
16543   "TARGET_USE_FANCY_MATH_387
16544    && flag_unsafe_math_optimizations"
16545 {
16546   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16547   DONE;
16548 })
16549
16550 (define_insn_and_split "*fistdi2_1"
16551   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16552         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16553          UNSPEC_FIST))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && flag_unsafe_math_optimizations
16556    && !(reload_completed || reload_in_progress)"
16557   "#"
16558   "&& 1"
16559   [(const_int 0)]
16560 {
16561   if (memory_operand (operands[0], VOIDmode))
16562     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16563   else
16564     {
16565       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16566       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16567                                          operands[2]));
16568     }
16569   DONE;
16570 }
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "DI")])
16573
16574 (define_insn "fistdi2"
16575   [(set (match_operand:DI 0 "memory_operand" "=m")
16576         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16577          UNSPEC_FIST))
16578    (clobber (match_scratch:XF 2 "=&1f"))]
16579   "TARGET_USE_FANCY_MATH_387
16580    && flag_unsafe_math_optimizations"
16581   "* return output_fix_trunc (insn, operands, 0);"
16582   [(set_attr "type" "fpspc")
16583    (set_attr "mode" "DI")])
16584
16585 (define_insn "fistdi2_with_temp"
16586   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16587         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16588          UNSPEC_FIST))
16589    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16590    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16591   "TARGET_USE_FANCY_MATH_387
16592    && flag_unsafe_math_optimizations"
16593   "#"
16594   [(set_attr "type" "fpspc")
16595    (set_attr "mode" "DI")])
16596
16597 (define_split 
16598   [(set (match_operand:DI 0 "register_operand" "")
16599         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16600          UNSPEC_FIST))
16601    (clobber (match_operand:DI 2 "memory_operand" ""))
16602    (clobber (match_scratch 3 ""))]
16603   "reload_completed"
16604   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16605               (clobber (match_dup 3))])
16606    (set (match_dup 0) (match_dup 2))]
16607   "")
16608
16609 (define_split 
16610   [(set (match_operand:DI 0 "memory_operand" "")
16611         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16612          UNSPEC_FIST))
16613    (clobber (match_operand:DI 2 "memory_operand" ""))
16614    (clobber (match_scratch 3 ""))]
16615   "reload_completed"
16616   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16617               (clobber (match_dup 3))])]
16618   "")
16619
16620 (define_insn_and_split "*fist<mode>2_1"
16621   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16622         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16623          UNSPEC_FIST))]
16624   "TARGET_USE_FANCY_MATH_387
16625    && flag_unsafe_math_optimizations
16626    && !(reload_completed || reload_in_progress)"
16627   "#"
16628   "&& 1"
16629   [(const_int 0)]
16630 {
16631   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16632   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16633                                         operands[2]));
16634   DONE;
16635 }
16636   [(set_attr "type" "fpspc")
16637    (set_attr "mode" "<MODE>")])
16638
16639 (define_insn "fist<mode>2"
16640   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16641         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16642          UNSPEC_FIST))]
16643   "TARGET_USE_FANCY_MATH_387
16644    && flag_unsafe_math_optimizations"
16645   "* return output_fix_trunc (insn, operands, 0);"
16646   [(set_attr "type" "fpspc")
16647    (set_attr "mode" "<MODE>")])
16648
16649 (define_insn "fist<mode>2_with_temp"
16650   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16651         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16652          UNSPEC_FIST))
16653    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations"
16656   "#"
16657   [(set_attr "type" "fpspc")
16658    (set_attr "mode" "<MODE>")])
16659
16660 (define_split 
16661   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16662         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16663          UNSPEC_FIST))
16664    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16665   "reload_completed"
16666   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16667                        UNSPEC_FIST))
16668    (set (match_dup 0) (match_dup 2))]
16669   "")
16670
16671 (define_split 
16672   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16673         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16674          UNSPEC_FIST))
16675    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16676   "reload_completed"
16677   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16678                        UNSPEC_FIST))]
16679   "")
16680
16681 (define_expand "lrint<mode>2"
16682   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16683         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16684          UNSPEC_FIST))]
16685   "TARGET_USE_FANCY_MATH_387
16686    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16687    && flag_unsafe_math_optimizations"
16688   "")
16689
16690 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16691 (define_insn_and_split "frndintxf2_floor"
16692   [(set (match_operand:XF 0 "register_operand" "=f")
16693         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16694          UNSPEC_FRNDINT_FLOOR))
16695    (clobber (reg:CC FLAGS_REG))]
16696   "TARGET_USE_FANCY_MATH_387
16697    && flag_unsafe_math_optimizations
16698    && !(reload_completed || reload_in_progress)"
16699   "#"
16700   "&& 1"
16701   [(const_int 0)]
16702 {
16703   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16704
16705   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16706   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16707
16708   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16709                                         operands[2], operands[3]));
16710   DONE;
16711 }
16712   [(set_attr "type" "frndint")
16713    (set_attr "i387_cw" "floor")
16714    (set_attr "mode" "XF")])
16715
16716 (define_insn "frndintxf2_floor_i387"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16719          UNSPEC_FRNDINT_FLOOR))
16720    (use (match_operand:HI 2 "memory_operand" "m"))
16721    (use (match_operand:HI 3 "memory_operand" "m"))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && flag_unsafe_math_optimizations"
16724   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16725   [(set_attr "type" "frndint")
16726    (set_attr "i387_cw" "floor")
16727    (set_attr "mode" "XF")])
16728
16729 (define_expand "floorxf2"
16730   [(use (match_operand:XF 0 "register_operand" ""))
16731    (use (match_operand:XF 1 "register_operand" ""))]
16732   "TARGET_USE_FANCY_MATH_387
16733    && flag_unsafe_math_optimizations"
16734 {
16735   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16736   DONE;
16737 })
16738
16739 (define_expand "floordf2"
16740   [(use (match_operand:DF 0 "register_operand" ""))
16741    (use (match_operand:DF 1 "register_operand" ""))]
16742   "TARGET_USE_FANCY_MATH_387
16743    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16744    && flag_unsafe_math_optimizations"
16745 {
16746   rtx op0 = gen_reg_rtx (XFmode);
16747   rtx op1 = gen_reg_rtx (XFmode);
16748
16749   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16750   emit_insn (gen_frndintxf2_floor (op0, op1));
16751
16752   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16753   DONE;
16754 })
16755
16756 (define_expand "floorsf2"
16757   [(use (match_operand:SF 0 "register_operand" ""))
16758    (use (match_operand:SF 1 "register_operand" ""))]
16759   "TARGET_USE_FANCY_MATH_387
16760    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16761    && flag_unsafe_math_optimizations"
16762 {
16763   rtx op0 = gen_reg_rtx (XFmode);
16764   rtx op1 = gen_reg_rtx (XFmode);
16765
16766   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16767   emit_insn (gen_frndintxf2_floor (op0, op1));
16768
16769   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16770   DONE;
16771 })
16772
16773 (define_insn_and_split "*fist<mode>2_floor_1"
16774   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16775         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16776          UNSPEC_FIST_FLOOR))
16777    (clobber (reg:CC FLAGS_REG))]
16778   "TARGET_USE_FANCY_MATH_387
16779    && flag_unsafe_math_optimizations
16780    && !(reload_completed || reload_in_progress)"
16781   "#"
16782   "&& 1"
16783   [(const_int 0)]
16784 {
16785   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16786
16787   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16788   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16789   if (memory_operand (operands[0], VOIDmode))
16790     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16791                                       operands[2], operands[3]));
16792   else
16793     {
16794       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16795       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16796                                                   operands[2], operands[3],
16797                                                   operands[4]));
16798     }
16799   DONE;
16800 }
16801   [(set_attr "type" "fistp")
16802    (set_attr "i387_cw" "floor")
16803    (set_attr "mode" "<MODE>")])
16804
16805 (define_insn "fistdi2_floor"
16806   [(set (match_operand:DI 0 "memory_operand" "=m")
16807         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16808          UNSPEC_FIST_FLOOR))
16809    (use (match_operand:HI 2 "memory_operand" "m"))
16810    (use (match_operand:HI 3 "memory_operand" "m"))
16811    (clobber (match_scratch:XF 4 "=&1f"))]
16812   "TARGET_USE_FANCY_MATH_387
16813    && flag_unsafe_math_optimizations"
16814   "* return output_fix_trunc (insn, operands, 0);"
16815   [(set_attr "type" "fistp")
16816    (set_attr "i387_cw" "floor")
16817    (set_attr "mode" "DI")])
16818
16819 (define_insn "fistdi2_floor_with_temp"
16820   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16821         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16822          UNSPEC_FIST_FLOOR))
16823    (use (match_operand:HI 2 "memory_operand" "m,m"))
16824    (use (match_operand:HI 3 "memory_operand" "m,m"))
16825    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16826    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16827   "TARGET_USE_FANCY_MATH_387
16828    && flag_unsafe_math_optimizations"
16829   "#"
16830   [(set_attr "type" "fistp")
16831    (set_attr "i387_cw" "floor")
16832    (set_attr "mode" "DI")])
16833
16834 (define_split 
16835   [(set (match_operand:DI 0 "register_operand" "")
16836         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16837          UNSPEC_FIST_FLOOR))
16838    (use (match_operand:HI 2 "memory_operand" ""))
16839    (use (match_operand:HI 3 "memory_operand" ""))
16840    (clobber (match_operand:DI 4 "memory_operand" ""))
16841    (clobber (match_scratch 5 ""))]
16842   "reload_completed"
16843   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16844               (use (match_dup 2))
16845               (use (match_dup 3))
16846               (clobber (match_dup 5))])
16847    (set (match_dup 0) (match_dup 4))]
16848   "")
16849
16850 (define_split 
16851   [(set (match_operand:DI 0 "memory_operand" "")
16852         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16853          UNSPEC_FIST_FLOOR))
16854    (use (match_operand:HI 2 "memory_operand" ""))
16855    (use (match_operand:HI 3 "memory_operand" ""))
16856    (clobber (match_operand:DI 4 "memory_operand" ""))
16857    (clobber (match_scratch 5 ""))]
16858   "reload_completed"
16859   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16860               (use (match_dup 2))
16861               (use (match_dup 3))
16862               (clobber (match_dup 5))])]
16863   "")
16864
16865 (define_insn "fist<mode>2_floor"
16866   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16867         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16868          UNSPEC_FIST_FLOOR))
16869    (use (match_operand:HI 2 "memory_operand" "m"))
16870    (use (match_operand:HI 3 "memory_operand" "m"))]
16871   "TARGET_USE_FANCY_MATH_387
16872    && flag_unsafe_math_optimizations"
16873   "* return output_fix_trunc (insn, operands, 0);"
16874   [(set_attr "type" "fistp")
16875    (set_attr "i387_cw" "floor")
16876    (set_attr "mode" "<MODE>")])
16877
16878 (define_insn "fist<mode>2_floor_with_temp"
16879   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16880         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16881          UNSPEC_FIST_FLOOR))
16882    (use (match_operand:HI 2 "memory_operand" "m,m"))
16883    (use (match_operand:HI 3 "memory_operand" "m,m"))
16884    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16885   "TARGET_USE_FANCY_MATH_387
16886    && flag_unsafe_math_optimizations"
16887   "#"
16888   [(set_attr "type" "fistp")
16889    (set_attr "i387_cw" "floor")
16890    (set_attr "mode" "<MODE>")])
16891
16892 (define_split 
16893   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16894         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16895          UNSPEC_FIST_FLOOR))
16896    (use (match_operand:HI 2 "memory_operand" ""))
16897    (use (match_operand:HI 3 "memory_operand" ""))
16898    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16899   "reload_completed"
16900   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16901                                   UNSPEC_FIST_FLOOR))
16902               (use (match_dup 2))
16903               (use (match_dup 3))])
16904    (set (match_dup 0) (match_dup 4))]
16905   "")
16906
16907 (define_split 
16908   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16909         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16910          UNSPEC_FIST_FLOOR))
16911    (use (match_operand:HI 2 "memory_operand" ""))
16912    (use (match_operand:HI 3 "memory_operand" ""))
16913    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16914   "reload_completed"
16915   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16916                                   UNSPEC_FIST_FLOOR))
16917               (use (match_dup 2))
16918               (use (match_dup 3))])]
16919   "")
16920
16921 (define_expand "lfloor<mode>2"
16922   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16923                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16924                     UNSPEC_FIST_FLOOR))
16925               (clobber (reg:CC FLAGS_REG))])]
16926   "TARGET_USE_FANCY_MATH_387
16927    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16928    && flag_unsafe_math_optimizations"
16929   "")
16930
16931 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16932 (define_insn_and_split "frndintxf2_ceil"
16933   [(set (match_operand:XF 0 "register_operand" "=f")
16934         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16935          UNSPEC_FRNDINT_CEIL))
16936    (clobber (reg:CC FLAGS_REG))]
16937   "TARGET_USE_FANCY_MATH_387
16938    && flag_unsafe_math_optimizations
16939    && !(reload_completed || reload_in_progress)"
16940   "#"
16941   "&& 1"
16942   [(const_int 0)]
16943 {
16944   ix86_optimize_mode_switching[I387_CEIL] = 1;
16945
16946   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16947   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16948
16949   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16950                                        operands[2], operands[3]));
16951   DONE;
16952 }
16953   [(set_attr "type" "frndint")
16954    (set_attr "i387_cw" "ceil")
16955    (set_attr "mode" "XF")])
16956
16957 (define_insn "frndintxf2_ceil_i387"
16958   [(set (match_operand:XF 0 "register_operand" "=f")
16959         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16960          UNSPEC_FRNDINT_CEIL))
16961    (use (match_operand:HI 2 "memory_operand" "m"))
16962    (use (match_operand:HI 3 "memory_operand" "m"))]
16963   "TARGET_USE_FANCY_MATH_387
16964    && flag_unsafe_math_optimizations"
16965   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16966   [(set_attr "type" "frndint")
16967    (set_attr "i387_cw" "ceil")
16968    (set_attr "mode" "XF")])
16969
16970 (define_expand "ceilxf2"
16971   [(use (match_operand:XF 0 "register_operand" ""))
16972    (use (match_operand:XF 1 "register_operand" ""))]
16973   "TARGET_USE_FANCY_MATH_387
16974    && flag_unsafe_math_optimizations"
16975 {
16976   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16977   DONE;
16978 })
16979
16980 (define_expand "ceildf2"
16981   [(use (match_operand:DF 0 "register_operand" ""))
16982    (use (match_operand:DF 1 "register_operand" ""))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16985    && flag_unsafe_math_optimizations"
16986 {
16987   rtx op0 = gen_reg_rtx (XFmode);
16988   rtx op1 = gen_reg_rtx (XFmode);
16989
16990   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16991   emit_insn (gen_frndintxf2_ceil (op0, op1));
16992
16993   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16994   DONE;
16995 })
16996
16997 (define_expand "ceilsf2"
16998   [(use (match_operand:SF 0 "register_operand" ""))
16999    (use (match_operand:SF 1 "register_operand" ""))]
17000   "TARGET_USE_FANCY_MATH_387
17001    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17002    && flag_unsafe_math_optimizations"
17003 {
17004   rtx op0 = gen_reg_rtx (XFmode);
17005   rtx op1 = gen_reg_rtx (XFmode);
17006
17007   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17008   emit_insn (gen_frndintxf2_ceil (op0, op1));
17009
17010   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17011   DONE;
17012 })
17013
17014 (define_insn_and_split "*fist<mode>2_ceil_1"
17015   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17016         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17017          UNSPEC_FIST_CEIL))
17018    (clobber (reg:CC FLAGS_REG))]
17019   "TARGET_USE_FANCY_MATH_387
17020    && flag_unsafe_math_optimizations
17021    && !(reload_completed || reload_in_progress)"
17022   "#"
17023   "&& 1"
17024   [(const_int 0)]
17025 {
17026   ix86_optimize_mode_switching[I387_CEIL] = 1;
17027
17028   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17029   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17030   if (memory_operand (operands[0], VOIDmode))
17031     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17032                                      operands[2], operands[3]));
17033   else
17034     {
17035       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17036       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17037                                                  operands[2], operands[3],
17038                                                  operands[4]));
17039     }
17040   DONE;
17041 }
17042   [(set_attr "type" "fistp")
17043    (set_attr "i387_cw" "ceil")
17044    (set_attr "mode" "<MODE>")])
17045
17046 (define_insn "fistdi2_ceil"
17047   [(set (match_operand:DI 0 "memory_operand" "=m")
17048         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17049          UNSPEC_FIST_CEIL))
17050    (use (match_operand:HI 2 "memory_operand" "m"))
17051    (use (match_operand:HI 3 "memory_operand" "m"))
17052    (clobber (match_scratch:XF 4 "=&1f"))]
17053   "TARGET_USE_FANCY_MATH_387
17054    && flag_unsafe_math_optimizations"
17055   "* return output_fix_trunc (insn, operands, 0);"
17056   [(set_attr "type" "fistp")
17057    (set_attr "i387_cw" "ceil")
17058    (set_attr "mode" "DI")])
17059
17060 (define_insn "fistdi2_ceil_with_temp"
17061   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17062         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17063          UNSPEC_FIST_CEIL))
17064    (use (match_operand:HI 2 "memory_operand" "m,m"))
17065    (use (match_operand:HI 3 "memory_operand" "m,m"))
17066    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17067    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17068   "TARGET_USE_FANCY_MATH_387
17069    && flag_unsafe_math_optimizations"
17070   "#"
17071   [(set_attr "type" "fistp")
17072    (set_attr "i387_cw" "ceil")
17073    (set_attr "mode" "DI")])
17074
17075 (define_split 
17076   [(set (match_operand:DI 0 "register_operand" "")
17077         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17078          UNSPEC_FIST_CEIL))
17079    (use (match_operand:HI 2 "memory_operand" ""))
17080    (use (match_operand:HI 3 "memory_operand" ""))
17081    (clobber (match_operand:DI 4 "memory_operand" ""))
17082    (clobber (match_scratch 5 ""))]
17083   "reload_completed"
17084   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17085               (use (match_dup 2))
17086               (use (match_dup 3))
17087               (clobber (match_dup 5))])
17088    (set (match_dup 0) (match_dup 4))]
17089   "")
17090
17091 (define_split 
17092   [(set (match_operand:DI 0 "memory_operand" "")
17093         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17094          UNSPEC_FIST_CEIL))
17095    (use (match_operand:HI 2 "memory_operand" ""))
17096    (use (match_operand:HI 3 "memory_operand" ""))
17097    (clobber (match_operand:DI 4 "memory_operand" ""))
17098    (clobber (match_scratch 5 ""))]
17099   "reload_completed"
17100   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17101               (use (match_dup 2))
17102               (use (match_dup 3))
17103               (clobber (match_dup 5))])]
17104   "")
17105
17106 (define_insn "fist<mode>2_ceil"
17107   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17108         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17109          UNSPEC_FIST_CEIL))
17110    (use (match_operand:HI 2 "memory_operand" "m"))
17111    (use (match_operand:HI 3 "memory_operand" "m"))]
17112   "TARGET_USE_FANCY_MATH_387
17113    && flag_unsafe_math_optimizations"
17114   "* return output_fix_trunc (insn, operands, 0);"
17115   [(set_attr "type" "fistp")
17116    (set_attr "i387_cw" "ceil")
17117    (set_attr "mode" "<MODE>")])
17118
17119 (define_insn "fist<mode>2_ceil_with_temp"
17120   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17121         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17122          UNSPEC_FIST_CEIL))
17123    (use (match_operand:HI 2 "memory_operand" "m,m"))
17124    (use (match_operand:HI 3 "memory_operand" "m,m"))
17125    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17126   "TARGET_USE_FANCY_MATH_387
17127    && flag_unsafe_math_optimizations"
17128   "#"
17129   [(set_attr "type" "fistp")
17130    (set_attr "i387_cw" "ceil")
17131    (set_attr "mode" "<MODE>")])
17132
17133 (define_split 
17134   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17135         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17136          UNSPEC_FIST_CEIL))
17137    (use (match_operand:HI 2 "memory_operand" ""))
17138    (use (match_operand:HI 3 "memory_operand" ""))
17139    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17140   "reload_completed"
17141   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17142                                   UNSPEC_FIST_CEIL))
17143               (use (match_dup 2))
17144               (use (match_dup 3))])
17145    (set (match_dup 0) (match_dup 4))]
17146   "")
17147
17148 (define_split 
17149   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17150         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17151          UNSPEC_FIST_CEIL))
17152    (use (match_operand:HI 2 "memory_operand" ""))
17153    (use (match_operand:HI 3 "memory_operand" ""))
17154    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17155   "reload_completed"
17156   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17157                                   UNSPEC_FIST_CEIL))
17158               (use (match_dup 2))
17159               (use (match_dup 3))])]
17160   "")
17161
17162 (define_expand "lceil<mode>2"
17163   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17164                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17165                     UNSPEC_FIST_CEIL))
17166               (clobber (reg:CC FLAGS_REG))])]
17167   "TARGET_USE_FANCY_MATH_387
17168    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17169    && flag_unsafe_math_optimizations"
17170   "")
17171
17172 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17173 (define_insn_and_split "frndintxf2_trunc"
17174   [(set (match_operand:XF 0 "register_operand" "=f")
17175         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17176          UNSPEC_FRNDINT_TRUNC))
17177    (clobber (reg:CC FLAGS_REG))]
17178   "TARGET_USE_FANCY_MATH_387
17179    && flag_unsafe_math_optimizations
17180    && !(reload_completed || reload_in_progress)"
17181   "#"
17182   "&& 1"
17183   [(const_int 0)]
17184 {
17185   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17186
17187   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17188   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17189
17190   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17191                                         operands[2], operands[3]));
17192   DONE;
17193 }
17194   [(set_attr "type" "frndint")
17195    (set_attr "i387_cw" "trunc")
17196    (set_attr "mode" "XF")])
17197
17198 (define_insn "frndintxf2_trunc_i387"
17199   [(set (match_operand:XF 0 "register_operand" "=f")
17200         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17201          UNSPEC_FRNDINT_TRUNC))
17202    (use (match_operand:HI 2 "memory_operand" "m"))
17203    (use (match_operand:HI 3 "memory_operand" "m"))]
17204   "TARGET_USE_FANCY_MATH_387
17205    && flag_unsafe_math_optimizations"
17206   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17207   [(set_attr "type" "frndint")
17208    (set_attr "i387_cw" "trunc")
17209    (set_attr "mode" "XF")])
17210
17211 (define_expand "btruncxf2"
17212   [(use (match_operand:XF 0 "register_operand" ""))
17213    (use (match_operand:XF 1 "register_operand" ""))]
17214   "TARGET_USE_FANCY_MATH_387
17215    && flag_unsafe_math_optimizations"
17216 {
17217   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17218   DONE;
17219 })
17220
17221 (define_expand "btruncdf2"
17222   [(use (match_operand:DF 0 "register_operand" ""))
17223    (use (match_operand:DF 1 "register_operand" ""))]
17224   "TARGET_USE_FANCY_MATH_387
17225    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17226    && flag_unsafe_math_optimizations"
17227 {
17228   rtx op0 = gen_reg_rtx (XFmode);
17229   rtx op1 = gen_reg_rtx (XFmode);
17230
17231   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17232   emit_insn (gen_frndintxf2_trunc (op0, op1));
17233
17234   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17235   DONE;
17236 })
17237
17238 (define_expand "btruncsf2"
17239   [(use (match_operand:SF 0 "register_operand" ""))
17240    (use (match_operand:SF 1 "register_operand" ""))]
17241   "TARGET_USE_FANCY_MATH_387
17242    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17243    && flag_unsafe_math_optimizations"
17244 {
17245   rtx op0 = gen_reg_rtx (XFmode);
17246   rtx op1 = gen_reg_rtx (XFmode);
17247
17248   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17249   emit_insn (gen_frndintxf2_trunc (op0, op1));
17250
17251   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17252   DONE;
17253 })
17254
17255 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17256 (define_insn_and_split "frndintxf2_mask_pm"
17257   [(set (match_operand:XF 0 "register_operand" "=f")
17258         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17259          UNSPEC_FRNDINT_MASK_PM))
17260    (clobber (reg:CC FLAGS_REG))]
17261   "TARGET_USE_FANCY_MATH_387
17262    && flag_unsafe_math_optimizations
17263    && !(reload_completed || reload_in_progress)"
17264   "#"
17265   "&& 1"
17266   [(const_int 0)]
17267 {
17268   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17269
17270   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17271   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17272
17273   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17274                                           operands[2], operands[3]));
17275   DONE;
17276 }
17277   [(set_attr "type" "frndint")
17278    (set_attr "i387_cw" "mask_pm")
17279    (set_attr "mode" "XF")])
17280
17281 (define_insn "frndintxf2_mask_pm_i387"
17282   [(set (match_operand:XF 0 "register_operand" "=f")
17283         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17284          UNSPEC_FRNDINT_MASK_PM))
17285    (use (match_operand:HI 2 "memory_operand" "m"))
17286    (use (match_operand:HI 3 "memory_operand" "m"))]
17287   "TARGET_USE_FANCY_MATH_387
17288    && flag_unsafe_math_optimizations"
17289   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17290   [(set_attr "type" "frndint")
17291    (set_attr "i387_cw" "mask_pm")
17292    (set_attr "mode" "XF")])
17293
17294 (define_expand "nearbyintxf2"
17295   [(use (match_operand:XF 0 "register_operand" ""))
17296    (use (match_operand:XF 1 "register_operand" ""))]
17297   "TARGET_USE_FANCY_MATH_387
17298    && flag_unsafe_math_optimizations"
17299 {
17300   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17301
17302   DONE;
17303 })
17304
17305 (define_expand "nearbyintdf2"
17306   [(use (match_operand:DF 0 "register_operand" ""))
17307    (use (match_operand:DF 1 "register_operand" ""))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17310    && flag_unsafe_math_optimizations"
17311 {
17312   rtx op0 = gen_reg_rtx (XFmode);
17313   rtx op1 = gen_reg_rtx (XFmode);
17314
17315   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17316   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17317
17318   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17319   DONE;
17320 })
17321
17322 (define_expand "nearbyintsf2"
17323   [(use (match_operand:SF 0 "register_operand" ""))
17324    (use (match_operand:SF 1 "register_operand" ""))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17327    && flag_unsafe_math_optimizations"
17328 {
17329   rtx op0 = gen_reg_rtx (XFmode);
17330   rtx op1 = gen_reg_rtx (XFmode);
17331
17332   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17333   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17334
17335   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17336   DONE;
17337 })
17338
17339 \f
17340 ;; Block operation instructions
17341
17342 (define_insn "cld"
17343  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17344  ""
17345  "cld"
17346   [(set_attr "type" "cld")])
17347
17348 (define_expand "movmemsi"
17349   [(use (match_operand:BLK 0 "memory_operand" ""))
17350    (use (match_operand:BLK 1 "memory_operand" ""))
17351    (use (match_operand:SI 2 "nonmemory_operand" ""))
17352    (use (match_operand:SI 3 "const_int_operand" ""))]
17353   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17354 {
17355  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17356    DONE;
17357  else
17358    FAIL;
17359 })
17360
17361 (define_expand "movmemdi"
17362   [(use (match_operand:BLK 0 "memory_operand" ""))
17363    (use (match_operand:BLK 1 "memory_operand" ""))
17364    (use (match_operand:DI 2 "nonmemory_operand" ""))
17365    (use (match_operand:DI 3 "const_int_operand" ""))]
17366   "TARGET_64BIT"
17367 {
17368  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17369    DONE;
17370  else
17371    FAIL;
17372 })
17373
17374 ;; Most CPUs don't like single string operations
17375 ;; Handle this case here to simplify previous expander.
17376
17377 (define_expand "strmov"
17378   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17379    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17380    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17381               (clobber (reg:CC FLAGS_REG))])
17382    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17383               (clobber (reg:CC FLAGS_REG))])]
17384   ""
17385 {
17386   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17387
17388   /* If .md ever supports :P for Pmode, these can be directly
17389      in the pattern above.  */
17390   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17391   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17392
17393   if (TARGET_SINGLE_STRINGOP || optimize_size)
17394     {
17395       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17396                                       operands[2], operands[3],
17397                                       operands[5], operands[6]));
17398       DONE;
17399     }
17400
17401   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17402 })
17403
17404 (define_expand "strmov_singleop"
17405   [(parallel [(set (match_operand 1 "memory_operand" "")
17406                    (match_operand 3 "memory_operand" ""))
17407               (set (match_operand 0 "register_operand" "")
17408                    (match_operand 4 "" ""))
17409               (set (match_operand 2 "register_operand" "")
17410                    (match_operand 5 "" ""))
17411               (use (reg:SI DIRFLAG_REG))])]
17412   "TARGET_SINGLE_STRINGOP || optimize_size"
17413   "")
17414
17415 (define_insn "*strmovdi_rex_1"
17416   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17417         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17418    (set (match_operand:DI 0 "register_operand" "=D")
17419         (plus:DI (match_dup 2)
17420                  (const_int 8)))
17421    (set (match_operand:DI 1 "register_operand" "=S")
17422         (plus:DI (match_dup 3)
17423                  (const_int 8)))
17424    (use (reg:SI DIRFLAG_REG))]
17425   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17426   "movsq"
17427   [(set_attr "type" "str")
17428    (set_attr "mode" "DI")
17429    (set_attr "memory" "both")])
17430
17431 (define_insn "*strmovsi_1"
17432   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17433         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17434    (set (match_operand:SI 0 "register_operand" "=D")
17435         (plus:SI (match_dup 2)
17436                  (const_int 4)))
17437    (set (match_operand:SI 1 "register_operand" "=S")
17438         (plus:SI (match_dup 3)
17439                  (const_int 4)))
17440    (use (reg:SI DIRFLAG_REG))]
17441   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17442   "{movsl|movsd}"
17443   [(set_attr "type" "str")
17444    (set_attr "mode" "SI")
17445    (set_attr "memory" "both")])
17446
17447 (define_insn "*strmovsi_rex_1"
17448   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17449         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17450    (set (match_operand:DI 0 "register_operand" "=D")
17451         (plus:DI (match_dup 2)
17452                  (const_int 4)))
17453    (set (match_operand:DI 1 "register_operand" "=S")
17454         (plus:DI (match_dup 3)
17455                  (const_int 4)))
17456    (use (reg:SI DIRFLAG_REG))]
17457   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17458   "{movsl|movsd}"
17459   [(set_attr "type" "str")
17460    (set_attr "mode" "SI")
17461    (set_attr "memory" "both")])
17462
17463 (define_insn "*strmovhi_1"
17464   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17465         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17466    (set (match_operand:SI 0 "register_operand" "=D")
17467         (plus:SI (match_dup 2)
17468                  (const_int 2)))
17469    (set (match_operand:SI 1 "register_operand" "=S")
17470         (plus:SI (match_dup 3)
17471                  (const_int 2)))
17472    (use (reg:SI DIRFLAG_REG))]
17473   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17474   "movsw"
17475   [(set_attr "type" "str")
17476    (set_attr "memory" "both")
17477    (set_attr "mode" "HI")])
17478
17479 (define_insn "*strmovhi_rex_1"
17480   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17481         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17482    (set (match_operand:DI 0 "register_operand" "=D")
17483         (plus:DI (match_dup 2)
17484                  (const_int 2)))
17485    (set (match_operand:DI 1 "register_operand" "=S")
17486         (plus:DI (match_dup 3)
17487                  (const_int 2)))
17488    (use (reg:SI DIRFLAG_REG))]
17489   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17490   "movsw"
17491   [(set_attr "type" "str")
17492    (set_attr "memory" "both")
17493    (set_attr "mode" "HI")])
17494
17495 (define_insn "*strmovqi_1"
17496   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17497         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17498    (set (match_operand:SI 0 "register_operand" "=D")
17499         (plus:SI (match_dup 2)
17500                  (const_int 1)))
17501    (set (match_operand:SI 1 "register_operand" "=S")
17502         (plus:SI (match_dup 3)
17503                  (const_int 1)))
17504    (use (reg:SI DIRFLAG_REG))]
17505   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17506   "movsb"
17507   [(set_attr "type" "str")
17508    (set_attr "memory" "both")
17509    (set_attr "mode" "QI")])
17510
17511 (define_insn "*strmovqi_rex_1"
17512   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17513         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17514    (set (match_operand:DI 0 "register_operand" "=D")
17515         (plus:DI (match_dup 2)
17516                  (const_int 1)))
17517    (set (match_operand:DI 1 "register_operand" "=S")
17518         (plus:DI (match_dup 3)
17519                  (const_int 1)))
17520    (use (reg:SI DIRFLAG_REG))]
17521   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17522   "movsb"
17523   [(set_attr "type" "str")
17524    (set_attr "memory" "both")
17525    (set_attr "mode" "QI")])
17526
17527 (define_expand "rep_mov"
17528   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17529               (set (match_operand 0 "register_operand" "")
17530                    (match_operand 5 "" ""))
17531               (set (match_operand 2 "register_operand" "")
17532                    (match_operand 6 "" ""))
17533               (set (match_operand 1 "memory_operand" "")
17534                    (match_operand 3 "memory_operand" ""))
17535               (use (match_dup 4))
17536               (use (reg:SI DIRFLAG_REG))])]
17537   ""
17538   "")
17539
17540 (define_insn "*rep_movdi_rex64"
17541   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17542    (set (match_operand:DI 0 "register_operand" "=D") 
17543         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17544                             (const_int 3))
17545                  (match_operand:DI 3 "register_operand" "0")))
17546    (set (match_operand:DI 1 "register_operand" "=S") 
17547         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17548                  (match_operand:DI 4 "register_operand" "1")))
17549    (set (mem:BLK (match_dup 3))
17550         (mem:BLK (match_dup 4)))
17551    (use (match_dup 5))
17552    (use (reg:SI DIRFLAG_REG))]
17553   "TARGET_64BIT"
17554   "{rep\;movsq|rep movsq}"
17555   [(set_attr "type" "str")
17556    (set_attr "prefix_rep" "1")
17557    (set_attr "memory" "both")
17558    (set_attr "mode" "DI")])
17559
17560 (define_insn "*rep_movsi"
17561   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17562    (set (match_operand:SI 0 "register_operand" "=D") 
17563         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17564                             (const_int 2))
17565                  (match_operand:SI 3 "register_operand" "0")))
17566    (set (match_operand:SI 1 "register_operand" "=S") 
17567         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17568                  (match_operand:SI 4 "register_operand" "1")))
17569    (set (mem:BLK (match_dup 3))
17570         (mem:BLK (match_dup 4)))
17571    (use (match_dup 5))
17572    (use (reg:SI DIRFLAG_REG))]
17573   "!TARGET_64BIT"
17574   "{rep\;movsl|rep movsd}"
17575   [(set_attr "type" "str")
17576    (set_attr "prefix_rep" "1")
17577    (set_attr "memory" "both")
17578    (set_attr "mode" "SI")])
17579
17580 (define_insn "*rep_movsi_rex64"
17581   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17582    (set (match_operand:DI 0 "register_operand" "=D") 
17583         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17584                             (const_int 2))
17585                  (match_operand:DI 3 "register_operand" "0")))
17586    (set (match_operand:DI 1 "register_operand" "=S") 
17587         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17588                  (match_operand:DI 4 "register_operand" "1")))
17589    (set (mem:BLK (match_dup 3))
17590         (mem:BLK (match_dup 4)))
17591    (use (match_dup 5))
17592    (use (reg:SI DIRFLAG_REG))]
17593   "TARGET_64BIT"
17594   "{rep\;movsl|rep movsd}"
17595   [(set_attr "type" "str")
17596    (set_attr "prefix_rep" "1")
17597    (set_attr "memory" "both")
17598    (set_attr "mode" "SI")])
17599
17600 (define_insn "*rep_movqi"
17601   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17602    (set (match_operand:SI 0 "register_operand" "=D") 
17603         (plus:SI (match_operand:SI 3 "register_operand" "0")
17604                  (match_operand:SI 5 "register_operand" "2")))
17605    (set (match_operand:SI 1 "register_operand" "=S") 
17606         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17607    (set (mem:BLK (match_dup 3))
17608         (mem:BLK (match_dup 4)))
17609    (use (match_dup 5))
17610    (use (reg:SI DIRFLAG_REG))]
17611   "!TARGET_64BIT"
17612   "{rep\;movsb|rep movsb}"
17613   [(set_attr "type" "str")
17614    (set_attr "prefix_rep" "1")
17615    (set_attr "memory" "both")
17616    (set_attr "mode" "SI")])
17617
17618 (define_insn "*rep_movqi_rex64"
17619   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17620    (set (match_operand:DI 0 "register_operand" "=D") 
17621         (plus:DI (match_operand:DI 3 "register_operand" "0")
17622                  (match_operand:DI 5 "register_operand" "2")))
17623    (set (match_operand:DI 1 "register_operand" "=S") 
17624         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17625    (set (mem:BLK (match_dup 3))
17626         (mem:BLK (match_dup 4)))
17627    (use (match_dup 5))
17628    (use (reg:SI DIRFLAG_REG))]
17629   "TARGET_64BIT"
17630   "{rep\;movsb|rep movsb}"
17631   [(set_attr "type" "str")
17632    (set_attr "prefix_rep" "1")
17633    (set_attr "memory" "both")
17634    (set_attr "mode" "SI")])
17635
17636 (define_expand "setmemsi"
17637    [(use (match_operand:BLK 0 "memory_operand" ""))
17638     (use (match_operand:SI 1 "nonmemory_operand" ""))
17639     (use (match_operand 2 "const_int_operand" ""))
17640     (use (match_operand 3 "const_int_operand" ""))]
17641   ""
17642 {
17643  /* If value to set is not zero, use the library routine.  */
17644  if (operands[2] != const0_rtx)
17645    FAIL;
17646
17647  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17648    DONE;
17649  else
17650    FAIL;
17651 })
17652
17653 (define_expand "setmemdi"
17654    [(use (match_operand:BLK 0 "memory_operand" ""))
17655     (use (match_operand:DI 1 "nonmemory_operand" ""))
17656     (use (match_operand 2 "const_int_operand" ""))
17657     (use (match_operand 3 "const_int_operand" ""))]
17658   "TARGET_64BIT"
17659 {
17660  /* If value to set is not zero, use the library routine.  */
17661  if (operands[2] != const0_rtx)
17662    FAIL;
17663
17664  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17665    DONE;
17666  else
17667    FAIL;
17668 })
17669
17670 ;; Most CPUs don't like single string operations
17671 ;; Handle this case here to simplify previous expander.
17672
17673 (define_expand "strset"
17674   [(set (match_operand 1 "memory_operand" "")
17675         (match_operand 2 "register_operand" ""))
17676    (parallel [(set (match_operand 0 "register_operand" "")
17677                    (match_dup 3))
17678               (clobber (reg:CC FLAGS_REG))])]
17679   ""
17680 {
17681   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17682     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17683
17684   /* If .md ever supports :P for Pmode, this can be directly
17685      in the pattern above.  */
17686   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17687                               GEN_INT (GET_MODE_SIZE (GET_MODE
17688                                                       (operands[2]))));
17689   if (TARGET_SINGLE_STRINGOP || optimize_size)
17690     {
17691       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17692                                       operands[3]));
17693       DONE;
17694     }
17695 })
17696
17697 (define_expand "strset_singleop"
17698   [(parallel [(set (match_operand 1 "memory_operand" "")
17699                    (match_operand 2 "register_operand" ""))
17700               (set (match_operand 0 "register_operand" "")
17701                    (match_operand 3 "" ""))
17702               (use (reg:SI DIRFLAG_REG))])]
17703   "TARGET_SINGLE_STRINGOP || optimize_size"
17704   "")
17705
17706 (define_insn "*strsetdi_rex_1"
17707   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17708         (match_operand:DI 2 "register_operand" "a"))
17709    (set (match_operand:DI 0 "register_operand" "=D")
17710         (plus:DI (match_dup 1)
17711                  (const_int 8)))
17712    (use (reg:SI DIRFLAG_REG))]
17713   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17714   "stosq"
17715   [(set_attr "type" "str")
17716    (set_attr "memory" "store")
17717    (set_attr "mode" "DI")])
17718
17719 (define_insn "*strsetsi_1"
17720   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17721         (match_operand:SI 2 "register_operand" "a"))
17722    (set (match_operand:SI 0 "register_operand" "=D")
17723         (plus:SI (match_dup 1)
17724                  (const_int 4)))
17725    (use (reg:SI DIRFLAG_REG))]
17726   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17727   "{stosl|stosd}"
17728   [(set_attr "type" "str")
17729    (set_attr "memory" "store")
17730    (set_attr "mode" "SI")])
17731
17732 (define_insn "*strsetsi_rex_1"
17733   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17734         (match_operand:SI 2 "register_operand" "a"))
17735    (set (match_operand:DI 0 "register_operand" "=D")
17736         (plus:DI (match_dup 1)
17737                  (const_int 4)))
17738    (use (reg:SI DIRFLAG_REG))]
17739   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17740   "{stosl|stosd}"
17741   [(set_attr "type" "str")
17742    (set_attr "memory" "store")
17743    (set_attr "mode" "SI")])
17744
17745 (define_insn "*strsethi_1"
17746   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17747         (match_operand:HI 2 "register_operand" "a"))
17748    (set (match_operand:SI 0 "register_operand" "=D")
17749         (plus:SI (match_dup 1)
17750                  (const_int 2)))
17751    (use (reg:SI DIRFLAG_REG))]
17752   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17753   "stosw"
17754   [(set_attr "type" "str")
17755    (set_attr "memory" "store")
17756    (set_attr "mode" "HI")])
17757
17758 (define_insn "*strsethi_rex_1"
17759   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17760         (match_operand:HI 2 "register_operand" "a"))
17761    (set (match_operand:DI 0 "register_operand" "=D")
17762         (plus:DI (match_dup 1)
17763                  (const_int 2)))
17764    (use (reg:SI DIRFLAG_REG))]
17765   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17766   "stosw"
17767   [(set_attr "type" "str")
17768    (set_attr "memory" "store")
17769    (set_attr "mode" "HI")])
17770
17771 (define_insn "*strsetqi_1"
17772   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17773         (match_operand:QI 2 "register_operand" "a"))
17774    (set (match_operand:SI 0 "register_operand" "=D")
17775         (plus:SI (match_dup 1)
17776                  (const_int 1)))
17777    (use (reg:SI DIRFLAG_REG))]
17778   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17779   "stosb"
17780   [(set_attr "type" "str")
17781    (set_attr "memory" "store")
17782    (set_attr "mode" "QI")])
17783
17784 (define_insn "*strsetqi_rex_1"
17785   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17786         (match_operand:QI 2 "register_operand" "a"))
17787    (set (match_operand:DI 0 "register_operand" "=D")
17788         (plus:DI (match_dup 1)
17789                  (const_int 1)))
17790    (use (reg:SI DIRFLAG_REG))]
17791   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17792   "stosb"
17793   [(set_attr "type" "str")
17794    (set_attr "memory" "store")
17795    (set_attr "mode" "QI")])
17796
17797 (define_expand "rep_stos"
17798   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17799               (set (match_operand 0 "register_operand" "")
17800                    (match_operand 4 "" ""))
17801               (set (match_operand 2 "memory_operand" "") (const_int 0))
17802               (use (match_operand 3 "register_operand" ""))
17803               (use (match_dup 1))
17804               (use (reg:SI DIRFLAG_REG))])]
17805   ""
17806   "")
17807
17808 (define_insn "*rep_stosdi_rex64"
17809   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17810    (set (match_operand:DI 0 "register_operand" "=D") 
17811         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17812                             (const_int 3))
17813                  (match_operand:DI 3 "register_operand" "0")))
17814    (set (mem:BLK (match_dup 3))
17815         (const_int 0))
17816    (use (match_operand:DI 2 "register_operand" "a"))
17817    (use (match_dup 4))
17818    (use (reg:SI DIRFLAG_REG))]
17819   "TARGET_64BIT"
17820   "{rep\;stosq|rep stosq}"
17821   [(set_attr "type" "str")
17822    (set_attr "prefix_rep" "1")
17823    (set_attr "memory" "store")
17824    (set_attr "mode" "DI")])
17825
17826 (define_insn "*rep_stossi"
17827   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17828    (set (match_operand:SI 0 "register_operand" "=D") 
17829         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17830                             (const_int 2))
17831                  (match_operand:SI 3 "register_operand" "0")))
17832    (set (mem:BLK (match_dup 3))
17833         (const_int 0))
17834    (use (match_operand:SI 2 "register_operand" "a"))
17835    (use (match_dup 4))
17836    (use (reg:SI DIRFLAG_REG))]
17837   "!TARGET_64BIT"
17838   "{rep\;stosl|rep stosd}"
17839   [(set_attr "type" "str")
17840    (set_attr "prefix_rep" "1")
17841    (set_attr "memory" "store")
17842    (set_attr "mode" "SI")])
17843
17844 (define_insn "*rep_stossi_rex64"
17845   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17846    (set (match_operand:DI 0 "register_operand" "=D") 
17847         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17848                             (const_int 2))
17849                  (match_operand:DI 3 "register_operand" "0")))
17850    (set (mem:BLK (match_dup 3))
17851         (const_int 0))
17852    (use (match_operand:SI 2 "register_operand" "a"))
17853    (use (match_dup 4))
17854    (use (reg:SI DIRFLAG_REG))]
17855   "TARGET_64BIT"
17856   "{rep\;stosl|rep stosd}"
17857   [(set_attr "type" "str")
17858    (set_attr "prefix_rep" "1")
17859    (set_attr "memory" "store")
17860    (set_attr "mode" "SI")])
17861
17862 (define_insn "*rep_stosqi"
17863   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17864    (set (match_operand:SI 0 "register_operand" "=D") 
17865         (plus:SI (match_operand:SI 3 "register_operand" "0")
17866                  (match_operand:SI 4 "register_operand" "1")))
17867    (set (mem:BLK (match_dup 3))
17868         (const_int 0))
17869    (use (match_operand:QI 2 "register_operand" "a"))
17870    (use (match_dup 4))
17871    (use (reg:SI DIRFLAG_REG))]
17872   "!TARGET_64BIT"
17873   "{rep\;stosb|rep stosb}"
17874   [(set_attr "type" "str")
17875    (set_attr "prefix_rep" "1")
17876    (set_attr "memory" "store")
17877    (set_attr "mode" "QI")])
17878
17879 (define_insn "*rep_stosqi_rex64"
17880   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17881    (set (match_operand:DI 0 "register_operand" "=D") 
17882         (plus:DI (match_operand:DI 3 "register_operand" "0")
17883                  (match_operand:DI 4 "register_operand" "1")))
17884    (set (mem:BLK (match_dup 3))
17885         (const_int 0))
17886    (use (match_operand:QI 2 "register_operand" "a"))
17887    (use (match_dup 4))
17888    (use (reg:SI DIRFLAG_REG))]
17889   "TARGET_64BIT"
17890   "{rep\;stosb|rep stosb}"
17891   [(set_attr "type" "str")
17892    (set_attr "prefix_rep" "1")
17893    (set_attr "memory" "store")
17894    (set_attr "mode" "QI")])
17895
17896 (define_expand "cmpstrnsi"
17897   [(set (match_operand:SI 0 "register_operand" "")
17898         (compare:SI (match_operand:BLK 1 "general_operand" "")
17899                     (match_operand:BLK 2 "general_operand" "")))
17900    (use (match_operand 3 "general_operand" ""))
17901    (use (match_operand 4 "immediate_operand" ""))]
17902   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17903 {
17904   rtx addr1, addr2, out, outlow, count, countreg, align;
17905
17906   /* Can't use this if the user has appropriated esi or edi.  */
17907   if (global_regs[4] || global_regs[5])
17908     FAIL;
17909
17910   out = operands[0];
17911   if (GET_CODE (out) != REG)
17912     out = gen_reg_rtx (SImode);
17913
17914   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17915   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17916   if (addr1 != XEXP (operands[1], 0))
17917     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17918   if (addr2 != XEXP (operands[2], 0))
17919     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17920
17921   count = operands[3];
17922   countreg = ix86_zero_extend_to_Pmode (count);
17923
17924   /* %%% Iff we are testing strict equality, we can use known alignment
17925      to good advantage.  This may be possible with combine, particularly
17926      once cc0 is dead.  */
17927   align = operands[4];
17928
17929   emit_insn (gen_cld ());
17930   if (GET_CODE (count) == CONST_INT)
17931     {
17932       if (INTVAL (count) == 0)
17933         {
17934           emit_move_insn (operands[0], const0_rtx);
17935           DONE;
17936         }
17937       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17938                                      operands[1], operands[2]));
17939     }
17940   else
17941     {
17942       if (TARGET_64BIT)
17943         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17944       else
17945         emit_insn (gen_cmpsi_1 (countreg, countreg));
17946       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17947                                   operands[1], operands[2]));
17948     }
17949
17950   outlow = gen_lowpart (QImode, out);
17951   emit_insn (gen_cmpintqi (outlow));
17952   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17953
17954   if (operands[0] != out)
17955     emit_move_insn (operands[0], out);
17956
17957   DONE;
17958 })
17959
17960 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17961
17962 (define_expand "cmpintqi"
17963   [(set (match_dup 1)
17964         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17965    (set (match_dup 2)
17966         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17967    (parallel [(set (match_operand:QI 0 "register_operand" "")
17968                    (minus:QI (match_dup 1)
17969                              (match_dup 2)))
17970               (clobber (reg:CC FLAGS_REG))])]
17971   ""
17972   "operands[1] = gen_reg_rtx (QImode);
17973    operands[2] = gen_reg_rtx (QImode);")
17974
17975 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17976 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17977
17978 (define_expand "cmpstrnqi_nz_1"
17979   [(parallel [(set (reg:CC FLAGS_REG)
17980                    (compare:CC (match_operand 4 "memory_operand" "")
17981                                (match_operand 5 "memory_operand" "")))
17982               (use (match_operand 2 "register_operand" ""))
17983               (use (match_operand:SI 3 "immediate_operand" ""))
17984               (use (reg:SI DIRFLAG_REG))
17985               (clobber (match_operand 0 "register_operand" ""))
17986               (clobber (match_operand 1 "register_operand" ""))
17987               (clobber (match_dup 2))])]
17988   ""
17989   "")
17990
17991 (define_insn "*cmpstrnqi_nz_1"
17992   [(set (reg:CC FLAGS_REG)
17993         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17994                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17995    (use (match_operand:SI 6 "register_operand" "2"))
17996    (use (match_operand:SI 3 "immediate_operand" "i"))
17997    (use (reg:SI DIRFLAG_REG))
17998    (clobber (match_operand:SI 0 "register_operand" "=S"))
17999    (clobber (match_operand:SI 1 "register_operand" "=D"))
18000    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18001   "!TARGET_64BIT"
18002   "repz{\;| }cmpsb"
18003   [(set_attr "type" "str")
18004    (set_attr "mode" "QI")
18005    (set_attr "prefix_rep" "1")])
18006
18007 (define_insn "*cmpstrnqi_nz_rex_1"
18008   [(set (reg:CC FLAGS_REG)
18009         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18010                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18011    (use (match_operand:DI 6 "register_operand" "2"))
18012    (use (match_operand:SI 3 "immediate_operand" "i"))
18013    (use (reg:SI DIRFLAG_REG))
18014    (clobber (match_operand:DI 0 "register_operand" "=S"))
18015    (clobber (match_operand:DI 1 "register_operand" "=D"))
18016    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18017   "TARGET_64BIT"
18018   "repz{\;| }cmpsb"
18019   [(set_attr "type" "str")
18020    (set_attr "mode" "QI")
18021    (set_attr "prefix_rep" "1")])
18022
18023 ;; The same, but the count is not known to not be zero.
18024
18025 (define_expand "cmpstrnqi_1"
18026   [(parallel [(set (reg:CC FLAGS_REG)
18027                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18028                                      (const_int 0))
18029                   (compare:CC (match_operand 4 "memory_operand" "")
18030                               (match_operand 5 "memory_operand" ""))
18031                   (const_int 0)))
18032               (use (match_operand:SI 3 "immediate_operand" ""))
18033               (use (reg:CC FLAGS_REG))
18034               (use (reg:SI DIRFLAG_REG))
18035               (clobber (match_operand 0 "register_operand" ""))
18036               (clobber (match_operand 1 "register_operand" ""))
18037               (clobber (match_dup 2))])]
18038   ""
18039   "")
18040
18041 (define_insn "*cmpstrnqi_1"
18042   [(set (reg:CC FLAGS_REG)
18043         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18044                              (const_int 0))
18045           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18046                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18047           (const_int 0)))
18048    (use (match_operand:SI 3 "immediate_operand" "i"))
18049    (use (reg:CC FLAGS_REG))
18050    (use (reg:SI DIRFLAG_REG))
18051    (clobber (match_operand:SI 0 "register_operand" "=S"))
18052    (clobber (match_operand:SI 1 "register_operand" "=D"))
18053    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18054   "!TARGET_64BIT"
18055   "repz{\;| }cmpsb"
18056   [(set_attr "type" "str")
18057    (set_attr "mode" "QI")
18058    (set_attr "prefix_rep" "1")])
18059
18060 (define_insn "*cmpstrnqi_rex_1"
18061   [(set (reg:CC FLAGS_REG)
18062         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18063                              (const_int 0))
18064           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18065                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18066           (const_int 0)))
18067    (use (match_operand:SI 3 "immediate_operand" "i"))
18068    (use (reg:CC FLAGS_REG))
18069    (use (reg:SI DIRFLAG_REG))
18070    (clobber (match_operand:DI 0 "register_operand" "=S"))
18071    (clobber (match_operand:DI 1 "register_operand" "=D"))
18072    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18073   "TARGET_64BIT"
18074   "repz{\;| }cmpsb"
18075   [(set_attr "type" "str")
18076    (set_attr "mode" "QI")
18077    (set_attr "prefix_rep" "1")])
18078
18079 (define_expand "strlensi"
18080   [(set (match_operand:SI 0 "register_operand" "")
18081         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18082                     (match_operand:QI 2 "immediate_operand" "")
18083                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18084   ""
18085 {
18086  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18087    DONE;
18088  else
18089    FAIL;
18090 })
18091
18092 (define_expand "strlendi"
18093   [(set (match_operand:DI 0 "register_operand" "")
18094         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18095                     (match_operand:QI 2 "immediate_operand" "")
18096                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18097   ""
18098 {
18099  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18100    DONE;
18101  else
18102    FAIL;
18103 })
18104
18105 (define_expand "strlenqi_1"
18106   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18107               (use (reg:SI DIRFLAG_REG))
18108               (clobber (match_operand 1 "register_operand" ""))
18109               (clobber (reg:CC FLAGS_REG))])]
18110   ""
18111   "")
18112
18113 (define_insn "*strlenqi_1"
18114   [(set (match_operand:SI 0 "register_operand" "=&c")
18115         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18116                     (match_operand:QI 2 "register_operand" "a")
18117                     (match_operand:SI 3 "immediate_operand" "i")
18118                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18119    (use (reg:SI DIRFLAG_REG))
18120    (clobber (match_operand:SI 1 "register_operand" "=D"))
18121    (clobber (reg:CC FLAGS_REG))]
18122   "!TARGET_64BIT"
18123   "repnz{\;| }scasb"
18124   [(set_attr "type" "str")
18125    (set_attr "mode" "QI")
18126    (set_attr "prefix_rep" "1")])
18127
18128 (define_insn "*strlenqi_rex_1"
18129   [(set (match_operand:DI 0 "register_operand" "=&c")
18130         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18131                     (match_operand:QI 2 "register_operand" "a")
18132                     (match_operand:DI 3 "immediate_operand" "i")
18133                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18134    (use (reg:SI DIRFLAG_REG))
18135    (clobber (match_operand:DI 1 "register_operand" "=D"))
18136    (clobber (reg:CC FLAGS_REG))]
18137   "TARGET_64BIT"
18138   "repnz{\;| }scasb"
18139   [(set_attr "type" "str")
18140    (set_attr "mode" "QI")
18141    (set_attr "prefix_rep" "1")])
18142
18143 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18144 ;; handled in combine, but it is not currently up to the task.
18145 ;; When used for their truth value, the cmpstrn* expanders generate
18146 ;; code like this:
18147 ;;
18148 ;;   repz cmpsb
18149 ;;   seta       %al
18150 ;;   setb       %dl
18151 ;;   cmpb       %al, %dl
18152 ;;   jcc        label
18153 ;;
18154 ;; The intermediate three instructions are unnecessary.
18155
18156 ;; This one handles cmpstrn*_nz_1...
18157 (define_peephole2
18158   [(parallel[
18159      (set (reg:CC FLAGS_REG)
18160           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18161                       (mem:BLK (match_operand 5 "register_operand" ""))))
18162      (use (match_operand 6 "register_operand" ""))
18163      (use (match_operand:SI 3 "immediate_operand" ""))
18164      (use (reg:SI DIRFLAG_REG))
18165      (clobber (match_operand 0 "register_operand" ""))
18166      (clobber (match_operand 1 "register_operand" ""))
18167      (clobber (match_operand 2 "register_operand" ""))])
18168    (set (match_operand:QI 7 "register_operand" "")
18169         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18170    (set (match_operand:QI 8 "register_operand" "")
18171         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18172    (set (reg FLAGS_REG)
18173         (compare (match_dup 7) (match_dup 8)))
18174   ]
18175   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18176   [(parallel[
18177      (set (reg:CC FLAGS_REG)
18178           (compare:CC (mem:BLK (match_dup 4))
18179                       (mem:BLK (match_dup 5))))
18180      (use (match_dup 6))
18181      (use (match_dup 3))
18182      (use (reg:SI DIRFLAG_REG))
18183      (clobber (match_dup 0))
18184      (clobber (match_dup 1))
18185      (clobber (match_dup 2))])]
18186   "")
18187
18188 ;; ...and this one handles cmpstrn*_1.
18189 (define_peephole2
18190   [(parallel[
18191      (set (reg:CC FLAGS_REG)
18192           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18193                                (const_int 0))
18194             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18195                         (mem:BLK (match_operand 5 "register_operand" "")))
18196             (const_int 0)))
18197      (use (match_operand:SI 3 "immediate_operand" ""))
18198      (use (reg:CC FLAGS_REG))
18199      (use (reg:SI DIRFLAG_REG))
18200      (clobber (match_operand 0 "register_operand" ""))
18201      (clobber (match_operand 1 "register_operand" ""))
18202      (clobber (match_operand 2 "register_operand" ""))])
18203    (set (match_operand:QI 7 "register_operand" "")
18204         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18205    (set (match_operand:QI 8 "register_operand" "")
18206         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18207    (set (reg FLAGS_REG)
18208         (compare (match_dup 7) (match_dup 8)))
18209   ]
18210   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18211   [(parallel[
18212      (set (reg:CC FLAGS_REG)
18213           (if_then_else:CC (ne (match_dup 6)
18214                                (const_int 0))
18215             (compare:CC (mem:BLK (match_dup 4))
18216                         (mem:BLK (match_dup 5)))
18217             (const_int 0)))
18218      (use (match_dup 3))
18219      (use (reg:CC FLAGS_REG))
18220      (use (reg:SI DIRFLAG_REG))
18221      (clobber (match_dup 0))
18222      (clobber (match_dup 1))
18223      (clobber (match_dup 2))])]
18224   "")
18225
18226
18227 \f
18228 ;; Conditional move instructions.
18229
18230 (define_expand "movdicc"
18231   [(set (match_operand:DI 0 "register_operand" "")
18232         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18233                          (match_operand:DI 2 "general_operand" "")
18234                          (match_operand:DI 3 "general_operand" "")))]
18235   "TARGET_64BIT"
18236   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18237
18238 (define_insn "x86_movdicc_0_m1_rex64"
18239   [(set (match_operand:DI 0 "register_operand" "=r")
18240         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18241           (const_int -1)
18242           (const_int 0)))
18243    (clobber (reg:CC FLAGS_REG))]
18244   "TARGET_64BIT"
18245   "sbb{q}\t%0, %0"
18246   ; Since we don't have the proper number of operands for an alu insn,
18247   ; fill in all the blanks.
18248   [(set_attr "type" "alu")
18249    (set_attr "pent_pair" "pu")
18250    (set_attr "memory" "none")
18251    (set_attr "imm_disp" "false")
18252    (set_attr "mode" "DI")
18253    (set_attr "length_immediate" "0")])
18254
18255 (define_insn "*movdicc_c_rex64"
18256   [(set (match_operand:DI 0 "register_operand" "=r,r")
18257         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18258                                 [(reg FLAGS_REG) (const_int 0)])
18259                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18260                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18261   "TARGET_64BIT && TARGET_CMOVE
18262    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18263   "@
18264    cmov%O2%C1\t{%2, %0|%0, %2}
18265    cmov%O2%c1\t{%3, %0|%0, %3}"
18266   [(set_attr "type" "icmov")
18267    (set_attr "mode" "DI")])
18268
18269 (define_expand "movsicc"
18270   [(set (match_operand:SI 0 "register_operand" "")
18271         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18272                          (match_operand:SI 2 "general_operand" "")
18273                          (match_operand:SI 3 "general_operand" "")))]
18274   ""
18275   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18276
18277 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18278 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18279 ;; So just document what we're doing explicitly.
18280
18281 (define_insn "x86_movsicc_0_m1"
18282   [(set (match_operand:SI 0 "register_operand" "=r")
18283         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18284           (const_int -1)
18285           (const_int 0)))
18286    (clobber (reg:CC FLAGS_REG))]
18287   ""
18288   "sbb{l}\t%0, %0"
18289   ; Since we don't have the proper number of operands for an alu insn,
18290   ; fill in all the blanks.
18291   [(set_attr "type" "alu")
18292    (set_attr "pent_pair" "pu")
18293    (set_attr "memory" "none")
18294    (set_attr "imm_disp" "false")
18295    (set_attr "mode" "SI")
18296    (set_attr "length_immediate" "0")])
18297
18298 (define_insn "*movsicc_noc"
18299   [(set (match_operand:SI 0 "register_operand" "=r,r")
18300         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18301                                 [(reg FLAGS_REG) (const_int 0)])
18302                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18303                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18304   "TARGET_CMOVE
18305    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18306   "@
18307    cmov%O2%C1\t{%2, %0|%0, %2}
18308    cmov%O2%c1\t{%3, %0|%0, %3}"
18309   [(set_attr "type" "icmov")
18310    (set_attr "mode" "SI")])
18311
18312 (define_expand "movhicc"
18313   [(set (match_operand:HI 0 "register_operand" "")
18314         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18315                          (match_operand:HI 2 "general_operand" "")
18316                          (match_operand:HI 3 "general_operand" "")))]
18317   "TARGET_HIMODE_MATH"
18318   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18319
18320 (define_insn "*movhicc_noc"
18321   [(set (match_operand:HI 0 "register_operand" "=r,r")
18322         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18323                                 [(reg FLAGS_REG) (const_int 0)])
18324                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18325                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18326   "TARGET_CMOVE
18327    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18328   "@
18329    cmov%O2%C1\t{%2, %0|%0, %2}
18330    cmov%O2%c1\t{%3, %0|%0, %3}"
18331   [(set_attr "type" "icmov")
18332    (set_attr "mode" "HI")])
18333
18334 (define_expand "movqicc"
18335   [(set (match_operand:QI 0 "register_operand" "")
18336         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18337                          (match_operand:QI 2 "general_operand" "")
18338                          (match_operand:QI 3 "general_operand" "")))]
18339   "TARGET_QIMODE_MATH"
18340   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18341
18342 (define_insn_and_split "*movqicc_noc"
18343   [(set (match_operand:QI 0 "register_operand" "=r,r")
18344         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18345                                 [(match_operand 4 "flags_reg_operand" "")
18346                                  (const_int 0)])
18347                       (match_operand:QI 2 "register_operand" "r,0")
18348                       (match_operand:QI 3 "register_operand" "0,r")))]
18349   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18350   "#"
18351   "&& reload_completed"
18352   [(set (match_dup 0)
18353         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18354                       (match_dup 2)
18355                       (match_dup 3)))]
18356   "operands[0] = gen_lowpart (SImode, operands[0]);
18357    operands[2] = gen_lowpart (SImode, operands[2]);
18358    operands[3] = gen_lowpart (SImode, operands[3]);"
18359   [(set_attr "type" "icmov")
18360    (set_attr "mode" "SI")])
18361
18362 (define_expand "movsfcc"
18363   [(set (match_operand:SF 0 "register_operand" "")
18364         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18365                          (match_operand:SF 2 "register_operand" "")
18366                          (match_operand:SF 3 "register_operand" "")))]
18367   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18368   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18369
18370 (define_insn "*movsfcc_1_387"
18371   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18372         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18373                                 [(reg FLAGS_REG) (const_int 0)])
18374                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18375                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18376   "TARGET_80387 && TARGET_CMOVE
18377    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18378   "@
18379    fcmov%F1\t{%2, %0|%0, %2}
18380    fcmov%f1\t{%3, %0|%0, %3}
18381    cmov%O2%C1\t{%2, %0|%0, %2}
18382    cmov%O2%c1\t{%3, %0|%0, %3}"
18383   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18384    (set_attr "mode" "SF,SF,SI,SI")])
18385
18386 (define_expand "movdfcc"
18387   [(set (match_operand:DF 0 "register_operand" "")
18388         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18389                          (match_operand:DF 2 "register_operand" "")
18390                          (match_operand:DF 3 "register_operand" "")))]
18391   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18392   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18393
18394 (define_insn "*movdfcc_1"
18395   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18396         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18397                                 [(reg FLAGS_REG) (const_int 0)])
18398                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18399                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18400   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18401    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18402   "@
18403    fcmov%F1\t{%2, %0|%0, %2}
18404    fcmov%f1\t{%3, %0|%0, %3}
18405    #
18406    #"
18407   [(set_attr "type" "fcmov,fcmov,multi,multi")
18408    (set_attr "mode" "DF")])
18409
18410 (define_insn "*movdfcc_1_rex64"
18411   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18412         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18413                                 [(reg FLAGS_REG) (const_int 0)])
18414                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18415                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18416   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18417    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18418   "@
18419    fcmov%F1\t{%2, %0|%0, %2}
18420    fcmov%f1\t{%3, %0|%0, %3}
18421    cmov%O2%C1\t{%2, %0|%0, %2}
18422    cmov%O2%c1\t{%3, %0|%0, %3}"
18423   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18424    (set_attr "mode" "DF")])
18425
18426 (define_split
18427   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18428         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18429                                 [(match_operand 4 "flags_reg_operand" "")
18430                                  (const_int 0)])
18431                       (match_operand:DF 2 "nonimmediate_operand" "")
18432                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18433   "!TARGET_64BIT && reload_completed"
18434   [(set (match_dup 2)
18435         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18436                       (match_dup 5)
18437                       (match_dup 7)))
18438    (set (match_dup 3)
18439         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18440                       (match_dup 6)
18441                       (match_dup 8)))]
18442   "split_di (operands+2, 1, operands+5, operands+6);
18443    split_di (operands+3, 1, operands+7, operands+8);
18444    split_di (operands, 1, operands+2, operands+3);")
18445
18446 (define_expand "movxfcc"
18447   [(set (match_operand:XF 0 "register_operand" "")
18448         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18449                          (match_operand:XF 2 "register_operand" "")
18450                          (match_operand:XF 3 "register_operand" "")))]
18451   "TARGET_80387 && TARGET_CMOVE"
18452   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18453
18454 (define_insn "*movxfcc_1"
18455   [(set (match_operand:XF 0 "register_operand" "=f,f")
18456         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18457                                 [(reg FLAGS_REG) (const_int 0)])
18458                       (match_operand:XF 2 "register_operand" "f,0")
18459                       (match_operand:XF 3 "register_operand" "0,f")))]
18460   "TARGET_80387 && TARGET_CMOVE"
18461   "@
18462    fcmov%F1\t{%2, %0|%0, %2}
18463    fcmov%f1\t{%3, %0|%0, %3}"
18464   [(set_attr "type" "fcmov")
18465    (set_attr "mode" "XF")])
18466
18467 ;; These versions of the min/max patterns are intentionally ignorant of
18468 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18469 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18470 ;; are undefined in this condition, we're certain this is correct.
18471
18472 (define_insn "sminsf3"
18473   [(set (match_operand:SF 0 "register_operand" "=x")
18474         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18475                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18476   "TARGET_SSE_MATH"
18477   "minss\t{%2, %0|%0, %2}"
18478   [(set_attr "type" "sseadd")
18479    (set_attr "mode" "SF")])
18480
18481 (define_insn "smaxsf3"
18482   [(set (match_operand:SF 0 "register_operand" "=x")
18483         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18484                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18485   "TARGET_SSE_MATH"
18486   "maxss\t{%2, %0|%0, %2}"
18487   [(set_attr "type" "sseadd")
18488    (set_attr "mode" "SF")])
18489
18490 (define_insn "smindf3"
18491   [(set (match_operand:DF 0 "register_operand" "=x")
18492         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18493                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18494   "TARGET_SSE2 && TARGET_SSE_MATH"
18495   "minsd\t{%2, %0|%0, %2}"
18496   [(set_attr "type" "sseadd")
18497    (set_attr "mode" "DF")])
18498
18499 (define_insn "smaxdf3"
18500   [(set (match_operand:DF 0 "register_operand" "=x")
18501         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18502                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18503   "TARGET_SSE2 && TARGET_SSE_MATH"
18504   "maxsd\t{%2, %0|%0, %2}"
18505   [(set_attr "type" "sseadd")
18506    (set_attr "mode" "DF")])
18507
18508 ;; These versions of the min/max patterns implement exactly the operations
18509 ;;   min = (op1 < op2 ? op1 : op2)
18510 ;;   max = (!(op1 < op2) ? op1 : op2)
18511 ;; Their operands are not commutative, and thus they may be used in the
18512 ;; presence of -0.0 and NaN.
18513
18514 (define_insn "*ieee_sminsf3"
18515   [(set (match_operand:SF 0 "register_operand" "=x")
18516         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18517                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18518                    UNSPEC_IEEE_MIN))]
18519   "TARGET_SSE_MATH"
18520   "minss\t{%2, %0|%0, %2}"
18521   [(set_attr "type" "sseadd")
18522    (set_attr "mode" "SF")])
18523
18524 (define_insn "*ieee_smaxsf3"
18525   [(set (match_operand:SF 0 "register_operand" "=x")
18526         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18527                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18528                    UNSPEC_IEEE_MAX))]
18529   "TARGET_SSE_MATH"
18530   "maxss\t{%2, %0|%0, %2}"
18531   [(set_attr "type" "sseadd")
18532    (set_attr "mode" "SF")])
18533
18534 (define_insn "*ieee_smindf3"
18535   [(set (match_operand:DF 0 "register_operand" "=x")
18536         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18537                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18538                    UNSPEC_IEEE_MIN))]
18539   "TARGET_SSE2 && TARGET_SSE_MATH"
18540   "minsd\t{%2, %0|%0, %2}"
18541   [(set_attr "type" "sseadd")
18542    (set_attr "mode" "DF")])
18543
18544 (define_insn "*ieee_smaxdf3"
18545   [(set (match_operand:DF 0 "register_operand" "=x")
18546         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18547                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18548                    UNSPEC_IEEE_MAX))]
18549   "TARGET_SSE2 && TARGET_SSE_MATH"
18550   "maxsd\t{%2, %0|%0, %2}"
18551   [(set_attr "type" "sseadd")
18552    (set_attr "mode" "DF")])
18553
18554 ;; Conditional addition patterns
18555 (define_expand "addqicc"
18556   [(match_operand:QI 0 "register_operand" "")
18557    (match_operand 1 "comparison_operator" "")
18558    (match_operand:QI 2 "register_operand" "")
18559    (match_operand:QI 3 "const_int_operand" "")]
18560   ""
18561   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18562
18563 (define_expand "addhicc"
18564   [(match_operand:HI 0 "register_operand" "")
18565    (match_operand 1 "comparison_operator" "")
18566    (match_operand:HI 2 "register_operand" "")
18567    (match_operand:HI 3 "const_int_operand" "")]
18568   ""
18569   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18570
18571 (define_expand "addsicc"
18572   [(match_operand:SI 0 "register_operand" "")
18573    (match_operand 1 "comparison_operator" "")
18574    (match_operand:SI 2 "register_operand" "")
18575    (match_operand:SI 3 "const_int_operand" "")]
18576   ""
18577   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18578
18579 (define_expand "adddicc"
18580   [(match_operand:DI 0 "register_operand" "")
18581    (match_operand 1 "comparison_operator" "")
18582    (match_operand:DI 2 "register_operand" "")
18583    (match_operand:DI 3 "const_int_operand" "")]
18584   "TARGET_64BIT"
18585   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18586
18587 \f
18588 ;; Misc patterns (?)
18589
18590 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18591 ;; Otherwise there will be nothing to keep
18592 ;; 
18593 ;; [(set (reg ebp) (reg esp))]
18594 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18595 ;;  (clobber (eflags)]
18596 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18597 ;;
18598 ;; in proper program order.
18599 (define_insn "pro_epilogue_adjust_stack_1"
18600   [(set (match_operand:SI 0 "register_operand" "=r,r")
18601         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18602                  (match_operand:SI 2 "immediate_operand" "i,i")))
18603    (clobber (reg:CC FLAGS_REG))
18604    (clobber (mem:BLK (scratch)))]
18605   "!TARGET_64BIT"
18606 {
18607   switch (get_attr_type (insn))
18608     {
18609     case TYPE_IMOV:
18610       return "mov{l}\t{%1, %0|%0, %1}";
18611
18612     case TYPE_ALU:
18613       if (GET_CODE (operands[2]) == CONST_INT
18614           && (INTVAL (operands[2]) == 128
18615               || (INTVAL (operands[2]) < 0
18616                   && INTVAL (operands[2]) != -128)))
18617         {
18618           operands[2] = GEN_INT (-INTVAL (operands[2]));
18619           return "sub{l}\t{%2, %0|%0, %2}";
18620         }
18621       return "add{l}\t{%2, %0|%0, %2}";
18622
18623     case TYPE_LEA:
18624       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18625       return "lea{l}\t{%a2, %0|%0, %a2}";
18626
18627     default:
18628       gcc_unreachable ();
18629     }
18630 }
18631   [(set (attr "type")
18632         (cond [(eq_attr "alternative" "0")
18633                  (const_string "alu")
18634                (match_operand:SI 2 "const0_operand" "")
18635                  (const_string "imov")
18636               ]
18637               (const_string "lea")))
18638    (set_attr "mode" "SI")])
18639
18640 (define_insn "pro_epilogue_adjust_stack_rex64"
18641   [(set (match_operand:DI 0 "register_operand" "=r,r")
18642         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18643                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18644    (clobber (reg:CC FLAGS_REG))
18645    (clobber (mem:BLK (scratch)))]
18646   "TARGET_64BIT"
18647 {
18648   switch (get_attr_type (insn))
18649     {
18650     case TYPE_IMOV:
18651       return "mov{q}\t{%1, %0|%0, %1}";
18652
18653     case TYPE_ALU:
18654       if (GET_CODE (operands[2]) == CONST_INT
18655           /* Avoid overflows.  */
18656           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18657           && (INTVAL (operands[2]) == 128
18658               || (INTVAL (operands[2]) < 0
18659                   && INTVAL (operands[2]) != -128)))
18660         {
18661           operands[2] = GEN_INT (-INTVAL (operands[2]));
18662           return "sub{q}\t{%2, %0|%0, %2}";
18663         }
18664       return "add{q}\t{%2, %0|%0, %2}";
18665
18666     case TYPE_LEA:
18667       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18668       return "lea{q}\t{%a2, %0|%0, %a2}";
18669
18670     default:
18671       gcc_unreachable ();
18672     }
18673 }
18674   [(set (attr "type")
18675         (cond [(eq_attr "alternative" "0")
18676                  (const_string "alu")
18677                (match_operand:DI 2 "const0_operand" "")
18678                  (const_string "imov")
18679               ]
18680               (const_string "lea")))
18681    (set_attr "mode" "DI")])
18682
18683 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18684   [(set (match_operand:DI 0 "register_operand" "=r,r")
18685         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18686                  (match_operand:DI 3 "immediate_operand" "i,i")))
18687    (use (match_operand:DI 2 "register_operand" "r,r"))
18688    (clobber (reg:CC FLAGS_REG))
18689    (clobber (mem:BLK (scratch)))]
18690   "TARGET_64BIT"
18691 {
18692   switch (get_attr_type (insn))
18693     {
18694     case TYPE_ALU:
18695       return "add{q}\t{%2, %0|%0, %2}";
18696
18697     case TYPE_LEA:
18698       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18699       return "lea{q}\t{%a2, %0|%0, %a2}";
18700
18701     default:
18702       gcc_unreachable ();
18703     }
18704 }
18705   [(set_attr "type" "alu,lea")
18706    (set_attr "mode" "DI")])
18707
18708 (define_expand "allocate_stack_worker"
18709   [(match_operand:SI 0 "register_operand" "")]
18710   "TARGET_STACK_PROBE"
18711 {
18712   if (reload_completed)
18713     {
18714       if (TARGET_64BIT)
18715         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18716       else
18717         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18718     }
18719   else
18720     {
18721       if (TARGET_64BIT)
18722         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18723       else
18724         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18725     }
18726   DONE;
18727 })
18728
18729 (define_insn "allocate_stack_worker_1"
18730   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18731     UNSPECV_STACK_PROBE)
18732    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18733    (clobber (match_scratch:SI 1 "=0"))
18734    (clobber (reg:CC FLAGS_REG))]
18735   "!TARGET_64BIT && TARGET_STACK_PROBE"
18736   "call\t__alloca"
18737   [(set_attr "type" "multi")
18738    (set_attr "length" "5")])
18739
18740 (define_expand "allocate_stack_worker_postreload"
18741   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18742                                     UNSPECV_STACK_PROBE)
18743               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18744               (clobber (match_dup 0))
18745               (clobber (reg:CC FLAGS_REG))])]
18746   ""
18747   "")
18748
18749 (define_insn "allocate_stack_worker_rex64"
18750   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18751     UNSPECV_STACK_PROBE)
18752    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18753    (clobber (match_scratch:DI 1 "=0"))
18754    (clobber (reg:CC FLAGS_REG))]
18755   "TARGET_64BIT && TARGET_STACK_PROBE"
18756   "call\t__alloca"
18757   [(set_attr "type" "multi")
18758    (set_attr "length" "5")])
18759
18760 (define_expand "allocate_stack_worker_rex64_postreload"
18761   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18762                                     UNSPECV_STACK_PROBE)
18763               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18764               (clobber (match_dup 0))
18765               (clobber (reg:CC FLAGS_REG))])]
18766   ""
18767   "")
18768
18769 (define_expand "allocate_stack"
18770   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18771                    (minus:SI (reg:SI SP_REG)
18772                              (match_operand:SI 1 "general_operand" "")))
18773               (clobber (reg:CC FLAGS_REG))])
18774    (parallel [(set (reg:SI SP_REG)
18775                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18776               (clobber (reg:CC FLAGS_REG))])]
18777   "TARGET_STACK_PROBE"
18778 {
18779 #ifdef CHECK_STACK_LIMIT
18780   if (GET_CODE (operands[1]) == CONST_INT
18781       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18782     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18783                            operands[1]));
18784   else 
18785 #endif
18786     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18787                                                             operands[1])));
18788
18789   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18790   DONE;
18791 })
18792
18793 (define_expand "builtin_setjmp_receiver"
18794   [(label_ref (match_operand 0 "" ""))]
18795   "!TARGET_64BIT && flag_pic"
18796 {
18797   emit_insn (gen_set_got (pic_offset_table_rtx));
18798   DONE;
18799 })
18800 \f
18801 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18802
18803 (define_split
18804   [(set (match_operand 0 "register_operand" "")
18805         (match_operator 3 "promotable_binary_operator"
18806            [(match_operand 1 "register_operand" "")
18807             (match_operand 2 "aligned_operand" "")]))
18808    (clobber (reg:CC FLAGS_REG))]
18809   "! TARGET_PARTIAL_REG_STALL && reload_completed
18810    && ((GET_MODE (operands[0]) == HImode 
18811         && ((!optimize_size && !TARGET_FAST_PREFIX)
18812             || GET_CODE (operands[2]) != CONST_INT
18813             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18814        || (GET_MODE (operands[0]) == QImode 
18815            && (TARGET_PROMOTE_QImode || optimize_size)))"
18816   [(parallel [(set (match_dup 0)
18817                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18818               (clobber (reg:CC FLAGS_REG))])]
18819   "operands[0] = gen_lowpart (SImode, operands[0]);
18820    operands[1] = gen_lowpart (SImode, operands[1]);
18821    if (GET_CODE (operands[3]) != ASHIFT)
18822      operands[2] = gen_lowpart (SImode, operands[2]);
18823    PUT_MODE (operands[3], SImode);")
18824
18825 ; Promote the QImode tests, as i386 has encoding of the AND
18826 ; instruction with 32-bit sign-extended immediate and thus the
18827 ; instruction size is unchanged, except in the %eax case for
18828 ; which it is increased by one byte, hence the ! optimize_size.
18829 (define_split
18830   [(set (match_operand 0 "flags_reg_operand" "")
18831         (match_operator 2 "compare_operator"
18832           [(and (match_operand 3 "aligned_operand" "")
18833                 (match_operand 4 "const_int_operand" ""))
18834            (const_int 0)]))
18835    (set (match_operand 1 "register_operand" "")
18836         (and (match_dup 3) (match_dup 4)))]
18837   "! TARGET_PARTIAL_REG_STALL && reload_completed
18838    /* Ensure that the operand will remain sign-extended immediate.  */
18839    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18840    && ! optimize_size
18841    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18842        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18843   [(parallel [(set (match_dup 0)
18844                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18845                                     (const_int 0)]))
18846               (set (match_dup 1)
18847                    (and:SI (match_dup 3) (match_dup 4)))])]
18848 {
18849   operands[4]
18850     = gen_int_mode (INTVAL (operands[4])
18851                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18852   operands[1] = gen_lowpart (SImode, operands[1]);
18853   operands[3] = gen_lowpart (SImode, operands[3]);
18854 })
18855
18856 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18857 ; the TEST instruction with 32-bit sign-extended immediate and thus
18858 ; the instruction size would at least double, which is not what we
18859 ; want even with ! optimize_size.
18860 (define_split
18861   [(set (match_operand 0 "flags_reg_operand" "")
18862         (match_operator 1 "compare_operator"
18863           [(and (match_operand:HI 2 "aligned_operand" "")
18864                 (match_operand:HI 3 "const_int_operand" ""))
18865            (const_int 0)]))]
18866   "! TARGET_PARTIAL_REG_STALL && reload_completed
18867    /* Ensure that the operand will remain sign-extended immediate.  */
18868    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18869    && ! TARGET_FAST_PREFIX
18870    && ! optimize_size"
18871   [(set (match_dup 0)
18872         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18873                          (const_int 0)]))]
18874 {
18875   operands[3]
18876     = gen_int_mode (INTVAL (operands[3])
18877                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18878   operands[2] = gen_lowpart (SImode, operands[2]);
18879 })
18880
18881 (define_split
18882   [(set (match_operand 0 "register_operand" "")
18883         (neg (match_operand 1 "register_operand" "")))
18884    (clobber (reg:CC FLAGS_REG))]
18885   "! TARGET_PARTIAL_REG_STALL && reload_completed
18886    && (GET_MODE (operands[0]) == HImode
18887        || (GET_MODE (operands[0]) == QImode 
18888            && (TARGET_PROMOTE_QImode || optimize_size)))"
18889   [(parallel [(set (match_dup 0)
18890                    (neg:SI (match_dup 1)))
18891               (clobber (reg:CC FLAGS_REG))])]
18892   "operands[0] = gen_lowpart (SImode, operands[0]);
18893    operands[1] = gen_lowpart (SImode, operands[1]);")
18894
18895 (define_split
18896   [(set (match_operand 0 "register_operand" "")
18897         (not (match_operand 1 "register_operand" "")))]
18898   "! TARGET_PARTIAL_REG_STALL && reload_completed
18899    && (GET_MODE (operands[0]) == HImode
18900        || (GET_MODE (operands[0]) == QImode 
18901            && (TARGET_PROMOTE_QImode || optimize_size)))"
18902   [(set (match_dup 0)
18903         (not:SI (match_dup 1)))]
18904   "operands[0] = gen_lowpart (SImode, operands[0]);
18905    operands[1] = gen_lowpart (SImode, operands[1]);")
18906
18907 (define_split 
18908   [(set (match_operand 0 "register_operand" "")
18909         (if_then_else (match_operator 1 "comparison_operator" 
18910                                 [(reg FLAGS_REG) (const_int 0)])
18911                       (match_operand 2 "register_operand" "")
18912                       (match_operand 3 "register_operand" "")))]
18913   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18914    && (GET_MODE (operands[0]) == HImode
18915        || (GET_MODE (operands[0]) == QImode 
18916            && (TARGET_PROMOTE_QImode || optimize_size)))"
18917   [(set (match_dup 0)
18918         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18919   "operands[0] = gen_lowpart (SImode, operands[0]);
18920    operands[2] = gen_lowpart (SImode, operands[2]);
18921    operands[3] = gen_lowpart (SImode, operands[3]);")
18922                         
18923 \f
18924 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18925 ;; transform a complex memory operation into two memory to register operations.
18926
18927 ;; Don't push memory operands
18928 (define_peephole2
18929   [(set (match_operand:SI 0 "push_operand" "")
18930         (match_operand:SI 1 "memory_operand" ""))
18931    (match_scratch:SI 2 "r")]
18932   "! optimize_size && ! TARGET_PUSH_MEMORY"
18933   [(set (match_dup 2) (match_dup 1))
18934    (set (match_dup 0) (match_dup 2))]
18935   "")
18936
18937 (define_peephole2
18938   [(set (match_operand:DI 0 "push_operand" "")
18939         (match_operand:DI 1 "memory_operand" ""))
18940    (match_scratch:DI 2 "r")]
18941   "! optimize_size && ! TARGET_PUSH_MEMORY"
18942   [(set (match_dup 2) (match_dup 1))
18943    (set (match_dup 0) (match_dup 2))]
18944   "")
18945
18946 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18947 ;; SImode pushes.
18948 (define_peephole2
18949   [(set (match_operand:SF 0 "push_operand" "")
18950         (match_operand:SF 1 "memory_operand" ""))
18951    (match_scratch:SF 2 "r")]
18952   "! optimize_size && ! TARGET_PUSH_MEMORY"
18953   [(set (match_dup 2) (match_dup 1))
18954    (set (match_dup 0) (match_dup 2))]
18955   "")
18956
18957 (define_peephole2
18958   [(set (match_operand:HI 0 "push_operand" "")
18959         (match_operand:HI 1 "memory_operand" ""))
18960    (match_scratch:HI 2 "r")]
18961   "! optimize_size && ! TARGET_PUSH_MEMORY"
18962   [(set (match_dup 2) (match_dup 1))
18963    (set (match_dup 0) (match_dup 2))]
18964   "")
18965
18966 (define_peephole2
18967   [(set (match_operand:QI 0 "push_operand" "")
18968         (match_operand:QI 1 "memory_operand" ""))
18969    (match_scratch:QI 2 "q")]
18970   "! optimize_size && ! TARGET_PUSH_MEMORY"
18971   [(set (match_dup 2) (match_dup 1))
18972    (set (match_dup 0) (match_dup 2))]
18973   "")
18974
18975 ;; Don't move an immediate directly to memory when the instruction
18976 ;; gets too big.
18977 (define_peephole2
18978   [(match_scratch:SI 1 "r")
18979    (set (match_operand:SI 0 "memory_operand" "")
18980         (const_int 0))]
18981   "! optimize_size
18982    && ! TARGET_USE_MOV0
18983    && TARGET_SPLIT_LONG_MOVES
18984    && get_attr_length (insn) >= ix86_cost->large_insn
18985    && peep2_regno_dead_p (0, FLAGS_REG)"
18986   [(parallel [(set (match_dup 1) (const_int 0))
18987               (clobber (reg:CC FLAGS_REG))])
18988    (set (match_dup 0) (match_dup 1))]
18989   "")
18990
18991 (define_peephole2
18992   [(match_scratch:HI 1 "r")
18993    (set (match_operand:HI 0 "memory_operand" "")
18994         (const_int 0))]
18995   "! optimize_size
18996    && ! TARGET_USE_MOV0
18997    && TARGET_SPLIT_LONG_MOVES
18998    && get_attr_length (insn) >= ix86_cost->large_insn
18999    && peep2_regno_dead_p (0, FLAGS_REG)"
19000   [(parallel [(set (match_dup 2) (const_int 0))
19001               (clobber (reg:CC FLAGS_REG))])
19002    (set (match_dup 0) (match_dup 1))]
19003   "operands[2] = gen_lowpart (SImode, operands[1]);")
19004
19005 (define_peephole2
19006   [(match_scratch:QI 1 "q")
19007    (set (match_operand:QI 0 "memory_operand" "")
19008         (const_int 0))]
19009   "! optimize_size
19010    && ! TARGET_USE_MOV0
19011    && TARGET_SPLIT_LONG_MOVES
19012    && get_attr_length (insn) >= ix86_cost->large_insn
19013    && peep2_regno_dead_p (0, FLAGS_REG)"
19014   [(parallel [(set (match_dup 2) (const_int 0))
19015               (clobber (reg:CC FLAGS_REG))])
19016    (set (match_dup 0) (match_dup 1))]
19017   "operands[2] = gen_lowpart (SImode, operands[1]);")
19018
19019 (define_peephole2
19020   [(match_scratch:SI 2 "r")
19021    (set (match_operand:SI 0 "memory_operand" "")
19022         (match_operand:SI 1 "immediate_operand" ""))]
19023   "! optimize_size
19024    && get_attr_length (insn) >= ix86_cost->large_insn
19025    && TARGET_SPLIT_LONG_MOVES"
19026   [(set (match_dup 2) (match_dup 1))
19027    (set (match_dup 0) (match_dup 2))]
19028   "")
19029
19030 (define_peephole2
19031   [(match_scratch:HI 2 "r")
19032    (set (match_operand:HI 0 "memory_operand" "")
19033         (match_operand:HI 1 "immediate_operand" ""))]
19034   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19035   && TARGET_SPLIT_LONG_MOVES"
19036   [(set (match_dup 2) (match_dup 1))
19037    (set (match_dup 0) (match_dup 2))]
19038   "")
19039
19040 (define_peephole2
19041   [(match_scratch:QI 2 "q")
19042    (set (match_operand:QI 0 "memory_operand" "")
19043         (match_operand:QI 1 "immediate_operand" ""))]
19044   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19045   && TARGET_SPLIT_LONG_MOVES"
19046   [(set (match_dup 2) (match_dup 1))
19047    (set (match_dup 0) (match_dup 2))]
19048   "")
19049
19050 ;; Don't compare memory with zero, load and use a test instead.
19051 (define_peephole2
19052   [(set (match_operand 0 "flags_reg_operand" "")
19053         (match_operator 1 "compare_operator"
19054           [(match_operand:SI 2 "memory_operand" "")
19055            (const_int 0)]))
19056    (match_scratch:SI 3 "r")]
19057   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19058   [(set (match_dup 3) (match_dup 2))
19059    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19060   "")
19061
19062 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19063 ;; Don't split NOTs with a displacement operand, because resulting XOR
19064 ;; will not be pairable anyway.
19065 ;;
19066 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19067 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19068 ;; so this split helps here as well.
19069 ;;
19070 ;; Note: Can't do this as a regular split because we can't get proper
19071 ;; lifetime information then.
19072
19073 (define_peephole2
19074   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19075         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19076   "!optimize_size
19077    && peep2_regno_dead_p (0, FLAGS_REG)
19078    && ((TARGET_PENTIUM 
19079         && (GET_CODE (operands[0]) != MEM
19080             || !memory_displacement_operand (operands[0], SImode)))
19081        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19082   [(parallel [(set (match_dup 0)
19083                    (xor:SI (match_dup 1) (const_int -1)))
19084               (clobber (reg:CC FLAGS_REG))])]
19085   "")
19086
19087 (define_peephole2
19088   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19089         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19090   "!optimize_size
19091    && peep2_regno_dead_p (0, FLAGS_REG)
19092    && ((TARGET_PENTIUM 
19093         && (GET_CODE (operands[0]) != MEM
19094             || !memory_displacement_operand (operands[0], HImode)))
19095        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19096   [(parallel [(set (match_dup 0)
19097                    (xor:HI (match_dup 1) (const_int -1)))
19098               (clobber (reg:CC FLAGS_REG))])]
19099   "")
19100
19101 (define_peephole2
19102   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19103         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19104   "!optimize_size
19105    && peep2_regno_dead_p (0, FLAGS_REG)
19106    && ((TARGET_PENTIUM 
19107         && (GET_CODE (operands[0]) != MEM
19108             || !memory_displacement_operand (operands[0], QImode)))
19109        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19110   [(parallel [(set (match_dup 0)
19111                    (xor:QI (match_dup 1) (const_int -1)))
19112               (clobber (reg:CC FLAGS_REG))])]
19113   "")
19114
19115 ;; Non pairable "test imm, reg" instructions can be translated to
19116 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19117 ;; byte opcode instead of two, have a short form for byte operands),
19118 ;; so do it for other CPUs as well.  Given that the value was dead,
19119 ;; this should not create any new dependencies.  Pass on the sub-word
19120 ;; versions if we're concerned about partial register stalls.
19121
19122 (define_peephole2
19123   [(set (match_operand 0 "flags_reg_operand" "")
19124         (match_operator 1 "compare_operator"
19125           [(and:SI (match_operand:SI 2 "register_operand" "")
19126                    (match_operand:SI 3 "immediate_operand" ""))
19127            (const_int 0)]))]
19128   "ix86_match_ccmode (insn, CCNOmode)
19129    && (true_regnum (operands[2]) != 0
19130        || (GET_CODE (operands[3]) == CONST_INT
19131            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19132    && peep2_reg_dead_p (1, operands[2])"
19133   [(parallel
19134      [(set (match_dup 0)
19135            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19136                             (const_int 0)]))
19137       (set (match_dup 2)
19138            (and:SI (match_dup 2) (match_dup 3)))])]
19139   "")
19140
19141 ;; We don't need to handle HImode case, because it will be promoted to SImode
19142 ;; on ! TARGET_PARTIAL_REG_STALL
19143
19144 (define_peephole2
19145   [(set (match_operand 0 "flags_reg_operand" "")
19146         (match_operator 1 "compare_operator"
19147           [(and:QI (match_operand:QI 2 "register_operand" "")
19148                    (match_operand:QI 3 "immediate_operand" ""))
19149            (const_int 0)]))]
19150   "! TARGET_PARTIAL_REG_STALL
19151    && ix86_match_ccmode (insn, CCNOmode)
19152    && true_regnum (operands[2]) != 0
19153    && peep2_reg_dead_p (1, operands[2])"
19154   [(parallel
19155      [(set (match_dup 0)
19156            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19157                             (const_int 0)]))
19158       (set (match_dup 2)
19159            (and:QI (match_dup 2) (match_dup 3)))])]
19160   "")
19161
19162 (define_peephole2
19163   [(set (match_operand 0 "flags_reg_operand" "")
19164         (match_operator 1 "compare_operator"
19165           [(and:SI
19166              (zero_extract:SI
19167                (match_operand 2 "ext_register_operand" "")
19168                (const_int 8)
19169                (const_int 8))
19170              (match_operand 3 "const_int_operand" ""))
19171            (const_int 0)]))]
19172   "! TARGET_PARTIAL_REG_STALL
19173    && ix86_match_ccmode (insn, CCNOmode)
19174    && true_regnum (operands[2]) != 0
19175    && peep2_reg_dead_p (1, operands[2])"
19176   [(parallel [(set (match_dup 0)
19177                    (match_op_dup 1
19178                      [(and:SI
19179                         (zero_extract:SI
19180                           (match_dup 2)
19181                           (const_int 8)
19182                           (const_int 8))
19183                         (match_dup 3))
19184                       (const_int 0)]))
19185               (set (zero_extract:SI (match_dup 2)
19186                                     (const_int 8)
19187                                     (const_int 8))
19188                    (and:SI 
19189                      (zero_extract:SI
19190                        (match_dup 2)
19191                        (const_int 8)
19192                        (const_int 8))
19193                      (match_dup 3)))])]
19194   "")
19195
19196 ;; Don't do logical operations with memory inputs.
19197 (define_peephole2
19198   [(match_scratch:SI 2 "r")
19199    (parallel [(set (match_operand:SI 0 "register_operand" "")
19200                    (match_operator:SI 3 "arith_or_logical_operator"
19201                      [(match_dup 0)
19202                       (match_operand:SI 1 "memory_operand" "")]))
19203               (clobber (reg:CC FLAGS_REG))])]
19204   "! optimize_size && ! TARGET_READ_MODIFY"
19205   [(set (match_dup 2) (match_dup 1))
19206    (parallel [(set (match_dup 0)
19207                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19208               (clobber (reg:CC FLAGS_REG))])]
19209   "")
19210
19211 (define_peephole2
19212   [(match_scratch:SI 2 "r")
19213    (parallel [(set (match_operand:SI 0 "register_operand" "")
19214                    (match_operator:SI 3 "arith_or_logical_operator"
19215                      [(match_operand:SI 1 "memory_operand" "")
19216                       (match_dup 0)]))
19217               (clobber (reg:CC FLAGS_REG))])]
19218   "! optimize_size && ! TARGET_READ_MODIFY"
19219   [(set (match_dup 2) (match_dup 1))
19220    (parallel [(set (match_dup 0)
19221                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19222               (clobber (reg:CC FLAGS_REG))])]
19223   "")
19224
19225 ; Don't do logical operations with memory outputs
19226 ;
19227 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19228 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19229 ; the same decoder scheduling characteristics as the original.
19230
19231 (define_peephole2
19232   [(match_scratch:SI 2 "r")
19233    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19234                    (match_operator:SI 3 "arith_or_logical_operator"
19235                      [(match_dup 0)
19236                       (match_operand:SI 1 "nonmemory_operand" "")]))
19237               (clobber (reg:CC FLAGS_REG))])]
19238   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19239   [(set (match_dup 2) (match_dup 0))
19240    (parallel [(set (match_dup 2)
19241                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19242               (clobber (reg:CC FLAGS_REG))])
19243    (set (match_dup 0) (match_dup 2))]
19244   "")
19245
19246 (define_peephole2
19247   [(match_scratch:SI 2 "r")
19248    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19249                    (match_operator:SI 3 "arith_or_logical_operator"
19250                      [(match_operand:SI 1 "nonmemory_operand" "")
19251                       (match_dup 0)]))
19252               (clobber (reg:CC FLAGS_REG))])]
19253   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19254   [(set (match_dup 2) (match_dup 0))
19255    (parallel [(set (match_dup 2)
19256                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19257               (clobber (reg:CC FLAGS_REG))])
19258    (set (match_dup 0) (match_dup 2))]
19259   "")
19260
19261 ;; Attempt to always use XOR for zeroing registers.
19262 (define_peephole2
19263   [(set (match_operand 0 "register_operand" "")
19264         (match_operand 1 "const0_operand" ""))]
19265   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19266    && (! TARGET_USE_MOV0 || optimize_size)
19267    && GENERAL_REG_P (operands[0])
19268    && peep2_regno_dead_p (0, FLAGS_REG)"
19269   [(parallel [(set (match_dup 0) (const_int 0))
19270               (clobber (reg:CC FLAGS_REG))])]
19271 {
19272   operands[0] = gen_lowpart (word_mode, operands[0]);
19273 })
19274
19275 (define_peephole2
19276   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19277         (const_int 0))]
19278   "(GET_MODE (operands[0]) == QImode
19279     || GET_MODE (operands[0]) == HImode)
19280    && (! TARGET_USE_MOV0 || optimize_size)
19281    && peep2_regno_dead_p (0, FLAGS_REG)"
19282   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19283               (clobber (reg:CC FLAGS_REG))])])
19284
19285 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19286 (define_peephole2
19287   [(set (match_operand 0 "register_operand" "")
19288         (const_int -1))]
19289   "(GET_MODE (operands[0]) == HImode
19290     || GET_MODE (operands[0]) == SImode 
19291     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19292    && (optimize_size || TARGET_PENTIUM)
19293    && peep2_regno_dead_p (0, FLAGS_REG)"
19294   [(parallel [(set (match_dup 0) (const_int -1))
19295               (clobber (reg:CC FLAGS_REG))])]
19296   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19297                               operands[0]);")
19298
19299 ;; Attempt to convert simple leas to adds. These can be created by
19300 ;; move expanders.
19301 (define_peephole2
19302   [(set (match_operand:SI 0 "register_operand" "")
19303         (plus:SI (match_dup 0)
19304                  (match_operand:SI 1 "nonmemory_operand" "")))]
19305   "peep2_regno_dead_p (0, FLAGS_REG)"
19306   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19307               (clobber (reg:CC FLAGS_REG))])]
19308   "")
19309
19310 (define_peephole2
19311   [(set (match_operand:SI 0 "register_operand" "")
19312         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19313                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19314   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19315   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19316               (clobber (reg:CC FLAGS_REG))])]
19317   "operands[2] = gen_lowpart (SImode, operands[2]);")
19318
19319 (define_peephole2
19320   [(set (match_operand:DI 0 "register_operand" "")
19321         (plus:DI (match_dup 0)
19322                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19323   "peep2_regno_dead_p (0, FLAGS_REG)"
19324   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19325               (clobber (reg:CC FLAGS_REG))])]
19326   "")
19327
19328 (define_peephole2
19329   [(set (match_operand:SI 0 "register_operand" "")
19330         (mult:SI (match_dup 0)
19331                  (match_operand:SI 1 "const_int_operand" "")))]
19332   "exact_log2 (INTVAL (operands[1])) >= 0
19333    && peep2_regno_dead_p (0, FLAGS_REG)"
19334   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19335               (clobber (reg:CC FLAGS_REG))])]
19336   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19337
19338 (define_peephole2
19339   [(set (match_operand:DI 0 "register_operand" "")
19340         (mult:DI (match_dup 0)
19341                  (match_operand:DI 1 "const_int_operand" "")))]
19342   "exact_log2 (INTVAL (operands[1])) >= 0
19343    && peep2_regno_dead_p (0, FLAGS_REG)"
19344   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19345               (clobber (reg:CC FLAGS_REG))])]
19346   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19347
19348 (define_peephole2
19349   [(set (match_operand:SI 0 "register_operand" "")
19350         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19351                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19352   "exact_log2 (INTVAL (operands[2])) >= 0
19353    && REGNO (operands[0]) == REGNO (operands[1])
19354    && peep2_regno_dead_p (0, FLAGS_REG)"
19355   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19356               (clobber (reg:CC FLAGS_REG))])]
19357   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19358
19359 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19360 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19361 ;; many CPUs it is also faster, since special hardware to avoid esp
19362 ;; dependencies is present.
19363
19364 ;; While some of these conversions may be done using splitters, we use peepholes
19365 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19366
19367 ;; Convert prologue esp subtractions to push.
19368 ;; We need register to push.  In order to keep verify_flow_info happy we have
19369 ;; two choices
19370 ;; - use scratch and clobber it in order to avoid dependencies
19371 ;; - use already live register
19372 ;; We can't use the second way right now, since there is no reliable way how to
19373 ;; verify that given register is live.  First choice will also most likely in
19374 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19375 ;; call clobbered registers are dead.  We may want to use base pointer as an
19376 ;; alternative when no register is available later.
19377
19378 (define_peephole2
19379   [(match_scratch:SI 0 "r")
19380    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19381               (clobber (reg:CC FLAGS_REG))
19382               (clobber (mem:BLK (scratch)))])]
19383   "optimize_size || !TARGET_SUB_ESP_4"
19384   [(clobber (match_dup 0))
19385    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19386               (clobber (mem:BLK (scratch)))])])
19387
19388 (define_peephole2
19389   [(match_scratch:SI 0 "r")
19390    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19391               (clobber (reg:CC FLAGS_REG))
19392               (clobber (mem:BLK (scratch)))])]
19393   "optimize_size || !TARGET_SUB_ESP_8"
19394   [(clobber (match_dup 0))
19395    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19396    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19397               (clobber (mem:BLK (scratch)))])])
19398
19399 ;; Convert esp subtractions to push.
19400 (define_peephole2
19401   [(match_scratch:SI 0 "r")
19402    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19403               (clobber (reg:CC FLAGS_REG))])]
19404   "optimize_size || !TARGET_SUB_ESP_4"
19405   [(clobber (match_dup 0))
19406    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19407
19408 (define_peephole2
19409   [(match_scratch:SI 0 "r")
19410    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19411               (clobber (reg:CC FLAGS_REG))])]
19412   "optimize_size || !TARGET_SUB_ESP_8"
19413   [(clobber (match_dup 0))
19414    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19415    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19416
19417 ;; Convert epilogue deallocator to pop.
19418 (define_peephole2
19419   [(match_scratch:SI 0 "r")
19420    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19421               (clobber (reg:CC FLAGS_REG))
19422               (clobber (mem:BLK (scratch)))])]
19423   "optimize_size || !TARGET_ADD_ESP_4"
19424   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19425               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19426               (clobber (mem:BLK (scratch)))])]
19427   "")
19428
19429 ;; Two pops case is tricky, since pop causes dependency on destination register.
19430 ;; We use two registers if available.
19431 (define_peephole2
19432   [(match_scratch:SI 0 "r")
19433    (match_scratch:SI 1 "r")
19434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19435               (clobber (reg:CC FLAGS_REG))
19436               (clobber (mem:BLK (scratch)))])]
19437   "optimize_size || !TARGET_ADD_ESP_8"
19438   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19439               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19440               (clobber (mem:BLK (scratch)))])
19441    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19442               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19443   "")
19444
19445 (define_peephole2
19446   [(match_scratch:SI 0 "r")
19447    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19448               (clobber (reg:CC FLAGS_REG))
19449               (clobber (mem:BLK (scratch)))])]
19450   "optimize_size"
19451   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19452               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19453               (clobber (mem:BLK (scratch)))])
19454    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19455               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19456   "")
19457
19458 ;; Convert esp additions to pop.
19459 (define_peephole2
19460   [(match_scratch:SI 0 "r")
19461    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19462               (clobber (reg:CC FLAGS_REG))])]
19463   ""
19464   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19465               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19466   "")
19467
19468 ;; Two pops case is tricky, since pop causes dependency on destination register.
19469 ;; We use two registers if available.
19470 (define_peephole2
19471   [(match_scratch:SI 0 "r")
19472    (match_scratch:SI 1 "r")
19473    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19474               (clobber (reg:CC FLAGS_REG))])]
19475   ""
19476   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19477               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19478    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19479               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19480   "")
19481
19482 (define_peephole2
19483   [(match_scratch:SI 0 "r")
19484    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19485               (clobber (reg:CC FLAGS_REG))])]
19486   "optimize_size"
19487   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19488               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19489    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19490               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19491   "")
19492 \f
19493 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19494 ;; required and register dies.  Similarly for 128 to plus -128.
19495 (define_peephole2
19496   [(set (match_operand 0 "flags_reg_operand" "")
19497         (match_operator 1 "compare_operator"
19498           [(match_operand 2 "register_operand" "")
19499            (match_operand 3 "const_int_operand" "")]))]
19500   "(INTVAL (operands[3]) == -1
19501     || INTVAL (operands[3]) == 1
19502     || INTVAL (operands[3]) == 128)
19503    && ix86_match_ccmode (insn, CCGCmode)
19504    && peep2_reg_dead_p (1, operands[2])"
19505   [(parallel [(set (match_dup 0)
19506                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19507               (clobber (match_dup 2))])]
19508   "")
19509 \f
19510 (define_peephole2
19511   [(match_scratch:DI 0 "r")
19512    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19513               (clobber (reg:CC FLAGS_REG))
19514               (clobber (mem:BLK (scratch)))])]
19515   "optimize_size || !TARGET_SUB_ESP_4"
19516   [(clobber (match_dup 0))
19517    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19518               (clobber (mem:BLK (scratch)))])])
19519
19520 (define_peephole2
19521   [(match_scratch:DI 0 "r")
19522    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19523               (clobber (reg:CC FLAGS_REG))
19524               (clobber (mem:BLK (scratch)))])]
19525   "optimize_size || !TARGET_SUB_ESP_8"
19526   [(clobber (match_dup 0))
19527    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19528    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19529               (clobber (mem:BLK (scratch)))])])
19530
19531 ;; Convert esp subtractions to push.
19532 (define_peephole2
19533   [(match_scratch:DI 0 "r")
19534    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19535               (clobber (reg:CC FLAGS_REG))])]
19536   "optimize_size || !TARGET_SUB_ESP_4"
19537   [(clobber (match_dup 0))
19538    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19539
19540 (define_peephole2
19541   [(match_scratch:DI 0 "r")
19542    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19543               (clobber (reg:CC FLAGS_REG))])]
19544   "optimize_size || !TARGET_SUB_ESP_8"
19545   [(clobber (match_dup 0))
19546    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19547    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19548
19549 ;; Convert epilogue deallocator to pop.
19550 (define_peephole2
19551   [(match_scratch:DI 0 "r")
19552    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19553               (clobber (reg:CC FLAGS_REG))
19554               (clobber (mem:BLK (scratch)))])]
19555   "optimize_size || !TARGET_ADD_ESP_4"
19556   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19557               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19558               (clobber (mem:BLK (scratch)))])]
19559   "")
19560
19561 ;; Two pops case is tricky, since pop causes dependency on destination register.
19562 ;; We use two registers if available.
19563 (define_peephole2
19564   [(match_scratch:DI 0 "r")
19565    (match_scratch:DI 1 "r")
19566    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19567               (clobber (reg:CC FLAGS_REG))
19568               (clobber (mem:BLK (scratch)))])]
19569   "optimize_size || !TARGET_ADD_ESP_8"
19570   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19571               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19572               (clobber (mem:BLK (scratch)))])
19573    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19574               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19575   "")
19576
19577 (define_peephole2
19578   [(match_scratch:DI 0 "r")
19579    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19580               (clobber (reg:CC FLAGS_REG))
19581               (clobber (mem:BLK (scratch)))])]
19582   "optimize_size"
19583   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19584               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19585               (clobber (mem:BLK (scratch)))])
19586    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19587               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19588   "")
19589
19590 ;; Convert esp additions to pop.
19591 (define_peephole2
19592   [(match_scratch:DI 0 "r")
19593    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19594               (clobber (reg:CC FLAGS_REG))])]
19595   ""
19596   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19597               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19598   "")
19599
19600 ;; Two pops case is tricky, since pop causes dependency on destination register.
19601 ;; We use two registers if available.
19602 (define_peephole2
19603   [(match_scratch:DI 0 "r")
19604    (match_scratch:DI 1 "r")
19605    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19606               (clobber (reg:CC FLAGS_REG))])]
19607   ""
19608   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19609               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19610    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19611               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19612   "")
19613
19614 (define_peephole2
19615   [(match_scratch:DI 0 "r")
19616    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19617               (clobber (reg:CC FLAGS_REG))])]
19618   "optimize_size"
19619   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19620               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19621    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19622               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19623   "")
19624 \f
19625 ;; Convert imul by three, five and nine into lea
19626 (define_peephole2
19627   [(parallel
19628     [(set (match_operand:SI 0 "register_operand" "")
19629           (mult:SI (match_operand:SI 1 "register_operand" "")
19630                    (match_operand:SI 2 "const_int_operand" "")))
19631      (clobber (reg:CC FLAGS_REG))])]
19632   "INTVAL (operands[2]) == 3
19633    || INTVAL (operands[2]) == 5
19634    || INTVAL (operands[2]) == 9"
19635   [(set (match_dup 0)
19636         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19637                  (match_dup 1)))]
19638   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19639
19640 (define_peephole2
19641   [(parallel
19642     [(set (match_operand:SI 0 "register_operand" "")
19643           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19644                    (match_operand:SI 2 "const_int_operand" "")))
19645      (clobber (reg:CC FLAGS_REG))])]
19646   "!optimize_size 
19647    && (INTVAL (operands[2]) == 3
19648        || INTVAL (operands[2]) == 5
19649        || INTVAL (operands[2]) == 9)"
19650   [(set (match_dup 0) (match_dup 1))
19651    (set (match_dup 0)
19652         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19653                  (match_dup 0)))]
19654   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19655
19656 (define_peephole2
19657   [(parallel
19658     [(set (match_operand:DI 0 "register_operand" "")
19659           (mult:DI (match_operand:DI 1 "register_operand" "")
19660                    (match_operand:DI 2 "const_int_operand" "")))
19661      (clobber (reg:CC FLAGS_REG))])]
19662   "TARGET_64BIT
19663    && (INTVAL (operands[2]) == 3
19664        || INTVAL (operands[2]) == 5
19665        || INTVAL (operands[2]) == 9)"
19666   [(set (match_dup 0)
19667         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19668                  (match_dup 1)))]
19669   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19670
19671 (define_peephole2
19672   [(parallel
19673     [(set (match_operand:DI 0 "register_operand" "")
19674           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19675                    (match_operand:DI 2 "const_int_operand" "")))
19676      (clobber (reg:CC FLAGS_REG))])]
19677   "TARGET_64BIT
19678    && !optimize_size 
19679    && (INTVAL (operands[2]) == 3
19680        || INTVAL (operands[2]) == 5
19681        || INTVAL (operands[2]) == 9)"
19682   [(set (match_dup 0) (match_dup 1))
19683    (set (match_dup 0)
19684         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19685                  (match_dup 0)))]
19686   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19687
19688 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19689 ;; imul $32bit_imm, reg, reg is direct decoded.
19690 (define_peephole2
19691   [(match_scratch:DI 3 "r")
19692    (parallel [(set (match_operand:DI 0 "register_operand" "")
19693                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19694                             (match_operand:DI 2 "immediate_operand" "")))
19695               (clobber (reg:CC FLAGS_REG))])]
19696   "TARGET_K8 && !optimize_size
19697    && (GET_CODE (operands[2]) != CONST_INT
19698        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19699   [(set (match_dup 3) (match_dup 1))
19700    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19701               (clobber (reg:CC FLAGS_REG))])]
19702 "")
19703
19704 (define_peephole2
19705   [(match_scratch:SI 3 "r")
19706    (parallel [(set (match_operand:SI 0 "register_operand" "")
19707                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19708                             (match_operand:SI 2 "immediate_operand" "")))
19709               (clobber (reg:CC FLAGS_REG))])]
19710   "TARGET_K8 && !optimize_size
19711    && (GET_CODE (operands[2]) != CONST_INT
19712        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19713   [(set (match_dup 3) (match_dup 1))
19714    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19715               (clobber (reg:CC FLAGS_REG))])]
19716 "")
19717
19718 (define_peephole2
19719   [(match_scratch:SI 3 "r")
19720    (parallel [(set (match_operand:DI 0 "register_operand" "")
19721                    (zero_extend:DI
19722                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19723                               (match_operand:SI 2 "immediate_operand" ""))))
19724               (clobber (reg:CC FLAGS_REG))])]
19725   "TARGET_K8 && !optimize_size
19726    && (GET_CODE (operands[2]) != CONST_INT
19727        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19728   [(set (match_dup 3) (match_dup 1))
19729    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19730               (clobber (reg:CC FLAGS_REG))])]
19731 "")
19732
19733 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19734 ;; Convert it into imul reg, reg
19735 ;; It would be better to force assembler to encode instruction using long
19736 ;; immediate, but there is apparently no way to do so.
19737 (define_peephole2
19738   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19739                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19740                             (match_operand:DI 2 "const_int_operand" "")))
19741               (clobber (reg:CC FLAGS_REG))])
19742    (match_scratch:DI 3 "r")]
19743   "TARGET_K8 && !optimize_size
19744    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19745   [(set (match_dup 3) (match_dup 2))
19746    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19747               (clobber (reg:CC FLAGS_REG))])]
19748 {
19749   if (!rtx_equal_p (operands[0], operands[1]))
19750     emit_move_insn (operands[0], operands[1]);
19751 })
19752
19753 (define_peephole2
19754   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19755                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19756                             (match_operand:SI 2 "const_int_operand" "")))
19757               (clobber (reg:CC FLAGS_REG))])
19758    (match_scratch:SI 3 "r")]
19759   "TARGET_K8 && !optimize_size
19760    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19761   [(set (match_dup 3) (match_dup 2))
19762    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19763               (clobber (reg:CC FLAGS_REG))])]
19764 {
19765   if (!rtx_equal_p (operands[0], operands[1]))
19766     emit_move_insn (operands[0], operands[1]);
19767 })
19768
19769 (define_peephole2
19770   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19771                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19772                             (match_operand:HI 2 "immediate_operand" "")))
19773               (clobber (reg:CC FLAGS_REG))])
19774    (match_scratch:HI 3 "r")]
19775   "TARGET_K8 && !optimize_size"
19776   [(set (match_dup 3) (match_dup 2))
19777    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19778               (clobber (reg:CC FLAGS_REG))])]
19779 {
19780   if (!rtx_equal_p (operands[0], operands[1]))
19781     emit_move_insn (operands[0], operands[1]);
19782 })
19783 \f
19784 ;; Call-value patterns last so that the wildcard operand does not
19785 ;; disrupt insn-recog's switch tables.
19786
19787 (define_insn "*call_value_pop_0"
19788   [(set (match_operand 0 "" "")
19789         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19790               (match_operand:SI 2 "" "")))
19791    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19792                             (match_operand:SI 3 "immediate_operand" "")))]
19793   "!TARGET_64BIT"
19794 {
19795   if (SIBLING_CALL_P (insn))
19796     return "jmp\t%P1";
19797   else
19798     return "call\t%P1";
19799 }
19800   [(set_attr "type" "callv")])
19801
19802 (define_insn "*call_value_pop_1"
19803   [(set (match_operand 0 "" "")
19804         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19805               (match_operand:SI 2 "" "")))
19806    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19807                             (match_operand:SI 3 "immediate_operand" "i")))]
19808   "!TARGET_64BIT"
19809 {
19810   if (constant_call_address_operand (operands[1], Pmode))
19811     {
19812       if (SIBLING_CALL_P (insn))
19813         return "jmp\t%P1";
19814       else
19815         return "call\t%P1";
19816     }
19817   if (SIBLING_CALL_P (insn))
19818     return "jmp\t%A1";
19819   else
19820     return "call\t%A1";
19821 }
19822   [(set_attr "type" "callv")])
19823
19824 (define_insn "*call_value_0"
19825   [(set (match_operand 0 "" "")
19826         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19827               (match_operand:SI 2 "" "")))]
19828   "!TARGET_64BIT"
19829 {
19830   if (SIBLING_CALL_P (insn))
19831     return "jmp\t%P1";
19832   else
19833     return "call\t%P1";
19834 }
19835   [(set_attr "type" "callv")])
19836
19837 (define_insn "*call_value_0_rex64"
19838   [(set (match_operand 0 "" "")
19839         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19840               (match_operand:DI 2 "const_int_operand" "")))]
19841   "TARGET_64BIT"
19842 {
19843   if (SIBLING_CALL_P (insn))
19844     return "jmp\t%P1";
19845   else
19846     return "call\t%P1";
19847 }
19848   [(set_attr "type" "callv")])
19849
19850 (define_insn "*call_value_1"
19851   [(set (match_operand 0 "" "")
19852         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19853               (match_operand:SI 2 "" "")))]
19854   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19855 {
19856   if (constant_call_address_operand (operands[1], Pmode))
19857     return "call\t%P1";
19858   return "call\t%A1";
19859 }
19860   [(set_attr "type" "callv")])
19861
19862 (define_insn "*sibcall_value_1"
19863   [(set (match_operand 0 "" "")
19864         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19865               (match_operand:SI 2 "" "")))]
19866   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19867 {
19868   if (constant_call_address_operand (operands[1], Pmode))
19869     return "jmp\t%P1";
19870   return "jmp\t%A1";
19871 }
19872   [(set_attr "type" "callv")])
19873
19874 (define_insn "*call_value_1_rex64"
19875   [(set (match_operand 0 "" "")
19876         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19877               (match_operand:DI 2 "" "")))]
19878   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19879 {
19880   if (constant_call_address_operand (operands[1], Pmode))
19881     return "call\t%P1";
19882   return "call\t%A1";
19883 }
19884   [(set_attr "type" "callv")])
19885
19886 (define_insn "*sibcall_value_1_rex64"
19887   [(set (match_operand 0 "" "")
19888         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19889               (match_operand:DI 2 "" "")))]
19890   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19891   "jmp\t%P1"
19892   [(set_attr "type" "callv")])
19893
19894 (define_insn "*sibcall_value_1_rex64_v"
19895   [(set (match_operand 0 "" "")
19896         (call (mem:QI (reg:DI 40))
19897               (match_operand:DI 1 "" "")))]
19898   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19899   "jmp\t*%%r11"
19900   [(set_attr "type" "callv")])
19901 \f
19902 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19903 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19904 ;; caught for use by garbage collectors and the like.  Using an insn that
19905 ;; maps to SIGILL makes it more likely the program will rightfully die.
19906 ;; Keeping with tradition, "6" is in honor of #UD.
19907 (define_insn "trap"
19908   [(trap_if (const_int 1) (const_int 6))]
19909   ""
19910   ".word\t0x0b0f"
19911   [(set_attr "length" "2")])
19912
19913 (define_expand "sse_prologue_save"
19914   [(parallel [(set (match_operand:BLK 0 "" "")
19915                    (unspec:BLK [(reg:DI 21)
19916                                 (reg:DI 22)
19917                                 (reg:DI 23)
19918                                 (reg:DI 24)
19919                                 (reg:DI 25)
19920                                 (reg:DI 26)
19921                                 (reg:DI 27)
19922                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19923               (use (match_operand:DI 1 "register_operand" ""))
19924               (use (match_operand:DI 2 "immediate_operand" ""))
19925               (use (label_ref:DI (match_operand 3 "" "")))])]
19926   "TARGET_64BIT"
19927   "")
19928
19929 (define_insn "*sse_prologue_save_insn"
19930   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19931                           (match_operand:DI 4 "const_int_operand" "n")))
19932         (unspec:BLK [(reg:DI 21)
19933                      (reg:DI 22)
19934                      (reg:DI 23)
19935                      (reg:DI 24)
19936                      (reg:DI 25)
19937                      (reg:DI 26)
19938                      (reg:DI 27)
19939                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19940    (use (match_operand:DI 1 "register_operand" "r"))
19941    (use (match_operand:DI 2 "const_int_operand" "i"))
19942    (use (label_ref:DI (match_operand 3 "" "X")))]
19943   "TARGET_64BIT
19944    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19945    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19946   "*
19947 {
19948   int i;
19949   operands[0] = gen_rtx_MEM (Pmode,
19950                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19951   output_asm_insn (\"jmp\\t%A1\", operands);
19952   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19953     {
19954       operands[4] = adjust_address (operands[0], DImode, i*16);
19955       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19956       PUT_MODE (operands[4], TImode);
19957       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19958         output_asm_insn (\"rex\", operands);
19959       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19960     }
19961   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19962                              CODE_LABEL_NUMBER (operands[3]));
19963   RET;
19964 }
19965   "
19966   [(set_attr "type" "other")
19967    (set_attr "length_immediate" "0")
19968    (set_attr "length_address" "0")
19969    (set_attr "length" "135")
19970    (set_attr "memory" "store")
19971    (set_attr "modrm" "0")
19972    (set_attr "mode" "DI")])
19973
19974 (define_expand "prefetch"
19975   [(prefetch (match_operand 0 "address_operand" "")
19976              (match_operand:SI 1 "const_int_operand" "")
19977              (match_operand:SI 2 "const_int_operand" ""))]
19978   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19979 {
19980   int rw = INTVAL (operands[1]);
19981   int locality = INTVAL (operands[2]);
19982
19983   gcc_assert (rw == 0 || rw == 1);
19984   gcc_assert (locality >= 0 && locality <= 3);
19985   gcc_assert (GET_MODE (operands[0]) == Pmode
19986               || GET_MODE (operands[0]) == VOIDmode);
19987
19988   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19989      supported by SSE counterpart or the SSE prefetch is not available
19990      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19991      of locality.  */
19992   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19993     operands[2] = GEN_INT (3);
19994   else
19995     operands[1] = const0_rtx;
19996 })
19997
19998 (define_insn "*prefetch_sse"
19999   [(prefetch (match_operand:SI 0 "address_operand" "p")
20000              (const_int 0)
20001              (match_operand:SI 1 "const_int_operand" ""))]
20002   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20003 {
20004   static const char * const patterns[4] = {
20005    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20006   };
20007
20008   int locality = INTVAL (operands[1]);
20009   gcc_assert (locality >= 0 && locality <= 3);
20010
20011   return patterns[locality];  
20012 }
20013   [(set_attr "type" "sse")
20014    (set_attr "memory" "none")])
20015
20016 (define_insn "*prefetch_sse_rex"
20017   [(prefetch (match_operand:DI 0 "address_operand" "p")
20018              (const_int 0)
20019              (match_operand:SI 1 "const_int_operand" ""))]
20020   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20021 {
20022   static const char * const patterns[4] = {
20023    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20024   };
20025
20026   int locality = INTVAL (operands[1]);
20027   gcc_assert (locality >= 0 && locality <= 3);
20028
20029   return patterns[locality];  
20030 }
20031   [(set_attr "type" "sse")
20032    (set_attr "memory" "none")])
20033
20034 (define_insn "*prefetch_3dnow"
20035   [(prefetch (match_operand:SI 0 "address_operand" "p")
20036              (match_operand:SI 1 "const_int_operand" "n")
20037              (const_int 3))]
20038   "TARGET_3DNOW && !TARGET_64BIT"
20039 {
20040   if (INTVAL (operands[1]) == 0)
20041     return "prefetch\t%a0";
20042   else
20043     return "prefetchw\t%a0";
20044 }
20045   [(set_attr "type" "mmx")
20046    (set_attr "memory" "none")])
20047
20048 (define_insn "*prefetch_3dnow_rex"
20049   [(prefetch (match_operand:DI 0 "address_operand" "p")
20050              (match_operand:SI 1 "const_int_operand" "n")
20051              (const_int 3))]
20052   "TARGET_3DNOW && TARGET_64BIT"
20053 {
20054   if (INTVAL (operands[1]) == 0)
20055     return "prefetch\t%a0";
20056   else
20057     return "prefetchw\t%a0";
20058 }
20059   [(set_attr "type" "mmx")
20060    (set_attr "memory" "none")])
20061
20062 (define_expand "stack_protect_set"
20063   [(match_operand 0 "memory_operand" "")
20064    (match_operand 1 "memory_operand" "")]
20065   ""
20066 {
20067 #ifdef TARGET_THREAD_SSP_OFFSET
20068   if (TARGET_64BIT)
20069     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20070                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20071   else
20072     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20073                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20074 #else
20075   if (TARGET_64BIT)
20076     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20077   else
20078     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20079 #endif
20080   DONE;
20081 })
20082
20083 (define_insn "stack_protect_set_si"
20084   [(set (match_operand:SI 0 "memory_operand" "=m")
20085         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20086    (set (match_scratch:SI 2 "=&r") (const_int 0))
20087    (clobber (reg:CC FLAGS_REG))]
20088   ""
20089   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20090   [(set_attr "type" "multi")])
20091
20092 (define_insn "stack_protect_set_di"
20093   [(set (match_operand:DI 0 "memory_operand" "=m")
20094         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20095    (set (match_scratch:DI 2 "=&r") (const_int 0))
20096    (clobber (reg:CC FLAGS_REG))]
20097   "TARGET_64BIT"
20098   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20099   [(set_attr "type" "multi")])
20100
20101 (define_insn "stack_tls_protect_set_si"
20102   [(set (match_operand:SI 0 "memory_operand" "=m")
20103         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20104    (set (match_scratch:SI 2 "=&r") (const_int 0))
20105    (clobber (reg:CC FLAGS_REG))]
20106   ""
20107   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20108   [(set_attr "type" "multi")])
20109
20110 (define_insn "stack_tls_protect_set_di"
20111   [(set (match_operand:DI 0 "memory_operand" "=m")
20112         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20113    (set (match_scratch:DI 2 "=&r") (const_int 0))
20114    (clobber (reg:CC FLAGS_REG))]
20115   "TARGET_64BIT"
20116   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20117   [(set_attr "type" "multi")])
20118
20119 (define_expand "stack_protect_test"
20120   [(match_operand 0 "memory_operand" "")
20121    (match_operand 1 "memory_operand" "")
20122    (match_operand 2 "" "")]
20123   ""
20124 {
20125   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20126   ix86_compare_op0 = operands[0];
20127   ix86_compare_op1 = operands[1];
20128   ix86_compare_emitted = flags;
20129
20130 #ifdef TARGET_THREAD_SSP_OFFSET
20131   if (TARGET_64BIT)
20132     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20133                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20134   else
20135     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20136                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20137 #else
20138   if (TARGET_64BIT)
20139     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20140   else
20141     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20142 #endif
20143   emit_jump_insn (gen_beq (operands[2]));
20144   DONE;
20145 })
20146
20147 (define_insn "stack_protect_test_si"
20148   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20149         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20150                      (match_operand:SI 2 "memory_operand" "m")]
20151                     UNSPEC_SP_TEST))
20152    (clobber (match_scratch:SI 3 "=&r"))]
20153   ""
20154   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20155   [(set_attr "type" "multi")])
20156
20157 (define_insn "stack_protect_test_di"
20158   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20159         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20160                      (match_operand:DI 2 "memory_operand" "m")]
20161                     UNSPEC_SP_TEST))
20162    (clobber (match_scratch:DI 3 "=&r"))]
20163   "TARGET_64BIT"
20164   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20165   [(set_attr "type" "multi")])
20166
20167 (define_insn "stack_tls_protect_test_si"
20168   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20169         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20170                      (match_operand:SI 2 "const_int_operand" "i")]
20171                     UNSPEC_SP_TLS_TEST))
20172    (clobber (match_scratch:SI 3 "=r"))]
20173   ""
20174   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20175   [(set_attr "type" "multi")])
20176
20177 (define_insn "stack_tls_protect_test_di"
20178   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20179         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20180                      (match_operand:DI 2 "const_int_operand" "i")]
20181                     UNSPEC_SP_TLS_TEST))
20182    (clobber (match_scratch:DI 3 "=r"))]
20183   "TARGET_64BIT"
20184   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20185   [(set_attr "type" "multi")])
20186
20187 (include "sse.md")
20188 (include "mmx.md")
20189 (include "sync.md")