OSDN Git Service

PR target/25554
[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    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 20)
79    (UNSPEC_FNSTSW               21)
80    (UNSPEC_SAHF                 22)
81    (UNSPEC_FSTCW                23)
82    (UNSPEC_ADD_CARRY            24)
83    (UNSPEC_FLDCW                25)
84    (UNSPEC_REP                  26)
85    (UNSPEC_EH_RETURN            27)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDQQU                47)
106
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
111
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
121
122    ; x87 Rounding
123    (UNSPEC_FRNDINT_FLOOR        70)
124    (UNSPEC_FRNDINT_CEIL         71)
125    (UNSPEC_FRNDINT_TRUNC        72)
126    (UNSPEC_FRNDINT_MASK_PM      73)
127    (UNSPEC_FIST_FLOOR           74)
128    (UNSPEC_FIST_CEIL            75)
129
130    ; x87 Double output FP
131    (UNSPEC_SINCOS_COS           80)
132    (UNSPEC_SINCOS_SIN           81)
133    (UNSPEC_TAN_ONE              82)
134    (UNSPEC_TAN_TAN              83)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
143
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149   ])
150
151 (define_constants
152   [(UNSPECV_BLOCKAGE            0)
153    (UNSPECV_STACK_PROBE         1)
154    (UNSPECV_EMMS                2)
155    (UNSPECV_LDMXCSR             3)
156    (UNSPECV_STMXCSR             4)
157    (UNSPECV_FEMMS               5)
158    (UNSPECV_CLFLUSH             6)
159    (UNSPECV_ALIGN               7)
160    (UNSPECV_MONITOR             8)
161    (UNSPECV_MWAIT               9)
162    (UNSPECV_CMPXCHG_1           10)
163    (UNSPECV_CMPXCHG_2           11)
164    (UNSPECV_XCHG                12)
165    (UNSPECV_LOCK                13)
166   ])
167
168 ;; Registers by name.
169 (define_constants
170   [(BP_REG                       6)
171    (SP_REG                       7)
172    (FLAGS_REG                   17)
173    (FPSR_REG                    18)
174    (DIRFLAG_REG                 19)
175   ])
176
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178 ;; from i386.c.
179
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first.  This allows for better optimization.  For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
184
185 \f
186 ;; Processor type.  This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189   (const (symbol_ref "ix86_tune")))
190
191 ;; A basic instruction type.  Refinements due to arguments to be
192 ;; provided in other attributes.
193 (define_attr "type"
194   "other,multi,
195    alu,alu1,negnot,imov,imovx,lea,
196    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197    icmp,test,ibr,setcc,icmov,
198    push,pop,call,callv,leave,
199    str,cld,
200    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201    sselog,sselog1,sseiadd,sseishft,sseimul,
202    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204   (const_string "other"))
205
206 ;; Main data type used by the insn
207 (define_attr "mode"
208   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209   (const_string "unknown"))
210
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214            (const_string "i387")
215          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
217            (const_string "sse")
218          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
219            (const_string "mmx")
220          (eq_attr "type" "other")
221            (const_string "unknown")]
222          (const_string "integer")))
223
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
227            (const_int 0)
228          (eq_attr "unit" "i387,sse,mmx")
229            (const_int 0)
230          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
231                           imul,icmp,push,pop")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233          (eq_attr "type" "imov,test")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235          (eq_attr "type" "call")
236            (if_then_else (match_operand 0 "constant_call_address_operand" "")
237              (const_int 4)
238              (const_int 0))
239          (eq_attr "type" "callv")
240            (if_then_else (match_operand 1 "constant_call_address_operand" "")
241              (const_int 4)
242              (const_int 0))
243          ;; We don't know the size before shorten_branches.  Expect
244          ;; the instruction to fit for better scheduling.
245          (eq_attr "type" "ibr")
246            (const_int 1)
247          ]
248          (symbol_ref "/* Update immediate_length and other attributes! */
249                       gcc_unreachable (),1")))
250
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
254            (const_int 0)
255          (and (eq_attr "type" "call")
256               (match_operand 0 "constant_call_address_operand" ""))
257              (const_int 0)
258          (and (eq_attr "type" "callv")
259               (match_operand 1 "constant_call_address_operand" ""))
260              (const_int 0)
261          ]
262          (symbol_ref "ix86_attr_length_address_default (insn)")))
263
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266   (if_then_else (ior (eq_attr "mode" "HI")
267                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
268     (const_int 1)
269     (const_int 0)))
270
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" "" 
273   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
274     (const_int 1)
275     (const_int 0)))
276
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
279   (if_then_else 
280     (ior (eq_attr "type" "imovx,setcc,icmov")
281          (eq_attr "unit" "sse,mmx"))
282     (const_int 1)
283     (const_int 0)))
284
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287   (cond [(and (eq_attr "mode" "DI")
288               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
289            (const_int 1)
290          (and (eq_attr "mode" "QI")
291               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
292                   (const_int 0)))
293            (const_int 1)
294          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
295              (const_int 0))
296            (const_int 1)
297         ]
298         (const_int 0)))
299
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302   (cond [(eq_attr "type" "str,cld,leave")
303            (const_int 0)
304          (eq_attr "unit" "i387")
305            (const_int 0)
306          (and (eq_attr "type" "incdec")
307               (ior (match_operand:SI 1 "register_operand" "")
308                    (match_operand:HI 1 "register_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "push")
311               (not (match_operand 1 "memory_operand" "")))
312            (const_int 0)
313          (and (eq_attr "type" "pop")
314               (not (match_operand 0 "memory_operand" "")))
315            (const_int 0)
316          (and (eq_attr "type" "imov")
317               (ior (and (match_operand 0 "register_operand" "")
318                         (match_operand 1 "immediate_operand" ""))
319                    (ior (and (match_operand 0 "ax_reg_operand" "")
320                              (match_operand 1 "memory_displacement_only_operand" ""))
321                         (and (match_operand 0 "memory_displacement_only_operand" "")
322                              (match_operand 1 "ax_reg_operand" "")))))
323            (const_int 0)
324          (and (eq_attr "type" "call")
325               (match_operand 0 "constant_call_address_operand" ""))
326              (const_int 0)
327          (and (eq_attr "type" "callv")
328               (match_operand 1 "constant_call_address_operand" ""))
329              (const_int 0)
330          ]
331          (const_int 1)))
332
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
336 ;; other insns.
337 (define_attr "length" ""
338   (cond [(eq_attr "type" "other,multi,fistp,frndint")
339            (const_int 16)
340          (eq_attr "type" "fcmp")
341            (const_int 4)
342          (eq_attr "unit" "i387")
343            (plus (const_int 2)
344                  (plus (attr "prefix_data16")
345                        (attr "length_address")))]
346          (plus (plus (attr "modrm")
347                      (plus (attr "prefix_0f")
348                            (plus (attr "prefix_rex")
349                                  (const_int 1))))
350                (plus (attr "prefix_rep")
351                      (plus (attr "prefix_data16")
352                            (plus (attr "length_immediate")
353                                  (attr "length_address")))))))
354
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
358
359 (define_attr "memory" "none,load,store,both,unknown"
360   (cond [(eq_attr "type" "other,multi,str")
361            (const_string "unknown")
362          (eq_attr "type" "lea,fcmov,fpspc,cld")
363            (const_string "none")
364          (eq_attr "type" "fistp,leave")
365            (const_string "both")
366          (eq_attr "type" "frndint")
367            (const_string "load")
368          (eq_attr "type" "push")
369            (if_then_else (match_operand 1 "memory_operand" "")
370              (const_string "both")
371              (const_string "store"))
372          (eq_attr "type" "pop")
373            (if_then_else (match_operand 0 "memory_operand" "")
374              (const_string "both")
375              (const_string "load"))
376          (eq_attr "type" "setcc")
377            (if_then_else (match_operand 0 "memory_operand" "")
378              (const_string "store")
379              (const_string "none"))
380          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381            (if_then_else (ior (match_operand 0 "memory_operand" "")
382                               (match_operand 1 "memory_operand" ""))
383              (const_string "load")
384              (const_string "none"))
385          (eq_attr "type" "ibr")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "load")
388              (const_string "none"))
389          (eq_attr "type" "call")
390            (if_then_else (match_operand 0 "constant_call_address_operand" "")
391              (const_string "none")
392              (const_string "load"))
393          (eq_attr "type" "callv")
394            (if_then_else (match_operand 1 "constant_call_address_operand" "")
395              (const_string "none")
396              (const_string "load"))
397          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398               (match_operand 1 "memory_operand" ""))
399            (const_string "both")
400          (and (match_operand 0 "memory_operand" "")
401               (match_operand 1 "memory_operand" ""))
402            (const_string "both")
403          (match_operand 0 "memory_operand" "")
404            (const_string "store")
405          (match_operand 1 "memory_operand" "")
406            (const_string "load")
407          (and (eq_attr "type"
408                  "!alu1,negnot,ishift1,
409                    imov,imovx,icmp,test,
410                    fmov,fcmp,fsgn,
411                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412                    mmx,mmxmov,mmxcmp,mmxcvt")
413               (match_operand 2 "memory_operand" ""))
414            (const_string "load")
415          (and (eq_attr "type" "icmov")
416               (match_operand 3 "memory_operand" ""))
417            (const_string "load")
418         ]
419         (const_string "none")))
420
421 ;; Indicates if an instruction has both an immediate and a displacement.
422
423 (define_attr "imm_disp" "false,true,unknown"
424   (cond [(eq_attr "type" "other,multi")
425            (const_string "unknown")
426          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427               (and (match_operand 0 "memory_displacement_operand" "")
428                    (match_operand 1 "immediate_operand" "")))
429            (const_string "true")
430          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431               (and (match_operand 0 "memory_displacement_operand" "")
432                    (match_operand 2 "immediate_operand" "")))
433            (const_string "true")
434         ]
435         (const_string "false")))
436
437 ;; Indicates if an FP operation has an integer source.
438
439 (define_attr "fp_int_src" "false,true"
440   (const_string "false"))
441
442 ;; Defines rounding mode of an FP operation.
443
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445   (const_string "any"))
446
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449   [(set_attr "length" "128")
450    (set_attr "type" "multi")])
451
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
454  
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
457
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
460
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
463  
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
466
467 \f
468 ;; Scheduling descriptions
469
470 (include "pentium.md")
471 (include "ppro.md")
472 (include "k6.md")
473 (include "athlon.md")
474
475 \f
476 ;; Operand and operator predicates
477
478 (include "predicates.md")
479
480 \f
481 ;; Compare instructions.
482
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
486
487 (define_expand "cmpti"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490                     (match_operand:TI 1 "x86_64_general_operand" "")))]
491   "TARGET_64BIT"
492 {
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (TImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
498 })
499
500 (define_expand "cmpdi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503                     (match_operand:DI 1 "x86_64_general_operand" "")))]
504   ""
505 {
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (DImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
511 })
512
513 (define_expand "cmpsi"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516                     (match_operand:SI 1 "general_operand" "")))]
517   ""
518 {
519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520     operands[0] = force_reg (SImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmphi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529                     (match_operand:HI 1 "general_operand" "")))]
530   ""
531 {
532   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533     operands[0] = force_reg (HImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpqi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542                     (match_operand:QI 1 "general_operand" "")))]
543   "TARGET_QIMODE_MATH"
544 {
545   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546     operands[0] = force_reg (QImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_insn "cmpdi_ccno_1_rex64"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:DI 1 "const0_operand" "n,n")))]
556   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{q}\t{%0, %0|%0, %0}
559    cmp{q}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "DI")])
563
564 (define_insn "*cmpdi_minus_1_rex64"
565   [(set (reg FLAGS_REG)
566         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
568                  (const_int 0)))]
569   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{q}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "DI")])
573
574 (define_expand "cmpdi_1_rex64"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577                     (match_operand:DI 1 "general_operand" "")))]
578   "TARGET_64BIT"
579   "")
580
581 (define_insn "cmpdi_1_insn_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586   "cmp{q}\t{%1, %0|%0, %1}"
587   [(set_attr "type" "icmp")
588    (set_attr "mode" "DI")])
589
590
591 (define_insn "*cmpsi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:SI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{l}\t{%0, %0|%0, %0}
598    cmp{l}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "SI")])
602
603 (define_insn "*cmpsi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:SI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{l}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "SI")])
612
613 (define_expand "cmpsi_1"
614   [(set (reg:CC FLAGS_REG)
615         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616                     (match_operand:SI 1 "general_operand" "ri,mr")))]
617   ""
618   "")
619
620 (define_insn "*cmpsi_1_insn"
621   [(set (reg FLAGS_REG)
622         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                  (match_operand:SI 1 "general_operand" "ri,mr")))]
624   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625     && ix86_match_ccmode (insn, CCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
629
630 (define_insn "*cmphi_ccno_1"
631   [(set (reg FLAGS_REG)
632         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633                  (match_operand:HI 1 "const0_operand" "n,n")))]
634   "ix86_match_ccmode (insn, CCNOmode)"
635   "@
636    test{w}\t{%0, %0|%0, %0}
637    cmp{w}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "test,icmp")
639    (set_attr "length_immediate" "0,1")
640    (set_attr "mode" "HI")])
641
642 (define_insn "*cmphi_minus_1"
643   [(set (reg FLAGS_REG)
644         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645                            (match_operand:HI 1 "general_operand" "ri,mr"))
646                  (const_int 0)))]
647   "ix86_match_ccmode (insn, CCGOCmode)"
648   "cmp{w}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "icmp")
650    (set_attr "mode" "HI")])
651
652 (define_insn "*cmphi_1"
653   [(set (reg FLAGS_REG)
654         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655                  (match_operand:HI 1 "general_operand" "ri,mr")))]
656   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657    && ix86_match_ccmode (insn, CCmode)"
658   "cmp{w}\t{%1, %0|%0, %1}"
659   [(set_attr "type" "icmp")
660    (set_attr "mode" "HI")])
661
662 (define_insn "*cmpqi_ccno_1"
663   [(set (reg FLAGS_REG)
664         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665                  (match_operand:QI 1 "const0_operand" "n,n")))]
666   "ix86_match_ccmode (insn, CCNOmode)"
667   "@
668    test{b}\t{%0, %0|%0, %0}
669    cmp{b}\t{$0, %0|%0, 0}"
670   [(set_attr "type" "test,icmp")
671    (set_attr "length_immediate" "0,1")
672    (set_attr "mode" "QI")])
673
674 (define_insn "*cmpqi_1"
675   [(set (reg FLAGS_REG)
676         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677                  (match_operand:QI 1 "general_operand" "qi,mq")))]
678   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679     && ix86_match_ccmode (insn, CCmode)"
680   "cmp{b}\t{%1, %0|%0, %1}"
681   [(set_attr "type" "icmp")
682    (set_attr "mode" "QI")])
683
684 (define_insn "*cmpqi_minus_1"
685   [(set (reg FLAGS_REG)
686         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687                            (match_operand:QI 1 "general_operand" "qi,mq"))
688                  (const_int 0)))]
689   "ix86_match_ccmode (insn, CCGOCmode)"
690   "cmp{b}\t{%1, %0|%0, %1}"
691   [(set_attr "type" "icmp")
692    (set_attr "mode" "QI")])
693
694 (define_insn "*cmpqi_ext_1"
695   [(set (reg FLAGS_REG)
696         (compare
697           (match_operand:QI 0 "general_operand" "Qm")
698           (subreg:QI
699             (zero_extract:SI
700               (match_operand 1 "ext_register_operand" "Q")
701               (const_int 8)
702               (const_int 8)) 0)))]
703   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704   "cmp{b}\t{%h1, %0|%0, %h1}"
705   [(set_attr "type" "icmp")
706    (set_attr "mode" "QI")])
707
708 (define_insn "*cmpqi_ext_1_rex64"
709   [(set (reg FLAGS_REG)
710         (compare
711           (match_operand:QI 0 "register_operand" "Q")
712           (subreg:QI
713             (zero_extract:SI
714               (match_operand 1 "ext_register_operand" "Q")
715               (const_int 8)
716               (const_int 8)) 0)))]
717   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718   "cmp{b}\t{%h1, %0|%0, %h1}"
719   [(set_attr "type" "icmp")
720    (set_attr "mode" "QI")])
721
722 (define_insn "*cmpqi_ext_2"
723   [(set (reg FLAGS_REG)
724         (compare
725           (subreg:QI
726             (zero_extract:SI
727               (match_operand 0 "ext_register_operand" "Q")
728               (const_int 8)
729               (const_int 8)) 0)
730           (match_operand:QI 1 "const0_operand" "n")))]
731   "ix86_match_ccmode (insn, CCNOmode)"
732   "test{b}\t%h0, %h0"
733   [(set_attr "type" "test")
734    (set_attr "length_immediate" "0")
735    (set_attr "mode" "QI")])
736
737 (define_expand "cmpqi_ext_3"
738   [(set (reg:CC FLAGS_REG)
739         (compare:CC
740           (subreg:QI
741             (zero_extract:SI
742               (match_operand 0 "ext_register_operand" "")
743               (const_int 8)
744               (const_int 8)) 0)
745           (match_operand:QI 1 "general_operand" "")))]
746   ""
747   "")
748
749 (define_insn "cmpqi_ext_3_insn"
750   [(set (reg FLAGS_REG)
751         (compare
752           (subreg:QI
753             (zero_extract:SI
754               (match_operand 0 "ext_register_operand" "Q")
755               (const_int 8)
756               (const_int 8)) 0)
757           (match_operand:QI 1 "general_operand" "Qmn")))]
758   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759   "cmp{b}\t{%1, %h0|%h0, %1}"
760   [(set_attr "type" "icmp")
761    (set_attr "mode" "QI")])
762
763 (define_insn "cmpqi_ext_3_insn_rex64"
764   [(set (reg FLAGS_REG)
765         (compare
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773   "cmp{b}\t{%1, %h0|%h0, %1}"
774   [(set_attr "type" "icmp")
775    (set_attr "mode" "QI")])
776
777 (define_insn "*cmpqi_ext_4"
778   [(set (reg FLAGS_REG)
779         (compare
780           (subreg:QI
781             (zero_extract:SI
782               (match_operand 0 "ext_register_operand" "Q")
783               (const_int 8)
784               (const_int 8)) 0)
785           (subreg:QI
786             (zero_extract:SI
787               (match_operand 1 "ext_register_operand" "Q")
788               (const_int 8)
789               (const_int 8)) 0)))]
790   "ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%h1, %h0|%h0, %h1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
794
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares.  Which is what
798 ;; the old patterns did, but with many more of them.
799
800 (define_expand "cmpxf"
801   [(set (reg:CC FLAGS_REG)
802         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803                     (match_operand:XF 1 "nonmemory_operand" "")))]
804   "TARGET_80387"
805 {
806   ix86_compare_op0 = operands[0];
807   ix86_compare_op1 = operands[1];
808   DONE;
809 })
810
811 (define_expand "cmpdf"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
816 {
817   ix86_compare_op0 = operands[0];
818   ix86_compare_op1 = operands[1];
819   DONE;
820 })
821
822 (define_expand "cmpsf"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826   "TARGET_80387 || TARGET_SSE_MATH"
827 {
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
831 })
832
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
835 ;;
836 ;; CCFPmode     compare with exceptions
837 ;; CCFPUmode    compare with no exceptions
838
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
841
842 (define_insn "*cmpfp_0"
843   [(set (match_operand:HI 0 "register_operand" "=a")
844         (unspec:HI
845           [(compare:CCFP
846              (match_operand 1 "register_operand" "f")
847              (match_operand 2 "const0_operand" "X"))]
848         UNSPEC_FNSTSW))]
849   "TARGET_80387
850    && FLOAT_MODE_P (GET_MODE (operands[1]))
851    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852   "* return output_fp_compare (insn, operands, 0, 0);"
853   [(set_attr "type" "multi")
854    (set_attr "unit" "i387")
855    (set (attr "mode")
856      (cond [(match_operand:SF 1 "" "")
857               (const_string "SF")
858             (match_operand:DF 1 "" "")
859               (const_string "DF")
860            ]
861            (const_string "XF")))])
862
863 (define_insn "*cmpfp_sf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:SF 1 "register_operand" "f")
868              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "unit" "i387")
874    (set_attr "mode" "SF")])
875
876 (define_insn "*cmpfp_df"
877   [(set (match_operand:HI 0 "register_operand" "=a")
878         (unspec:HI
879           [(compare:CCFP
880              (match_operand:DF 1 "register_operand" "f")
881              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
882           UNSPEC_FNSTSW))]
883   "TARGET_80387"
884   "* return output_fp_compare (insn, operands, 0, 0);"
885   [(set_attr "type" "multi")
886    (set_attr "unit" "i387")
887    (set_attr "mode" "DF")])
888
889 (define_insn "*cmpfp_xf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:XF 1 "register_operand" "f")
894              (match_operand:XF 2 "register_operand" "f"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "XF")])
901
902 (define_insn "*cmpfp_u"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFPU
906              (match_operand 1 "register_operand" "f")
907              (match_operand 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912   "* return output_fp_compare (insn, operands, 0, 1);"
913   [(set_attr "type" "multi")
914    (set_attr "unit" "i387")
915    (set (attr "mode")
916      (cond [(match_operand:SF 1 "" "")
917               (const_string "SF")
918             (match_operand:DF 1 "" "")
919               (const_string "DF")
920            ]
921            (const_string "XF")))])
922
923 (define_insn "*cmpfp_<mode>"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFP
927              (match_operand 1 "register_operand" "f")
928              (match_operator 3 "float_operator"
929                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
930           UNSPEC_FNSTSW))]
931   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932    && FLOAT_MODE_P (GET_MODE (operands[1]))
933    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934   "* return output_fp_compare (insn, operands, 0, 0);"
935   [(set_attr "type" "multi")
936    (set_attr "unit" "i387")
937    (set_attr "fp_int_src" "true")
938    (set_attr "mode" "<MODE>")])
939
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
942
943 (define_insn "x86_fnstsw_1"
944   [(set (match_operand:HI 0 "register_operand" "=a")
945         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
946   "TARGET_80387"
947   "fnstsw\t%0"
948   [(set_attr "length" "2")
949    (set_attr "mode" "SI")
950    (set_attr "unit" "i387")])
951
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
954
955 (define_insn "x86_sahf_1"
956   [(set (reg:CC FLAGS_REG)
957         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
958   "!TARGET_64BIT"
959   "sahf"
960   [(set_attr "length" "1")
961    (set_attr "athlon_decode" "vector")
962    (set_attr "mode" "SI")])
963
964 ;; Pentium Pro can do steps 1 through 3 in one go.
965
966 (define_insn "*cmpfp_i_mixed"
967   [(set (reg:CCFP FLAGS_REG)
968         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
970   "TARGET_MIX_SSE_I387
971    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973   "* return output_fp_compare (insn, operands, 1, 0);"
974   [(set_attr "type" "fcmp,ssecomi")
975    (set (attr "mode")
976      (if_then_else (match_operand:SF 1 "" "")
977         (const_string "SF")
978         (const_string "DF")))
979    (set_attr "athlon_decode" "vector")])
980
981 (define_insn "*cmpfp_i_sse"
982   [(set (reg:CCFP FLAGS_REG)
983         (compare:CCFP (match_operand 0 "register_operand" "x")
984                       (match_operand 1 "nonimmediate_operand" "xm")))]
985   "TARGET_SSE_MATH
986    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988   "* return output_fp_compare (insn, operands, 1, 0);"
989   [(set_attr "type" "ssecomi")
990    (set (attr "mode")
991      (if_then_else (match_operand:SF 1 "" "")
992         (const_string "SF")
993         (const_string "DF")))
994    (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_i_i387"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP (match_operand 0 "register_operand" "f")
999                       (match_operand 1 "register_operand" "f")))]
1000   "TARGET_80387 && TARGET_CMOVE
1001    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002    && FLOAT_MODE_P (GET_MODE (operands[0]))
1003    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004   "* return output_fp_compare (insn, operands, 1, 0);"
1005   [(set_attr "type" "fcmp")
1006    (set (attr "mode")
1007      (cond [(match_operand:SF 1 "" "")
1008               (const_string "SF")
1009             (match_operand:DF 1 "" "")
1010               (const_string "DF")
1011            ]
1012            (const_string "XF")))
1013    (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_iu_mixed"
1016   [(set (reg:CCFPU FLAGS_REG)
1017         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019   "TARGET_MIX_SSE_I387
1020    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 1);"
1023   [(set_attr "type" "fcmp,ssecomi")
1024    (set (attr "mode")
1025      (if_then_else (match_operand:SF 1 "" "")
1026         (const_string "SF")
1027         (const_string "DF")))
1028    (set_attr "athlon_decode" "vector")])
1029
1030 (define_insn "*cmpfp_iu_sse"
1031   [(set (reg:CCFPU FLAGS_REG)
1032         (compare:CCFPU (match_operand 0 "register_operand" "x")
1033                        (match_operand 1 "nonimmediate_operand" "xm")))]
1034   "TARGET_SSE_MATH
1035    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037   "* return output_fp_compare (insn, operands, 1, 1);"
1038   [(set_attr "type" "ssecomi")
1039    (set (attr "mode")
1040      (if_then_else (match_operand:SF 1 "" "")
1041         (const_string "SF")
1042         (const_string "DF")))
1043    (set_attr "athlon_decode" "vector")])
1044
1045 (define_insn "*cmpfp_iu_387"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f")
1048                        (match_operand 1 "register_operand" "f")))]
1049   "TARGET_80387 && TARGET_CMOVE
1050    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051    && FLOAT_MODE_P (GET_MODE (operands[0]))
1052    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053   "* return output_fp_compare (insn, operands, 1, 1);"
1054   [(set_attr "type" "fcmp")
1055    (set (attr "mode")
1056      (cond [(match_operand:SF 1 "" "")
1057               (const_string "SF")
1058             (match_operand:DF 1 "" "")
1059               (const_string "DF")
1060            ]
1061            (const_string "XF")))
1062    (set_attr "athlon_decode" "vector")])
1063 \f
1064 ;; Move instructions.
1065
1066 ;; General case of fullword move.
1067
1068 (define_expand "movsi"
1069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070         (match_operand:SI 1 "general_operand" ""))]
1071   ""
1072   "ix86_expand_move (SImode, operands); DONE;")
1073
1074 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1075 ;; general_operand.
1076 ;;
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1082
1083 (define_insn "*pushsi2"
1084   [(set (match_operand:SI 0 "push_operand" "=<")
1085         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1086   "!TARGET_64BIT"
1087   "push{l}\t%1"
1088   [(set_attr "type" "push")
1089    (set_attr "mode" "SI")])
1090
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093   [(set (match_operand:SI 0 "push_operand" "=X")
1094         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1095   "TARGET_64BIT"
1096   "push{q}\t%q1"
1097   [(set_attr "type" "push")
1098    (set_attr "mode" "SI")])
1099
1100 (define_insn "*pushsi2_prologue"
1101   [(set (match_operand:SI 0 "push_operand" "=<")
1102         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103    (clobber (mem:BLK (scratch)))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1108
1109 (define_insn "*popsi1_epilogue"
1110   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111         (mem:SI (reg:SI SP_REG)))
1112    (set (reg:SI SP_REG)
1113         (plus:SI (reg:SI SP_REG) (const_int 4)))
1114    (clobber (mem:BLK (scratch)))]
1115   "!TARGET_64BIT"
1116   "pop{l}\t%0"
1117   [(set_attr "type" "pop")
1118    (set_attr "mode" "SI")])
1119
1120 (define_insn "popsi1"
1121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122         (mem:SI (reg:SI SP_REG)))
1123    (set (reg:SI SP_REG)
1124         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1125   "!TARGET_64BIT"
1126   "pop{l}\t%0"
1127   [(set_attr "type" "pop")
1128    (set_attr "mode" "SI")])
1129
1130 (define_insn "*movsi_xor"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (match_operand:SI 1 "const0_operand" "i"))
1133    (clobber (reg:CC FLAGS_REG))]
1134   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135   "xor{l}\t{%0, %0|%0, %0}"
1136   [(set_attr "type" "alu1")
1137    (set_attr "mode" "SI")
1138    (set_attr "length_immediate" "0")])
1139  
1140 (define_insn "*movsi_or"
1141   [(set (match_operand:SI 0 "register_operand" "=r")
1142         (match_operand:SI 1 "immediate_operand" "i"))
1143    (clobber (reg:CC FLAGS_REG))]
1144   "reload_completed
1145    && operands[1] == constm1_rtx
1146    && (TARGET_PENTIUM || optimize_size)"
1147 {
1148   operands[1] = constm1_rtx;
1149   return "or{l}\t{%1, %0|%0, %1}";
1150 }
1151   [(set_attr "type" "alu1")
1152    (set_attr "mode" "SI")
1153    (set_attr "length_immediate" "1")])
1154
1155 (define_insn "*movsi_1"
1156   [(set (match_operand:SI 0 "nonimmediate_operand"
1157                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158         (match_operand:SI 1 "general_operand"
1159                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1160   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1161 {
1162   switch (get_attr_type (insn))
1163     {
1164     case TYPE_SSELOG1:
1165       if (get_attr_mode (insn) == MODE_TI)
1166         return "pxor\t%0, %0";
1167       return "xorps\t%0, %0";
1168
1169     case TYPE_SSEMOV:
1170       switch (get_attr_mode (insn))
1171         {
1172         case MODE_TI:
1173           return "movdqa\t{%1, %0|%0, %1}";
1174         case MODE_V4SF:
1175           return "movaps\t{%1, %0|%0, %1}";
1176         case MODE_SI:
1177           return "movd\t{%1, %0|%0, %1}";
1178         case MODE_SF:
1179           return "movss\t{%1, %0|%0, %1}";
1180         default:
1181           gcc_unreachable ();
1182         }
1183
1184     case TYPE_MMXADD:
1185       return "pxor\t%0, %0";
1186
1187     case TYPE_MMXMOV:
1188       if (get_attr_mode (insn) == MODE_DI)
1189         return "movq\t{%1, %0|%0, %1}";
1190       return "movd\t{%1, %0|%0, %1}";
1191
1192     case TYPE_LEA:
1193       return "lea{l}\t{%1, %0|%0, %1}";
1194
1195     default:
1196       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197       return "mov{l}\t{%1, %0|%0, %1}";
1198     }
1199 }
1200   [(set (attr "type")
1201      (cond [(eq_attr "alternative" "2")
1202               (const_string "mmxadd")
1203             (eq_attr "alternative" "3,4,5")
1204               (const_string "mmxmov")
1205             (eq_attr "alternative" "6")
1206               (const_string "sselog1")
1207             (eq_attr "alternative" "7,8,9,10,11")
1208               (const_string "ssemov")
1209             (match_operand:DI 1 "pic_32bit_operand" "")
1210               (const_string "lea")
1211            ]
1212            (const_string "imov")))
1213    (set (attr "mode")
1214      (cond [(eq_attr "alternative" "2,3")
1215               (const_string "DI")
1216             (eq_attr "alternative" "6,7")
1217               (if_then_else
1218                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219                 (const_string "V4SF")
1220                 (const_string "TI"))
1221             (and (eq_attr "alternative" "8,9,10,11")
1222                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1223               (const_string "SF")
1224            ]
1225            (const_string "SI")))])
1226
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1234   "@
1235    movabs{l}\t{%1, %P0|%P0, %1}
1236    mov{l}\t{%1, %a0|%a0, %1}"
1237   [(set_attr "type" "imov")
1238    (set_attr "modrm" "0,*")
1239    (set_attr "length_address" "8,0")
1240    (set_attr "length_immediate" "0,*")
1241    (set_attr "memory" "store")
1242    (set_attr "mode" "SI")])
1243
1244 (define_insn "*movabssi_2_rex64"
1245   [(set (match_operand:SI 0 "register_operand" "=a,r")
1246         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1248   "@
1249    movabs{l}\t{%P1, %0|%0, %P1}
1250    mov{l}\t{%a1, %0|%0, %a1}"
1251   [(set_attr "type" "imov")
1252    (set_attr "modrm" "0,*")
1253    (set_attr "length_address" "8,0")
1254    (set_attr "length_immediate" "0")
1255    (set_attr "memory" "load")
1256    (set_attr "mode" "SI")])
1257
1258 (define_insn "*swapsi"
1259   [(set (match_operand:SI 0 "register_operand" "+r")
1260         (match_operand:SI 1 "register_operand" "+r"))
1261    (set (match_dup 1)
1262         (match_dup 0))]
1263   ""
1264   "xchg{l}\t%1, %0"
1265   [(set_attr "type" "imov")
1266    (set_attr "mode" "SI")
1267    (set_attr "pent_pair" "np")
1268    (set_attr "athlon_decode" "vector")])
1269
1270 (define_expand "movhi"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272         (match_operand:HI 1 "general_operand" ""))]
1273   ""
1274   "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277   [(set (match_operand:HI 0 "push_operand" "=X")
1278         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1279   "!TARGET_64BIT"
1280   "push{l}\t%k1"
1281   [(set_attr "type" "push")
1282    (set_attr "mode" "SI")])
1283
1284 ;; For 64BIT abi we always round up to 8 bytes.
1285 (define_insn "*pushhi2_rex64"
1286   [(set (match_operand:HI 0 "push_operand" "=X")
1287         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1288   "TARGET_64BIT"
1289   "push{q}\t%q1"
1290   [(set_attr "type" "push")
1291    (set_attr "mode" "DI")])
1292
1293 (define_insn "*movhi_1"
1294   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1295         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1296   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1297 {
1298   switch (get_attr_type (insn))
1299     {
1300     case TYPE_IMOVX:
1301       /* movzwl is faster than movw on p2 due to partial word stalls,
1302          though not as fast as an aligned movl.  */
1303       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1304     default:
1305       if (get_attr_mode (insn) == MODE_SI)
1306         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1307       else
1308         return "mov{w}\t{%1, %0|%0, %1}";
1309     }
1310 }
1311   [(set (attr "type")
1312      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1313               (const_string "imov")
1314             (and (eq_attr "alternative" "0")
1315                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316                           (const_int 0))
1317                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1318                           (const_int 0))))
1319               (const_string "imov")
1320             (and (eq_attr "alternative" "1,2")
1321                  (match_operand:HI 1 "aligned_operand" ""))
1322               (const_string "imov")
1323             (and (ne (symbol_ref "TARGET_MOVX")
1324                      (const_int 0))
1325                  (eq_attr "alternative" "0,2"))
1326               (const_string "imovx")
1327            ]
1328            (const_string "imov")))
1329     (set (attr "mode")
1330       (cond [(eq_attr "type" "imovx")
1331                (const_string "SI")
1332              (and (eq_attr "alternative" "1,2")
1333                   (match_operand:HI 1 "aligned_operand" ""))
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "0")
1336                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1337                            (const_int 0))
1338                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1339                            (const_int 0))))
1340                (const_string "SI")
1341             ]
1342             (const_string "HI")))])
1343
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1351   "@
1352    movabs{w}\t{%1, %P0|%P0, %1}
1353    mov{w}\t{%1, %a0|%a0, %1}"
1354   [(set_attr "type" "imov")
1355    (set_attr "modrm" "0,*")
1356    (set_attr "length_address" "8,0")
1357    (set_attr "length_immediate" "0,*")
1358    (set_attr "memory" "store")
1359    (set_attr "mode" "HI")])
1360
1361 (define_insn "*movabshi_2_rex64"
1362   [(set (match_operand:HI 0 "register_operand" "=a,r")
1363         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1365   "@
1366    movabs{w}\t{%P1, %0|%0, %P1}
1367    mov{w}\t{%a1, %0|%0, %a1}"
1368   [(set_attr "type" "imov")
1369    (set_attr "modrm" "0,*")
1370    (set_attr "length_address" "8,0")
1371    (set_attr "length_immediate" "0")
1372    (set_attr "memory" "load")
1373    (set_attr "mode" "HI")])
1374
1375 (define_insn "*swaphi_1"
1376   [(set (match_operand:HI 0 "register_operand" "+r")
1377         (match_operand:HI 1 "register_operand" "+r"))
1378    (set (match_dup 1)
1379         (match_dup 0))]
1380   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1381   "xchg{l}\t%k1, %k0"
1382   [(set_attr "type" "imov")
1383    (set_attr "mode" "SI")
1384    (set_attr "pent_pair" "np")
1385    (set_attr "athlon_decode" "vector")])
1386
1387 (define_insn "*swaphi_2"
1388   [(set (match_operand:HI 0 "register_operand" "+r")
1389         (match_operand:HI 1 "register_operand" "+r"))
1390    (set (match_dup 1)
1391         (match_dup 0))]
1392   "TARGET_PARTIAL_REG_STALL"
1393   "xchg{w}\t%1, %0"
1394   [(set_attr "type" "imov")
1395    (set_attr "mode" "HI")
1396    (set_attr "pent_pair" "np")
1397    (set_attr "athlon_decode" "vector")])
1398
1399 (define_expand "movstricthi"
1400   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1401         (match_operand:HI 1 "general_operand" ""))]
1402   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1403 {
1404   /* Don't generate memory->memory moves, go through a register */
1405   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1406     operands[1] = force_reg (HImode, operands[1]);
1407 })
1408
1409 (define_insn "*movstricthi_1"
1410   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1411         (match_operand:HI 1 "general_operand" "rn,m"))]
1412   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1413    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1414   "mov{w}\t{%1, %0|%0, %1}"
1415   [(set_attr "type" "imov")
1416    (set_attr "mode" "HI")])
1417
1418 (define_insn "*movstricthi_xor"
1419   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1420         (match_operand:HI 1 "const0_operand" "i"))
1421    (clobber (reg:CC FLAGS_REG))]
1422   "reload_completed
1423    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1424   "xor{w}\t{%0, %0|%0, %0}"
1425   [(set_attr "type" "alu1")
1426    (set_attr "mode" "HI")
1427    (set_attr "length_immediate" "0")])
1428
1429 (define_expand "movqi"
1430   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1431         (match_operand:QI 1 "general_operand" ""))]
1432   ""
1433   "ix86_expand_move (QImode, operands); DONE;")
1434
1435 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1436 ;; "push a byte".  But actually we use pushl, which has the effect
1437 ;; of rounding the amount pushed up to a word.
1438
1439 (define_insn "*pushqi2"
1440   [(set (match_operand:QI 0 "push_operand" "=X")
1441         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1442   "!TARGET_64BIT"
1443   "push{l}\t%k1"
1444   [(set_attr "type" "push")
1445    (set_attr "mode" "SI")])
1446
1447 ;; For 64BIT abi we always round up to 8 bytes.
1448 (define_insn "*pushqi2_rex64"
1449   [(set (match_operand:QI 0 "push_operand" "=X")
1450         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1451   "TARGET_64BIT"
1452   "push{q}\t%q1"
1453   [(set_attr "type" "push")
1454    (set_attr "mode" "DI")])
1455
1456 ;; Situation is quite tricky about when to choose full sized (SImode) move
1457 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1458 ;; partial register dependency machines (such as AMD Athlon), where QImode
1459 ;; moves issue extra dependency and for partial register stalls machines
1460 ;; that don't use QImode patterns (and QImode move cause stall on the next
1461 ;; instruction).
1462 ;;
1463 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1464 ;; register stall machines with, where we use QImode instructions, since
1465 ;; partial register stall can be caused there.  Then we use movzx.
1466 (define_insn "*movqi_1"
1467   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1468         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1469   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1470 {
1471   switch (get_attr_type (insn))
1472     {
1473     case TYPE_IMOVX:
1474       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1475       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1476     default:
1477       if (get_attr_mode (insn) == MODE_SI)
1478         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1479       else
1480         return "mov{b}\t{%1, %0|%0, %1}";
1481     }
1482 }
1483   [(set (attr "type")
1484      (cond [(and (eq_attr "alternative" "5")
1485                  (not (match_operand:QI 1 "aligned_operand" "")))
1486               (const_string "imovx")
1487             (ne (symbol_ref "optimize_size") (const_int 0))
1488               (const_string "imov")
1489             (and (eq_attr "alternative" "3")
1490                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491                           (const_int 0))
1492                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1493                           (const_int 0))))
1494               (const_string "imov")
1495             (eq_attr "alternative" "3,5")
1496               (const_string "imovx")
1497             (and (ne (symbol_ref "TARGET_MOVX")
1498                      (const_int 0))
1499                  (eq_attr "alternative" "2"))
1500               (const_string "imovx")
1501            ]
1502            (const_string "imov")))
1503    (set (attr "mode")
1504       (cond [(eq_attr "alternative" "3,4,5")
1505                (const_string "SI")
1506              (eq_attr "alternative" "6")
1507                (const_string "QI")
1508              (eq_attr "type" "imovx")
1509                (const_string "SI")
1510              (and (eq_attr "type" "imov")
1511                   (and (eq_attr "alternative" "0,1")
1512                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513                            (const_int 0))))
1514                (const_string "SI")
1515              ;; Avoid partial register stalls when not using QImode arithmetic
1516              (and (eq_attr "type" "imov")
1517                   (and (eq_attr "alternative" "0,1")
1518                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                 (const_int 0))
1520                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1521                                 (const_int 0)))))
1522                (const_string "SI")
1523            ]
1524            (const_string "QI")))])
1525
1526 (define_expand "reload_outqi"
1527   [(parallel [(match_operand:QI 0 "" "=m")
1528               (match_operand:QI 1 "register_operand" "r")
1529               (match_operand:QI 2 "register_operand" "=&q")])]
1530   ""
1531 {
1532   rtx op0, op1, op2;
1533   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534
1535   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1536   if (! q_regs_operand (op1, QImode))
1537     {
1538       emit_insn (gen_movqi (op2, op1));
1539       op1 = op2;
1540     }
1541   emit_insn (gen_movqi (op0, op1));
1542   DONE;
1543 })
1544
1545 (define_insn "*swapqi_1"
1546   [(set (match_operand:QI 0 "register_operand" "+r")
1547         (match_operand:QI 1 "register_operand" "+r"))
1548    (set (match_dup 1)
1549         (match_dup 0))]
1550   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551   "xchg{l}\t%k1, %k0"
1552   [(set_attr "type" "imov")
1553    (set_attr "mode" "SI")
1554    (set_attr "pent_pair" "np")
1555    (set_attr "athlon_decode" "vector")])
1556
1557 (define_insn "*swapqi_2"
1558   [(set (match_operand:QI 0 "register_operand" "+q")
1559         (match_operand:QI 1 "register_operand" "+q"))
1560    (set (match_dup 1)
1561         (match_dup 0))]
1562   "TARGET_PARTIAL_REG_STALL"
1563   "xchg{b}\t%1, %0"
1564   [(set_attr "type" "imov")
1565    (set_attr "mode" "QI")
1566    (set_attr "pent_pair" "np")
1567    (set_attr "athlon_decode" "vector")])
1568
1569 (define_expand "movstrictqi"
1570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1571         (match_operand:QI 1 "general_operand" ""))]
1572   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1573 {
1574   /* Don't generate memory->memory moves, go through a register.  */
1575   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1576     operands[1] = force_reg (QImode, operands[1]);
1577 })
1578
1579 (define_insn "*movstrictqi_1"
1580   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1581         (match_operand:QI 1 "general_operand" "*qn,m"))]
1582   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1583    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1584   "mov{b}\t{%1, %0|%0, %1}"
1585   [(set_attr "type" "imov")
1586    (set_attr "mode" "QI")])
1587
1588 (define_insn "*movstrictqi_xor"
1589   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1590         (match_operand:QI 1 "const0_operand" "i"))
1591    (clobber (reg:CC FLAGS_REG))]
1592   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1593   "xor{b}\t{%0, %0|%0, %0}"
1594   [(set_attr "type" "alu1")
1595    (set_attr "mode" "QI")
1596    (set_attr "length_immediate" "0")])
1597
1598 (define_insn "*movsi_extv_1"
1599   [(set (match_operand:SI 0 "register_operand" "=R")
1600         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1601                          (const_int 8)
1602                          (const_int 8)))]
1603   ""
1604   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1605   [(set_attr "type" "imovx")
1606    (set_attr "mode" "SI")])
1607
1608 (define_insn "*movhi_extv_1"
1609   [(set (match_operand:HI 0 "register_operand" "=R")
1610         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1611                          (const_int 8)
1612                          (const_int 8)))]
1613   ""
1614   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1615   [(set_attr "type" "imovx")
1616    (set_attr "mode" "SI")])
1617
1618 (define_insn "*movqi_extv_1"
1619   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1620         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1621                          (const_int 8)
1622                          (const_int 8)))]
1623   "!TARGET_64BIT"
1624 {
1625   switch (get_attr_type (insn))
1626     {
1627     case TYPE_IMOVX:
1628       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1629     default:
1630       return "mov{b}\t{%h1, %0|%0, %h1}";
1631     }
1632 }
1633   [(set (attr "type")
1634      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1635                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1636                              (ne (symbol_ref "TARGET_MOVX")
1637                                  (const_int 0))))
1638         (const_string "imovx")
1639         (const_string "imov")))
1640    (set (attr "mode")
1641      (if_then_else (eq_attr "type" "imovx")
1642         (const_string "SI")
1643         (const_string "QI")))])
1644
1645 (define_insn "*movqi_extv_1_rex64"
1646   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1647         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1648                          (const_int 8)
1649                          (const_int 8)))]
1650   "TARGET_64BIT"
1651 {
1652   switch (get_attr_type (insn))
1653     {
1654     case TYPE_IMOVX:
1655       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1656     default:
1657       return "mov{b}\t{%h1, %0|%0, %h1}";
1658     }
1659 }
1660   [(set (attr "type")
1661      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1662                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1663                              (ne (symbol_ref "TARGET_MOVX")
1664                                  (const_int 0))))
1665         (const_string "imovx")
1666         (const_string "imov")))
1667    (set (attr "mode")
1668      (if_then_else (eq_attr "type" "imovx")
1669         (const_string "SI")
1670         (const_string "QI")))])
1671
1672 ;; Stores and loads of ax to arbitrary constant address.
1673 ;; We fake an second form of instruction to force reload to load address
1674 ;; into register when rax is not available
1675 (define_insn "*movabsqi_1_rex64"
1676   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1677         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1678   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1679   "@
1680    movabs{b}\t{%1, %P0|%P0, %1}
1681    mov{b}\t{%1, %a0|%a0, %1}"
1682   [(set_attr "type" "imov")
1683    (set_attr "modrm" "0,*")
1684    (set_attr "length_address" "8,0")
1685    (set_attr "length_immediate" "0,*")
1686    (set_attr "memory" "store")
1687    (set_attr "mode" "QI")])
1688
1689 (define_insn "*movabsqi_2_rex64"
1690   [(set (match_operand:QI 0 "register_operand" "=a,r")
1691         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1692   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1693   "@
1694    movabs{b}\t{%P1, %0|%0, %P1}
1695    mov{b}\t{%a1, %0|%0, %a1}"
1696   [(set_attr "type" "imov")
1697    (set_attr "modrm" "0,*")
1698    (set_attr "length_address" "8,0")
1699    (set_attr "length_immediate" "0")
1700    (set_attr "memory" "load")
1701    (set_attr "mode" "QI")])
1702
1703 (define_insn "*movdi_extzv_1"
1704   [(set (match_operand:DI 0 "register_operand" "=R")
1705         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1706                          (const_int 8)
1707                          (const_int 8)))]
1708   "TARGET_64BIT"
1709   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1710   [(set_attr "type" "imovx")
1711    (set_attr "mode" "DI")])
1712
1713 (define_insn "*movsi_extzv_1"
1714   [(set (match_operand:SI 0 "register_operand" "=R")
1715         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1716                          (const_int 8)
1717                          (const_int 8)))]
1718   ""
1719   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1720   [(set_attr "type" "imovx")
1721    (set_attr "mode" "SI")])
1722
1723 (define_insn "*movqi_extzv_2"
1724   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1725         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1726                                     (const_int 8)
1727                                     (const_int 8)) 0))]
1728   "!TARGET_64BIT"
1729 {
1730   switch (get_attr_type (insn))
1731     {
1732     case TYPE_IMOVX:
1733       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1734     default:
1735       return "mov{b}\t{%h1, %0|%0, %h1}";
1736     }
1737 }
1738   [(set (attr "type")
1739      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1740                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1741                              (ne (symbol_ref "TARGET_MOVX")
1742                                  (const_int 0))))
1743         (const_string "imovx")
1744         (const_string "imov")))
1745    (set (attr "mode")
1746      (if_then_else (eq_attr "type" "imovx")
1747         (const_string "SI")
1748         (const_string "QI")))])
1749
1750 (define_insn "*movqi_extzv_2_rex64"
1751   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1752         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1753                                     (const_int 8)
1754                                     (const_int 8)) 0))]
1755   "TARGET_64BIT"
1756 {
1757   switch (get_attr_type (insn))
1758     {
1759     case TYPE_IMOVX:
1760       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1761     default:
1762       return "mov{b}\t{%h1, %0|%0, %h1}";
1763     }
1764 }
1765   [(set (attr "type")
1766      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1767                         (ne (symbol_ref "TARGET_MOVX")
1768                             (const_int 0)))
1769         (const_string "imovx")
1770         (const_string "imov")))
1771    (set (attr "mode")
1772      (if_then_else (eq_attr "type" "imovx")
1773         (const_string "SI")
1774         (const_string "QI")))])
1775
1776 (define_insn "movsi_insv_1"
1777   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778                          (const_int 8)
1779                          (const_int 8))
1780         (match_operand:SI 1 "general_operand" "Qmn"))]
1781   "!TARGET_64BIT"
1782   "mov{b}\t{%b1, %h0|%h0, %b1}"
1783   [(set_attr "type" "imov")
1784    (set_attr "mode" "QI")])
1785
1786 (define_insn "movdi_insv_1_rex64"
1787   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1788                          (const_int 8)
1789                          (const_int 8))
1790         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1791   "TARGET_64BIT"
1792   "mov{b}\t{%b1, %h0|%h0, %b1}"
1793   [(set_attr "type" "imov")
1794    (set_attr "mode" "QI")])
1795
1796 (define_insn "*movqi_insv_2"
1797   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1798                          (const_int 8)
1799                          (const_int 8))
1800         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1801                      (const_int 8)))]
1802   ""
1803   "mov{b}\t{%h1, %h0|%h0, %h1}"
1804   [(set_attr "type" "imov")
1805    (set_attr "mode" "QI")])
1806
1807 (define_expand "movdi"
1808   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1809         (match_operand:DI 1 "general_operand" ""))]
1810   ""
1811   "ix86_expand_move (DImode, operands); DONE;")
1812
1813 (define_insn "*pushdi"
1814   [(set (match_operand:DI 0 "push_operand" "=<")
1815         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1816   "!TARGET_64BIT"
1817   "#")
1818
1819 (define_insn "*pushdi2_rex64"
1820   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1821         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1822   "TARGET_64BIT"
1823   "@
1824    push{q}\t%1
1825    #"
1826   [(set_attr "type" "push,multi")
1827    (set_attr "mode" "DI")])
1828
1829 ;; Convert impossible pushes of immediate to existing instructions.
1830 ;; First try to get scratch register and go through it.  In case this
1831 ;; fails, push sign extended lower part first and then overwrite
1832 ;; upper part by 32bit move.
1833 (define_peephole2
1834   [(match_scratch:DI 2 "r")
1835    (set (match_operand:DI 0 "push_operand" "")
1836         (match_operand:DI 1 "immediate_operand" ""))]
1837   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1838    && !x86_64_immediate_operand (operands[1], DImode)"
1839   [(set (match_dup 2) (match_dup 1))
1840    (set (match_dup 0) (match_dup 2))]
1841   "")
1842
1843 ;; We need to define this as both peepholer and splitter for case
1844 ;; peephole2 pass is not run.
1845 ;; "&& 1" is needed to keep it from matching the previous pattern.
1846 (define_peephole2
1847   [(set (match_operand:DI 0 "push_operand" "")
1848         (match_operand:DI 1 "immediate_operand" ""))]
1849   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1850    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1851   [(set (match_dup 0) (match_dup 1))
1852    (set (match_dup 2) (match_dup 3))]
1853   "split_di (operands + 1, 1, operands + 2, operands + 3);
1854    operands[1] = gen_lowpart (DImode, operands[2]);
1855    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1856                                                     GEN_INT (4)));
1857   ")
1858
1859 (define_split
1860   [(set (match_operand:DI 0 "push_operand" "")
1861         (match_operand:DI 1 "immediate_operand" ""))]
1862   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1863                     ? flow2_completed : reload_completed)
1864    && !symbolic_operand (operands[1], DImode)
1865    && !x86_64_immediate_operand (operands[1], DImode)"
1866   [(set (match_dup 0) (match_dup 1))
1867    (set (match_dup 2) (match_dup 3))]
1868   "split_di (operands + 1, 1, operands + 2, operands + 3);
1869    operands[1] = gen_lowpart (DImode, operands[2]);
1870    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1871                                                     GEN_INT (4)));
1872   ")
1873
1874 (define_insn "*pushdi2_prologue_rex64"
1875   [(set (match_operand:DI 0 "push_operand" "=<")
1876         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1877    (clobber (mem:BLK (scratch)))]
1878   "TARGET_64BIT"
1879   "push{q}\t%1"
1880   [(set_attr "type" "push")
1881    (set_attr "mode" "DI")])
1882
1883 (define_insn "*popdi1_epilogue_rex64"
1884   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1885         (mem:DI (reg:DI SP_REG)))
1886    (set (reg:DI SP_REG)
1887         (plus:DI (reg:DI SP_REG) (const_int 8)))
1888    (clobber (mem:BLK (scratch)))]
1889   "TARGET_64BIT"
1890   "pop{q}\t%0"
1891   [(set_attr "type" "pop")
1892    (set_attr "mode" "DI")])
1893
1894 (define_insn "popdi1"
1895   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1896         (mem:DI (reg:DI SP_REG)))
1897    (set (reg:DI SP_REG)
1898         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1899   "TARGET_64BIT"
1900   "pop{q}\t%0"
1901   [(set_attr "type" "pop")
1902    (set_attr "mode" "DI")])
1903
1904 (define_insn "*movdi_xor_rex64"
1905   [(set (match_operand:DI 0 "register_operand" "=r")
1906         (match_operand:DI 1 "const0_operand" "i"))
1907    (clobber (reg:CC FLAGS_REG))]
1908   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1909    && reload_completed"
1910   "xor{l}\t{%k0, %k0|%k0, %k0}"
1911   [(set_attr "type" "alu1")
1912    (set_attr "mode" "SI")
1913    (set_attr "length_immediate" "0")])
1914
1915 (define_insn "*movdi_or_rex64"
1916   [(set (match_operand:DI 0 "register_operand" "=r")
1917         (match_operand:DI 1 "const_int_operand" "i"))
1918    (clobber (reg:CC FLAGS_REG))]
1919   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1920    && reload_completed
1921    && operands[1] == constm1_rtx"
1922 {
1923   operands[1] = constm1_rtx;
1924   return "or{q}\t{%1, %0|%0, %1}";
1925 }
1926   [(set_attr "type" "alu1")
1927    (set_attr "mode" "DI")
1928    (set_attr "length_immediate" "1")])
1929
1930 (define_insn "*movdi_2"
1931   [(set (match_operand:DI 0 "nonimmediate_operand"
1932                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1933         (match_operand:DI 1 "general_operand"
1934                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1935   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936   "@
1937    #
1938    #
1939    pxor\t%0, %0
1940    movq\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    pxor\t%0, %0
1943    movq\t{%1, %0|%0, %1}
1944    movdqa\t{%1, %0|%0, %1}
1945    movq\t{%1, %0|%0, %1}
1946    xorps\t%0, %0
1947    movlps\t{%1, %0|%0, %1}
1948    movaps\t{%1, %0|%0, %1}
1949    movlps\t{%1, %0|%0, %1}"
1950   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1951    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1952
1953 (define_split
1954   [(set (match_operand:DI 0 "push_operand" "")
1955         (match_operand:DI 1 "general_operand" ""))]
1956   "!TARGET_64BIT && reload_completed
1957    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1958   [(const_int 0)]
1959   "ix86_split_long_move (operands); DONE;")
1960
1961 ;; %%% This multiword shite has got to go.
1962 (define_split
1963   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1964         (match_operand:DI 1 "general_operand" ""))]
1965   "!TARGET_64BIT && reload_completed
1966    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1967    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1968   [(const_int 0)]
1969   "ix86_split_long_move (operands); DONE;")
1970
1971 (define_insn "*movdi_1_rex64"
1972   [(set (match_operand:DI 0 "nonimmediate_operand"
1973                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1974         (match_operand:DI 1 "general_operand"
1975                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1976   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1977 {
1978   switch (get_attr_type (insn))
1979     {
1980     case TYPE_SSECVT:
1981       if (which_alternative == 13)
1982         return "movq2dq\t{%1, %0|%0, %1}";
1983       else
1984         return "movdq2q\t{%1, %0|%0, %1}";
1985     case TYPE_SSEMOV:
1986       if (get_attr_mode (insn) == MODE_TI)
1987           return "movdqa\t{%1, %0|%0, %1}";
1988       /* FALLTHRU */
1989     case TYPE_MMXMOV:
1990       /* Moves from and into integer register is done using movd opcode with
1991          REX prefix.  */
1992       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993           return "movd\t{%1, %0|%0, %1}";
1994       return "movq\t{%1, %0|%0, %1}";
1995     case TYPE_SSELOG1:
1996     case TYPE_MMXADD:
1997       return "pxor\t%0, %0";
1998     case TYPE_MULTI:
1999       return "#";
2000     case TYPE_LEA:
2001       return "lea{q}\t{%a1, %0|%0, %a1}";
2002     default:
2003       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2004       if (get_attr_mode (insn) == MODE_SI)
2005         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2006       else if (which_alternative == 2)
2007         return "movabs{q}\t{%1, %0|%0, %1}";
2008       else
2009         return "mov{q}\t{%1, %0|%0, %1}";
2010     }
2011 }
2012   [(set (attr "type")
2013      (cond [(eq_attr "alternative" "5")
2014               (const_string "mmxadd")
2015             (eq_attr "alternative" "6,7,8")
2016               (const_string "mmxmov")
2017             (eq_attr "alternative" "9")
2018               (const_string "sselog1")
2019             (eq_attr "alternative" "10,11,12")
2020               (const_string "ssemov")
2021             (eq_attr "alternative" "13,14")
2022               (const_string "ssecvt")
2023             (eq_attr "alternative" "4")
2024               (const_string "multi")
2025             (match_operand:DI 1 "pic_32bit_operand" "")
2026               (const_string "lea")
2027            ]
2028            (const_string "imov")))
2029    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2030    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2031    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2032
2033 ;; Stores and loads of ax to arbitrary constant address.
2034 ;; We fake an second form of instruction to force reload to load address
2035 ;; into register when rax is not available
2036 (define_insn "*movabsdi_1_rex64"
2037   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2038         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2039   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2040   "@
2041    movabs{q}\t{%1, %P0|%P0, %1}
2042    mov{q}\t{%1, %a0|%a0, %1}"
2043   [(set_attr "type" "imov")
2044    (set_attr "modrm" "0,*")
2045    (set_attr "length_address" "8,0")
2046    (set_attr "length_immediate" "0,*")
2047    (set_attr "memory" "store")
2048    (set_attr "mode" "DI")])
2049
2050 (define_insn "*movabsdi_2_rex64"
2051   [(set (match_operand:DI 0 "register_operand" "=a,r")
2052         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2053   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2054   "@
2055    movabs{q}\t{%P1, %0|%0, %P1}
2056    mov{q}\t{%a1, %0|%0, %a1}"
2057   [(set_attr "type" "imov")
2058    (set_attr "modrm" "0,*")
2059    (set_attr "length_address" "8,0")
2060    (set_attr "length_immediate" "0")
2061    (set_attr "memory" "load")
2062    (set_attr "mode" "DI")])
2063
2064 ;; Convert impossible stores of immediate to existing instructions.
2065 ;; First try to get scratch register and go through it.  In case this
2066 ;; fails, move by 32bit parts.
2067 (define_peephole2
2068   [(match_scratch:DI 2 "r")
2069    (set (match_operand:DI 0 "memory_operand" "")
2070         (match_operand:DI 1 "immediate_operand" ""))]
2071   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072    && !x86_64_immediate_operand (operands[1], DImode)"
2073   [(set (match_dup 2) (match_dup 1))
2074    (set (match_dup 0) (match_dup 2))]
2075   "")
2076
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 (define_peephole2
2081   [(set (match_operand:DI 0 "memory_operand" "")
2082         (match_operand:DI 1 "immediate_operand" ""))]
2083   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085   [(set (match_dup 2) (match_dup 3))
2086    (set (match_dup 4) (match_dup 5))]
2087   "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_split
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2093                     ? flow2_completed : reload_completed)
2094    && !symbolic_operand (operands[1], DImode)
2095    && !x86_64_immediate_operand (operands[1], DImode)"
2096   [(set (match_dup 2) (match_dup 3))
2097    (set (match_dup 4) (match_dup 5))]
2098   "split_di (operands, 2, operands + 2, operands + 4);")
2099
2100 (define_insn "*swapdi_rex64"
2101   [(set (match_operand:DI 0 "register_operand" "+r")
2102         (match_operand:DI 1 "register_operand" "+r"))
2103    (set (match_dup 1)
2104         (match_dup 0))]
2105   "TARGET_64BIT"
2106   "xchg{q}\t%1, %0"
2107   [(set_attr "type" "imov")
2108    (set_attr "mode" "DI")
2109    (set_attr "pent_pair" "np")
2110    (set_attr "athlon_decode" "vector")])
2111
2112 (define_expand "movti"
2113   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2114         (match_operand:TI 1 "nonimmediate_operand" ""))]
2115   "TARGET_SSE || TARGET_64BIT"
2116 {
2117   if (TARGET_64BIT)
2118     ix86_expand_move (TImode, operands);
2119   else
2120     ix86_expand_vector_move (TImode, operands);
2121   DONE;
2122 })
2123
2124 (define_insn "*movti_internal"
2125   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2126         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2127   "TARGET_SSE && !TARGET_64BIT
2128    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2129 {
2130   switch (which_alternative)
2131     {
2132     case 0:
2133       if (get_attr_mode (insn) == MODE_V4SF)
2134         return "xorps\t%0, %0";
2135       else
2136         return "pxor\t%0, %0";
2137     case 1:
2138     case 2:
2139       if (get_attr_mode (insn) == MODE_V4SF)
2140         return "movaps\t{%1, %0|%0, %1}";
2141       else
2142         return "movdqa\t{%1, %0|%0, %1}";
2143     default:
2144       gcc_unreachable ();
2145     }
2146 }
2147   [(set_attr "type" "sselog1,ssemov,ssemov")
2148    (set (attr "mode")
2149         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2150                     (ne (symbol_ref "optimize_size") (const_int 0)))
2151                  (const_string "V4SF")
2152                (and (eq_attr "alternative" "2")
2153                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2154                         (const_int 0)))
2155                  (const_string "V4SF")]
2156               (const_string "TI")))])
2157
2158 (define_insn "*movti_rex64"
2159   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2160         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2161   "TARGET_64BIT
2162    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163 {
2164   switch (which_alternative)
2165     {
2166     case 0:
2167     case 1:
2168       return "#";
2169     case 2:
2170       if (get_attr_mode (insn) == MODE_V4SF)
2171         return "xorps\t%0, %0";
2172       else
2173         return "pxor\t%0, %0";
2174     case 3:
2175     case 4:
2176       if (get_attr_mode (insn) == MODE_V4SF)
2177         return "movaps\t{%1, %0|%0, %1}";
2178       else
2179         return "movdqa\t{%1, %0|%0, %1}";
2180     default:
2181       gcc_unreachable ();
2182     }
2183 }
2184   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2185    (set (attr "mode")
2186         (cond [(eq_attr "alternative" "2,3")
2187                  (if_then_else
2188                    (ne (symbol_ref "optimize_size")
2189                        (const_int 0))
2190                    (const_string "V4SF")
2191                    (const_string "TI"))
2192                (eq_attr "alternative" "4")
2193                  (if_then_else
2194                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2195                             (const_int 0))
2196                         (ne (symbol_ref "optimize_size")
2197                             (const_int 0)))
2198                    (const_string "V4SF")
2199                    (const_string "TI"))]
2200                (const_string "DI")))])
2201
2202 (define_split
2203   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2204         (match_operand:TI 1 "general_operand" ""))]
2205   "reload_completed && !SSE_REG_P (operands[0])
2206    && !SSE_REG_P (operands[1])"
2207   [(const_int 0)]
2208   "ix86_split_long_move (operands); DONE;")
2209
2210 (define_expand "movsf"
2211   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2212         (match_operand:SF 1 "general_operand" ""))]
2213   ""
2214   "ix86_expand_move (SFmode, operands); DONE;")
2215
2216 (define_insn "*pushsf"
2217   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2218         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2219   "!TARGET_64BIT"
2220 {
2221   /* Anything else should be already split before reg-stack.  */
2222   gcc_assert (which_alternative == 1);
2223   return "push{l}\t%1";
2224 }
2225   [(set_attr "type" "multi,push,multi")
2226    (set_attr "unit" "i387,*,*")
2227    (set_attr "mode" "SF,SI,SF")])
2228
2229 (define_insn "*pushsf_rex64"
2230   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2231         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2232   "TARGET_64BIT"
2233 {
2234   /* Anything else should be already split before reg-stack.  */
2235   gcc_assert (which_alternative == 1);
2236   return "push{q}\t%q1";
2237 }
2238   [(set_attr "type" "multi,push,multi")
2239    (set_attr "unit" "i387,*,*")
2240    (set_attr "mode" "SF,DI,SF")])
2241
2242 (define_split
2243   [(set (match_operand:SF 0 "push_operand" "")
2244         (match_operand:SF 1 "memory_operand" ""))]
2245   "reload_completed
2246    && GET_CODE (operands[1]) == MEM
2247    && constant_pool_reference_p (operands[1])"
2248   [(set (match_dup 0)
2249         (match_dup 1))]
2250   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2251
2252
2253 ;; %%% Kill this when call knows how to work this out.
2254 (define_split
2255   [(set (match_operand:SF 0 "push_operand" "")
2256         (match_operand:SF 1 "any_fp_register_operand" ""))]
2257   "!TARGET_64BIT"
2258   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2259    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2260
2261 (define_split
2262   [(set (match_operand:SF 0 "push_operand" "")
2263         (match_operand:SF 1 "any_fp_register_operand" ""))]
2264   "TARGET_64BIT"
2265   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2266    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2267
2268 (define_insn "*movsf_1"
2269   [(set (match_operand:SF 0 "nonimmediate_operand"
2270           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2271         (match_operand:SF 1 "general_operand"
2272           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2273   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2274    && (reload_in_progress || reload_completed
2275        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2276        || GET_CODE (operands[1]) != CONST_DOUBLE
2277        || memory_operand (operands[0], SFmode))" 
2278 {
2279   switch (which_alternative)
2280     {
2281     case 0:
2282       return output_387_reg_move (insn, operands);
2283
2284     case 1:
2285       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2286         return "fstp%z0\t%y0";
2287       else
2288         return "fst%z0\t%y0";
2289
2290     case 2:
2291       return standard_80387_constant_opcode (operands[1]);
2292
2293     case 3:
2294     case 4:
2295       return "mov{l}\t{%1, %0|%0, %1}";
2296     case 5:
2297       if (get_attr_mode (insn) == MODE_TI)
2298         return "pxor\t%0, %0";
2299       else
2300         return "xorps\t%0, %0";
2301     case 6:
2302       if (get_attr_mode (insn) == MODE_V4SF)
2303         return "movaps\t{%1, %0|%0, %1}";
2304       else
2305         return "movss\t{%1, %0|%0, %1}";
2306     case 7:
2307     case 8:
2308       return "movss\t{%1, %0|%0, %1}";
2309
2310     case 9:
2311     case 10:
2312       return "movd\t{%1, %0|%0, %1}";
2313
2314     case 11:
2315       return "movq\t{%1, %0|%0, %1}";
2316
2317     default:
2318       gcc_unreachable ();
2319     }
2320 }
2321   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2322    (set (attr "mode")
2323         (cond [(eq_attr "alternative" "3,4,9,10")
2324                  (const_string "SI")
2325                (eq_attr "alternative" "5")
2326                  (if_then_else
2327                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2328                                  (const_int 0))
2329                              (ne (symbol_ref "TARGET_SSE2")
2330                                  (const_int 0)))
2331                         (eq (symbol_ref "optimize_size")
2332                             (const_int 0)))
2333                    (const_string "TI")
2334                    (const_string "V4SF"))
2335                /* For architectures resolving dependencies on
2336                   whole SSE registers use APS move to break dependency
2337                   chains, otherwise use short move to avoid extra work. 
2338
2339                   Do the same for architectures resolving dependencies on
2340                   the parts.  While in DF mode it is better to always handle
2341                   just register parts, the SF mode is different due to lack
2342                   of instructions to load just part of the register.  It is
2343                   better to maintain the whole registers in single format
2344                   to avoid problems on using packed logical operations.  */
2345                (eq_attr "alternative" "6")
2346                  (if_then_else
2347                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2348                             (const_int 0))
2349                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2350                             (const_int 0)))
2351                    (const_string "V4SF")
2352                    (const_string "SF"))
2353                (eq_attr "alternative" "11")
2354                  (const_string "DI")]
2355                (const_string "SF")))])
2356
2357 (define_insn "*swapsf"
2358   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2359         (match_operand:SF 1 "fp_register_operand" "+f"))
2360    (set (match_dup 1)
2361         (match_dup 0))]
2362   "reload_completed || TARGET_80387"
2363 {
2364   if (STACK_TOP_P (operands[0]))
2365     return "fxch\t%1";
2366   else
2367     return "fxch\t%0";
2368 }
2369   [(set_attr "type" "fxch")
2370    (set_attr "mode" "SF")])
2371
2372 (define_expand "movdf"
2373   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2374         (match_operand:DF 1 "general_operand" ""))]
2375   ""
2376   "ix86_expand_move (DFmode, operands); DONE;")
2377
2378 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2379 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2380 ;; On the average, pushdf using integers can be still shorter.  Allow this
2381 ;; pattern for optimize_size too.
2382
2383 (define_insn "*pushdf_nointeger"
2384   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2385         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2386   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2387 {
2388   /* This insn should be already split before reg-stack.  */
2389   gcc_unreachable ();
2390 }
2391   [(set_attr "type" "multi")
2392    (set_attr "unit" "i387,*,*,*")
2393    (set_attr "mode" "DF,SI,SI,DF")])
2394
2395 (define_insn "*pushdf_integer"
2396   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2397         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2398   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400   /* This insn should be already split before reg-stack.  */
2401   gcc_unreachable ();
2402 }
2403   [(set_attr "type" "multi")
2404    (set_attr "unit" "i387,*,*")
2405    (set_attr "mode" "DF,SI,DF")])
2406
2407 ;; %%% Kill this when call knows how to work this out.
2408 (define_split
2409   [(set (match_operand:DF 0 "push_operand" "")
2410         (match_operand:DF 1 "any_fp_register_operand" ""))]
2411   "!TARGET_64BIT && reload_completed"
2412   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2413    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2414   "")
2415
2416 (define_split
2417   [(set (match_operand:DF 0 "push_operand" "")
2418         (match_operand:DF 1 "any_fp_register_operand" ""))]
2419   "TARGET_64BIT && reload_completed"
2420   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2421    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2422   "")
2423
2424 (define_split
2425   [(set (match_operand:DF 0 "push_operand" "")
2426         (match_operand:DF 1 "general_operand" ""))]
2427   "reload_completed"
2428   [(const_int 0)]
2429   "ix86_split_long_move (operands); DONE;")
2430
2431 ;; Moving is usually shorter when only FP registers are used. This separate
2432 ;; movdf pattern avoids the use of integer registers for FP operations
2433 ;; when optimizing for size.
2434
2435 (define_insn "*movdf_nointeger"
2436   [(set (match_operand:DF 0 "nonimmediate_operand"
2437                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2438         (match_operand:DF 1 "general_operand"
2439                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2440   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2441    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2442    && (reload_in_progress || reload_completed
2443        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2444        || GET_CODE (operands[1]) != CONST_DOUBLE
2445        || memory_operand (operands[0], DFmode))" 
2446 {
2447   switch (which_alternative)
2448     {
2449     case 0:
2450       return output_387_reg_move (insn, operands);
2451
2452     case 1:
2453       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2454         return "fstp%z0\t%y0";
2455       else
2456         return "fst%z0\t%y0";
2457
2458     case 2:
2459       return standard_80387_constant_opcode (operands[1]);
2460
2461     case 3:
2462     case 4:
2463       return "#";
2464     case 5:
2465       switch (get_attr_mode (insn))
2466         {
2467         case MODE_V4SF:
2468           return "xorps\t%0, %0";
2469         case MODE_V2DF:
2470           return "xorpd\t%0, %0";
2471         case MODE_TI:
2472           return "pxor\t%0, %0";
2473         default:
2474           gcc_unreachable ();
2475         }
2476     case 6:
2477     case 7:
2478     case 8:
2479       switch (get_attr_mode (insn))
2480         {
2481         case MODE_V4SF:
2482           return "movaps\t{%1, %0|%0, %1}";
2483         case MODE_V2DF:
2484           return "movapd\t{%1, %0|%0, %1}";
2485         case MODE_TI:
2486           return "movdqa\t{%1, %0|%0, %1}";
2487         case MODE_DI:
2488           return "movq\t{%1, %0|%0, %1}";
2489         case MODE_DF:
2490           return "movsd\t{%1, %0|%0, %1}";
2491         case MODE_V1DF:
2492           return "movlpd\t{%1, %0|%0, %1}";
2493         case MODE_V2SF:
2494           return "movlps\t{%1, %0|%0, %1}";
2495         default:
2496           gcc_unreachable ();
2497         }
2498
2499     default:
2500       gcc_unreachable ();
2501     }
2502 }
2503   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2504    (set (attr "mode")
2505         (cond [(eq_attr "alternative" "0,1,2")
2506                  (const_string "DF")
2507                (eq_attr "alternative" "3,4")
2508                  (const_string "SI")
2509
2510                /* For SSE1, we have many fewer alternatives.  */
2511                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2512                  (cond [(eq_attr "alternative" "5,6")
2513                           (const_string "V4SF")
2514                        ]
2515                    (const_string "V2SF"))
2516
2517                /* xorps is one byte shorter.  */
2518                (eq_attr "alternative" "5")
2519                  (cond [(ne (symbol_ref "optimize_size")
2520                             (const_int 0))
2521                           (const_string "V4SF")
2522                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2523                             (const_int 0))
2524                           (const_string "TI")
2525                        ]
2526                        (const_string "V2DF"))
2527
2528                /* For architectures resolving dependencies on
2529                   whole SSE registers use APD move to break dependency
2530                   chains, otherwise use short move to avoid extra work.
2531
2532                   movaps encodes one byte shorter.  */
2533                (eq_attr "alternative" "6")
2534                  (cond
2535                    [(ne (symbol_ref "optimize_size")
2536                         (const_int 0))
2537                       (const_string "V4SF")
2538                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2539                         (const_int 0))
2540                       (const_string "V2DF")
2541                    ]
2542                    (const_string "DF"))
2543                /* For architectures resolving dependencies on register
2544                   parts we may avoid extra work to zero out upper part
2545                   of register.  */
2546                (eq_attr "alternative" "7")
2547                  (if_then_else
2548                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2549                        (const_int 0))
2550                    (const_string "V1DF")
2551                    (const_string "DF"))
2552               ]
2553               (const_string "DF")))])
2554
2555 (define_insn "*movdf_integer"
2556   [(set (match_operand:DF 0 "nonimmediate_operand"
2557                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2558         (match_operand:DF 1 "general_operand"
2559                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2560   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2561    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2562    && (reload_in_progress || reload_completed
2563        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2564        || GET_CODE (operands[1]) != CONST_DOUBLE
2565        || memory_operand (operands[0], DFmode))" 
2566 {
2567   switch (which_alternative)
2568     {
2569     case 0:
2570       return output_387_reg_move (insn, operands);
2571
2572     case 1:
2573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2574         return "fstp%z0\t%y0";
2575       else
2576         return "fst%z0\t%y0";
2577
2578     case 2:
2579       return standard_80387_constant_opcode (operands[1]);
2580
2581     case 3:
2582     case 4:
2583       return "#";
2584
2585     case 5:
2586       switch (get_attr_mode (insn))
2587         {
2588         case MODE_V4SF:
2589           return "xorps\t%0, %0";
2590         case MODE_V2DF:
2591           return "xorpd\t%0, %0";
2592         case MODE_TI:
2593           return "pxor\t%0, %0";
2594         default:
2595           gcc_unreachable ();
2596         }
2597     case 6:
2598     case 7:
2599     case 8:
2600       switch (get_attr_mode (insn))
2601         {
2602         case MODE_V4SF:
2603           return "movaps\t{%1, %0|%0, %1}";
2604         case MODE_V2DF:
2605           return "movapd\t{%1, %0|%0, %1}";
2606         case MODE_TI:
2607           return "movdqa\t{%1, %0|%0, %1}";
2608         case MODE_DI:
2609           return "movq\t{%1, %0|%0, %1}";
2610         case MODE_DF:
2611           return "movsd\t{%1, %0|%0, %1}";
2612         case MODE_V1DF:
2613           return "movlpd\t{%1, %0|%0, %1}";
2614         case MODE_V2SF:
2615           return "movlps\t{%1, %0|%0, %1}";
2616         default:
2617           gcc_unreachable ();
2618         }
2619
2620     default:
2621       gcc_unreachable();
2622     }
2623 }
2624   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2625    (set (attr "mode")
2626         (cond [(eq_attr "alternative" "0,1,2")
2627                  (const_string "DF")
2628                (eq_attr "alternative" "3,4")
2629                  (const_string "SI")
2630
2631                /* For SSE1, we have many fewer alternatives.  */
2632                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2633                  (cond [(eq_attr "alternative" "5,6")
2634                           (const_string "V4SF")
2635                        ]
2636                    (const_string "V2SF"))
2637
2638                /* xorps is one byte shorter.  */
2639                (eq_attr "alternative" "5")
2640                  (cond [(ne (symbol_ref "optimize_size")
2641                             (const_int 0))
2642                           (const_string "V4SF")
2643                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2644                             (const_int 0))
2645                           (const_string "TI")
2646                        ]
2647                        (const_string "V2DF"))
2648
2649                /* For architectures resolving dependencies on
2650                   whole SSE registers use APD move to break dependency
2651                   chains, otherwise use short move to avoid extra work.
2652
2653                   movaps encodes one byte shorter.  */
2654                (eq_attr "alternative" "6")
2655                  (cond
2656                    [(ne (symbol_ref "optimize_size")
2657                         (const_int 0))
2658                       (const_string "V4SF")
2659                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2660                         (const_int 0))
2661                       (const_string "V2DF")
2662                    ]
2663                    (const_string "DF"))
2664                /* For architectures resolving dependencies on register
2665                   parts we may avoid extra work to zero out upper part
2666                   of register.  */
2667                (eq_attr "alternative" "7")
2668                  (if_then_else
2669                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2670                        (const_int 0))
2671                    (const_string "V1DF")
2672                    (const_string "DF"))
2673               ]
2674               (const_string "DF")))])
2675
2676 (define_split
2677   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2678         (match_operand:DF 1 "general_operand" ""))]
2679   "reload_completed
2680    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2681    && ! (ANY_FP_REG_P (operands[0]) || 
2682          (GET_CODE (operands[0]) == SUBREG
2683           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2684    && ! (ANY_FP_REG_P (operands[1]) || 
2685          (GET_CODE (operands[1]) == SUBREG
2686           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2687   [(const_int 0)]
2688   "ix86_split_long_move (operands); DONE;")
2689
2690 (define_insn "*swapdf"
2691   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2692         (match_operand:DF 1 "fp_register_operand" "+f"))
2693    (set (match_dup 1)
2694         (match_dup 0))]
2695   "reload_completed || TARGET_80387"
2696 {
2697   if (STACK_TOP_P (operands[0]))
2698     return "fxch\t%1";
2699   else
2700     return "fxch\t%0";
2701 }
2702   [(set_attr "type" "fxch")
2703    (set_attr "mode" "DF")])
2704
2705 (define_expand "movxf"
2706   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2707         (match_operand:XF 1 "general_operand" ""))]
2708   ""
2709   "ix86_expand_move (XFmode, operands); DONE;")
2710
2711 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2712 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2713 ;; Pushing using integer instructions is longer except for constants
2714 ;; and direct memory references.
2715 ;; (assuming that any given constant is pushed only once, but this ought to be
2716 ;;  handled elsewhere).
2717
2718 (define_insn "*pushxf_nointeger"
2719   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2720         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2721   "optimize_size"
2722 {
2723   /* This insn should be already split before reg-stack.  */
2724   gcc_unreachable ();
2725 }
2726   [(set_attr "type" "multi")
2727    (set_attr "unit" "i387,*,*")
2728    (set_attr "mode" "XF,SI,SI")])
2729
2730 (define_insn "*pushxf_integer"
2731   [(set (match_operand:XF 0 "push_operand" "=<,<")
2732         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2733   "!optimize_size"
2734 {
2735   /* This insn should be already split before reg-stack.  */
2736   gcc_unreachable ();
2737 }
2738   [(set_attr "type" "multi")
2739    (set_attr "unit" "i387,*")
2740    (set_attr "mode" "XF,SI")])
2741
2742 (define_split
2743   [(set (match_operand 0 "push_operand" "")
2744         (match_operand 1 "general_operand" ""))]
2745   "reload_completed
2746    && (GET_MODE (operands[0]) == XFmode
2747        || GET_MODE (operands[0]) == DFmode)
2748    && !ANY_FP_REG_P (operands[1])"
2749   [(const_int 0)]
2750   "ix86_split_long_move (operands); DONE;")
2751
2752 (define_split
2753   [(set (match_operand:XF 0 "push_operand" "")
2754         (match_operand:XF 1 "any_fp_register_operand" ""))]
2755   "!TARGET_64BIT"
2756   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2757    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2758   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2759
2760 (define_split
2761   [(set (match_operand:XF 0 "push_operand" "")
2762         (match_operand:XF 1 "any_fp_register_operand" ""))]
2763   "TARGET_64BIT"
2764   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2765    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2766   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767
2768 ;; Do not use integer registers when optimizing for size
2769 (define_insn "*movxf_nointeger"
2770   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2771         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2772   "optimize_size
2773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2774    && (reload_in_progress || reload_completed
2775        || GET_CODE (operands[1]) != CONST_DOUBLE
2776        || memory_operand (operands[0], XFmode))" 
2777 {
2778   switch (which_alternative)
2779     {
2780     case 0:
2781       return output_387_reg_move (insn, operands);
2782
2783     case 1:
2784       /* There is no non-popping store to memory for XFmode.  So if
2785          we need one, follow the store with a load.  */
2786       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787         return "fstp%z0\t%y0\;fld%z0\t%y0";
2788       else
2789         return "fstp%z0\t%y0";
2790
2791     case 2:
2792       return standard_80387_constant_opcode (operands[1]);
2793
2794     case 3: case 4:
2795       return "#";
2796     default:
2797       gcc_unreachable ();
2798     }
2799 }
2800   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2801    (set_attr "mode" "XF,XF,XF,SI,SI")])
2802
2803 (define_insn "*movxf_integer"
2804   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2805         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2806   "!optimize_size
2807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808    && (reload_in_progress || reload_completed
2809        || GET_CODE (operands[1]) != CONST_DOUBLE
2810        || memory_operand (operands[0], XFmode))" 
2811 {
2812   switch (which_alternative)
2813     {
2814     case 0:
2815       return output_387_reg_move (insn, operands);
2816
2817     case 1:
2818       /* There is no non-popping store to memory for XFmode.  So if
2819          we need one, follow the store with a load.  */
2820       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821         return "fstp%z0\t%y0\;fld%z0\t%y0";
2822       else
2823         return "fstp%z0\t%y0";
2824
2825     case 2:
2826       return standard_80387_constant_opcode (operands[1]);
2827
2828     case 3: case 4:
2829       return "#";
2830
2831     default:
2832       gcc_unreachable ();
2833     }
2834 }
2835   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2836    (set_attr "mode" "XF,XF,XF,SI,SI")])
2837
2838 (define_split
2839   [(set (match_operand 0 "nonimmediate_operand" "")
2840         (match_operand 1 "general_operand" ""))]
2841   "reload_completed
2842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2843    && GET_MODE (operands[0]) == XFmode
2844    && ! (ANY_FP_REG_P (operands[0]) || 
2845          (GET_CODE (operands[0]) == SUBREG
2846           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2847    && ! (ANY_FP_REG_P (operands[1]) || 
2848          (GET_CODE (operands[1]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2850   [(const_int 0)]
2851   "ix86_split_long_move (operands); DONE;")
2852
2853 (define_split
2854   [(set (match_operand 0 "register_operand" "")
2855         (match_operand 1 "memory_operand" ""))]
2856   "reload_completed
2857    && GET_CODE (operands[1]) == MEM
2858    && (GET_MODE (operands[0]) == XFmode
2859        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2860    && constant_pool_reference_p (operands[1])"
2861   [(set (match_dup 0) (match_dup 1))]
2862 {
2863   rtx c = avoid_constant_pool_reference (operands[1]);
2864   rtx r = operands[0];
2865
2866   if (GET_CODE (r) == SUBREG)
2867     r = SUBREG_REG (r);
2868
2869   if (SSE_REG_P (r))
2870     {
2871       if (!standard_sse_constant_p (c))
2872         FAIL;
2873     }
2874   else if (FP_REG_P (r))
2875     {
2876       if (!standard_80387_constant_p (c))
2877         FAIL;
2878     }
2879   else if (MMX_REG_P (r))
2880     FAIL;
2881
2882   operands[1] = c;
2883 })
2884
2885 (define_insn "swapxf"
2886   [(set (match_operand:XF 0 "register_operand" "+f")
2887         (match_operand:XF 1 "register_operand" "+f"))
2888    (set (match_dup 1)
2889         (match_dup 0))]
2890   "TARGET_80387"
2891 {
2892   if (STACK_TOP_P (operands[0]))
2893     return "fxch\t%1";
2894   else
2895     return "fxch\t%0";
2896 }
2897   [(set_attr "type" "fxch")
2898    (set_attr "mode" "XF")])
2899
2900 (define_expand "movtf"
2901   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2902         (match_operand:TF 1 "nonimmediate_operand" ""))]
2903   "TARGET_64BIT"
2904 {
2905   ix86_expand_move (TFmode, operands);
2906   DONE;
2907 })
2908
2909 (define_insn "*movtf_internal"
2910   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2911         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2912   "TARGET_64BIT
2913    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2914 {
2915   switch (which_alternative)
2916     {
2917     case 0:
2918     case 1:
2919       return "#";
2920     case 2:
2921       if (get_attr_mode (insn) == MODE_V4SF)
2922         return "xorps\t%0, %0";
2923       else
2924         return "pxor\t%0, %0";
2925     case 3:
2926     case 4:
2927       if (get_attr_mode (insn) == MODE_V4SF)
2928         return "movaps\t{%1, %0|%0, %1}";
2929       else
2930         return "movdqa\t{%1, %0|%0, %1}";
2931     default:
2932       gcc_unreachable ();
2933     }
2934 }
2935   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2936    (set (attr "mode")
2937         (cond [(eq_attr "alternative" "2,3")
2938                  (if_then_else
2939                    (ne (symbol_ref "optimize_size")
2940                        (const_int 0))
2941                    (const_string "V4SF")
2942                    (const_string "TI"))
2943                (eq_attr "alternative" "4")
2944                  (if_then_else
2945                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2946                             (const_int 0))
2947                         (ne (symbol_ref "optimize_size")
2948                             (const_int 0)))
2949                    (const_string "V4SF")
2950                    (const_string "TI"))]
2951                (const_string "DI")))])
2952
2953 (define_split
2954   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2955         (match_operand:TF 1 "general_operand" ""))]
2956   "reload_completed && !SSE_REG_P (operands[0])
2957    && !SSE_REG_P (operands[1])"
2958   [(const_int 0)]
2959   "ix86_split_long_move (operands); DONE;")
2960 \f
2961 ;; Zero extension instructions
2962
2963 (define_expand "zero_extendhisi2"
2964   [(set (match_operand:SI 0 "register_operand" "")
2965      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2966   ""
2967 {
2968   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2969     {
2970       operands[1] = force_reg (HImode, operands[1]);
2971       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2972       DONE;
2973     }
2974 })
2975
2976 (define_insn "zero_extendhisi2_and"
2977   [(set (match_operand:SI 0 "register_operand" "=r")
2978      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2979    (clobber (reg:CC FLAGS_REG))]
2980   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2981   "#"
2982   [(set_attr "type" "alu1")
2983    (set_attr "mode" "SI")])
2984
2985 (define_split
2986   [(set (match_operand:SI 0 "register_operand" "")
2987         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2988    (clobber (reg:CC FLAGS_REG))]
2989   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2990   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2991               (clobber (reg:CC FLAGS_REG))])]
2992   "")
2993
2994 (define_insn "*zero_extendhisi2_movzwl"
2995   [(set (match_operand:SI 0 "register_operand" "=r")
2996      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2997   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2998   "movz{wl|x}\t{%1, %0|%0, %1}"
2999   [(set_attr "type" "imovx")
3000    (set_attr "mode" "SI")])
3001
3002 (define_expand "zero_extendqihi2"
3003   [(parallel
3004     [(set (match_operand:HI 0 "register_operand" "")
3005        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3006      (clobber (reg:CC FLAGS_REG))])]
3007   ""
3008   "")
3009
3010 (define_insn "*zero_extendqihi2_and"
3011   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3012      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3013    (clobber (reg:CC FLAGS_REG))]
3014   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015   "#"
3016   [(set_attr "type" "alu1")
3017    (set_attr "mode" "HI")])
3018
3019 (define_insn "*zero_extendqihi2_movzbw_and"
3020   [(set (match_operand:HI 0 "register_operand" "=r,r")
3021      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3024   "#"
3025   [(set_attr "type" "imovx,alu1")
3026    (set_attr "mode" "HI")])
3027
3028 ; zero extend to SImode here to avoid partial register stalls
3029 (define_insn "*zero_extendqihi2_movzbl"
3030   [(set (match_operand:HI 0 "register_operand" "=r")
3031      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3032   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3033   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3034   [(set_attr "type" "imovx")
3035    (set_attr "mode" "SI")])
3036
3037 ;; For the movzbw case strip only the clobber
3038 (define_split
3039   [(set (match_operand:HI 0 "register_operand" "")
3040         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3041    (clobber (reg:CC FLAGS_REG))]
3042   "reload_completed 
3043    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3044    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3047
3048 ;; When source and destination does not overlap, clear destination
3049 ;; first and then do the movb
3050 (define_split
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053    (clobber (reg:CC FLAGS_REG))]
3054   "reload_completed
3055    && ANY_QI_REG_P (operands[0])
3056    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3057    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3058   [(set (match_dup 0) (const_int 0))
3059    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3060   "operands[2] = gen_lowpart (QImode, operands[0]);")
3061
3062 ;; Rest is handled by single and.
3063 (define_split
3064   [(set (match_operand:HI 0 "register_operand" "")
3065         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3066    (clobber (reg:CC FLAGS_REG))]
3067   "reload_completed
3068    && true_regnum (operands[0]) == true_regnum (operands[1])"
3069   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3070               (clobber (reg:CC FLAGS_REG))])]
3071   "")
3072
3073 (define_expand "zero_extendqisi2"
3074   [(parallel
3075     [(set (match_operand:SI 0 "register_operand" "")
3076        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3077      (clobber (reg:CC FLAGS_REG))])]
3078   ""
3079   "")
3080
3081 (define_insn "*zero_extendqisi2_and"
3082   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3083      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3084    (clobber (reg:CC FLAGS_REG))]
3085   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3086   "#"
3087   [(set_attr "type" "alu1")
3088    (set_attr "mode" "SI")])
3089
3090 (define_insn "*zero_extendqisi2_movzbw_and"
3091   [(set (match_operand:SI 0 "register_operand" "=r,r")
3092      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3093    (clobber (reg:CC FLAGS_REG))]
3094   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3095   "#"
3096   [(set_attr "type" "imovx,alu1")
3097    (set_attr "mode" "SI")])
3098
3099 (define_insn "*zero_extendqisi2_movzbw"
3100   [(set (match_operand:SI 0 "register_operand" "=r")
3101      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3102   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3103   "movz{bl|x}\t{%1, %0|%0, %1}"
3104   [(set_attr "type" "imovx")
3105    (set_attr "mode" "SI")])
3106
3107 ;; For the movzbl case strip only the clobber
3108 (define_split
3109   [(set (match_operand:SI 0 "register_operand" "")
3110         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111    (clobber (reg:CC FLAGS_REG))]
3112   "reload_completed 
3113    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3114    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3115   [(set (match_dup 0)
3116         (zero_extend:SI (match_dup 1)))])
3117
3118 ;; When source and destination does not overlap, clear destination
3119 ;; first and then do the movb
3120 (define_split
3121   [(set (match_operand:SI 0 "register_operand" "")
3122         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123    (clobber (reg:CC FLAGS_REG))]
3124   "reload_completed
3125    && ANY_QI_REG_P (operands[0])
3126    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3127    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3128    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3129   [(set (match_dup 0) (const_int 0))
3130    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3131   "operands[2] = gen_lowpart (QImode, operands[0]);")
3132
3133 ;; Rest is handled by single and.
3134 (define_split
3135   [(set (match_operand:SI 0 "register_operand" "")
3136         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3137    (clobber (reg:CC FLAGS_REG))]
3138   "reload_completed
3139    && true_regnum (operands[0]) == true_regnum (operands[1])"
3140   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3141               (clobber (reg:CC FLAGS_REG))])]
3142   "")
3143
3144 ;; %%% Kill me once multi-word ops are sane.
3145 (define_expand "zero_extendsidi2"
3146   [(set (match_operand:DI 0 "register_operand" "=r")
3147      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3148   ""
3149   "if (!TARGET_64BIT)
3150      {
3151        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3152        DONE;
3153      }
3154   ")
3155
3156 (define_insn "zero_extendsidi2_32"
3157   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3158         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3159    (clobber (reg:CC FLAGS_REG))]
3160   "!TARGET_64BIT"
3161   "@
3162    #
3163    #
3164    #
3165    movd\t{%1, %0|%0, %1}
3166    movd\t{%1, %0|%0, %1}"
3167   [(set_attr "mode" "SI,SI,SI,DI,TI")
3168    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3169
3170 (define_insn "zero_extendsidi2_rex64"
3171   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3172      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3173   "TARGET_64BIT"
3174   "@
3175    mov\t{%k1, %k0|%k0, %k1}
3176    #
3177    movd\t{%1, %0|%0, %1}
3178    movd\t{%1, %0|%0, %1}"
3179   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3180    (set_attr "mode" "SI,DI,SI,SI")])
3181
3182 (define_split
3183   [(set (match_operand:DI 0 "memory_operand" "")
3184      (zero_extend:DI (match_dup 0)))]
3185   "TARGET_64BIT"
3186   [(set (match_dup 4) (const_int 0))]
3187   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3188
3189 (define_split 
3190   [(set (match_operand:DI 0 "register_operand" "")
3191         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3192    (clobber (reg:CC FLAGS_REG))]
3193   "!TARGET_64BIT && reload_completed
3194    && true_regnum (operands[0]) == true_regnum (operands[1])"
3195   [(set (match_dup 4) (const_int 0))]
3196   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197
3198 (define_split 
3199   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3200         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3201    (clobber (reg:CC FLAGS_REG))]
3202   "!TARGET_64BIT && reload_completed
3203    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3204   [(set (match_dup 3) (match_dup 1))
3205    (set (match_dup 4) (const_int 0))]
3206   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3207
3208 (define_insn "zero_extendhidi2"
3209   [(set (match_operand:DI 0 "register_operand" "=r")
3210      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3211   "TARGET_64BIT"
3212   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3213   [(set_attr "type" "imovx")
3214    (set_attr "mode" "DI")])
3215
3216 (define_insn "zero_extendqidi2"
3217   [(set (match_operand:DI 0 "register_operand" "=r")
3218      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3219   "TARGET_64BIT"
3220   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3221   [(set_attr "type" "imovx")
3222    (set_attr "mode" "DI")])
3223 \f
3224 ;; Sign extension instructions
3225
3226 (define_expand "extendsidi2"
3227   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3228                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3229               (clobber (reg:CC FLAGS_REG))
3230               (clobber (match_scratch:SI 2 ""))])]
3231   ""
3232 {
3233   if (TARGET_64BIT)
3234     {
3235       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3236       DONE;
3237     }
3238 })
3239
3240 (define_insn "*extendsidi2_1"
3241   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3242         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3243    (clobber (reg:CC FLAGS_REG))
3244    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3245   "!TARGET_64BIT"
3246   "#")
3247
3248 (define_insn "extendsidi2_rex64"
3249   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3250         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3251   "TARGET_64BIT"
3252   "@
3253    {cltq|cdqe}
3254    movs{lq|x}\t{%1,%0|%0, %1}"
3255   [(set_attr "type" "imovx")
3256    (set_attr "mode" "DI")
3257    (set_attr "prefix_0f" "0")
3258    (set_attr "modrm" "0,1")])
3259
3260 (define_insn "extendhidi2"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3263   "TARGET_64BIT"
3264   "movs{wq|x}\t{%1,%0|%0, %1}"
3265   [(set_attr "type" "imovx")
3266    (set_attr "mode" "DI")])
3267
3268 (define_insn "extendqidi2"
3269   [(set (match_operand:DI 0 "register_operand" "=r")
3270         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3271   "TARGET_64BIT"
3272   "movs{bq|x}\t{%1,%0|%0, %1}"
3273    [(set_attr "type" "imovx")
3274     (set_attr "mode" "DI")])
3275
3276 ;; Extend to memory case when source register does die.
3277 (define_split 
3278   [(set (match_operand:DI 0 "memory_operand" "")
3279         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3280    (clobber (reg:CC FLAGS_REG))
3281    (clobber (match_operand:SI 2 "register_operand" ""))]
3282   "(reload_completed
3283     && dead_or_set_p (insn, operands[1])
3284     && !reg_mentioned_p (operands[1], operands[0]))"
3285   [(set (match_dup 3) (match_dup 1))
3286    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3287               (clobber (reg:CC FLAGS_REG))])
3288    (set (match_dup 4) (match_dup 1))]
3289   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3290
3291 ;; Extend to memory case when source register does not die.
3292 (define_split 
3293   [(set (match_operand:DI 0 "memory_operand" "")
3294         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295    (clobber (reg:CC FLAGS_REG))
3296    (clobber (match_operand:SI 2 "register_operand" ""))]
3297   "reload_completed"
3298   [(const_int 0)]
3299 {
3300   split_di (&operands[0], 1, &operands[3], &operands[4]);
3301
3302   emit_move_insn (operands[3], operands[1]);
3303
3304   /* Generate a cltd if possible and doing so it profitable.  */
3305   if (true_regnum (operands[1]) == 0
3306       && true_regnum (operands[2]) == 1
3307       && (optimize_size || TARGET_USE_CLTD))
3308     {
3309       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3310     }
3311   else
3312     {
3313       emit_move_insn (operands[2], operands[1]);
3314       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3315     }
3316   emit_move_insn (operands[4], operands[2]);
3317   DONE;
3318 })
3319
3320 ;; Extend to register case.  Optimize case where source and destination
3321 ;; registers match and cases where we can use cltd.
3322 (define_split 
3323   [(set (match_operand:DI 0 "register_operand" "")
3324         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3325    (clobber (reg:CC FLAGS_REG))
3326    (clobber (match_scratch:SI 2 ""))]
3327   "reload_completed"
3328   [(const_int 0)]
3329 {
3330   split_di (&operands[0], 1, &operands[3], &operands[4]);
3331
3332   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3333     emit_move_insn (operands[3], operands[1]);
3334
3335   /* Generate a cltd if possible and doing so it profitable.  */
3336   if (true_regnum (operands[3]) == 0
3337       && (optimize_size || TARGET_USE_CLTD))
3338     {
3339       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3340       DONE;
3341     }
3342
3343   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3344     emit_move_insn (operands[4], operands[1]);
3345
3346   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3347   DONE;
3348 })
3349
3350 (define_insn "extendhisi2"
3351   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3352         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3353   ""
3354 {
3355   switch (get_attr_prefix_0f (insn))
3356     {
3357     case 0:
3358       return "{cwtl|cwde}";
3359     default:
3360       return "movs{wl|x}\t{%1,%0|%0, %1}";
3361     }
3362 }
3363   [(set_attr "type" "imovx")
3364    (set_attr "mode" "SI")
3365    (set (attr "prefix_0f")
3366      ;; movsx is short decodable while cwtl is vector decoded.
3367      (if_then_else (and (eq_attr "cpu" "!k6")
3368                         (eq_attr "alternative" "0"))
3369         (const_string "0")
3370         (const_string "1")))
3371    (set (attr "modrm")
3372      (if_then_else (eq_attr "prefix_0f" "0")
3373         (const_string "0")
3374         (const_string "1")))])
3375
3376 (define_insn "*extendhisi2_zext"
3377   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3378         (zero_extend:DI
3379           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3380   "TARGET_64BIT"
3381 {
3382   switch (get_attr_prefix_0f (insn))
3383     {
3384     case 0:
3385       return "{cwtl|cwde}";
3386     default:
3387       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3388     }
3389 }
3390   [(set_attr "type" "imovx")
3391    (set_attr "mode" "SI")
3392    (set (attr "prefix_0f")
3393      ;; movsx is short decodable while cwtl is vector decoded.
3394      (if_then_else (and (eq_attr "cpu" "!k6")
3395                         (eq_attr "alternative" "0"))
3396         (const_string "0")
3397         (const_string "1")))
3398    (set (attr "modrm")
3399      (if_then_else (eq_attr "prefix_0f" "0")
3400         (const_string "0")
3401         (const_string "1")))])
3402
3403 (define_insn "extendqihi2"
3404   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3405         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3406   ""
3407 {
3408   switch (get_attr_prefix_0f (insn))
3409     {
3410     case 0:
3411       return "{cbtw|cbw}";
3412     default:
3413       return "movs{bw|x}\t{%1,%0|%0, %1}";
3414     }
3415 }
3416   [(set_attr "type" "imovx")
3417    (set_attr "mode" "HI")
3418    (set (attr "prefix_0f")
3419      ;; movsx is short decodable while cwtl is vector decoded.
3420      (if_then_else (and (eq_attr "cpu" "!k6")
3421                         (eq_attr "alternative" "0"))
3422         (const_string "0")
3423         (const_string "1")))
3424    (set (attr "modrm")
3425      (if_then_else (eq_attr "prefix_0f" "0")
3426         (const_string "0")
3427         (const_string "1")))])
3428
3429 (define_insn "extendqisi2"
3430   [(set (match_operand:SI 0 "register_operand" "=r")
3431         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3432   ""
3433   "movs{bl|x}\t{%1,%0|%0, %1}"
3434    [(set_attr "type" "imovx")
3435     (set_attr "mode" "SI")])
3436
3437 (define_insn "*extendqisi2_zext"
3438   [(set (match_operand:DI 0 "register_operand" "=r")
3439         (zero_extend:DI
3440           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3441   "TARGET_64BIT"
3442   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3443    [(set_attr "type" "imovx")
3444     (set_attr "mode" "SI")])
3445 \f
3446 ;; Conversions between float and double.
3447
3448 ;; These are all no-ops in the model used for the 80387.  So just
3449 ;; emit moves.
3450
3451 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3452 (define_insn "*dummy_extendsfdf2"
3453   [(set (match_operand:DF 0 "push_operand" "=<")
3454         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3455   "0"
3456   "#")
3457
3458 (define_split
3459   [(set (match_operand:DF 0 "push_operand" "")
3460         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3461   "!TARGET_64BIT"
3462   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3463    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3464
3465 (define_split
3466   [(set (match_operand:DF 0 "push_operand" "")
3467         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "TARGET_64BIT"
3469   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3470    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3471
3472 (define_insn "*dummy_extendsfxf2"
3473   [(set (match_operand:XF 0 "push_operand" "=<")
3474         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3475   "0"
3476   "#")
3477
3478 (define_split
3479   [(set (match_operand:XF 0 "push_operand" "")
3480         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3481   ""
3482   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3483    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3484   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3485
3486 (define_split
3487   [(set (match_operand:XF 0 "push_operand" "")
3488         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3489   "TARGET_64BIT"
3490   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3491    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3492   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493
3494 (define_split
3495   [(set (match_operand:XF 0 "push_operand" "")
3496         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3497   ""
3498   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3499    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3500   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501
3502 (define_split
3503   [(set (match_operand:XF 0 "push_operand" "")
3504         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3505   "TARGET_64BIT"
3506   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3507    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3508   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509
3510 (define_expand "extendsfdf2"
3511   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3512         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3513   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3514 {
3515   /* ??? Needed for compress_float_constant since all fp constants
3516      are LEGITIMATE_CONSTANT_P.  */
3517   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3518     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3520     operands[1] = force_reg (SFmode, operands[1]);
3521 })
3522
3523 (define_insn "*extendsfdf2_mixed"
3524   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3525         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3526   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3527    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3528 {
3529   switch (which_alternative)
3530     {
3531     case 0:
3532       return output_387_reg_move (insn, operands);
3533
3534     case 1:
3535       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3536         return "fstp%z0\t%y0";
3537       else
3538         return "fst%z0\t%y0";
3539
3540     case 2:
3541       return "cvtss2sd\t{%1, %0|%0, %1}";
3542
3543     default:
3544       gcc_unreachable ();
3545     }
3546 }
3547   [(set_attr "type" "fmov,fmov,ssecvt")
3548    (set_attr "mode" "SF,XF,DF")])
3549
3550 (define_insn "*extendsfdf2_sse"
3551   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3552         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3553   "TARGET_SSE2 && TARGET_SSE_MATH
3554    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3555   "cvtss2sd\t{%1, %0|%0, %1}"
3556   [(set_attr "type" "ssecvt")
3557    (set_attr "mode" "DF")])
3558
3559 (define_insn "*extendsfdf2_i387"
3560   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3561         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3562   "TARGET_80387
3563    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3564 {
3565   switch (which_alternative)
3566     {
3567     case 0:
3568       return output_387_reg_move (insn, operands);
3569
3570     case 1:
3571       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3572         return "fstp%z0\t%y0";
3573       else
3574         return "fst%z0\t%y0";
3575
3576     default:
3577       gcc_unreachable ();
3578     }
3579 }
3580   [(set_attr "type" "fmov")
3581    (set_attr "mode" "SF,XF")])
3582
3583 (define_expand "extendsfxf2"
3584   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3585         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3586   "TARGET_80387"
3587 {
3588   /* ??? Needed for compress_float_constant since all fp constants
3589      are LEGITIMATE_CONSTANT_P.  */
3590   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3591     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3592   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3593     operands[1] = force_reg (SFmode, operands[1]);
3594 })
3595
3596 (define_insn "*extendsfxf2_i387"
3597   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3598         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3599   "TARGET_80387
3600    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3601 {
3602   switch (which_alternative)
3603     {
3604     case 0:
3605       return output_387_reg_move (insn, operands);
3606
3607     case 1:
3608       /* There is no non-popping store to memory for XFmode.  So if
3609          we need one, follow the store with a load.  */
3610       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3611         return "fstp%z0\t%y0";
3612       else
3613         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3614
3615     default:
3616       gcc_unreachable ();
3617     }
3618 }
3619   [(set_attr "type" "fmov")
3620    (set_attr "mode" "SF,XF")])
3621
3622 (define_expand "extenddfxf2"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3624         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3625   "TARGET_80387"
3626 {
3627   /* ??? Needed for compress_float_constant since all fp constants
3628      are LEGITIMATE_CONSTANT_P.  */
3629   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3630     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3631   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3632     operands[1] = force_reg (DFmode, operands[1]);
3633 })
3634
3635 (define_insn "*extenddfxf2_i387"
3636   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3637         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3638   "TARGET_80387
3639    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3640 {
3641   switch (which_alternative)
3642     {
3643     case 0:
3644       return output_387_reg_move (insn, operands);
3645
3646     case 1:
3647       /* There is no non-popping store to memory for XFmode.  So if
3648          we need one, follow the store with a load.  */
3649       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3650         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3651       else
3652         return "fstp%z0\t%y0";
3653
3654     default:
3655       gcc_unreachable ();
3656     }
3657 }
3658   [(set_attr "type" "fmov")
3659    (set_attr "mode" "DF,XF")])
3660
3661 ;; %%% This seems bad bad news.
3662 ;; This cannot output into an f-reg because there is no way to be sure
3663 ;; of truncating in that case.  Otherwise this is just like a simple move
3664 ;; insn.  So we pretend we can output to a reg in order to get better
3665 ;; register preferencing, but we really use a stack slot.
3666
3667 ;; Conversion from DFmode to SFmode.
3668
3669 (define_expand "truncdfsf2"
3670   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3671         (float_truncate:SF
3672           (match_operand:DF 1 "nonimmediate_operand" "")))]
3673   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3674 {
3675   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3676     operands[1] = force_reg (DFmode, operands[1]);
3677
3678   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3679     ;
3680   else if (flag_unsafe_math_optimizations)
3681     ;
3682   else
3683     {
3684       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3685       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3686       DONE;
3687     }
3688 })
3689
3690 (define_expand "truncdfsf2_with_temp"
3691   [(parallel [(set (match_operand:SF 0 "" "")
3692                    (float_truncate:SF (match_operand:DF 1 "" "")))
3693               (clobber (match_operand:SF 2 "" ""))])]
3694   "")
3695
3696 (define_insn "*truncdfsf_fast_mixed"
3697   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3698         (float_truncate:SF
3699           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3700   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3701 {
3702   switch (which_alternative)
3703     {
3704     case 0:
3705       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3706         return "fstp%z0\t%y0";
3707       else
3708         return "fst%z0\t%y0";
3709     case 1:
3710       return output_387_reg_move (insn, operands);
3711     case 2:
3712       return "cvtsd2ss\t{%1, %0|%0, %1}";
3713     default:
3714       gcc_unreachable ();
3715     }
3716 }
3717   [(set_attr "type" "fmov,fmov,ssecvt")
3718    (set_attr "mode" "SF")])
3719
3720 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3721 ;; because nothing we do here is unsafe.
3722 (define_insn "*truncdfsf_fast_sse"
3723   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3724         (float_truncate:SF
3725           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3726   "TARGET_SSE2 && TARGET_SSE_MATH"
3727   "cvtsd2ss\t{%1, %0|%0, %1}"
3728   [(set_attr "type" "ssecvt")
3729    (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf_fast_i387"
3732   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3735   "TARGET_80387 && flag_unsafe_math_optimizations"
3736   "* return output_387_reg_move (insn, operands);"
3737   [(set_attr "type" "fmov")
3738    (set_attr "mode" "SF")])
3739
3740 (define_insn "*truncdfsf_mixed"
3741   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3742         (float_truncate:SF
3743           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3744    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3745   "TARGET_MIX_SSE_I387"
3746 {
3747   switch (which_alternative)
3748     {
3749     case 0:
3750       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3751         return "fstp%z0\t%y0";
3752       else
3753         return "fst%z0\t%y0";
3754     case 1:
3755       return "#";
3756     case 2:
3757       return "cvtsd2ss\t{%1, %0|%0, %1}";
3758     default:
3759       gcc_unreachable ();
3760     }
3761 }
3762   [(set_attr "type" "fmov,multi,ssecvt")
3763    (set_attr "unit" "*,i387,*")
3764    (set_attr "mode" "SF")])
3765
3766 (define_insn "*truncdfsf_i387"
3767   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3768         (float_truncate:SF
3769           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3770    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3771   "TARGET_80387"
3772 {
3773   switch (which_alternative)
3774     {
3775     case 0:
3776       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777         return "fstp%z0\t%y0";
3778       else
3779         return "fst%z0\t%y0";
3780     case 1:
3781       return "#";
3782     default:
3783       gcc_unreachable ();
3784     }
3785 }
3786   [(set_attr "type" "fmov,multi")
3787    (set_attr "unit" "*,i387")
3788    (set_attr "mode" "SF")])
3789
3790 (define_insn "*truncdfsf2_i387_1"
3791   [(set (match_operand:SF 0 "memory_operand" "=m")
3792         (float_truncate:SF
3793           (match_operand:DF 1 "register_operand" "f")))]
3794   "TARGET_80387
3795    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3796    && !TARGET_MIX_SSE_I387"
3797 {
3798   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799     return "fstp%z0\t%y0";
3800   else
3801     return "fst%z0\t%y0";
3802 }
3803   [(set_attr "type" "fmov")
3804    (set_attr "mode" "SF")])
3805
3806 (define_split
3807   [(set (match_operand:SF 0 "register_operand" "")
3808         (float_truncate:SF
3809          (match_operand:DF 1 "fp_register_operand" "")))
3810    (clobber (match_operand 2 "" ""))]
3811   "reload_completed"
3812   [(set (match_dup 2) (match_dup 1))
3813    (set (match_dup 0) (match_dup 2))]
3814 {
3815   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3816 })
3817
3818 ;; Conversion from XFmode to SFmode.
3819
3820 (define_expand "truncxfsf2"
3821   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3822                    (float_truncate:SF
3823                     (match_operand:XF 1 "register_operand" "")))
3824               (clobber (match_dup 2))])]
3825   "TARGET_80387"
3826 {
3827   if (flag_unsafe_math_optimizations)
3828     {
3829       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3830       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3831       if (reg != operands[0])
3832         emit_move_insn (operands[0], reg);
3833       DONE;
3834     }
3835   else
3836     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3837 })
3838
3839 (define_insn "*truncxfsf2_mixed"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841         (float_truncate:SF
3842          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844   "TARGET_MIX_SSE_I387"
3845 {
3846   gcc_assert (!which_alternative);
3847   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3848     return "fstp%z0\t%y0";
3849   else
3850     return "fst%z0\t%y0";
3851 }
3852   [(set_attr "type" "fmov,multi,multi,multi")
3853    (set_attr "unit" "*,i387,i387,i387")
3854    (set_attr "mode" "SF")])
3855
3856 (define_insn "truncxfsf2_i387_noop"
3857   [(set (match_operand:SF 0 "register_operand" "=f")
3858         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3859   "TARGET_80387 && flag_unsafe_math_optimizations"
3860 {
3861   return output_387_reg_move (insn, operands);
3862 }
3863   [(set_attr "type" "fmov")
3864    (set_attr "mode" "SF")])
3865
3866 (define_insn "*truncxfsf2_i387"
3867   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3868         (float_truncate:SF
3869          (match_operand:XF 1 "register_operand" "f,f,f")))
3870    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3871   "TARGET_80387"
3872 {
3873   gcc_assert (!which_alternative);
3874   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3875     return "fstp%z0\t%y0";
3876    else
3877      return "fst%z0\t%y0";
3878 }
3879   [(set_attr "type" "fmov,multi,multi")
3880    (set_attr "unit" "*,i387,i387")
3881    (set_attr "mode" "SF")])
3882
3883 (define_insn "*truncxfsf2_i387_1"
3884   [(set (match_operand:SF 0 "memory_operand" "=m")
3885         (float_truncate:SF
3886          (match_operand:XF 1 "register_operand" "f")))]
3887   "TARGET_80387"
3888 {
3889   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3890     return "fstp%z0\t%y0";
3891   else
3892     return "fst%z0\t%y0";
3893 }
3894   [(set_attr "type" "fmov")
3895    (set_attr "mode" "SF")])
3896
3897 (define_split
3898   [(set (match_operand:SF 0 "register_operand" "")
3899         (float_truncate:SF
3900          (match_operand:XF 1 "register_operand" "")))
3901    (clobber (match_operand:SF 2 "memory_operand" ""))]
3902   "TARGET_80387 && reload_completed"
3903   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3904    (set (match_dup 0) (match_dup 2))]
3905   "")
3906
3907 (define_split
3908   [(set (match_operand:SF 0 "memory_operand" "")
3909         (float_truncate:SF
3910          (match_operand:XF 1 "register_operand" "")))
3911    (clobber (match_operand:SF 2 "memory_operand" ""))]
3912   "TARGET_80387"
3913   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3914   "")
3915
3916 ;; Conversion from XFmode to DFmode.
3917
3918 (define_expand "truncxfdf2"
3919   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3920                    (float_truncate:DF
3921                     (match_operand:XF 1 "register_operand" "")))
3922               (clobber (match_dup 2))])]
3923   "TARGET_80387"
3924 {
3925   if (flag_unsafe_math_optimizations)
3926     {
3927       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3928       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3929       if (reg != operands[0])
3930         emit_move_insn (operands[0], reg);
3931       DONE;
3932     }
3933   else
3934     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3935 })
3936
3937 (define_insn "*truncxfdf2_mixed"
3938   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3939         (float_truncate:DF
3940          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3941    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3942   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3943 {
3944   gcc_assert (!which_alternative);
3945   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946     return "fstp%z0\t%y0";
3947   else
3948     return "fst%z0\t%y0";
3949 }
3950   [(set_attr "type" "fmov,multi,multi,multi")
3951    (set_attr "unit" "*,i387,i387,i387")
3952    (set_attr "mode" "DF")])
3953
3954 (define_insn "truncxfdf2_i387_noop"
3955   [(set (match_operand:DF 0 "register_operand" "=f")
3956         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3957   "TARGET_80387 && flag_unsafe_math_optimizations"
3958 {
3959   return output_387_reg_move (insn, operands);
3960 }
3961   [(set_attr "type" "fmov")
3962    (set_attr "mode" "DF")])
3963
3964 (define_insn "*truncxfdf2_i387"
3965   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3966         (float_truncate:DF
3967          (match_operand:XF 1 "register_operand" "f,f,f")))
3968    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3969   "TARGET_80387"
3970 {
3971   gcc_assert (!which_alternative);
3972   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3973     return "fstp%z0\t%y0";
3974   else
3975     return "fst%z0\t%y0";
3976 }
3977   [(set_attr "type" "fmov,multi,multi")
3978    (set_attr "unit" "*,i387,i387")
3979    (set_attr "mode" "DF")])
3980
3981 (define_insn "*truncxfdf2_i387_1"
3982   [(set (match_operand:DF 0 "memory_operand" "=m")
3983         (float_truncate:DF
3984           (match_operand:XF 1 "register_operand" "f")))]
3985   "TARGET_80387"
3986 {
3987   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988     return "fstp%z0\t%y0";
3989   else
3990     return "fst%z0\t%y0";
3991 }
3992   [(set_attr "type" "fmov")
3993    (set_attr "mode" "DF")])
3994
3995 (define_split
3996   [(set (match_operand:DF 0 "register_operand" "")
3997         (float_truncate:DF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:DF 2 "memory_operand" ""))]
4000   "TARGET_80387 && reload_completed"
4001   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4002    (set (match_dup 0) (match_dup 2))]
4003   "")
4004
4005 (define_split
4006   [(set (match_operand:DF 0 "memory_operand" "")
4007         (float_truncate:DF
4008          (match_operand:XF 1 "register_operand" "")))
4009    (clobber (match_operand:DF 2 "memory_operand" ""))]
4010   "TARGET_80387"
4011   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4012   "")
4013 \f
4014 ;; Signed conversion to DImode.
4015
4016 (define_expand "fix_truncxfdi2"
4017   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4019               (clobber (reg:CC FLAGS_REG))])]
4020   "TARGET_80387"
4021 {
4022   if (TARGET_FISTTP)
4023    {
4024      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4025      DONE;
4026    }
4027 })
4028
4029 (define_expand "fix_trunc<mode>di2"
4030   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4031                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4032               (clobber (reg:CC FLAGS_REG))])]
4033   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4034 {
4035   if (TARGET_FISTTP
4036       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4037    {
4038      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4039      DONE;
4040    }
4041   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4042    {
4043      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4044      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4045      if (out != operands[0])
4046         emit_move_insn (operands[0], out);
4047      DONE;
4048    }
4049 })
4050
4051 ;; Signed conversion to SImode.
4052
4053 (define_expand "fix_truncxfsi2"
4054   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4055                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4056               (clobber (reg:CC FLAGS_REG))])]
4057   "TARGET_80387"
4058 {
4059   if (TARGET_FISTTP)
4060    {
4061      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4062      DONE;
4063    }
4064 })
4065
4066 (define_expand "fix_trunc<mode>si2"
4067   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4068                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4069               (clobber (reg:CC FLAGS_REG))])]
4070   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4071 {
4072   if (TARGET_FISTTP
4073       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4074    {
4075      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4076      DONE;
4077    }
4078   if (SSE_FLOAT_MODE_P (<MODE>mode))
4079    {
4080      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4081      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4082      if (out != operands[0])
4083         emit_move_insn (operands[0], out);
4084      DONE;
4085    }
4086 })
4087
4088 ;; Signed conversion to HImode.
4089
4090 (define_expand "fix_trunc<mode>hi2"
4091   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4092                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4093               (clobber (reg:CC FLAGS_REG))])]
4094   "TARGET_80387
4095    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4096 {
4097   if (TARGET_FISTTP)
4098    {
4099      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4100      DONE;
4101    }
4102 })
4103
4104 ;; When SSE is available, it is always faster to use it!
4105 (define_insn "fix_truncsfdi_sse"
4106   [(set (match_operand:DI 0 "register_operand" "=r,r")
4107         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4108   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4109   "cvttss2si{q}\t{%1, %0|%0, %1}"
4110   [(set_attr "type" "sseicvt")
4111    (set_attr "mode" "SF")
4112    (set_attr "athlon_decode" "double,vector")])
4113
4114 (define_insn "fix_truncdfdi_sse"
4115   [(set (match_operand:DI 0 "register_operand" "=r,r")
4116         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4117   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4118   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4119   [(set_attr "type" "sseicvt")
4120    (set_attr "mode" "DF")
4121    (set_attr "athlon_decode" "double,vector")])
4122
4123 (define_insn "fix_truncsfsi_sse"
4124   [(set (match_operand:SI 0 "register_operand" "=r,r")
4125         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4126   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4127   "cvttss2si\t{%1, %0|%0, %1}"
4128   [(set_attr "type" "sseicvt")
4129    (set_attr "mode" "DF")
4130    (set_attr "athlon_decode" "double,vector")])
4131
4132 (define_insn "fix_truncdfsi_sse"
4133   [(set (match_operand:SI 0 "register_operand" "=r,r")
4134         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4135   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4136   "cvttsd2si\t{%1, %0|%0, %1}"
4137   [(set_attr "type" "sseicvt")
4138    (set_attr "mode" "DF")
4139    (set_attr "athlon_decode" "double,vector")])
4140
4141 ;; Avoid vector decoded forms of the instruction.
4142 (define_peephole2
4143   [(match_scratch:DF 2 "Y")
4144    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4145         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4146   "TARGET_K8 && !optimize_size"
4147   [(set (match_dup 2) (match_dup 1))
4148    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4149   "")
4150
4151 (define_peephole2
4152   [(match_scratch:SF 2 "x")
4153    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4154         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4155   "TARGET_K8 && !optimize_size"
4156   [(set (match_dup 2) (match_dup 1))
4157    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4158   "")
4159
4160 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4161   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4162         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4163   "TARGET_FISTTP
4164    && FLOAT_MODE_P (GET_MODE (operands[1]))
4165    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4166          && (TARGET_64BIT || <MODE>mode != DImode))
4167         && TARGET_SSE_MATH)
4168    && !(reload_completed || reload_in_progress)"
4169   "#"
4170   "&& 1"
4171   [(const_int 0)]
4172 {
4173   if (memory_operand (operands[0], VOIDmode))
4174     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4175   else
4176     {
4177       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4178       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4179                                                             operands[1],
4180                                                             operands[2]));
4181     }
4182   DONE;
4183 }
4184   [(set_attr "type" "fisttp")
4185    (set_attr "mode" "<MODE>")])
4186
4187 (define_insn "fix_trunc<mode>_i387_fisttp"
4188   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4189         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4190    (clobber (match_scratch:XF 2 "=&1f"))]
4191   "TARGET_FISTTP
4192    && FLOAT_MODE_P (GET_MODE (operands[1]))
4193    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4194          && (TARGET_64BIT || <MODE>mode != DImode))
4195         && TARGET_SSE_MATH)"
4196   "* return output_fix_trunc (insn, operands, 1);"
4197   [(set_attr "type" "fisttp")
4198    (set_attr "mode" "<MODE>")])
4199
4200 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4201   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4202         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4203    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4204    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4205   "TARGET_FISTTP
4206    && FLOAT_MODE_P (GET_MODE (operands[1]))
4207    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4208         && (TARGET_64BIT || <MODE>mode != DImode))
4209         && TARGET_SSE_MATH)"
4210   "#"
4211   [(set_attr "type" "fisttp")
4212    (set_attr "mode" "<MODE>")])
4213
4214 (define_split
4215   [(set (match_operand:X87MODEI 0 "register_operand" "")
4216         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4217    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4218    (clobber (match_scratch 3 ""))]
4219   "reload_completed"
4220   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4221               (clobber (match_dup 3))])
4222    (set (match_dup 0) (match_dup 2))]
4223   "")
4224
4225 (define_split
4226   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4227         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4228    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4229    (clobber (match_scratch 3 ""))]
4230   "reload_completed"
4231   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4232               (clobber (match_dup 3))])]
4233   "")
4234
4235 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4236 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4237 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4238 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4239 ;; function in i386.c.
4240 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4241   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4242         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4243    (clobber (reg:CC FLAGS_REG))]
4244   "TARGET_80387 && !TARGET_FISTTP
4245    && FLOAT_MODE_P (GET_MODE (operands[1]))
4246    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4247          && (TARGET_64BIT || <MODE>mode != DImode))
4248    && !(reload_completed || reload_in_progress)"
4249   "#"
4250   "&& 1"
4251   [(const_int 0)]
4252 {
4253   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4254
4255   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4256   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4257   if (memory_operand (operands[0], VOIDmode))
4258     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4259                                          operands[2], operands[3]));
4260   else
4261     {
4262       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4263       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4264                                                      operands[2], operands[3],
4265                                                      operands[4]));
4266     }
4267   DONE;
4268 }
4269   [(set_attr "type" "fistp")
4270    (set_attr "i387_cw" "trunc")
4271    (set_attr "mode" "<MODE>")])
4272
4273 (define_insn "fix_truncdi_i387"
4274   [(set (match_operand:DI 0 "memory_operand" "=m")
4275         (fix:DI (match_operand 1 "register_operand" "f")))
4276    (use (match_operand:HI 2 "memory_operand" "m"))
4277    (use (match_operand:HI 3 "memory_operand" "m"))
4278    (clobber (match_scratch:XF 4 "=&1f"))]
4279   "TARGET_80387 && !TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4282   "* return output_fix_trunc (insn, operands, 0);"
4283   [(set_attr "type" "fistp")
4284    (set_attr "i387_cw" "trunc")
4285    (set_attr "mode" "DI")])
4286
4287 (define_insn "fix_truncdi_i387_with_temp"
4288   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4289         (fix:DI (match_operand 1 "register_operand" "f,f")))
4290    (use (match_operand:HI 2 "memory_operand" "m,m"))
4291    (use (match_operand:HI 3 "memory_operand" "m,m"))
4292    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4293    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4294   "TARGET_80387 && !TARGET_FISTTP
4295    && FLOAT_MODE_P (GET_MODE (operands[1]))
4296    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4297   "#"
4298   [(set_attr "type" "fistp")
4299    (set_attr "i387_cw" "trunc")
4300    (set_attr "mode" "DI")])
4301
4302 (define_split 
4303   [(set (match_operand:DI 0 "register_operand" "")
4304         (fix:DI (match_operand 1 "register_operand" "")))
4305    (use (match_operand:HI 2 "memory_operand" ""))
4306    (use (match_operand:HI 3 "memory_operand" ""))
4307    (clobber (match_operand:DI 4 "memory_operand" ""))
4308    (clobber (match_scratch 5 ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4311               (use (match_dup 2))
4312               (use (match_dup 3))
4313               (clobber (match_dup 5))])
4314    (set (match_dup 0) (match_dup 4))]
4315   "")
4316
4317 (define_split 
4318   [(set (match_operand:DI 0 "memory_operand" "")
4319         (fix:DI (match_operand 1 "register_operand" "")))
4320    (use (match_operand:HI 2 "memory_operand" ""))
4321    (use (match_operand:HI 3 "memory_operand" ""))
4322    (clobber (match_operand:DI 4 "memory_operand" ""))
4323    (clobber (match_scratch 5 ""))]
4324   "reload_completed"
4325   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4326               (use (match_dup 2))
4327               (use (match_dup 3))
4328               (clobber (match_dup 5))])]
4329   "")
4330
4331 (define_insn "fix_trunc<mode>_i387"
4332   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4333         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4334    (use (match_operand:HI 2 "memory_operand" "m"))
4335    (use (match_operand:HI 3 "memory_operand" "m"))]
4336   "TARGET_80387 && !TARGET_FISTTP
4337    && FLOAT_MODE_P (GET_MODE (operands[1]))
4338    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4339   "* return output_fix_trunc (insn, operands, 0);"
4340   [(set_attr "type" "fistp")
4341    (set_attr "i387_cw" "trunc")
4342    (set_attr "mode" "<MODE>")])
4343
4344 (define_insn "fix_trunc<mode>_i387_with_temp"
4345   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4346         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4347    (use (match_operand:HI 2 "memory_operand" "m,m"))
4348    (use (match_operand:HI 3 "memory_operand" "m,m"))
4349    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4350   "TARGET_80387 && !TARGET_FISTTP
4351    && FLOAT_MODE_P (GET_MODE (operands[1]))
4352    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4353   "#"
4354   [(set_attr "type" "fistp")
4355    (set_attr "i387_cw" "trunc")
4356    (set_attr "mode" "<MODE>")])
4357
4358 (define_split 
4359   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4360         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4361    (use (match_operand:HI 2 "memory_operand" ""))
4362    (use (match_operand:HI 3 "memory_operand" ""))
4363    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4364   "reload_completed"
4365   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4366               (use (match_dup 2))
4367               (use (match_dup 3))])
4368    (set (match_dup 0) (match_dup 4))]
4369   "")
4370
4371 (define_split 
4372   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4373         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4374    (use (match_operand:HI 2 "memory_operand" ""))
4375    (use (match_operand:HI 3 "memory_operand" ""))
4376    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4377   "reload_completed"
4378   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4379               (use (match_dup 2))
4380               (use (match_dup 3))])]
4381   "")
4382
4383 (define_insn "x86_fnstcw_1"
4384   [(set (match_operand:HI 0 "memory_operand" "=m")
4385         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4386   "TARGET_80387"
4387   "fnstcw\t%0"
4388   [(set_attr "length" "2")
4389    (set_attr "mode" "HI")
4390    (set_attr "unit" "i387")])
4391
4392 (define_insn "x86_fldcw_1"
4393   [(set (reg:HI FPSR_REG)
4394         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4395   "TARGET_80387"
4396   "fldcw\t%0"
4397   [(set_attr "length" "2")
4398    (set_attr "mode" "HI")
4399    (set_attr "unit" "i387")
4400    (set_attr "athlon_decode" "vector")])
4401 \f
4402 ;; Conversion between fixed point and floating point.
4403
4404 ;; Even though we only accept memory inputs, the backend _really_
4405 ;; wants to be able to do this between registers.
4406
4407 (define_expand "floathisf2"
4408   [(set (match_operand:SF 0 "register_operand" "")
4409         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4410   "TARGET_80387 || TARGET_SSE_MATH"
4411 {
4412   if (TARGET_SSE_MATH)
4413     {
4414       emit_insn (gen_floatsisf2 (operands[0],
4415                                  convert_to_mode (SImode, operands[1], 0)));
4416       DONE;
4417     }
4418 })
4419
4420 (define_insn "*floathisf2_i387"
4421   [(set (match_operand:SF 0 "register_operand" "=f,f")
4422         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4423   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4424   "@
4425    fild%z1\t%1
4426    #"
4427   [(set_attr "type" "fmov,multi")
4428    (set_attr "mode" "SF")
4429    (set_attr "unit" "*,i387")
4430    (set_attr "fp_int_src" "true")])
4431
4432 (define_expand "floatsisf2"
4433   [(set (match_operand:SF 0 "register_operand" "")
4434         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4435   "TARGET_80387 || TARGET_SSE_MATH"
4436   "")
4437
4438 (define_insn "*floatsisf2_mixed"
4439   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4440         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4441   "TARGET_MIX_SSE_I387"
4442   "@
4443    fild%z1\t%1
4444    #
4445    cvtsi2ss\t{%1, %0|%0, %1}
4446    cvtsi2ss\t{%1, %0|%0, %1}"
4447   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4448    (set_attr "mode" "SF")
4449    (set_attr "unit" "*,i387,*,*")
4450    (set_attr "athlon_decode" "*,*,vector,double")
4451    (set_attr "fp_int_src" "true")])
4452
4453 (define_insn "*floatsisf2_sse"
4454   [(set (match_operand:SF 0 "register_operand" "=x,x")
4455         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4456   "TARGET_SSE_MATH"
4457   "cvtsi2ss\t{%1, %0|%0, %1}"
4458   [(set_attr "type" "sseicvt")
4459    (set_attr "mode" "SF")
4460    (set_attr "athlon_decode" "vector,double")
4461    (set_attr "fp_int_src" "true")])
4462
4463 (define_insn "*floatsisf2_i387"
4464   [(set (match_operand:SF 0 "register_operand" "=f,f")
4465         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4466   "TARGET_80387"
4467   "@
4468    fild%z1\t%1
4469    #"
4470   [(set_attr "type" "fmov,multi")
4471    (set_attr "mode" "SF")
4472    (set_attr "unit" "*,i387")
4473    (set_attr "fp_int_src" "true")])
4474
4475 (define_expand "floatdisf2"
4476   [(set (match_operand:SF 0 "register_operand" "")
4477         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4478   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4479   "")
4480
4481 (define_insn "*floatdisf2_mixed"
4482   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4483         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4484   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4485   "@
4486    fild%z1\t%1
4487    #
4488    cvtsi2ss{q}\t{%1, %0|%0, %1}
4489    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4490   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4491    (set_attr "mode" "SF")
4492    (set_attr "unit" "*,i387,*,*")
4493    (set_attr "athlon_decode" "*,*,vector,double")
4494    (set_attr "fp_int_src" "true")])
4495
4496 (define_insn "*floatdisf2_sse"
4497   [(set (match_operand:SF 0 "register_operand" "=x,x")
4498         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4499   "TARGET_64BIT && TARGET_SSE_MATH"
4500   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4501   [(set_attr "type" "sseicvt")
4502    (set_attr "mode" "SF")
4503    (set_attr "athlon_decode" "vector,double")
4504    (set_attr "fp_int_src" "true")])
4505
4506 (define_insn "*floatdisf2_i387"
4507   [(set (match_operand:SF 0 "register_operand" "=f,f")
4508         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4509   "TARGET_80387"
4510   "@
4511    fild%z1\t%1
4512    #"
4513   [(set_attr "type" "fmov,multi")
4514    (set_attr "mode" "SF")
4515    (set_attr "unit" "*,i387")
4516    (set_attr "fp_int_src" "true")])
4517
4518 (define_expand "floathidf2"
4519   [(set (match_operand:DF 0 "register_operand" "")
4520         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4521   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4522 {
4523   if (TARGET_SSE2 && TARGET_SSE_MATH)
4524     {
4525       emit_insn (gen_floatsidf2 (operands[0],
4526                                  convert_to_mode (SImode, operands[1], 0)));
4527       DONE;
4528     }
4529 })
4530
4531 (define_insn "*floathidf2_i387"
4532   [(set (match_operand:DF 0 "register_operand" "=f,f")
4533         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4534   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4535   "@
4536    fild%z1\t%1
4537    #"
4538   [(set_attr "type" "fmov,multi")
4539    (set_attr "mode" "DF")
4540    (set_attr "unit" "*,i387")
4541    (set_attr "fp_int_src" "true")])
4542
4543 (define_expand "floatsidf2"
4544   [(set (match_operand:DF 0 "register_operand" "")
4545         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4546   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4547   "")
4548
4549 (define_insn "*floatsidf2_mixed"
4550   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4551         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4552   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4553   "@
4554    fild%z1\t%1
4555    #
4556    cvtsi2sd\t{%1, %0|%0, %1}
4557    cvtsi2sd\t{%1, %0|%0, %1}"
4558   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4559    (set_attr "mode" "DF")
4560    (set_attr "unit" "*,i387,*,*")
4561    (set_attr "athlon_decode" "*,*,double,direct")
4562    (set_attr "fp_int_src" "true")])
4563
4564 (define_insn "*floatsidf2_sse"
4565   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4566         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4567   "TARGET_SSE2 && TARGET_SSE_MATH"
4568   "cvtsi2sd\t{%1, %0|%0, %1}"
4569   [(set_attr "type" "sseicvt")
4570    (set_attr "mode" "DF")
4571    (set_attr "athlon_decode" "double,direct")
4572    (set_attr "fp_int_src" "true")])
4573
4574 (define_insn "*floatsidf2_i387"
4575   [(set (match_operand:DF 0 "register_operand" "=f,f")
4576         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4577   "TARGET_80387"
4578   "@
4579    fild%z1\t%1
4580    #"
4581   [(set_attr "type" "fmov,multi")
4582    (set_attr "mode" "DF")
4583    (set_attr "unit" "*,i387")
4584    (set_attr "fp_int_src" "true")])
4585
4586 (define_expand "floatdidf2"
4587   [(set (match_operand:DF 0 "register_operand" "")
4588         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4589   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4590   "")
4591
4592 (define_insn "*floatdidf2_mixed"
4593   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4594         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4595   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4596   "@
4597    fild%z1\t%1
4598    #
4599    cvtsi2sd{q}\t{%1, %0|%0, %1}
4600    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4601   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4602    (set_attr "mode" "DF")
4603    (set_attr "unit" "*,i387,*,*")
4604    (set_attr "athlon_decode" "*,*,double,direct")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_insn "*floatdidf2_sse"
4608   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4609         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4610   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4611   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4612   [(set_attr "type" "sseicvt")
4613    (set_attr "mode" "DF")
4614    (set_attr "athlon_decode" "double,direct")
4615    (set_attr "fp_int_src" "true")])
4616
4617 (define_insn "*floatdidf2_i387"
4618   [(set (match_operand:DF 0 "register_operand" "=f,f")
4619         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4620   "TARGET_80387"
4621   "@
4622    fild%z1\t%1
4623    #"
4624   [(set_attr "type" "fmov,multi")
4625    (set_attr "mode" "DF")
4626    (set_attr "unit" "*,i387")
4627    (set_attr "fp_int_src" "true")])
4628
4629 (define_insn "floathixf2"
4630   [(set (match_operand:XF 0 "register_operand" "=f,f")
4631         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4632   "TARGET_80387"
4633   "@
4634    fild%z1\t%1
4635    #"
4636   [(set_attr "type" "fmov,multi")
4637    (set_attr "mode" "XF")
4638    (set_attr "unit" "*,i387")
4639    (set_attr "fp_int_src" "true")])
4640
4641 (define_insn "floatsixf2"
4642   [(set (match_operand:XF 0 "register_operand" "=f,f")
4643         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4644   "TARGET_80387"
4645   "@
4646    fild%z1\t%1
4647    #"
4648   [(set_attr "type" "fmov,multi")
4649    (set_attr "mode" "XF")
4650    (set_attr "unit" "*,i387")
4651    (set_attr "fp_int_src" "true")])
4652
4653 (define_insn "floatdixf2"
4654   [(set (match_operand:XF 0 "register_operand" "=f,f")
4655         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4656   "TARGET_80387"
4657   "@
4658    fild%z1\t%1
4659    #"
4660   [(set_attr "type" "fmov,multi")
4661    (set_attr "mode" "XF")
4662    (set_attr "unit" "*,i387")
4663    (set_attr "fp_int_src" "true")])
4664
4665 ;; %%% Kill these when reload knows how to do it.
4666 (define_split
4667   [(set (match_operand 0 "fp_register_operand" "")
4668         (float (match_operand 1 "register_operand" "")))]
4669   "reload_completed
4670    && TARGET_80387
4671    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4672   [(const_int 0)]
4673 {
4674   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4675   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4676   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4677   ix86_free_from_memory (GET_MODE (operands[1]));
4678   DONE;
4679 })
4680
4681 (define_expand "floatunssisf2"
4682   [(use (match_operand:SF 0 "register_operand" ""))
4683    (use (match_operand:SI 1 "register_operand" ""))]
4684   "!TARGET_64BIT && TARGET_SSE_MATH"
4685   "x86_emit_floatuns (operands); DONE;")
4686
4687 (define_expand "floatunsdisf2"
4688   [(use (match_operand:SF 0 "register_operand" ""))
4689    (use (match_operand:DI 1 "register_operand" ""))]
4690   "TARGET_64BIT && TARGET_SSE_MATH"
4691   "x86_emit_floatuns (operands); DONE;")
4692
4693 (define_expand "floatunsdidf2"
4694   [(use (match_operand:DF 0 "register_operand" ""))
4695    (use (match_operand:DI 1 "register_operand" ""))]
4696   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4697   "x86_emit_floatuns (operands); DONE;")
4698 \f
4699 ;; SSE extract/set expanders
4700
4701 \f
4702 ;; Add instructions
4703
4704 ;; %%% splits for addditi3
4705
4706 (define_expand "addti3"
4707   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4708         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4709                  (match_operand:TI 2 "x86_64_general_operand" "")))
4710    (clobber (reg:CC FLAGS_REG))]
4711   "TARGET_64BIT"
4712   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4713
4714 (define_insn "*addti3_1"
4715   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4716         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4717                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4718    (clobber (reg:CC FLAGS_REG))]
4719   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4720   "#")
4721
4722 (define_split
4723   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4724         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4725                  (match_operand:TI 2 "general_operand" "")))
4726    (clobber (reg:CC FLAGS_REG))]
4727   "TARGET_64BIT && reload_completed"
4728   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4729                                           UNSPEC_ADD_CARRY))
4730               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4731    (parallel [(set (match_dup 3)
4732                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4733                                      (match_dup 4))
4734                             (match_dup 5)))
4735               (clobber (reg:CC FLAGS_REG))])]
4736   "split_ti (operands+0, 1, operands+0, operands+3);
4737    split_ti (operands+1, 1, operands+1, operands+4);
4738    split_ti (operands+2, 1, operands+2, operands+5);")
4739
4740 ;; %%% splits for addsidi3
4741 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4742 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4743 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4744
4745 (define_expand "adddi3"
4746   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4748                  (match_operand:DI 2 "x86_64_general_operand" "")))
4749    (clobber (reg:CC FLAGS_REG))]
4750   ""
4751   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4752
4753 (define_insn "*adddi3_1"
4754   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4755         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4756                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4757    (clobber (reg:CC FLAGS_REG))]
4758   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4759   "#")
4760
4761 (define_split
4762   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4763         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4764                  (match_operand:DI 2 "general_operand" "")))
4765    (clobber (reg:CC FLAGS_REG))]
4766   "!TARGET_64BIT && reload_completed"
4767   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4768                                           UNSPEC_ADD_CARRY))
4769               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4770    (parallel [(set (match_dup 3)
4771                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4772                                      (match_dup 4))
4773                             (match_dup 5)))
4774               (clobber (reg:CC FLAGS_REG))])]
4775   "split_di (operands+0, 1, operands+0, operands+3);
4776    split_di (operands+1, 1, operands+1, operands+4);
4777    split_di (operands+2, 1, operands+2, operands+5);")
4778
4779 (define_insn "adddi3_carry_rex64"
4780   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4781           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4782                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4783                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4784    (clobber (reg:CC FLAGS_REG))]
4785   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4786   "adc{q}\t{%2, %0|%0, %2}"
4787   [(set_attr "type" "alu")
4788    (set_attr "pent_pair" "pu")
4789    (set_attr "mode" "DI")])
4790
4791 (define_insn "*adddi3_cc_rex64"
4792   [(set (reg:CC FLAGS_REG)
4793         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4794                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4795                    UNSPEC_ADD_CARRY))
4796    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4797         (plus:DI (match_dup 1) (match_dup 2)))]
4798   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4799   "add{q}\t{%2, %0|%0, %2}"
4800   [(set_attr "type" "alu")
4801    (set_attr "mode" "DI")])
4802
4803 (define_insn "addqi3_carry"
4804   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4805           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4806                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4807                    (match_operand:QI 2 "general_operand" "qi,qm")))
4808    (clobber (reg:CC FLAGS_REG))]
4809   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4810   "adc{b}\t{%2, %0|%0, %2}"
4811   [(set_attr "type" "alu")
4812    (set_attr "pent_pair" "pu")
4813    (set_attr "mode" "QI")])
4814
4815 (define_insn "addhi3_carry"
4816   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4817           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4818                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4819                    (match_operand:HI 2 "general_operand" "ri,rm")))
4820    (clobber (reg:CC FLAGS_REG))]
4821   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4822   "adc{w}\t{%2, %0|%0, %2}"
4823   [(set_attr "type" "alu")
4824    (set_attr "pent_pair" "pu")
4825    (set_attr "mode" "HI")])
4826
4827 (define_insn "addsi3_carry"
4828   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4829           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4830                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4831                    (match_operand:SI 2 "general_operand" "ri,rm")))
4832    (clobber (reg:CC FLAGS_REG))]
4833   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4834   "adc{l}\t{%2, %0|%0, %2}"
4835   [(set_attr "type" "alu")
4836    (set_attr "pent_pair" "pu")
4837    (set_attr "mode" "SI")])
4838
4839 (define_insn "*addsi3_carry_zext"
4840   [(set (match_operand:DI 0 "register_operand" "=r")
4841           (zero_extend:DI 
4842             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4843                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4844                      (match_operand:SI 2 "general_operand" "rim"))))
4845    (clobber (reg:CC FLAGS_REG))]
4846   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4847   "adc{l}\t{%2, %k0|%k0, %2}"
4848   [(set_attr "type" "alu")
4849    (set_attr "pent_pair" "pu")
4850    (set_attr "mode" "SI")])
4851
4852 (define_insn "*addsi3_cc"
4853   [(set (reg:CC FLAGS_REG)
4854         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4855                     (match_operand:SI 2 "general_operand" "ri,rm")]
4856                    UNSPEC_ADD_CARRY))
4857    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4858         (plus:SI (match_dup 1) (match_dup 2)))]
4859   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4860   "add{l}\t{%2, %0|%0, %2}"
4861   [(set_attr "type" "alu")
4862    (set_attr "mode" "SI")])
4863
4864 (define_insn "addqi3_cc"
4865   [(set (reg:CC FLAGS_REG)
4866         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4867                     (match_operand:QI 2 "general_operand" "qi,qm")]
4868                    UNSPEC_ADD_CARRY))
4869    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4870         (plus:QI (match_dup 1) (match_dup 2)))]
4871   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4872   "add{b}\t{%2, %0|%0, %2}"
4873   [(set_attr "type" "alu")
4874    (set_attr "mode" "QI")])
4875
4876 (define_expand "addsi3"
4877   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4878                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4879                             (match_operand:SI 2 "general_operand" "")))
4880               (clobber (reg:CC FLAGS_REG))])]
4881   ""
4882   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4883
4884 (define_insn "*lea_1"
4885   [(set (match_operand:SI 0 "register_operand" "=r")
4886         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4887   "!TARGET_64BIT"
4888   "lea{l}\t{%a1, %0|%0, %a1}"
4889   [(set_attr "type" "lea")
4890    (set_attr "mode" "SI")])
4891
4892 (define_insn "*lea_1_rex64"
4893   [(set (match_operand:SI 0 "register_operand" "=r")
4894         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4895   "TARGET_64BIT"
4896   "lea{l}\t{%a1, %0|%0, %a1}"
4897   [(set_attr "type" "lea")
4898    (set_attr "mode" "SI")])
4899
4900 (define_insn "*lea_1_zext"
4901   [(set (match_operand:DI 0 "register_operand" "=r")
4902         (zero_extend:DI
4903          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4904   "TARGET_64BIT"
4905   "lea{l}\t{%a1, %k0|%k0, %a1}"
4906   [(set_attr "type" "lea")
4907    (set_attr "mode" "SI")])
4908
4909 (define_insn "*lea_2_rex64"
4910   [(set (match_operand:DI 0 "register_operand" "=r")
4911         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4912   "TARGET_64BIT"
4913   "lea{q}\t{%a1, %0|%0, %a1}"
4914   [(set_attr "type" "lea")
4915    (set_attr "mode" "DI")])
4916
4917 ;; The lea patterns for non-Pmodes needs to be matched by several
4918 ;; insns converted to real lea by splitters.
4919
4920 (define_insn_and_split "*lea_general_1"
4921   [(set (match_operand 0 "register_operand" "=r")
4922         (plus (plus (match_operand 1 "index_register_operand" "l")
4923                     (match_operand 2 "register_operand" "r"))
4924               (match_operand 3 "immediate_operand" "i")))]
4925   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4926     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4927    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4928    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4929    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4930    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4931        || GET_MODE (operands[3]) == VOIDmode)"
4932   "#"
4933   "&& reload_completed"
4934   [(const_int 0)]
4935 {
4936   rtx pat;
4937   operands[0] = gen_lowpart (SImode, operands[0]);
4938   operands[1] = gen_lowpart (Pmode, operands[1]);
4939   operands[2] = gen_lowpart (Pmode, operands[2]);
4940   operands[3] = gen_lowpart (Pmode, operands[3]);
4941   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4942                       operands[3]);
4943   if (Pmode != SImode)
4944     pat = gen_rtx_SUBREG (SImode, pat, 0);
4945   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4946   DONE;
4947 }
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "SI")])
4950
4951 (define_insn_and_split "*lea_general_1_zext"
4952   [(set (match_operand:DI 0 "register_operand" "=r")
4953         (zero_extend:DI
4954           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4955                             (match_operand:SI 2 "register_operand" "r"))
4956                    (match_operand:SI 3 "immediate_operand" "i"))))]
4957   "TARGET_64BIT"
4958   "#"
4959   "&& reload_completed"
4960   [(set (match_dup 0)
4961         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4962                                                      (match_dup 2))
4963                                             (match_dup 3)) 0)))]
4964 {
4965   operands[1] = gen_lowpart (Pmode, operands[1]);
4966   operands[2] = gen_lowpart (Pmode, operands[2]);
4967   operands[3] = gen_lowpart (Pmode, operands[3]);
4968 }
4969   [(set_attr "type" "lea")
4970    (set_attr "mode" "SI")])
4971
4972 (define_insn_and_split "*lea_general_2"
4973   [(set (match_operand 0 "register_operand" "=r")
4974         (plus (mult (match_operand 1 "index_register_operand" "l")
4975                     (match_operand 2 "const248_operand" "i"))
4976               (match_operand 3 "nonmemory_operand" "ri")))]
4977   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4978     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4979    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4980    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4981    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4982        || GET_MODE (operands[3]) == VOIDmode)"
4983   "#"
4984   "&& reload_completed"
4985   [(const_int 0)]
4986 {
4987   rtx pat;
4988   operands[0] = gen_lowpart (SImode, operands[0]);
4989   operands[1] = gen_lowpart (Pmode, operands[1]);
4990   operands[3] = gen_lowpart (Pmode, operands[3]);
4991   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4992                       operands[3]);
4993   if (Pmode != SImode)
4994     pat = gen_rtx_SUBREG (SImode, pat, 0);
4995   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4996   DONE;
4997 }
4998   [(set_attr "type" "lea")
4999    (set_attr "mode" "SI")])
5000
5001 (define_insn_and_split "*lea_general_2_zext"
5002   [(set (match_operand:DI 0 "register_operand" "=r")
5003         (zero_extend:DI
5004           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5005                             (match_operand:SI 2 "const248_operand" "n"))
5006                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5007   "TARGET_64BIT"
5008   "#"
5009   "&& reload_completed"
5010   [(set (match_dup 0)
5011         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5012                                                      (match_dup 2))
5013                                             (match_dup 3)) 0)))]
5014 {
5015   operands[1] = gen_lowpart (Pmode, operands[1]);
5016   operands[3] = gen_lowpart (Pmode, operands[3]);
5017 }
5018   [(set_attr "type" "lea")
5019    (set_attr "mode" "SI")])
5020
5021 (define_insn_and_split "*lea_general_3"
5022   [(set (match_operand 0 "register_operand" "=r")
5023         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5024                           (match_operand 2 "const248_operand" "i"))
5025                     (match_operand 3 "register_operand" "r"))
5026               (match_operand 4 "immediate_operand" "i")))]
5027   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5032   "#"
5033   "&& reload_completed"
5034   [(const_int 0)]
5035 {
5036   rtx pat;
5037   operands[0] = gen_lowpart (SImode, operands[0]);
5038   operands[1] = gen_lowpart (Pmode, operands[1]);
5039   operands[3] = gen_lowpart (Pmode, operands[3]);
5040   operands[4] = gen_lowpart (Pmode, operands[4]);
5041   pat = gen_rtx_PLUS (Pmode,
5042                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5043                                                          operands[2]),
5044                                     operands[3]),
5045                       operands[4]);
5046   if (Pmode != SImode)
5047     pat = gen_rtx_SUBREG (SImode, pat, 0);
5048   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5049   DONE;
5050 }
5051   [(set_attr "type" "lea")
5052    (set_attr "mode" "SI")])
5053
5054 (define_insn_and_split "*lea_general_3_zext"
5055   [(set (match_operand:DI 0 "register_operand" "=r")
5056         (zero_extend:DI
5057           (plus:SI (plus:SI (mult:SI
5058                               (match_operand:SI 1 "index_register_operand" "l")
5059                               (match_operand:SI 2 "const248_operand" "n"))
5060                             (match_operand:SI 3 "register_operand" "r"))
5061                    (match_operand:SI 4 "immediate_operand" "i"))))]
5062   "TARGET_64BIT"
5063   "#"
5064   "&& reload_completed"
5065   [(set (match_dup 0)
5066         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5067                                                               (match_dup 2))
5068                                                      (match_dup 3))
5069                                             (match_dup 4)) 0)))]
5070 {
5071   operands[1] = gen_lowpart (Pmode, operands[1]);
5072   operands[3] = gen_lowpart (Pmode, operands[3]);
5073   operands[4] = gen_lowpart (Pmode, operands[4]);
5074 }
5075   [(set_attr "type" "lea")
5076    (set_attr "mode" "SI")])
5077
5078 (define_insn "*adddi_1_rex64"
5079   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5080         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5081                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5082    (clobber (reg:CC FLAGS_REG))]
5083   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5084 {
5085   switch (get_attr_type (insn))
5086     {
5087     case TYPE_LEA:
5088       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5089       return "lea{q}\t{%a2, %0|%0, %a2}";
5090
5091     case TYPE_INCDEC:
5092       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5093       if (operands[2] == const1_rtx)
5094         return "inc{q}\t%0";
5095       else
5096         {
5097           gcc_assert (operands[2] == constm1_rtx);
5098           return "dec{q}\t%0";
5099         }
5100
5101     default:
5102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5103
5104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5106       if (GET_CODE (operands[2]) == CONST_INT
5107           /* Avoid overflows.  */
5108           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5109           && (INTVAL (operands[2]) == 128
5110               || (INTVAL (operands[2]) < 0
5111                   && INTVAL (operands[2]) != -128)))
5112         {
5113           operands[2] = GEN_INT (-INTVAL (operands[2]));
5114           return "sub{q}\t{%2, %0|%0, %2}";
5115         }
5116       return "add{q}\t{%2, %0|%0, %2}";
5117     }
5118 }
5119   [(set (attr "type")
5120      (cond [(eq_attr "alternative" "2")
5121               (const_string "lea")
5122             ; Current assemblers are broken and do not allow @GOTOFF in
5123             ; ought but a memory context.
5124             (match_operand:DI 2 "pic_symbolic_operand" "")
5125               (const_string "lea")
5126             (match_operand:DI 2 "incdec_operand" "")
5127               (const_string "incdec")
5128            ]
5129            (const_string "alu")))
5130    (set_attr "mode" "DI")])
5131
5132 ;; Convert lea to the lea pattern to avoid flags dependency.
5133 (define_split
5134   [(set (match_operand:DI 0 "register_operand" "")
5135         (plus:DI (match_operand:DI 1 "register_operand" "")
5136                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5137    (clobber (reg:CC FLAGS_REG))]
5138   "TARGET_64BIT && reload_completed
5139    && true_regnum (operands[0]) != true_regnum (operands[1])"
5140   [(set (match_dup 0)
5141         (plus:DI (match_dup 1)
5142                  (match_dup 2)))]
5143   "")
5144
5145 (define_insn "*adddi_2_rex64"
5146   [(set (reg FLAGS_REG)
5147         (compare
5148           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5149                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5150           (const_int 0)))                       
5151    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5152         (plus:DI (match_dup 1) (match_dup 2)))]
5153   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5154    && ix86_binary_operator_ok (PLUS, DImode, operands)
5155    /* Current assemblers are broken and do not allow @GOTOFF in
5156       ought but a memory context.  */
5157    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5158 {
5159   switch (get_attr_type (insn))
5160     {
5161     case TYPE_INCDEC:
5162       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5163       if (operands[2] == const1_rtx)
5164         return "inc{q}\t%0";
5165       else
5166         {
5167           gcc_assert (operands[2] == constm1_rtx);
5168           return "dec{q}\t%0";
5169         }
5170
5171     default:
5172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173       /* ???? We ought to handle there the 32bit case too
5174          - do we need new constraint?  */
5175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5177       if (GET_CODE (operands[2]) == CONST_INT
5178           /* Avoid overflows.  */
5179           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180           && (INTVAL (operands[2]) == 128
5181               || (INTVAL (operands[2]) < 0
5182                   && INTVAL (operands[2]) != -128)))
5183         {
5184           operands[2] = GEN_INT (-INTVAL (operands[2]));
5185           return "sub{q}\t{%2, %0|%0, %2}";
5186         }
5187       return "add{q}\t{%2, %0|%0, %2}";
5188     }
5189 }
5190   [(set (attr "type")
5191      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192         (const_string "incdec")
5193         (const_string "alu")))
5194    (set_attr "mode" "DI")])
5195
5196 (define_insn "*adddi_3_rex64"
5197   [(set (reg FLAGS_REG)
5198         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5199                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5200    (clobber (match_scratch:DI 0 "=r"))]
5201   "TARGET_64BIT
5202    && ix86_match_ccmode (insn, CCZmode)
5203    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5204    /* Current assemblers are broken and do not allow @GOTOFF in
5205       ought but a memory context.  */
5206    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5207 {
5208   switch (get_attr_type (insn))
5209     {
5210     case TYPE_INCDEC:
5211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5212       if (operands[2] == const1_rtx)
5213         return "inc{q}\t%0";
5214       else
5215         {
5216           gcc_assert (operands[2] == constm1_rtx);
5217           return "dec{q}\t%0";
5218         }
5219
5220     default:
5221       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222       /* ???? We ought to handle there the 32bit case too
5223          - do we need new constraint?  */
5224       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5225          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5226       if (GET_CODE (operands[2]) == CONST_INT
5227           /* Avoid overflows.  */
5228           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5229           && (INTVAL (operands[2]) == 128
5230               || (INTVAL (operands[2]) < 0
5231                   && INTVAL (operands[2]) != -128)))
5232         {
5233           operands[2] = GEN_INT (-INTVAL (operands[2]));
5234           return "sub{q}\t{%2, %0|%0, %2}";
5235         }
5236       return "add{q}\t{%2, %0|%0, %2}";
5237     }
5238 }
5239   [(set (attr "type")
5240      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5241         (const_string "incdec")
5242         (const_string "alu")))
5243    (set_attr "mode" "DI")])
5244
5245 ; For comparisons against 1, -1 and 128, we may generate better code
5246 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5247 ; is matched then.  We can't accept general immediate, because for
5248 ; case of overflows,  the result is messed up.
5249 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5250 ; when negated.
5251 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5252 ; only for comparisons not depending on it.
5253 (define_insn "*adddi_4_rex64"
5254   [(set (reg FLAGS_REG)
5255         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5256                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5257    (clobber (match_scratch:DI 0 "=rm"))]
5258   "TARGET_64BIT
5259    &&  ix86_match_ccmode (insn, CCGCmode)"
5260 {
5261   switch (get_attr_type (insn))
5262     {
5263     case TYPE_INCDEC:
5264       if (operands[2] == constm1_rtx)
5265         return "inc{q}\t%0";
5266       else
5267         {
5268           gcc_assert (operands[2] == const1_rtx);
5269           return "dec{q}\t%0";
5270         }
5271
5272     default:
5273       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5274       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5276       if ((INTVAL (operands[2]) == -128
5277            || (INTVAL (operands[2]) > 0
5278                && INTVAL (operands[2]) != 128))
5279           /* Avoid overflows.  */
5280           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5281         return "sub{q}\t{%2, %0|%0, %2}";
5282       operands[2] = GEN_INT (-INTVAL (operands[2]));
5283       return "add{q}\t{%2, %0|%0, %2}";
5284     }
5285 }
5286   [(set (attr "type")
5287      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5288         (const_string "incdec")
5289         (const_string "alu")))
5290    (set_attr "mode" "DI")])
5291
5292 (define_insn "*adddi_5_rex64"
5293   [(set (reg FLAGS_REG)
5294         (compare
5295           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5296                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5297           (const_int 0)))                       
5298    (clobber (match_scratch:DI 0 "=r"))]
5299   "TARGET_64BIT
5300    && ix86_match_ccmode (insn, CCGOCmode)
5301    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5302    /* Current assemblers are broken and do not allow @GOTOFF in
5303       ought but a memory context.  */
5304    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5305 {
5306   switch (get_attr_type (insn))
5307     {
5308     case TYPE_INCDEC:
5309       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5310       if (operands[2] == const1_rtx)
5311         return "inc{q}\t%0";
5312       else
5313         {
5314           gcc_assert (operands[2] == constm1_rtx);
5315           return "dec{q}\t%0";
5316         }
5317
5318     default:
5319       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5320       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5321          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5322       if (GET_CODE (operands[2]) == CONST_INT
5323           /* Avoid overflows.  */
5324           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5325           && (INTVAL (operands[2]) == 128
5326               || (INTVAL (operands[2]) < 0
5327                   && INTVAL (operands[2]) != -128)))
5328         {
5329           operands[2] = GEN_INT (-INTVAL (operands[2]));
5330           return "sub{q}\t{%2, %0|%0, %2}";
5331         }
5332       return "add{q}\t{%2, %0|%0, %2}";
5333     }
5334 }
5335   [(set (attr "type")
5336      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5337         (const_string "incdec")
5338         (const_string "alu")))
5339    (set_attr "mode" "DI")])
5340
5341
5342 (define_insn "*addsi_1"
5343   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5344         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5345                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5346    (clobber (reg:CC FLAGS_REG))]
5347   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5348 {
5349   switch (get_attr_type (insn))
5350     {
5351     case TYPE_LEA:
5352       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5353       return "lea{l}\t{%a2, %0|%0, %a2}";
5354
5355     case TYPE_INCDEC:
5356       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357       if (operands[2] == const1_rtx)
5358         return "inc{l}\t%0";
5359       else
5360         {
5361           gcc_assert (operands[2] == constm1_rtx);
5362           return "dec{l}\t%0";
5363         }
5364
5365     default:
5366       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5367
5368       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5369          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5370       if (GET_CODE (operands[2]) == CONST_INT
5371           && (INTVAL (operands[2]) == 128
5372               || (INTVAL (operands[2]) < 0
5373                   && INTVAL (operands[2]) != -128)))
5374         {
5375           operands[2] = GEN_INT (-INTVAL (operands[2]));
5376           return "sub{l}\t{%2, %0|%0, %2}";
5377         }
5378       return "add{l}\t{%2, %0|%0, %2}";
5379     }
5380 }
5381   [(set (attr "type")
5382      (cond [(eq_attr "alternative" "2")
5383               (const_string "lea")
5384             ; Current assemblers are broken and do not allow @GOTOFF in
5385             ; ought but a memory context.
5386             (match_operand:SI 2 "pic_symbolic_operand" "")
5387               (const_string "lea")
5388             (match_operand:SI 2 "incdec_operand" "")
5389               (const_string "incdec")
5390            ]
5391            (const_string "alu")))
5392    (set_attr "mode" "SI")])
5393
5394 ;; Convert lea to the lea pattern to avoid flags dependency.
5395 (define_split
5396   [(set (match_operand 0 "register_operand" "")
5397         (plus (match_operand 1 "register_operand" "")
5398               (match_operand 2 "nonmemory_operand" "")))
5399    (clobber (reg:CC FLAGS_REG))]
5400   "reload_completed
5401    && true_regnum (operands[0]) != true_regnum (operands[1])"
5402   [(const_int 0)]
5403 {
5404   rtx pat;
5405   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5406      may confuse gen_lowpart.  */
5407   if (GET_MODE (operands[0]) != Pmode)
5408     {
5409       operands[1] = gen_lowpart (Pmode, operands[1]);
5410       operands[2] = gen_lowpart (Pmode, operands[2]);
5411     }
5412   operands[0] = gen_lowpart (SImode, operands[0]);
5413   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5414   if (Pmode != SImode)
5415     pat = gen_rtx_SUBREG (SImode, pat, 0);
5416   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5417   DONE;
5418 })
5419
5420 ;; It may seem that nonimmediate operand is proper one for operand 1.
5421 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5422 ;; we take care in ix86_binary_operator_ok to not allow two memory
5423 ;; operands so proper swapping will be done in reload.  This allow
5424 ;; patterns constructed from addsi_1 to match.
5425 (define_insn "addsi_1_zext"
5426   [(set (match_operand:DI 0 "register_operand" "=r,r")
5427         (zero_extend:DI
5428           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5429                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5430    (clobber (reg:CC FLAGS_REG))]
5431   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5432 {
5433   switch (get_attr_type (insn))
5434     {
5435     case TYPE_LEA:
5436       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5438
5439     case TYPE_INCDEC:
5440       if (operands[2] == const1_rtx)
5441         return "inc{l}\t%k0";
5442       else
5443         {
5444           gcc_assert (operands[2] == constm1_rtx);
5445           return "dec{l}\t%k0";
5446         }
5447
5448     default:
5449       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5450          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5451       if (GET_CODE (operands[2]) == CONST_INT
5452           && (INTVAL (operands[2]) == 128
5453               || (INTVAL (operands[2]) < 0
5454                   && INTVAL (operands[2]) != -128)))
5455         {
5456           operands[2] = GEN_INT (-INTVAL (operands[2]));
5457           return "sub{l}\t{%2, %k0|%k0, %2}";
5458         }
5459       return "add{l}\t{%2, %k0|%k0, %2}";
5460     }
5461 }
5462   [(set (attr "type")
5463      (cond [(eq_attr "alternative" "1")
5464               (const_string "lea")
5465             ; Current assemblers are broken and do not allow @GOTOFF in
5466             ; ought but a memory context.
5467             (match_operand:SI 2 "pic_symbolic_operand" "")
5468               (const_string "lea")
5469             (match_operand:SI 2 "incdec_operand" "")
5470               (const_string "incdec")
5471            ]
5472            (const_string "alu")))
5473    (set_attr "mode" "SI")])
5474
5475 ;; Convert lea to the lea pattern to avoid flags dependency.
5476 (define_split
5477   [(set (match_operand:DI 0 "register_operand" "")
5478         (zero_extend:DI
5479           (plus:SI (match_operand:SI 1 "register_operand" "")
5480                    (match_operand:SI 2 "nonmemory_operand" ""))))
5481    (clobber (reg:CC FLAGS_REG))]
5482   "TARGET_64BIT && reload_completed
5483    && true_regnum (operands[0]) != true_regnum (operands[1])"
5484   [(set (match_dup 0)
5485         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5486 {
5487   operands[1] = gen_lowpart (Pmode, operands[1]);
5488   operands[2] = gen_lowpart (Pmode, operands[2]);
5489 })
5490
5491 (define_insn "*addsi_2"
5492   [(set (reg FLAGS_REG)
5493         (compare
5494           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5495                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5496           (const_int 0)))                       
5497    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5498         (plus:SI (match_dup 1) (match_dup 2)))]
5499   "ix86_match_ccmode (insn, CCGOCmode)
5500    && ix86_binary_operator_ok (PLUS, SImode, operands)
5501    /* Current assemblers are broken and do not allow @GOTOFF in
5502       ought but a memory context.  */
5503    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5504 {
5505   switch (get_attr_type (insn))
5506     {
5507     case TYPE_INCDEC:
5508       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5509       if (operands[2] == const1_rtx)
5510         return "inc{l}\t%0";
5511       else
5512         {
5513           gcc_assert (operands[2] == constm1_rtx);
5514           return "dec{l}\t%0";
5515         }
5516
5517     default:
5518       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5520          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5521       if (GET_CODE (operands[2]) == CONST_INT
5522           && (INTVAL (operands[2]) == 128
5523               || (INTVAL (operands[2]) < 0
5524                   && INTVAL (operands[2]) != -128)))
5525         {
5526           operands[2] = GEN_INT (-INTVAL (operands[2]));
5527           return "sub{l}\t{%2, %0|%0, %2}";
5528         }
5529       return "add{l}\t{%2, %0|%0, %2}";
5530     }
5531 }
5532   [(set (attr "type")
5533      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5534         (const_string "incdec")
5535         (const_string "alu")))
5536    (set_attr "mode" "SI")])
5537
5538 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5539 (define_insn "*addsi_2_zext"
5540   [(set (reg FLAGS_REG)
5541         (compare
5542           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5543                    (match_operand:SI 2 "general_operand" "rmni"))
5544           (const_int 0)))                       
5545    (set (match_operand:DI 0 "register_operand" "=r")
5546         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5547   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5548    && ix86_binary_operator_ok (PLUS, SImode, operands)
5549    /* Current assemblers are broken and do not allow @GOTOFF in
5550       ought but a memory context.  */
5551    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5552 {
5553   switch (get_attr_type (insn))
5554     {
5555     case TYPE_INCDEC:
5556       if (operands[2] == const1_rtx)
5557         return "inc{l}\t%k0";
5558       else
5559         {
5560           gcc_assert (operands[2] == constm1_rtx);
5561           return "dec{l}\t%k0";
5562         }
5563
5564     default:
5565       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5566          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5567       if (GET_CODE (operands[2]) == CONST_INT
5568           && (INTVAL (operands[2]) == 128
5569               || (INTVAL (operands[2]) < 0
5570                   && INTVAL (operands[2]) != -128)))
5571         {
5572           operands[2] = GEN_INT (-INTVAL (operands[2]));
5573           return "sub{l}\t{%2, %k0|%k0, %2}";
5574         }
5575       return "add{l}\t{%2, %k0|%k0, %2}";
5576     }
5577 }
5578   [(set (attr "type")
5579      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5580         (const_string "incdec")
5581         (const_string "alu")))
5582    (set_attr "mode" "SI")])
5583
5584 (define_insn "*addsi_3"
5585   [(set (reg FLAGS_REG)
5586         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5587                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5588    (clobber (match_scratch:SI 0 "=r"))]
5589   "ix86_match_ccmode (insn, CCZmode)
5590    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 {
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%0";
5601       else
5602         {
5603           gcc_assert (operands[2] == constm1_rtx);
5604           return "dec{l}\t%0";
5605         }
5606
5607     default:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5611       if (GET_CODE (operands[2]) == CONST_INT
5612           && (INTVAL (operands[2]) == 128
5613               || (INTVAL (operands[2]) < 0
5614                   && INTVAL (operands[2]) != -128)))
5615         {
5616           operands[2] = GEN_INT (-INTVAL (operands[2]));
5617           return "sub{l}\t{%2, %0|%0, %2}";
5618         }
5619       return "add{l}\t{%2, %0|%0, %2}";
5620     }
5621 }
5622   [(set (attr "type")
5623      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624         (const_string "incdec")
5625         (const_string "alu")))
5626    (set_attr "mode" "SI")])
5627
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_3_zext"
5630   [(set (reg FLAGS_REG)
5631         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5632                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5633    (set (match_operand:DI 0 "register_operand" "=r")
5634         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5635   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5636    && ix86_binary_operator_ok (PLUS, SImode, operands)
5637    /* Current assemblers are broken and do not allow @GOTOFF in
5638       ought but a memory context.  */
5639    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5640 {
5641   switch (get_attr_type (insn))
5642     {
5643     case TYPE_INCDEC:
5644       if (operands[2] == const1_rtx)
5645         return "inc{l}\t%k0";
5646       else
5647         {
5648           gcc_assert (operands[2] == constm1_rtx);
5649           return "dec{l}\t%k0";
5650         }
5651
5652     default:
5653       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5654          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5655       if (GET_CODE (operands[2]) == CONST_INT
5656           && (INTVAL (operands[2]) == 128
5657               || (INTVAL (operands[2]) < 0
5658                   && INTVAL (operands[2]) != -128)))
5659         {
5660           operands[2] = GEN_INT (-INTVAL (operands[2]));
5661           return "sub{l}\t{%2, %k0|%k0, %2}";
5662         }
5663       return "add{l}\t{%2, %k0|%k0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5668         (const_string "incdec")
5669         (const_string "alu")))
5670    (set_attr "mode" "SI")])
5671
5672 ; For comparisons against 1, -1 and 128, we may generate better code
5673 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5674 ; is matched then.  We can't accept general immediate, because for
5675 ; case of overflows,  the result is messed up.
5676 ; This pattern also don't hold of 0x80000000, since the value overflows
5677 ; when negated.
5678 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5679 ; only for comparisons not depending on it.
5680 (define_insn "*addsi_4"
5681   [(set (reg FLAGS_REG)
5682         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5683                  (match_operand:SI 2 "const_int_operand" "n")))
5684    (clobber (match_scratch:SI 0 "=rm"))]
5685   "ix86_match_ccmode (insn, CCGCmode)
5686    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5687 {
5688   switch (get_attr_type (insn))
5689     {
5690     case TYPE_INCDEC:
5691       if (operands[2] == constm1_rtx)
5692         return "inc{l}\t%0";
5693       else
5694         {
5695           gcc_assert (operands[2] == const1_rtx);
5696           return "dec{l}\t%0";
5697         }
5698
5699     default:
5700       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5702          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5703       if ((INTVAL (operands[2]) == -128
5704            || (INTVAL (operands[2]) > 0
5705                && INTVAL (operands[2]) != 128)))
5706         return "sub{l}\t{%2, %0|%0, %2}";
5707       operands[2] = GEN_INT (-INTVAL (operands[2]));
5708       return "add{l}\t{%2, %0|%0, %2}";
5709     }
5710 }
5711   [(set (attr "type")
5712      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713         (const_string "incdec")
5714         (const_string "alu")))
5715    (set_attr "mode" "SI")])
5716
5717 (define_insn "*addsi_5"
5718   [(set (reg FLAGS_REG)
5719         (compare
5720           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5721                    (match_operand:SI 2 "general_operand" "rmni"))
5722           (const_int 0)))                       
5723    (clobber (match_scratch:SI 0 "=r"))]
5724   "ix86_match_ccmode (insn, CCGOCmode)
5725    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5726    /* Current assemblers are broken and do not allow @GOTOFF in
5727       ought but a memory context.  */
5728    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5729 {
5730   switch (get_attr_type (insn))
5731     {
5732     case TYPE_INCDEC:
5733       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734       if (operands[2] == const1_rtx)
5735         return "inc{l}\t%0";
5736       else
5737         {
5738           gcc_assert (operands[2] == constm1_rtx);
5739           return "dec{l}\t%0";
5740         }
5741
5742     default:
5743       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5746       if (GET_CODE (operands[2]) == CONST_INT
5747           && (INTVAL (operands[2]) == 128
5748               || (INTVAL (operands[2]) < 0
5749                   && INTVAL (operands[2]) != -128)))
5750         {
5751           operands[2] = GEN_INT (-INTVAL (operands[2]));
5752           return "sub{l}\t{%2, %0|%0, %2}";
5753         }
5754       return "add{l}\t{%2, %0|%0, %2}";
5755     }
5756 }
5757   [(set (attr "type")
5758      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5759         (const_string "incdec")
5760         (const_string "alu")))
5761    (set_attr "mode" "SI")])
5762
5763 (define_expand "addhi3"
5764   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5765                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5766                             (match_operand:HI 2 "general_operand" "")))
5767               (clobber (reg:CC FLAGS_REG))])]
5768   "TARGET_HIMODE_MATH"
5769   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5770
5771 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5772 ;; type optimizations enabled by define-splits.  This is not important
5773 ;; for PII, and in fact harmful because of partial register stalls.
5774
5775 (define_insn "*addhi_1_lea"
5776   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5777         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5778                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5779    (clobber (reg:CC FLAGS_REG))]
5780   "!TARGET_PARTIAL_REG_STALL
5781    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 {
5783   switch (get_attr_type (insn))
5784     {
5785     case TYPE_LEA:
5786       return "#";
5787     case TYPE_INCDEC:
5788       if (operands[2] == const1_rtx)
5789         return "inc{w}\t%0";
5790       else
5791         {
5792           gcc_assert (operands[2] == constm1_rtx);
5793           return "dec{w}\t%0";
5794         }
5795
5796     default:
5797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5799       if (GET_CODE (operands[2]) == CONST_INT
5800           && (INTVAL (operands[2]) == 128
5801               || (INTVAL (operands[2]) < 0
5802                   && INTVAL (operands[2]) != -128)))
5803         {
5804           operands[2] = GEN_INT (-INTVAL (operands[2]));
5805           return "sub{w}\t{%2, %0|%0, %2}";
5806         }
5807       return "add{w}\t{%2, %0|%0, %2}";
5808     }
5809 }
5810   [(set (attr "type")
5811      (if_then_else (eq_attr "alternative" "2")
5812         (const_string "lea")
5813         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5814            (const_string "incdec")
5815            (const_string "alu"))))
5816    (set_attr "mode" "HI,HI,SI")])
5817
5818 (define_insn "*addhi_1"
5819   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5820         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5821                  (match_operand:HI 2 "general_operand" "ri,rm")))
5822    (clobber (reg:CC FLAGS_REG))]
5823   "TARGET_PARTIAL_REG_STALL
5824    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5825 {
5826   switch (get_attr_type (insn))
5827     {
5828     case TYPE_INCDEC:
5829       if (operands[2] == const1_rtx)
5830         return "inc{w}\t%0";
5831       else
5832         {
5833           gcc_assert (operands[2] == constm1_rtx);
5834           return "dec{w}\t%0";
5835         }
5836
5837     default:
5838       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5840       if (GET_CODE (operands[2]) == CONST_INT
5841           && (INTVAL (operands[2]) == 128
5842               || (INTVAL (operands[2]) < 0
5843                   && INTVAL (operands[2]) != -128)))
5844         {
5845           operands[2] = GEN_INT (-INTVAL (operands[2]));
5846           return "sub{w}\t{%2, %0|%0, %2}";
5847         }
5848       return "add{w}\t{%2, %0|%0, %2}";
5849     }
5850 }
5851   [(set (attr "type")
5852      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5853         (const_string "incdec")
5854         (const_string "alu")))
5855    (set_attr "mode" "HI")])
5856
5857 (define_insn "*addhi_2"
5858   [(set (reg FLAGS_REG)
5859         (compare
5860           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5861                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5862           (const_int 0)))                       
5863    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5864         (plus:HI (match_dup 1) (match_dup 2)))]
5865   "ix86_match_ccmode (insn, CCGOCmode)
5866    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5867 {
5868   switch (get_attr_type (insn))
5869     {
5870     case TYPE_INCDEC:
5871       if (operands[2] == const1_rtx)
5872         return "inc{w}\t%0";
5873       else
5874         {
5875           gcc_assert (operands[2] == constm1_rtx);
5876           return "dec{w}\t%0";
5877         }
5878
5879     default:
5880       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5882       if (GET_CODE (operands[2]) == CONST_INT
5883           && (INTVAL (operands[2]) == 128
5884               || (INTVAL (operands[2]) < 0
5885                   && INTVAL (operands[2]) != -128)))
5886         {
5887           operands[2] = GEN_INT (-INTVAL (operands[2]));
5888           return "sub{w}\t{%2, %0|%0, %2}";
5889         }
5890       return "add{w}\t{%2, %0|%0, %2}";
5891     }
5892 }
5893   [(set (attr "type")
5894      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5895         (const_string "incdec")
5896         (const_string "alu")))
5897    (set_attr "mode" "HI")])
5898
5899 (define_insn "*addhi_3"
5900   [(set (reg FLAGS_REG)
5901         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5902                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5903    (clobber (match_scratch:HI 0 "=r"))]
5904   "ix86_match_ccmode (insn, CCZmode)
5905    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5906 {
5907   switch (get_attr_type (insn))
5908     {
5909     case TYPE_INCDEC:
5910       if (operands[2] == const1_rtx)
5911         return "inc{w}\t%0";
5912       else
5913         {
5914           gcc_assert (operands[2] == constm1_rtx);
5915           return "dec{w}\t%0";
5916         }
5917
5918     default:
5919       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5920          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5921       if (GET_CODE (operands[2]) == CONST_INT
5922           && (INTVAL (operands[2]) == 128
5923               || (INTVAL (operands[2]) < 0
5924                   && INTVAL (operands[2]) != -128)))
5925         {
5926           operands[2] = GEN_INT (-INTVAL (operands[2]));
5927           return "sub{w}\t{%2, %0|%0, %2}";
5928         }
5929       return "add{w}\t{%2, %0|%0, %2}";
5930     }
5931 }
5932   [(set (attr "type")
5933      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5934         (const_string "incdec")
5935         (const_string "alu")))
5936    (set_attr "mode" "HI")])
5937
5938 ; See comments above addsi_4 for details.
5939 (define_insn "*addhi_4"
5940   [(set (reg FLAGS_REG)
5941         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5942                  (match_operand:HI 2 "const_int_operand" "n")))
5943    (clobber (match_scratch:HI 0 "=rm"))]
5944   "ix86_match_ccmode (insn, CCGCmode)
5945    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5946 {
5947   switch (get_attr_type (insn))
5948     {
5949     case TYPE_INCDEC:
5950       if (operands[2] == constm1_rtx)
5951         return "inc{w}\t%0";
5952       else
5953         {
5954           gcc_assert (operands[2] == const1_rtx);
5955           return "dec{w}\t%0";
5956         }
5957
5958     default:
5959       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5962       if ((INTVAL (operands[2]) == -128
5963            || (INTVAL (operands[2]) > 0
5964                && INTVAL (operands[2]) != 128)))
5965         return "sub{w}\t{%2, %0|%0, %2}";
5966       operands[2] = GEN_INT (-INTVAL (operands[2]));
5967       return "add{w}\t{%2, %0|%0, %2}";
5968     }
5969 }
5970   [(set (attr "type")
5971      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5972         (const_string "incdec")
5973         (const_string "alu")))
5974    (set_attr "mode" "SI")])
5975
5976
5977 (define_insn "*addhi_5"
5978   [(set (reg FLAGS_REG)
5979         (compare
5980           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5981                    (match_operand:HI 2 "general_operand" "rmni"))
5982           (const_int 0)))                       
5983    (clobber (match_scratch:HI 0 "=r"))]
5984   "ix86_match_ccmode (insn, CCGOCmode)
5985    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5986 {
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_INCDEC:
5990       if (operands[2] == const1_rtx)
5991         return "inc{w}\t%0";
5992       else
5993         {
5994           gcc_assert (operands[2] == constm1_rtx);
5995           return "dec{w}\t%0";
5996         }
5997
5998     default:
5999       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6000          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6001       if (GET_CODE (operands[2]) == CONST_INT
6002           && (INTVAL (operands[2]) == 128
6003               || (INTVAL (operands[2]) < 0
6004                   && INTVAL (operands[2]) != -128)))
6005         {
6006           operands[2] = GEN_INT (-INTVAL (operands[2]));
6007           return "sub{w}\t{%2, %0|%0, %2}";
6008         }
6009       return "add{w}\t{%2, %0|%0, %2}";
6010     }
6011 }
6012   [(set (attr "type")
6013      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6014         (const_string "incdec")
6015         (const_string "alu")))
6016    (set_attr "mode" "HI")])
6017
6018 (define_expand "addqi3"
6019   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6020                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6021                             (match_operand:QI 2 "general_operand" "")))
6022               (clobber (reg:CC FLAGS_REG))])]
6023   "TARGET_QIMODE_MATH"
6024   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6025
6026 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6027 (define_insn "*addqi_1_lea"
6028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6029         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6030                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "!TARGET_PARTIAL_REG_STALL
6033    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6034 {
6035   int widen = (which_alternative == 2);
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_LEA:
6039       return "#";
6040     case TYPE_INCDEC:
6041       if (operands[2] == const1_rtx)
6042         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6043       else
6044         {
6045           gcc_assert (operands[2] == constm1_rtx);
6046           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6047         }
6048
6049     default:
6050       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6052       if (GET_CODE (operands[2]) == CONST_INT
6053           && (INTVAL (operands[2]) == 128
6054               || (INTVAL (operands[2]) < 0
6055                   && INTVAL (operands[2]) != -128)))
6056         {
6057           operands[2] = GEN_INT (-INTVAL (operands[2]));
6058           if (widen)
6059             return "sub{l}\t{%2, %k0|%k0, %2}";
6060           else
6061             return "sub{b}\t{%2, %0|%0, %2}";
6062         }
6063       if (widen)
6064         return "add{l}\t{%k2, %k0|%k0, %k2}";
6065       else
6066         return "add{b}\t{%2, %0|%0, %2}";
6067     }
6068 }
6069   [(set (attr "type")
6070      (if_then_else (eq_attr "alternative" "3")
6071         (const_string "lea")
6072         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6073            (const_string "incdec")
6074            (const_string "alu"))))
6075    (set_attr "mode" "QI,QI,SI,SI")])
6076
6077 (define_insn "*addqi_1"
6078   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6079         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6080                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6081    (clobber (reg:CC FLAGS_REG))]
6082   "TARGET_PARTIAL_REG_STALL
6083    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6084 {
6085   int widen = (which_alternative == 2);
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_INCDEC:
6089       if (operands[2] == const1_rtx)
6090         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6091       else
6092         {
6093           gcc_assert (operands[2] == constm1_rtx);
6094           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6095         }
6096
6097     default:
6098       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6099          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6100       if (GET_CODE (operands[2]) == CONST_INT
6101           && (INTVAL (operands[2]) == 128
6102               || (INTVAL (operands[2]) < 0
6103                   && INTVAL (operands[2]) != -128)))
6104         {
6105           operands[2] = GEN_INT (-INTVAL (operands[2]));
6106           if (widen)
6107             return "sub{l}\t{%2, %k0|%k0, %2}";
6108           else
6109             return "sub{b}\t{%2, %0|%0, %2}";
6110         }
6111       if (widen)
6112         return "add{l}\t{%k2, %k0|%k0, %k2}";
6113       else
6114         return "add{b}\t{%2, %0|%0, %2}";
6115     }
6116 }
6117   [(set (attr "type")
6118      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6119         (const_string "incdec")
6120         (const_string "alu")))
6121    (set_attr "mode" "QI,QI,SI")])
6122
6123 (define_insn "*addqi_1_slp"
6124   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6125         (plus:QI (match_dup 0)
6126                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6129    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_INCDEC:
6134       if (operands[1] == const1_rtx)
6135         return "inc{b}\t%0";
6136       else
6137         {
6138           gcc_assert (operands[1] == constm1_rtx);
6139           return "dec{b}\t%0";
6140         }
6141
6142     default:
6143       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6144       if (GET_CODE (operands[1]) == CONST_INT
6145           && INTVAL (operands[1]) < 0)
6146         {
6147           operands[1] = GEN_INT (-INTVAL (operands[1]));
6148           return "sub{b}\t{%1, %0|%0, %1}";
6149         }
6150       return "add{b}\t{%1, %0|%0, %1}";
6151     }
6152 }
6153   [(set (attr "type")
6154      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6155         (const_string "incdec")
6156         (const_string "alu1")))
6157    (set (attr "memory")
6158      (if_then_else (match_operand 1 "memory_operand" "")
6159         (const_string "load")
6160         (const_string "none")))
6161    (set_attr "mode" "QI")])
6162
6163 (define_insn "*addqi_2"
6164   [(set (reg FLAGS_REG)
6165         (compare
6166           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6167                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6168           (const_int 0)))
6169    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6170         (plus:QI (match_dup 1) (match_dup 2)))]
6171   "ix86_match_ccmode (insn, CCGOCmode)
6172    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6173 {
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return "inc{b}\t%0";
6179       else
6180         {
6181           gcc_assert (operands[2] == constm1_rtx
6182                       || (GET_CODE (operands[2]) == CONST_INT
6183                           && INTVAL (operands[2]) == 255));
6184           return "dec{b}\t%0";
6185         }
6186
6187     default:
6188       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6189       if (GET_CODE (operands[2]) == CONST_INT
6190           && INTVAL (operands[2]) < 0)
6191         {
6192           operands[2] = GEN_INT (-INTVAL (operands[2]));
6193           return "sub{b}\t{%2, %0|%0, %2}";
6194         }
6195       return "add{b}\t{%2, %0|%0, %2}";
6196     }
6197 }
6198   [(set (attr "type")
6199      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6200         (const_string "incdec")
6201         (const_string "alu")))
6202    (set_attr "mode" "QI")])
6203
6204 (define_insn "*addqi_3"
6205   [(set (reg FLAGS_REG)
6206         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6207                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6208    (clobber (match_scratch:QI 0 "=q"))]
6209   "ix86_match_ccmode (insn, CCZmode)
6210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6211 {
6212   switch (get_attr_type (insn))
6213     {
6214     case TYPE_INCDEC:
6215       if (operands[2] == const1_rtx)
6216         return "inc{b}\t%0";
6217       else
6218         {
6219           gcc_assert (operands[2] == constm1_rtx
6220                       || (GET_CODE (operands[2]) == CONST_INT
6221                           && INTVAL (operands[2]) == 255));
6222           return "dec{b}\t%0";
6223         }
6224
6225     default:
6226       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6227       if (GET_CODE (operands[2]) == CONST_INT
6228           && INTVAL (operands[2]) < 0)
6229         {
6230           operands[2] = GEN_INT (-INTVAL (operands[2]));
6231           return "sub{b}\t{%2, %0|%0, %2}";
6232         }
6233       return "add{b}\t{%2, %0|%0, %2}";
6234     }
6235 }
6236   [(set (attr "type")
6237      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6238         (const_string "incdec")
6239         (const_string "alu")))
6240    (set_attr "mode" "QI")])
6241
6242 ; See comments above addsi_4 for details.
6243 (define_insn "*addqi_4"
6244   [(set (reg FLAGS_REG)
6245         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6246                  (match_operand:QI 2 "const_int_operand" "n")))
6247    (clobber (match_scratch:QI 0 "=qm"))]
6248   "ix86_match_ccmode (insn, CCGCmode)
6249    && (INTVAL (operands[2]) & 0xff) != 0x80"
6250 {
6251   switch (get_attr_type (insn))
6252     {
6253     case TYPE_INCDEC:
6254       if (operands[2] == constm1_rtx
6255           || (GET_CODE (operands[2]) == CONST_INT
6256               && INTVAL (operands[2]) == 255))
6257         return "inc{b}\t%0";
6258       else
6259         {
6260           gcc_assert (operands[2] == const1_rtx);
6261           return "dec{b}\t%0";
6262         }
6263
6264     default:
6265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6266       if (INTVAL (operands[2]) < 0)
6267         {
6268           operands[2] = GEN_INT (-INTVAL (operands[2]));
6269           return "add{b}\t{%2, %0|%0, %2}";
6270         }
6271       return "sub{b}\t{%2, %0|%0, %2}";
6272     }
6273 }
6274   [(set (attr "type")
6275      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6276         (const_string "incdec")
6277         (const_string "alu")))
6278    (set_attr "mode" "QI")])
6279
6280
6281 (define_insn "*addqi_5"
6282   [(set (reg FLAGS_REG)
6283         (compare
6284           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6285                    (match_operand:QI 2 "general_operand" "qmni"))
6286           (const_int 0)))
6287    (clobber (match_scratch:QI 0 "=q"))]
6288   "ix86_match_ccmode (insn, CCGOCmode)
6289    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6290 {
6291   switch (get_attr_type (insn))
6292     {
6293     case TYPE_INCDEC:
6294       if (operands[2] == const1_rtx)
6295         return "inc{b}\t%0";
6296       else
6297         {
6298           gcc_assert (operands[2] == constm1_rtx
6299                       || (GET_CODE (operands[2]) == CONST_INT
6300                           && INTVAL (operands[2]) == 255));
6301           return "dec{b}\t%0";
6302         }
6303
6304     default:
6305       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6306       if (GET_CODE (operands[2]) == CONST_INT
6307           && INTVAL (operands[2]) < 0)
6308         {
6309           operands[2] = GEN_INT (-INTVAL (operands[2]));
6310           return "sub{b}\t{%2, %0|%0, %2}";
6311         }
6312       return "add{b}\t{%2, %0|%0, %2}";
6313     }
6314 }
6315   [(set (attr "type")
6316      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6317         (const_string "incdec")
6318         (const_string "alu")))
6319    (set_attr "mode" "QI")])
6320
6321
6322 (define_insn "addqi_ext_1"
6323   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6324                          (const_int 8)
6325                          (const_int 8))
6326         (plus:SI
6327           (zero_extract:SI
6328             (match_operand 1 "ext_register_operand" "0")
6329             (const_int 8)
6330             (const_int 8))
6331           (match_operand:QI 2 "general_operand" "Qmn")))
6332    (clobber (reg:CC FLAGS_REG))]
6333   "!TARGET_64BIT"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{b}\t%h0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx
6343                       || (GET_CODE (operands[2]) == CONST_INT
6344                           && INTVAL (operands[2]) == 255));
6345           return "dec{b}\t%h0";
6346         }
6347
6348     default:
6349       return "add{b}\t{%2, %h0|%h0, %2}";
6350     }
6351 }
6352   [(set (attr "type")
6353      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6354         (const_string "incdec")
6355         (const_string "alu")))
6356    (set_attr "mode" "QI")])
6357
6358 (define_insn "*addqi_ext_1_rex64"
6359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6360                          (const_int 8)
6361                          (const_int 8))
6362         (plus:SI
6363           (zero_extract:SI
6364             (match_operand 1 "ext_register_operand" "0")
6365             (const_int 8)
6366             (const_int 8))
6367           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6368    (clobber (reg:CC FLAGS_REG))]
6369   "TARGET_64BIT"
6370 {
6371   switch (get_attr_type (insn))
6372     {
6373     case TYPE_INCDEC:
6374       if (operands[2] == const1_rtx)
6375         return "inc{b}\t%h0";
6376       else
6377         {
6378           gcc_assert (operands[2] == constm1_rtx
6379                       || (GET_CODE (operands[2]) == CONST_INT
6380                           && INTVAL (operands[2]) == 255));
6381           return "dec{b}\t%h0";
6382         }
6383
6384     default:
6385       return "add{b}\t{%2, %h0|%h0, %2}";
6386     }
6387 }
6388   [(set (attr "type")
6389      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390         (const_string "incdec")
6391         (const_string "alu")))
6392    (set_attr "mode" "QI")])
6393
6394 (define_insn "*addqi_ext_2"
6395   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6396                          (const_int 8)
6397                          (const_int 8))
6398         (plus:SI
6399           (zero_extract:SI
6400             (match_operand 1 "ext_register_operand" "%0")
6401             (const_int 8)
6402             (const_int 8))
6403           (zero_extract:SI
6404             (match_operand 2 "ext_register_operand" "Q")
6405             (const_int 8)
6406             (const_int 8))))
6407    (clobber (reg:CC FLAGS_REG))]
6408   ""
6409   "add{b}\t{%h2, %h0|%h0, %h2}"
6410   [(set_attr "type" "alu")
6411    (set_attr "mode" "QI")])
6412
6413 ;; The patterns that match these are at the end of this file.
6414
6415 (define_expand "addxf3"
6416   [(set (match_operand:XF 0 "register_operand" "")
6417         (plus:XF (match_operand:XF 1 "register_operand" "")
6418                  (match_operand:XF 2 "register_operand" "")))]
6419   "TARGET_80387"
6420   "")
6421
6422 (define_expand "adddf3"
6423   [(set (match_operand:DF 0 "register_operand" "")
6424         (plus:DF (match_operand:DF 1 "register_operand" "")
6425                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6426   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6427   "")
6428
6429 (define_expand "addsf3"
6430   [(set (match_operand:SF 0 "register_operand" "")
6431         (plus:SF (match_operand:SF 1 "register_operand" "")
6432                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6433   "TARGET_80387 || TARGET_SSE_MATH"
6434   "")
6435 \f
6436 ;; Subtract instructions
6437
6438 ;; %%% splits for subditi3
6439
6440 (define_expand "subti3"
6441   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6442                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6443                              (match_operand:TI 2 "x86_64_general_operand" "")))
6444               (clobber (reg:CC FLAGS_REG))])]
6445   "TARGET_64BIT"
6446   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6447
6448 (define_insn "*subti3_1"
6449   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6450         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6451                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6452    (clobber (reg:CC FLAGS_REG))]
6453   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6454   "#")
6455
6456 (define_split
6457   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6458         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6459                   (match_operand:TI 2 "general_operand" "")))
6460    (clobber (reg:CC FLAGS_REG))]
6461   "TARGET_64BIT && reload_completed"
6462   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6463               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6464    (parallel [(set (match_dup 3)
6465                    (minus:DI (match_dup 4)
6466                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6467                                       (match_dup 5))))
6468               (clobber (reg:CC FLAGS_REG))])]
6469   "split_ti (operands+0, 1, operands+0, operands+3);
6470    split_ti (operands+1, 1, operands+1, operands+4);
6471    split_ti (operands+2, 1, operands+2, operands+5);")
6472
6473 ;; %%% splits for subsidi3
6474
6475 (define_expand "subdi3"
6476   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6477                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6478                              (match_operand:DI 2 "x86_64_general_operand" "")))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   ""
6481   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6482
6483 (define_insn "*subdi3_1"
6484   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6485         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6486                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6489   "#")
6490
6491 (define_split
6492   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6493         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6494                   (match_operand:DI 2 "general_operand" "")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "!TARGET_64BIT && reload_completed"
6497   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6499    (parallel [(set (match_dup 3)
6500                    (minus:SI (match_dup 4)
6501                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6502                                       (match_dup 5))))
6503               (clobber (reg:CC FLAGS_REG))])]
6504   "split_di (operands+0, 1, operands+0, operands+3);
6505    split_di (operands+1, 1, operands+1, operands+4);
6506    split_di (operands+2, 1, operands+2, operands+5);")
6507
6508 (define_insn "subdi3_carry_rex64"
6509   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6510           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6511             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6512                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6513    (clobber (reg:CC FLAGS_REG))]
6514   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6515   "sbb{q}\t{%2, %0|%0, %2}"
6516   [(set_attr "type" "alu")
6517    (set_attr "pent_pair" "pu")
6518    (set_attr "mode" "DI")])
6519
6520 (define_insn "*subdi_1_rex64"
6521   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6522         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6523                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6524    (clobber (reg:CC FLAGS_REG))]
6525   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6526   "sub{q}\t{%2, %0|%0, %2}"
6527   [(set_attr "type" "alu")
6528    (set_attr "mode" "DI")])
6529
6530 (define_insn "*subdi_2_rex64"
6531   [(set (reg FLAGS_REG)
6532         (compare
6533           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6534                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6535           (const_int 0)))
6536    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6537         (minus:DI (match_dup 1) (match_dup 2)))]
6538   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6539    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6540   "sub{q}\t{%2, %0|%0, %2}"
6541   [(set_attr "type" "alu")
6542    (set_attr "mode" "DI")])
6543
6544 (define_insn "*subdi_3_rex63"
6545   [(set (reg FLAGS_REG)
6546         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6547                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6548    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6549         (minus:DI (match_dup 1) (match_dup 2)))]
6550   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6551    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6552   "sub{q}\t{%2, %0|%0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "mode" "DI")])
6555
6556 (define_insn "subqi3_carry"
6557   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6558           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6559             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6560                (match_operand:QI 2 "general_operand" "qi,qm"))))
6561    (clobber (reg:CC FLAGS_REG))]
6562   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6563   "sbb{b}\t{%2, %0|%0, %2}"
6564   [(set_attr "type" "alu")
6565    (set_attr "pent_pair" "pu")
6566    (set_attr "mode" "QI")])
6567
6568 (define_insn "subhi3_carry"
6569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6570           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6571             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6572                (match_operand:HI 2 "general_operand" "ri,rm"))))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6575   "sbb{w}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "pent_pair" "pu")
6578    (set_attr "mode" "HI")])
6579
6580 (define_insn "subsi3_carry"
6581   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6582           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6583             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6584                (match_operand:SI 2 "general_operand" "ri,rm"))))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sbb{l}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "pent_pair" "pu")
6590    (set_attr "mode" "SI")])
6591
6592 (define_insn "subsi3_carry_zext"
6593   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6594           (zero_extend:DI
6595             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6596               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6597                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6598    (clobber (reg:CC FLAGS_REG))]
6599   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6600   "sbb{l}\t{%2, %k0|%k0, %2}"
6601   [(set_attr "type" "alu")
6602    (set_attr "pent_pair" "pu")
6603    (set_attr "mode" "SI")])
6604
6605 (define_expand "subsi3"
6606   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6607                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6608                              (match_operand:SI 2 "general_operand" "")))
6609               (clobber (reg:CC FLAGS_REG))])]
6610   ""
6611   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6612
6613 (define_insn "*subsi_1"
6614   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6615         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6616                   (match_operand:SI 2 "general_operand" "ri,rm")))
6617    (clobber (reg:CC FLAGS_REG))]
6618   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6619   "sub{l}\t{%2, %0|%0, %2}"
6620   [(set_attr "type" "alu")
6621    (set_attr "mode" "SI")])
6622
6623 (define_insn "*subsi_1_zext"
6624   [(set (match_operand:DI 0 "register_operand" "=r")
6625         (zero_extend:DI
6626           (minus:SI (match_operand:SI 1 "register_operand" "0")
6627                     (match_operand:SI 2 "general_operand" "rim"))))
6628    (clobber (reg:CC FLAGS_REG))]
6629   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6630   "sub{l}\t{%2, %k0|%k0, %2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "SI")])
6633
6634 (define_insn "*subsi_2"
6635   [(set (reg FLAGS_REG)
6636         (compare
6637           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6638                     (match_operand:SI 2 "general_operand" "ri,rm"))
6639           (const_int 0)))
6640    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6641         (minus:SI (match_dup 1) (match_dup 2)))]
6642   "ix86_match_ccmode (insn, CCGOCmode)
6643    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6644   "sub{l}\t{%2, %0|%0, %2}"
6645   [(set_attr "type" "alu")
6646    (set_attr "mode" "SI")])
6647
6648 (define_insn "*subsi_2_zext"
6649   [(set (reg FLAGS_REG)
6650         (compare
6651           (minus:SI (match_operand:SI 1 "register_operand" "0")
6652                     (match_operand:SI 2 "general_operand" "rim"))
6653           (const_int 0)))
6654    (set (match_operand:DI 0 "register_operand" "=r")
6655         (zero_extend:DI
6656           (minus:SI (match_dup 1)
6657                     (match_dup 2))))]
6658   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6659    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6660   "sub{l}\t{%2, %k0|%k0, %2}"
6661   [(set_attr "type" "alu")
6662    (set_attr "mode" "SI")])
6663
6664 (define_insn "*subsi_3"
6665   [(set (reg FLAGS_REG)
6666         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6667                  (match_operand:SI 2 "general_operand" "ri,rm")))
6668    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669         (minus:SI (match_dup 1) (match_dup 2)))]
6670   "ix86_match_ccmode (insn, CCmode)
6671    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672   "sub{l}\t{%2, %0|%0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "mode" "SI")])
6675
6676 (define_insn "*subsi_3_zext"
6677   [(set (reg FLAGS_REG)
6678         (compare (match_operand:SI 1 "register_operand" "0")
6679                  (match_operand:SI 2 "general_operand" "rim")))
6680    (set (match_operand:DI 0 "register_operand" "=r")
6681         (zero_extend:DI
6682           (minus:SI (match_dup 1)
6683                     (match_dup 2))))]
6684   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6685    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686   "sub{q}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "DI")])
6689
6690 (define_expand "subhi3"
6691   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6692                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6693                              (match_operand:HI 2 "general_operand" "")))
6694               (clobber (reg:CC FLAGS_REG))])]
6695   "TARGET_HIMODE_MATH"
6696   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6697
6698 (define_insn "*subhi_1"
6699   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701                   (match_operand:HI 2 "general_operand" "ri,rm")))
6702    (clobber (reg:CC FLAGS_REG))]
6703   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6704   "sub{w}\t{%2, %0|%0, %2}"
6705   [(set_attr "type" "alu")
6706    (set_attr "mode" "HI")])
6707
6708 (define_insn "*subhi_2"
6709   [(set (reg FLAGS_REG)
6710         (compare
6711           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6712                     (match_operand:HI 2 "general_operand" "ri,rm"))
6713           (const_int 0)))
6714    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6715         (minus:HI (match_dup 1) (match_dup 2)))]
6716   "ix86_match_ccmode (insn, CCGOCmode)
6717    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6718   "sub{w}\t{%2, %0|%0, %2}"
6719   [(set_attr "type" "alu")
6720    (set_attr "mode" "HI")])
6721
6722 (define_insn "*subhi_3"
6723   [(set (reg FLAGS_REG)
6724         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6725                  (match_operand:HI 2 "general_operand" "ri,rm")))
6726    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6727         (minus:HI (match_dup 1) (match_dup 2)))]
6728   "ix86_match_ccmode (insn, CCmode)
6729    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6730   "sub{w}\t{%2, %0|%0, %2}"
6731   [(set_attr "type" "alu")
6732    (set_attr "mode" "HI")])
6733
6734 (define_expand "subqi3"
6735   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6736                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6737                              (match_operand:QI 2 "general_operand" "")))
6738               (clobber (reg:CC FLAGS_REG))])]
6739   "TARGET_QIMODE_MATH"
6740   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6741
6742 (define_insn "*subqi_1"
6743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6744         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6745                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6746    (clobber (reg:CC FLAGS_REG))]
6747   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6748   "sub{b}\t{%2, %0|%0, %2}"
6749   [(set_attr "type" "alu")
6750    (set_attr "mode" "QI")])
6751
6752 (define_insn "*subqi_1_slp"
6753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6754         (minus:QI (match_dup 0)
6755                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6756    (clobber (reg:CC FLAGS_REG))]
6757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6758    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6759   "sub{b}\t{%1, %0|%0, %1}"
6760   [(set_attr "type" "alu1")
6761    (set_attr "mode" "QI")])
6762
6763 (define_insn "*subqi_2"
6764   [(set (reg FLAGS_REG)
6765         (compare
6766           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6767                     (match_operand:QI 2 "general_operand" "qi,qm"))
6768           (const_int 0)))
6769    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6770         (minus:HI (match_dup 1) (match_dup 2)))]
6771   "ix86_match_ccmode (insn, CCGOCmode)
6772    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6773   "sub{b}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "alu")
6775    (set_attr "mode" "QI")])
6776
6777 (define_insn "*subqi_3"
6778   [(set (reg FLAGS_REG)
6779         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780                  (match_operand:QI 2 "general_operand" "qi,qm")))
6781    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6782         (minus:HI (match_dup 1) (match_dup 2)))]
6783   "ix86_match_ccmode (insn, CCmode)
6784    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6785   "sub{b}\t{%2, %0|%0, %2}"
6786   [(set_attr "type" "alu")
6787    (set_attr "mode" "QI")])
6788
6789 ;; The patterns that match these are at the end of this file.
6790
6791 (define_expand "subxf3"
6792   [(set (match_operand:XF 0 "register_operand" "")
6793         (minus:XF (match_operand:XF 1 "register_operand" "")
6794                   (match_operand:XF 2 "register_operand" "")))]
6795   "TARGET_80387"
6796   "")
6797
6798 (define_expand "subdf3"
6799   [(set (match_operand:DF 0 "register_operand" "")
6800         (minus:DF (match_operand:DF 1 "register_operand" "")
6801                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6802   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6803   "")
6804
6805 (define_expand "subsf3"
6806   [(set (match_operand:SF 0 "register_operand" "")
6807         (minus:SF (match_operand:SF 1 "register_operand" "")
6808                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6809   "TARGET_80387 || TARGET_SSE_MATH"
6810   "")
6811 \f
6812 ;; Multiply instructions
6813
6814 (define_expand "muldi3"
6815   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6816                    (mult:DI (match_operand:DI 1 "register_operand" "")
6817                             (match_operand:DI 2 "x86_64_general_operand" "")))
6818               (clobber (reg:CC FLAGS_REG))])]
6819   "TARGET_64BIT"
6820   "")
6821
6822 (define_insn "*muldi3_1_rex64"
6823   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6824         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6825                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6826    (clobber (reg:CC FLAGS_REG))]
6827   "TARGET_64BIT
6828    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6829   "@
6830    imul{q}\t{%2, %1, %0|%0, %1, %2}
6831    imul{q}\t{%2, %1, %0|%0, %1, %2}
6832    imul{q}\t{%2, %0|%0, %2}"
6833   [(set_attr "type" "imul")
6834    (set_attr "prefix_0f" "0,0,1")
6835    (set (attr "athlon_decode")
6836         (cond [(eq_attr "cpu" "athlon")
6837                   (const_string "vector")
6838                (eq_attr "alternative" "1")
6839                   (const_string "vector")
6840                (and (eq_attr "alternative" "2")
6841                     (match_operand 1 "memory_operand" ""))
6842                   (const_string "vector")]
6843               (const_string "direct")))
6844    (set_attr "mode" "DI")])
6845
6846 (define_expand "mulsi3"
6847   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6848                    (mult:SI (match_operand:SI 1 "register_operand" "")
6849                             (match_operand:SI 2 "general_operand" "")))
6850               (clobber (reg:CC FLAGS_REG))])]
6851   ""
6852   "")
6853
6854 (define_insn "*mulsi3_1"
6855   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6856         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6857                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6860   "@
6861    imul{l}\t{%2, %1, %0|%0, %1, %2}
6862    imul{l}\t{%2, %1, %0|%0, %1, %2}
6863    imul{l}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "imul")
6865    (set_attr "prefix_0f" "0,0,1")
6866    (set (attr "athlon_decode")
6867         (cond [(eq_attr "cpu" "athlon")
6868                   (const_string "vector")
6869                (eq_attr "alternative" "1")
6870                   (const_string "vector")
6871                (and (eq_attr "alternative" "2")
6872                     (match_operand 1 "memory_operand" ""))
6873                   (const_string "vector")]
6874               (const_string "direct")))
6875    (set_attr "mode" "SI")])
6876
6877 (define_insn "*mulsi3_1_zext"
6878   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6879         (zero_extend:DI
6880           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6881                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6882    (clobber (reg:CC FLAGS_REG))]
6883   "TARGET_64BIT
6884    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6885   "@
6886    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6887    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888    imul{l}\t{%2, %k0|%k0, %2}"
6889   [(set_attr "type" "imul")
6890    (set_attr "prefix_0f" "0,0,1")
6891    (set (attr "athlon_decode")
6892         (cond [(eq_attr "cpu" "athlon")
6893                   (const_string "vector")
6894                (eq_attr "alternative" "1")
6895                   (const_string "vector")
6896                (and (eq_attr "alternative" "2")
6897                     (match_operand 1 "memory_operand" ""))
6898                   (const_string "vector")]
6899               (const_string "direct")))
6900    (set_attr "mode" "SI")])
6901
6902 (define_expand "mulhi3"
6903   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6904                    (mult:HI (match_operand:HI 1 "register_operand" "")
6905                             (match_operand:HI 2 "general_operand" "")))
6906               (clobber (reg:CC FLAGS_REG))])]
6907   "TARGET_HIMODE_MATH"
6908   "")
6909
6910 (define_insn "*mulhi3_1"
6911   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6912         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6913                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6916   "@
6917    imul{w}\t{%2, %1, %0|%0, %1, %2}
6918    imul{w}\t{%2, %1, %0|%0, %1, %2}
6919    imul{w}\t{%2, %0|%0, %2}"
6920   [(set_attr "type" "imul")
6921    (set_attr "prefix_0f" "0,0,1")
6922    (set (attr "athlon_decode")
6923         (cond [(eq_attr "cpu" "athlon")
6924                   (const_string "vector")
6925                (eq_attr "alternative" "1,2")
6926                   (const_string "vector")]
6927               (const_string "direct")))
6928    (set_attr "mode" "HI")])
6929
6930 (define_expand "mulqi3"
6931   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6932                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6933                             (match_operand:QI 2 "register_operand" "")))
6934               (clobber (reg:CC FLAGS_REG))])]
6935   "TARGET_QIMODE_MATH"
6936   "")
6937
6938 (define_insn "*mulqi3_1"
6939   [(set (match_operand:QI 0 "register_operand" "=a")
6940         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6941                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "TARGET_QIMODE_MATH
6944    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6945   "mul{b}\t%2"
6946   [(set_attr "type" "imul")
6947    (set_attr "length_immediate" "0")
6948    (set (attr "athlon_decode")
6949      (if_then_else (eq_attr "cpu" "athlon")
6950         (const_string "vector")
6951         (const_string "direct")))
6952    (set_attr "mode" "QI")])
6953
6954 (define_expand "umulqihi3"
6955   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6956                    (mult:HI (zero_extend:HI
6957                               (match_operand:QI 1 "nonimmediate_operand" ""))
6958                             (zero_extend:HI
6959                               (match_operand:QI 2 "register_operand" ""))))
6960               (clobber (reg:CC FLAGS_REG))])]
6961   "TARGET_QIMODE_MATH"
6962   "")
6963
6964 (define_insn "*umulqihi3_1"
6965   [(set (match_operand:HI 0 "register_operand" "=a")
6966         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "TARGET_QIMODE_MATH
6970    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6971   "mul{b}\t%2"
6972   [(set_attr "type" "imul")
6973    (set_attr "length_immediate" "0")
6974    (set (attr "athlon_decode")
6975      (if_then_else (eq_attr "cpu" "athlon")
6976         (const_string "vector")
6977         (const_string "direct")))
6978    (set_attr "mode" "QI")])
6979
6980 (define_expand "mulqihi3"
6981   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6982                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6983                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6984               (clobber (reg:CC FLAGS_REG))])]
6985   "TARGET_QIMODE_MATH"
6986   "")
6987
6988 (define_insn "*mulqihi3_insn"
6989   [(set (match_operand:HI 0 "register_operand" "=a")
6990         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6991                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6992    (clobber (reg:CC FLAGS_REG))]
6993   "TARGET_QIMODE_MATH
6994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6995   "imul{b}\t%2"
6996   [(set_attr "type" "imul")
6997    (set_attr "length_immediate" "0")
6998    (set (attr "athlon_decode")
6999      (if_then_else (eq_attr "cpu" "athlon")
7000         (const_string "vector")
7001         (const_string "direct")))
7002    (set_attr "mode" "QI")])
7003
7004 (define_expand "umulditi3"
7005   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7006                    (mult:TI (zero_extend:TI
7007                               (match_operand:DI 1 "nonimmediate_operand" ""))
7008                             (zero_extend:TI
7009                               (match_operand:DI 2 "register_operand" ""))))
7010               (clobber (reg:CC FLAGS_REG))])]
7011   "TARGET_64BIT"
7012   "")
7013
7014 (define_insn "*umulditi3_insn"
7015   [(set (match_operand:TI 0 "register_operand" "=A")
7016         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7017                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7018    (clobber (reg:CC FLAGS_REG))]
7019   "TARGET_64BIT
7020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7021   "mul{q}\t%2"
7022   [(set_attr "type" "imul")
7023    (set_attr "length_immediate" "0")
7024    (set (attr "athlon_decode")
7025      (if_then_else (eq_attr "cpu" "athlon")
7026         (const_string "vector")
7027         (const_string "double")))
7028    (set_attr "mode" "DI")])
7029
7030 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7031 (define_expand "umulsidi3"
7032   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7033                    (mult:DI (zero_extend:DI
7034                               (match_operand:SI 1 "nonimmediate_operand" ""))
7035                             (zero_extend:DI
7036                               (match_operand:SI 2 "register_operand" ""))))
7037               (clobber (reg:CC FLAGS_REG))])]
7038   "!TARGET_64BIT"
7039   "")
7040
7041 (define_insn "*umulsidi3_insn"
7042   [(set (match_operand:DI 0 "register_operand" "=A")
7043         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7044                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "!TARGET_64BIT
7047    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7048   "mul{l}\t%2"
7049   [(set_attr "type" "imul")
7050    (set_attr "length_immediate" "0")
7051    (set (attr "athlon_decode")
7052      (if_then_else (eq_attr "cpu" "athlon")
7053         (const_string "vector")
7054         (const_string "double")))
7055    (set_attr "mode" "SI")])
7056
7057 (define_expand "mulditi3"
7058   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7059                    (mult:TI (sign_extend:TI
7060                               (match_operand:DI 1 "nonimmediate_operand" ""))
7061                             (sign_extend:TI
7062                               (match_operand:DI 2 "register_operand" ""))))
7063               (clobber (reg:CC FLAGS_REG))])]
7064   "TARGET_64BIT"
7065   "")
7066
7067 (define_insn "*mulditi3_insn"
7068   [(set (match_operand:TI 0 "register_operand" "=A")
7069         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7070                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7071    (clobber (reg:CC FLAGS_REG))]
7072   "TARGET_64BIT
7073    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7074   "imul{q}\t%2"
7075   [(set_attr "type" "imul")
7076    (set_attr "length_immediate" "0")
7077    (set (attr "athlon_decode")
7078      (if_then_else (eq_attr "cpu" "athlon")
7079         (const_string "vector")
7080         (const_string "double")))
7081    (set_attr "mode" "DI")])
7082
7083 (define_expand "mulsidi3"
7084   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7085                    (mult:DI (sign_extend:DI
7086                               (match_operand:SI 1 "nonimmediate_operand" ""))
7087                             (sign_extend:DI
7088                               (match_operand:SI 2 "register_operand" ""))))
7089               (clobber (reg:CC FLAGS_REG))])]
7090   "!TARGET_64BIT"
7091   "")
7092
7093 (define_insn "*mulsidi3_insn"
7094   [(set (match_operand:DI 0 "register_operand" "=A")
7095         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7096                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "!TARGET_64BIT
7099    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7100   "imul{l}\t%2"
7101   [(set_attr "type" "imul")
7102    (set_attr "length_immediate" "0")
7103    (set (attr "athlon_decode")
7104      (if_then_else (eq_attr "cpu" "athlon")
7105         (const_string "vector")
7106         (const_string "double")))
7107    (set_attr "mode" "SI")])
7108
7109 (define_expand "umuldi3_highpart"
7110   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7111                    (truncate:DI
7112                      (lshiftrt:TI
7113                        (mult:TI (zero_extend:TI
7114                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7115                                 (zero_extend:TI
7116                                   (match_operand:DI 2 "register_operand" "")))
7117                        (const_int 64))))
7118               (clobber (match_scratch:DI 3 ""))
7119               (clobber (reg:CC FLAGS_REG))])]
7120   "TARGET_64BIT"
7121   "")
7122
7123 (define_insn "*umuldi3_highpart_rex64"
7124   [(set (match_operand:DI 0 "register_operand" "=d")
7125         (truncate:DI
7126           (lshiftrt:TI
7127             (mult:TI (zero_extend:TI
7128                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7129                      (zero_extend:TI
7130                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7131             (const_int 64))))
7132    (clobber (match_scratch:DI 3 "=1"))
7133    (clobber (reg:CC FLAGS_REG))]
7134   "TARGET_64BIT
7135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7136   "mul{q}\t%2"
7137   [(set_attr "type" "imul")
7138    (set_attr "length_immediate" "0")
7139    (set (attr "athlon_decode")
7140      (if_then_else (eq_attr "cpu" "athlon")
7141         (const_string "vector")
7142         (const_string "double")))
7143    (set_attr "mode" "DI")])
7144
7145 (define_expand "umulsi3_highpart"
7146   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7147                    (truncate:SI
7148                      (lshiftrt:DI
7149                        (mult:DI (zero_extend:DI
7150                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7151                                 (zero_extend:DI
7152                                   (match_operand:SI 2 "register_operand" "")))
7153                        (const_int 32))))
7154               (clobber (match_scratch:SI 3 ""))
7155               (clobber (reg:CC FLAGS_REG))])]
7156   ""
7157   "")
7158
7159 (define_insn "*umulsi3_highpart_insn"
7160   [(set (match_operand:SI 0 "register_operand" "=d")
7161         (truncate:SI
7162           (lshiftrt:DI
7163             (mult:DI (zero_extend:DI
7164                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7165                      (zero_extend:DI
7166                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7167             (const_int 32))))
7168    (clobber (match_scratch:SI 3 "=1"))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7171   "mul{l}\t%2"
7172   [(set_attr "type" "imul")
7173    (set_attr "length_immediate" "0")
7174    (set (attr "athlon_decode")
7175      (if_then_else (eq_attr "cpu" "athlon")
7176         (const_string "vector")
7177         (const_string "double")))
7178    (set_attr "mode" "SI")])
7179
7180 (define_insn "*umulsi3_highpart_zext"
7181   [(set (match_operand:DI 0 "register_operand" "=d")
7182         (zero_extend:DI (truncate:SI
7183           (lshiftrt:DI
7184             (mult:DI (zero_extend:DI
7185                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7186                      (zero_extend:DI
7187                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7188             (const_int 32)))))
7189    (clobber (match_scratch:SI 3 "=1"))
7190    (clobber (reg:CC FLAGS_REG))]
7191   "TARGET_64BIT
7192    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7193   "mul{l}\t%2"
7194   [(set_attr "type" "imul")
7195    (set_attr "length_immediate" "0")
7196    (set (attr "athlon_decode")
7197      (if_then_else (eq_attr "cpu" "athlon")
7198         (const_string "vector")
7199         (const_string "double")))
7200    (set_attr "mode" "SI")])
7201
7202 (define_expand "smuldi3_highpart"
7203   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7204                    (truncate:DI
7205                      (lshiftrt:TI
7206                        (mult:TI (sign_extend:TI
7207                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7208                                 (sign_extend:TI
7209                                   (match_operand:DI 2 "register_operand" "")))
7210                        (const_int 64))))
7211               (clobber (match_scratch:DI 3 ""))
7212               (clobber (reg:CC FLAGS_REG))])]
7213   "TARGET_64BIT"
7214   "")
7215
7216 (define_insn "*smuldi3_highpart_rex64"
7217   [(set (match_operand:DI 0 "register_operand" "=d")
7218         (truncate:DI
7219           (lshiftrt:TI
7220             (mult:TI (sign_extend:TI
7221                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7222                      (sign_extend:TI
7223                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7224             (const_int 64))))
7225    (clobber (match_scratch:DI 3 "=1"))
7226    (clobber (reg:CC FLAGS_REG))]
7227   "TARGET_64BIT
7228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7229   "imul{q}\t%2"
7230   [(set_attr "type" "imul")
7231    (set (attr "athlon_decode")
7232      (if_then_else (eq_attr "cpu" "athlon")
7233         (const_string "vector")
7234         (const_string "double")))
7235    (set_attr "mode" "DI")])
7236
7237 (define_expand "smulsi3_highpart"
7238   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7239                    (truncate:SI
7240                      (lshiftrt:DI
7241                        (mult:DI (sign_extend:DI
7242                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7243                                 (sign_extend:DI
7244                                   (match_operand:SI 2 "register_operand" "")))
7245                        (const_int 32))))
7246               (clobber (match_scratch:SI 3 ""))
7247               (clobber (reg:CC FLAGS_REG))])]
7248   ""
7249   "")
7250
7251 (define_insn "*smulsi3_highpart_insn"
7252   [(set (match_operand:SI 0 "register_operand" "=d")
7253         (truncate:SI
7254           (lshiftrt:DI
7255             (mult:DI (sign_extend:DI
7256                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7257                      (sign_extend:DI
7258                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7259             (const_int 32))))
7260    (clobber (match_scratch:SI 3 "=1"))
7261    (clobber (reg:CC FLAGS_REG))]
7262   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7263   "imul{l}\t%2"
7264   [(set_attr "type" "imul")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "double")))
7269    (set_attr "mode" "SI")])
7270
7271 (define_insn "*smulsi3_highpart_zext"
7272   [(set (match_operand:DI 0 "register_operand" "=d")
7273         (zero_extend:DI (truncate:SI
7274           (lshiftrt:DI
7275             (mult:DI (sign_extend:DI
7276                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7277                      (sign_extend:DI
7278                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279             (const_int 32)))))
7280    (clobber (match_scratch:SI 3 "=1"))
7281    (clobber (reg:CC FLAGS_REG))]
7282   "TARGET_64BIT
7283    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7284   "imul{l}\t%2"
7285   [(set_attr "type" "imul")
7286    (set (attr "athlon_decode")
7287      (if_then_else (eq_attr "cpu" "athlon")
7288         (const_string "vector")
7289         (const_string "double")))
7290    (set_attr "mode" "SI")])
7291
7292 ;; The patterns that match these are at the end of this file.
7293
7294 (define_expand "mulxf3"
7295   [(set (match_operand:XF 0 "register_operand" "")
7296         (mult:XF (match_operand:XF 1 "register_operand" "")
7297                  (match_operand:XF 2 "register_operand" "")))]
7298   "TARGET_80387"
7299   "")
7300
7301 (define_expand "muldf3"
7302   [(set (match_operand:DF 0 "register_operand" "")
7303         (mult:DF (match_operand:DF 1 "register_operand" "")
7304                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7305   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7306   "")
7307
7308 (define_expand "mulsf3"
7309   [(set (match_operand:SF 0 "register_operand" "")
7310         (mult:SF (match_operand:SF 1 "register_operand" "")
7311                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7312   "TARGET_80387 || TARGET_SSE_MATH"
7313   "")
7314 \f
7315 ;; Divide instructions
7316
7317 (define_insn "divqi3"
7318   [(set (match_operand:QI 0 "register_operand" "=a")
7319         (div:QI (match_operand:HI 1 "register_operand" "0")
7320                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7321    (clobber (reg:CC FLAGS_REG))]
7322   "TARGET_QIMODE_MATH"
7323   "idiv{b}\t%2"
7324   [(set_attr "type" "idiv")
7325    (set_attr "mode" "QI")])
7326
7327 (define_insn "udivqi3"
7328   [(set (match_operand:QI 0 "register_operand" "=a")
7329         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7330                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_QIMODE_MATH"
7333   "div{b}\t%2"
7334   [(set_attr "type" "idiv")
7335    (set_attr "mode" "QI")])
7336
7337 ;; The patterns that match these are at the end of this file.
7338
7339 (define_expand "divxf3"
7340   [(set (match_operand:XF 0 "register_operand" "")
7341         (div:XF (match_operand:XF 1 "register_operand" "")
7342                 (match_operand:XF 2 "register_operand" "")))]
7343   "TARGET_80387"
7344   "")
7345
7346 (define_expand "divdf3"
7347   [(set (match_operand:DF 0 "register_operand" "")
7348         (div:DF (match_operand:DF 1 "register_operand" "")
7349                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7350    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7351    "")
7352  
7353 (define_expand "divsf3"
7354   [(set (match_operand:SF 0 "register_operand" "")
7355         (div:SF (match_operand:SF 1 "register_operand" "")
7356                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7357   "TARGET_80387 || TARGET_SSE_MATH"
7358   "")
7359 \f
7360 ;; Remainder instructions.
7361
7362 (define_expand "divmoddi4"
7363   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7364                    (div:DI (match_operand:DI 1 "register_operand" "")
7365                            (match_operand:DI 2 "nonimmediate_operand" "")))
7366               (set (match_operand:DI 3 "register_operand" "")
7367                    (mod:DI (match_dup 1) (match_dup 2)))
7368               (clobber (reg:CC FLAGS_REG))])]
7369   "TARGET_64BIT"
7370   "")
7371
7372 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7373 ;; Penalize eax case slightly because it results in worse scheduling
7374 ;; of code.
7375 (define_insn "*divmoddi4_nocltd_rex64"
7376   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7377         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7378                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7379    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7380         (mod:DI (match_dup 2) (match_dup 3)))
7381    (clobber (reg:CC FLAGS_REG))]
7382   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7383   "#"
7384   [(set_attr "type" "multi")])
7385
7386 (define_insn "*divmoddi4_cltd_rex64"
7387   [(set (match_operand:DI 0 "register_operand" "=a")
7388         (div:DI (match_operand:DI 2 "register_operand" "a")
7389                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7390    (set (match_operand:DI 1 "register_operand" "=&d")
7391         (mod:DI (match_dup 2) (match_dup 3)))
7392    (clobber (reg:CC FLAGS_REG))]
7393   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7394   "#"
7395   [(set_attr "type" "multi")])
7396
7397 (define_insn "*divmoddi_noext_rex64"
7398   [(set (match_operand:DI 0 "register_operand" "=a")
7399         (div:DI (match_operand:DI 1 "register_operand" "0")
7400                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7401    (set (match_operand:DI 3 "register_operand" "=d")
7402         (mod:DI (match_dup 1) (match_dup 2)))
7403    (use (match_operand:DI 4 "register_operand" "3"))
7404    (clobber (reg:CC FLAGS_REG))]
7405   "TARGET_64BIT"
7406   "idiv{q}\t%2"
7407   [(set_attr "type" "idiv")
7408    (set_attr "mode" "DI")])
7409
7410 (define_split
7411   [(set (match_operand:DI 0 "register_operand" "")
7412         (div:DI (match_operand:DI 1 "register_operand" "")
7413                 (match_operand:DI 2 "nonimmediate_operand" "")))
7414    (set (match_operand:DI 3 "register_operand" "")
7415         (mod:DI (match_dup 1) (match_dup 2)))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "TARGET_64BIT && reload_completed"
7418   [(parallel [(set (match_dup 3)
7419                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7420               (clobber (reg:CC FLAGS_REG))])
7421    (parallel [(set (match_dup 0)
7422                    (div:DI (reg:DI 0) (match_dup 2)))
7423               (set (match_dup 3)
7424                    (mod:DI (reg:DI 0) (match_dup 2)))
7425               (use (match_dup 3))
7426               (clobber (reg:CC FLAGS_REG))])]
7427 {
7428   /* Avoid use of cltd in favor of a mov+shift.  */
7429   if (!TARGET_USE_CLTD && !optimize_size)
7430     {
7431       if (true_regnum (operands[1]))
7432         emit_move_insn (operands[0], operands[1]);
7433       else
7434         emit_move_insn (operands[3], operands[1]);
7435       operands[4] = operands[3];
7436     }
7437   else
7438     {
7439       gcc_assert (!true_regnum (operands[1]));
7440       operands[4] = operands[1];
7441     }
7442 })
7443
7444
7445 (define_expand "divmodsi4"
7446   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7447                    (div:SI (match_operand:SI 1 "register_operand" "")
7448                            (match_operand:SI 2 "nonimmediate_operand" "")))
7449               (set (match_operand:SI 3 "register_operand" "")
7450                    (mod:SI (match_dup 1) (match_dup 2)))
7451               (clobber (reg:CC FLAGS_REG))])]
7452   ""
7453   "")
7454
7455 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7456 ;; Penalize eax case slightly because it results in worse scheduling
7457 ;; of code.
7458 (define_insn "*divmodsi4_nocltd"
7459   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7460         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7461                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7462    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7463         (mod:SI (match_dup 2) (match_dup 3)))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "!optimize_size && !TARGET_USE_CLTD"
7466   "#"
7467   [(set_attr "type" "multi")])
7468
7469 (define_insn "*divmodsi4_cltd"
7470   [(set (match_operand:SI 0 "register_operand" "=a")
7471         (div:SI (match_operand:SI 2 "register_operand" "a")
7472                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7473    (set (match_operand:SI 1 "register_operand" "=&d")
7474         (mod:SI (match_dup 2) (match_dup 3)))
7475    (clobber (reg:CC FLAGS_REG))]
7476   "optimize_size || TARGET_USE_CLTD"
7477   "#"
7478   [(set_attr "type" "multi")])
7479
7480 (define_insn "*divmodsi_noext"
7481   [(set (match_operand:SI 0 "register_operand" "=a")
7482         (div:SI (match_operand:SI 1 "register_operand" "0")
7483                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7484    (set (match_operand:SI 3 "register_operand" "=d")
7485         (mod:SI (match_dup 1) (match_dup 2)))
7486    (use (match_operand:SI 4 "register_operand" "3"))
7487    (clobber (reg:CC FLAGS_REG))]
7488   ""
7489   "idiv{l}\t%2"
7490   [(set_attr "type" "idiv")
7491    (set_attr "mode" "SI")])
7492
7493 (define_split
7494   [(set (match_operand:SI 0 "register_operand" "")
7495         (div:SI (match_operand:SI 1 "register_operand" "")
7496                 (match_operand:SI 2 "nonimmediate_operand" "")))
7497    (set (match_operand:SI 3 "register_operand" "")
7498         (mod:SI (match_dup 1) (match_dup 2)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "reload_completed"
7501   [(parallel [(set (match_dup 3)
7502                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7503               (clobber (reg:CC FLAGS_REG))])
7504    (parallel [(set (match_dup 0)
7505                    (div:SI (reg:SI 0) (match_dup 2)))
7506               (set (match_dup 3)
7507                    (mod:SI (reg:SI 0) (match_dup 2)))
7508               (use (match_dup 3))
7509               (clobber (reg:CC FLAGS_REG))])]
7510 {
7511   /* Avoid use of cltd in favor of a mov+shift.  */
7512   if (!TARGET_USE_CLTD && !optimize_size)
7513     {
7514       if (true_regnum (operands[1]))
7515         emit_move_insn (operands[0], operands[1]);
7516       else
7517         emit_move_insn (operands[3], operands[1]);
7518       operands[4] = operands[3];
7519     }
7520   else
7521     {
7522       gcc_assert (!true_regnum (operands[1]));
7523       operands[4] = operands[1];
7524     }
7525 })
7526 ;; %%% Split me.
7527 (define_insn "divmodhi4"
7528   [(set (match_operand:HI 0 "register_operand" "=a")
7529         (div:HI (match_operand:HI 1 "register_operand" "0")
7530                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7531    (set (match_operand:HI 3 "register_operand" "=&d")
7532         (mod:HI (match_dup 1) (match_dup 2)))
7533    (clobber (reg:CC FLAGS_REG))]
7534   "TARGET_HIMODE_MATH"
7535   "cwtd\;idiv{w}\t%2"
7536   [(set_attr "type" "multi")
7537    (set_attr "length_immediate" "0")
7538    (set_attr "mode" "SI")])
7539
7540 (define_insn "udivmoddi4"
7541   [(set (match_operand:DI 0 "register_operand" "=a")
7542         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7543                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7544    (set (match_operand:DI 3 "register_operand" "=&d")
7545         (umod:DI (match_dup 1) (match_dup 2)))
7546    (clobber (reg:CC FLAGS_REG))]
7547   "TARGET_64BIT"
7548   "xor{q}\t%3, %3\;div{q}\t%2"
7549   [(set_attr "type" "multi")
7550    (set_attr "length_immediate" "0")
7551    (set_attr "mode" "DI")])
7552
7553 (define_insn "*udivmoddi4_noext"
7554   [(set (match_operand:DI 0 "register_operand" "=a")
7555         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7556                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7557    (set (match_operand:DI 3 "register_operand" "=d")
7558         (umod:DI (match_dup 1) (match_dup 2)))
7559    (use (match_dup 3))
7560    (clobber (reg:CC FLAGS_REG))]
7561   "TARGET_64BIT"
7562   "div{q}\t%2"
7563   [(set_attr "type" "idiv")
7564    (set_attr "mode" "DI")])
7565
7566 (define_split
7567   [(set (match_operand:DI 0 "register_operand" "")
7568         (udiv:DI (match_operand:DI 1 "register_operand" "")
7569                  (match_operand:DI 2 "nonimmediate_operand" "")))
7570    (set (match_operand:DI 3 "register_operand" "")
7571         (umod:DI (match_dup 1) (match_dup 2)))
7572    (clobber (reg:CC FLAGS_REG))]
7573   "TARGET_64BIT && reload_completed"
7574   [(set (match_dup 3) (const_int 0))
7575    (parallel [(set (match_dup 0)
7576                    (udiv:DI (match_dup 1) (match_dup 2)))
7577               (set (match_dup 3)
7578                    (umod:DI (match_dup 1) (match_dup 2)))
7579               (use (match_dup 3))
7580               (clobber (reg:CC FLAGS_REG))])]
7581   "")
7582
7583 (define_insn "udivmodsi4"
7584   [(set (match_operand:SI 0 "register_operand" "=a")
7585         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7586                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7587    (set (match_operand:SI 3 "register_operand" "=&d")
7588         (umod:SI (match_dup 1) (match_dup 2)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   ""
7591   "xor{l}\t%3, %3\;div{l}\t%2"
7592   [(set_attr "type" "multi")
7593    (set_attr "length_immediate" "0")
7594    (set_attr "mode" "SI")])
7595
7596 (define_insn "*udivmodsi4_noext"
7597   [(set (match_operand:SI 0 "register_operand" "=a")
7598         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7599                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7600    (set (match_operand:SI 3 "register_operand" "=d")
7601         (umod:SI (match_dup 1) (match_dup 2)))
7602    (use (match_dup 3))
7603    (clobber (reg:CC FLAGS_REG))]
7604   ""
7605   "div{l}\t%2"
7606   [(set_attr "type" "idiv")
7607    (set_attr "mode" "SI")])
7608
7609 (define_split
7610   [(set (match_operand:SI 0 "register_operand" "")
7611         (udiv:SI (match_operand:SI 1 "register_operand" "")
7612                  (match_operand:SI 2 "nonimmediate_operand" "")))
7613    (set (match_operand:SI 3 "register_operand" "")
7614         (umod:SI (match_dup 1) (match_dup 2)))
7615    (clobber (reg:CC FLAGS_REG))]
7616   "reload_completed"
7617   [(set (match_dup 3) (const_int 0))
7618    (parallel [(set (match_dup 0)
7619                    (udiv:SI (match_dup 1) (match_dup 2)))
7620               (set (match_dup 3)
7621                    (umod:SI (match_dup 1) (match_dup 2)))
7622               (use (match_dup 3))
7623               (clobber (reg:CC FLAGS_REG))])]
7624   "")
7625
7626 (define_expand "udivmodhi4"
7627   [(set (match_dup 4) (const_int 0))
7628    (parallel [(set (match_operand:HI 0 "register_operand" "")
7629                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7630                             (match_operand:HI 2 "nonimmediate_operand" "")))
7631               (set (match_operand:HI 3 "register_operand" "")
7632                    (umod:HI (match_dup 1) (match_dup 2)))
7633               (use (match_dup 4))
7634               (clobber (reg:CC FLAGS_REG))])]
7635   "TARGET_HIMODE_MATH"
7636   "operands[4] = gen_reg_rtx (HImode);")
7637
7638 (define_insn "*udivmodhi_noext"
7639   [(set (match_operand:HI 0 "register_operand" "=a")
7640         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7641                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7642    (set (match_operand:HI 3 "register_operand" "=d")
7643         (umod:HI (match_dup 1) (match_dup 2)))
7644    (use (match_operand:HI 4 "register_operand" "3"))
7645    (clobber (reg:CC FLAGS_REG))]
7646   ""
7647   "div{w}\t%2"
7648   [(set_attr "type" "idiv")
7649    (set_attr "mode" "HI")])
7650
7651 ;; We cannot use div/idiv for double division, because it causes
7652 ;; "division by zero" on the overflow and that's not what we expect
7653 ;; from truncate.  Because true (non truncating) double division is
7654 ;; never generated, we can't create this insn anyway.
7655 ;
7656 ;(define_insn ""
7657 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7658 ;       (truncate:SI
7659 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7660 ;                  (zero_extend:DI
7661 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7662 ;   (set (match_operand:SI 3 "register_operand" "=d")
7663 ;       (truncate:SI
7664 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7665 ;   (clobber (reg:CC FLAGS_REG))]
7666 ;  ""
7667 ;  "div{l}\t{%2, %0|%0, %2}"
7668 ;  [(set_attr "type" "idiv")])
7669 \f
7670 ;;- Logical AND instructions
7671
7672 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7673 ;; Note that this excludes ah.
7674
7675 (define_insn "*testdi_1_rex64"
7676   [(set (reg FLAGS_REG)
7677         (compare
7678           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7679                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7680           (const_int 0)))]
7681   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7682    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7683   "@
7684    test{l}\t{%k1, %k0|%k0, %k1}
7685    test{l}\t{%k1, %k0|%k0, %k1}
7686    test{q}\t{%1, %0|%0, %1}
7687    test{q}\t{%1, %0|%0, %1}
7688    test{q}\t{%1, %0|%0, %1}"
7689   [(set_attr "type" "test")
7690    (set_attr "modrm" "0,1,0,1,1")
7691    (set_attr "mode" "SI,SI,DI,DI,DI")
7692    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7693
7694 (define_insn "testsi_1"
7695   [(set (reg FLAGS_REG)
7696         (compare
7697           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7698                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7699           (const_int 0)))]
7700   "ix86_match_ccmode (insn, CCNOmode)
7701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7702   "test{l}\t{%1, %0|%0, %1}"
7703   [(set_attr "type" "test")
7704    (set_attr "modrm" "0,1,1")
7705    (set_attr "mode" "SI")
7706    (set_attr "pent_pair" "uv,np,uv")])
7707
7708 (define_expand "testsi_ccno_1"
7709   [(set (reg:CCNO FLAGS_REG)
7710         (compare:CCNO
7711           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7712                   (match_operand:SI 1 "nonmemory_operand" ""))
7713           (const_int 0)))]
7714   ""
7715   "")
7716
7717 (define_insn "*testhi_1"
7718   [(set (reg FLAGS_REG)
7719         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7720                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7721                  (const_int 0)))]
7722   "ix86_match_ccmode (insn, CCNOmode)
7723    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724   "test{w}\t{%1, %0|%0, %1}"
7725   [(set_attr "type" "test")
7726    (set_attr "modrm" "0,1,1")
7727    (set_attr "mode" "HI")
7728    (set_attr "pent_pair" "uv,np,uv")])
7729
7730 (define_expand "testqi_ccz_1"
7731   [(set (reg:CCZ FLAGS_REG)
7732         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7733                              (match_operand:QI 1 "nonmemory_operand" ""))
7734                  (const_int 0)))]
7735   ""
7736   "")
7737
7738 (define_insn "*testqi_1_maybe_si"
7739   [(set (reg FLAGS_REG)
7740         (compare
7741           (and:QI
7742             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7743             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7744           (const_int 0)))]
7745    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7746     && ix86_match_ccmode (insn,
7747                          GET_CODE (operands[1]) == CONST_INT
7748                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7749 {
7750   if (which_alternative == 3)
7751     {
7752       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7753         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7754       return "test{l}\t{%1, %k0|%k0, %1}";
7755     }
7756   return "test{b}\t{%1, %0|%0, %1}";
7757 }
7758   [(set_attr "type" "test")
7759    (set_attr "modrm" "0,1,1,1")
7760    (set_attr "mode" "QI,QI,QI,SI")
7761    (set_attr "pent_pair" "uv,np,uv,np")])
7762
7763 (define_insn "*testqi_1"
7764   [(set (reg FLAGS_REG)
7765         (compare
7766           (and:QI
7767             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7768             (match_operand:QI 1 "general_operand" "n,n,qn"))
7769           (const_int 0)))]
7770   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7771    && ix86_match_ccmode (insn, CCNOmode)"
7772   "test{b}\t{%1, %0|%0, %1}"
7773   [(set_attr "type" "test")
7774    (set_attr "modrm" "0,1,1")
7775    (set_attr "mode" "QI")
7776    (set_attr "pent_pair" "uv,np,uv")])
7777
7778 (define_expand "testqi_ext_ccno_0"
7779   [(set (reg:CCNO FLAGS_REG)
7780         (compare:CCNO
7781           (and:SI
7782             (zero_extract:SI
7783               (match_operand 0 "ext_register_operand" "")
7784               (const_int 8)
7785               (const_int 8))
7786             (match_operand 1 "const_int_operand" ""))
7787           (const_int 0)))]
7788   ""
7789   "")
7790
7791 (define_insn "*testqi_ext_0"
7792   [(set (reg FLAGS_REG)
7793         (compare
7794           (and:SI
7795             (zero_extract:SI
7796               (match_operand 0 "ext_register_operand" "Q")
7797               (const_int 8)
7798               (const_int 8))
7799             (match_operand 1 "const_int_operand" "n"))
7800           (const_int 0)))]
7801   "ix86_match_ccmode (insn, CCNOmode)"
7802   "test{b}\t{%1, %h0|%h0, %1}"
7803   [(set_attr "type" "test")
7804    (set_attr "mode" "QI")
7805    (set_attr "length_immediate" "1")
7806    (set_attr "pent_pair" "np")])
7807
7808 (define_insn "*testqi_ext_1"
7809   [(set (reg FLAGS_REG)
7810         (compare
7811           (and:SI
7812             (zero_extract:SI
7813               (match_operand 0 "ext_register_operand" "Q")
7814               (const_int 8)
7815               (const_int 8))
7816             (zero_extend:SI
7817               (match_operand:QI 1 "general_operand" "Qm")))
7818           (const_int 0)))]
7819   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7820    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7821   "test{b}\t{%1, %h0|%h0, %1}"
7822   [(set_attr "type" "test")
7823    (set_attr "mode" "QI")])
7824
7825 (define_insn "*testqi_ext_1_rex64"
7826   [(set (reg FLAGS_REG)
7827         (compare
7828           (and:SI
7829             (zero_extract:SI
7830               (match_operand 0 "ext_register_operand" "Q")
7831               (const_int 8)
7832               (const_int 8))
7833             (zero_extend:SI
7834               (match_operand:QI 1 "register_operand" "Q")))
7835           (const_int 0)))]
7836   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7837   "test{b}\t{%1, %h0|%h0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "mode" "QI")])
7840
7841 (define_insn "*testqi_ext_2"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (zero_extract:SI
7850               (match_operand 1 "ext_register_operand" "Q")
7851               (const_int 8)
7852               (const_int 8)))
7853           (const_int 0)))]
7854   "ix86_match_ccmode (insn, CCNOmode)"
7855   "test{b}\t{%h1, %h0|%h0, %h1}"
7856   [(set_attr "type" "test")
7857    (set_attr "mode" "QI")])
7858
7859 ;; Combine likes to form bit extractions for some tests.  Humor it.
7860 (define_insn "*testqi_ext_3"
7861   [(set (reg FLAGS_REG)
7862         (compare (zero_extract:SI
7863                    (match_operand 0 "nonimmediate_operand" "rm")
7864                    (match_operand:SI 1 "const_int_operand" "")
7865                    (match_operand:SI 2 "const_int_operand" ""))
7866                  (const_int 0)))]
7867   "ix86_match_ccmode (insn, CCNOmode)
7868    && INTVAL (operands[1]) > 0
7869    && INTVAL (operands[2]) >= 0
7870    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7871    && (GET_MODE (operands[0]) == SImode
7872        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7873        || GET_MODE (operands[0]) == HImode
7874        || GET_MODE (operands[0]) == QImode)"
7875   "#")
7876
7877 (define_insn "*testqi_ext_3_rex64"
7878   [(set (reg FLAGS_REG)
7879         (compare (zero_extract:DI
7880                    (match_operand 0 "nonimmediate_operand" "rm")
7881                    (match_operand:DI 1 "const_int_operand" "")
7882                    (match_operand:DI 2 "const_int_operand" ""))
7883                  (const_int 0)))]
7884   "TARGET_64BIT
7885    && ix86_match_ccmode (insn, CCNOmode)
7886    && INTVAL (operands[1]) > 0
7887    && INTVAL (operands[2]) >= 0
7888    /* Ensure that resulting mask is zero or sign extended operand.  */
7889    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7890        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7891            && INTVAL (operands[1]) > 32))
7892    && (GET_MODE (operands[0]) == SImode
7893        || GET_MODE (operands[0]) == DImode
7894        || GET_MODE (operands[0]) == HImode
7895        || GET_MODE (operands[0]) == QImode)"
7896   "#")
7897
7898 (define_split
7899   [(set (match_operand 0 "flags_reg_operand" "")
7900         (match_operator 1 "compare_operator"
7901           [(zero_extract
7902              (match_operand 2 "nonimmediate_operand" "")
7903              (match_operand 3 "const_int_operand" "")
7904              (match_operand 4 "const_int_operand" ""))
7905            (const_int 0)]))]
7906   "ix86_match_ccmode (insn, CCNOmode)"
7907   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7908 {
7909   rtx val = operands[2];
7910   HOST_WIDE_INT len = INTVAL (operands[3]);
7911   HOST_WIDE_INT pos = INTVAL (operands[4]);
7912   HOST_WIDE_INT mask;
7913   enum machine_mode mode, submode;
7914
7915   mode = GET_MODE (val);
7916   if (GET_CODE (val) == MEM)
7917     {
7918       /* ??? Combine likes to put non-volatile mem extractions in QImode
7919          no matter the size of the test.  So find a mode that works.  */
7920       if (! MEM_VOLATILE_P (val))
7921         {
7922           mode = smallest_mode_for_size (pos + len, MODE_INT);
7923           val = adjust_address (val, mode, 0);
7924         }
7925     }
7926   else if (GET_CODE (val) == SUBREG
7927            && (submode = GET_MODE (SUBREG_REG (val)),
7928                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7929            && pos + len <= GET_MODE_BITSIZE (submode))
7930     {
7931       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7932       mode = submode;
7933       val = SUBREG_REG (val);
7934     }
7935   else if (mode == HImode && pos + len <= 8)
7936     {
7937       /* Small HImode tests can be converted to QImode.  */
7938       mode = QImode;
7939       val = gen_lowpart (QImode, val);
7940     }
7941
7942   if (len == HOST_BITS_PER_WIDE_INT)
7943     mask = -1;
7944   else
7945     mask = ((HOST_WIDE_INT)1 << len) - 1;
7946   mask <<= pos;
7947
7948   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7949 })
7950
7951 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7952 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7953 ;; this is relatively important trick.
7954 ;; Do the conversion only post-reload to avoid limiting of the register class
7955 ;; to QI regs.
7956 (define_split
7957   [(set (match_operand 0 "flags_reg_operand" "")
7958         (match_operator 1 "compare_operator"
7959           [(and (match_operand 2 "register_operand" "")
7960                 (match_operand 3 "const_int_operand" ""))
7961            (const_int 0)]))]
7962    "reload_completed
7963     && QI_REG_P (operands[2])
7964     && GET_MODE (operands[2]) != QImode
7965     && ((ix86_match_ccmode (insn, CCZmode)
7966          && !(INTVAL (operands[3]) & ~(255 << 8)))
7967         || (ix86_match_ccmode (insn, CCNOmode)
7968             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7969   [(set (match_dup 0)
7970         (match_op_dup 1
7971           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7972                    (match_dup 3))
7973            (const_int 0)]))]
7974   "operands[2] = gen_lowpart (SImode, operands[2]);
7975    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7976
7977 (define_split
7978   [(set (match_operand 0 "flags_reg_operand" "")
7979         (match_operator 1 "compare_operator"
7980           [(and (match_operand 2 "nonimmediate_operand" "")
7981                 (match_operand 3 "const_int_operand" ""))
7982            (const_int 0)]))]
7983    "reload_completed
7984     && GET_MODE (operands[2]) != QImode
7985     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7986     && ((ix86_match_ccmode (insn, CCZmode)
7987          && !(INTVAL (operands[3]) & ~255))
7988         || (ix86_match_ccmode (insn, CCNOmode)
7989             && !(INTVAL (operands[3]) & ~127)))"
7990   [(set (match_dup 0)
7991         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7992                          (const_int 0)]))]
7993   "operands[2] = gen_lowpart (QImode, operands[2]);
7994    operands[3] = gen_lowpart (QImode, operands[3]);")
7995
7996
7997 ;; %%% This used to optimize known byte-wide and operations to memory,
7998 ;; and sometimes to QImode registers.  If this is considered useful,
7999 ;; it should be done with splitters.
8000
8001 (define_expand "anddi3"
8002   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8003         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8004                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8005    (clobber (reg:CC FLAGS_REG))]
8006   "TARGET_64BIT"
8007   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8008
8009 (define_insn "*anddi_1_rex64"
8010   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8011         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8012                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8015 {
8016   switch (get_attr_type (insn))
8017     {
8018     case TYPE_IMOVX:
8019       {
8020         enum machine_mode mode;
8021
8022         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8023         if (INTVAL (operands[2]) == 0xff)
8024           mode = QImode;
8025         else
8026           {
8027             gcc_assert (INTVAL (operands[2]) == 0xffff);
8028             mode = HImode;
8029           }
8030         
8031         operands[1] = gen_lowpart (mode, operands[1]);
8032         if (mode == QImode)
8033           return "movz{bq|x}\t{%1,%0|%0, %1}";
8034         else
8035           return "movz{wq|x}\t{%1,%0|%0, %1}";
8036       }
8037
8038     default:
8039       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8040       if (get_attr_mode (insn) == MODE_SI)
8041         return "and{l}\t{%k2, %k0|%k0, %k2}";
8042       else
8043         return "and{q}\t{%2, %0|%0, %2}";
8044     }
8045 }
8046   [(set_attr "type" "alu,alu,alu,imovx")
8047    (set_attr "length_immediate" "*,*,*,0")
8048    (set_attr "mode" "SI,DI,DI,DI")])
8049
8050 (define_insn "*anddi_2"
8051   [(set (reg FLAGS_REG)
8052         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054                  (const_int 0)))
8055    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056         (and:DI (match_dup 1) (match_dup 2)))]
8057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058    && ix86_binary_operator_ok (AND, DImode, operands)"
8059   "@
8060    and{l}\t{%k2, %k0|%k0, %k2}
8061    and{q}\t{%2, %0|%0, %2}
8062    and{q}\t{%2, %0|%0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "mode" "SI,DI,DI")])
8065
8066 (define_expand "andsi3"
8067   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8068         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8069                 (match_operand:SI 2 "general_operand" "")))
8070    (clobber (reg:CC FLAGS_REG))]
8071   ""
8072   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8073
8074 (define_insn "*andsi_1"
8075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8076         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8077                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8078    (clobber (reg:CC FLAGS_REG))]
8079   "ix86_binary_operator_ok (AND, SImode, operands)"
8080 {
8081   switch (get_attr_type (insn))
8082     {
8083     case TYPE_IMOVX:
8084       {
8085         enum machine_mode mode;
8086
8087         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8088         if (INTVAL (operands[2]) == 0xff)
8089           mode = QImode;
8090         else
8091           {
8092             gcc_assert (INTVAL (operands[2]) == 0xffff);
8093             mode = HImode;
8094           }
8095         
8096         operands[1] = gen_lowpart (mode, operands[1]);
8097         if (mode == QImode)
8098           return "movz{bl|x}\t{%1,%0|%0, %1}";
8099         else
8100           return "movz{wl|x}\t{%1,%0|%0, %1}";
8101       }
8102
8103     default:
8104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8105       return "and{l}\t{%2, %0|%0, %2}";
8106     }
8107 }
8108   [(set_attr "type" "alu,alu,imovx")
8109    (set_attr "length_immediate" "*,*,0")
8110    (set_attr "mode" "SI")])
8111
8112 (define_split
8113   [(set (match_operand 0 "register_operand" "")
8114         (and (match_dup 0)
8115              (const_int -65536)))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8118   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8119   "operands[1] = gen_lowpart (HImode, operands[0]);")
8120
8121 (define_split
8122   [(set (match_operand 0 "ext_register_operand" "")
8123         (and (match_dup 0)
8124              (const_int -256)))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8127   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8128   "operands[1] = gen_lowpart (QImode, operands[0]);")
8129
8130 (define_split
8131   [(set (match_operand 0 "ext_register_operand" "")
8132         (and (match_dup 0)
8133              (const_int -65281)))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8136   [(parallel [(set (zero_extract:SI (match_dup 0)
8137                                     (const_int 8)
8138                                     (const_int 8))
8139                    (xor:SI 
8140                      (zero_extract:SI (match_dup 0)
8141                                       (const_int 8)
8142                                       (const_int 8))
8143                      (zero_extract:SI (match_dup 0)
8144                                       (const_int 8)
8145                                       (const_int 8))))
8146               (clobber (reg:CC FLAGS_REG))])]
8147   "operands[0] = gen_lowpart (SImode, operands[0]);")
8148
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_1_zext"
8151   [(set (match_operand:DI 0 "register_operand" "=r")
8152         (zero_extend:DI
8153           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8154                   (match_operand:SI 2 "general_operand" "rim"))))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8157   "and{l}\t{%2, %k0|%k0, %2}"
8158   [(set_attr "type" "alu")
8159    (set_attr "mode" "SI")])
8160
8161 (define_insn "*andsi_2"
8162   [(set (reg FLAGS_REG)
8163         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8164                          (match_operand:SI 2 "general_operand" "rim,ri"))
8165                  (const_int 0)))
8166    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8167         (and:SI (match_dup 1) (match_dup 2)))]
8168   "ix86_match_ccmode (insn, CCNOmode)
8169    && ix86_binary_operator_ok (AND, SImode, operands)"
8170   "and{l}\t{%2, %0|%0, %2}"
8171   [(set_attr "type" "alu")
8172    (set_attr "mode" "SI")])
8173
8174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8175 (define_insn "*andsi_2_zext"
8176   [(set (reg FLAGS_REG)
8177         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8178                          (match_operand:SI 2 "general_operand" "rim"))
8179                  (const_int 0)))
8180    (set (match_operand:DI 0 "register_operand" "=r")
8181         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8182   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183    && ix86_binary_operator_ok (AND, SImode, operands)"
8184   "and{l}\t{%2, %k0|%k0, %2}"
8185   [(set_attr "type" "alu")
8186    (set_attr "mode" "SI")])
8187
8188 (define_expand "andhi3"
8189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8190         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8191                 (match_operand:HI 2 "general_operand" "")))
8192    (clobber (reg:CC FLAGS_REG))]
8193   "TARGET_HIMODE_MATH"
8194   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8195
8196 (define_insn "*andhi_1"
8197   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8198         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8199                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "ix86_binary_operator_ok (AND, HImode, operands)"
8202 {
8203   switch (get_attr_type (insn))
8204     {
8205     case TYPE_IMOVX:
8206       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8207       gcc_assert (INTVAL (operands[2]) == 0xff);
8208       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8209
8210     default:
8211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8212
8213       return "and{w}\t{%2, %0|%0, %2}";
8214     }
8215 }
8216   [(set_attr "type" "alu,alu,imovx")
8217    (set_attr "length_immediate" "*,*,0")
8218    (set_attr "mode" "HI,HI,SI")])
8219
8220 (define_insn "*andhi_2"
8221   [(set (reg FLAGS_REG)
8222         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8223                          (match_operand:HI 2 "general_operand" "rim,ri"))
8224                  (const_int 0)))
8225    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8226         (and:HI (match_dup 1) (match_dup 2)))]
8227   "ix86_match_ccmode (insn, CCNOmode)
8228    && ix86_binary_operator_ok (AND, HImode, operands)"
8229   "and{w}\t{%2, %0|%0, %2}"
8230   [(set_attr "type" "alu")
8231    (set_attr "mode" "HI")])
8232
8233 (define_expand "andqi3"
8234   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8235         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8236                 (match_operand:QI 2 "general_operand" "")))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "TARGET_QIMODE_MATH"
8239   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8240
8241 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8242 (define_insn "*andqi_1"
8243   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8244         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8245                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8246    (clobber (reg:CC FLAGS_REG))]
8247   "ix86_binary_operator_ok (AND, QImode, operands)"
8248   "@
8249    and{b}\t{%2, %0|%0, %2}
8250    and{b}\t{%2, %0|%0, %2}
8251    and{l}\t{%k2, %k0|%k0, %k2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "mode" "QI,QI,SI")])
8254
8255 (define_insn "*andqi_1_slp"
8256   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8257         (and:QI (match_dup 0)
8258                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8261    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262   "and{b}\t{%1, %0|%0, %1}"
8263   [(set_attr "type" "alu1")
8264    (set_attr "mode" "QI")])
8265
8266 (define_insn "*andqi_2_maybe_si"
8267   [(set (reg FLAGS_REG)
8268         (compare (and:QI
8269                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8270                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8271                  (const_int 0)))
8272    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8273         (and:QI (match_dup 1) (match_dup 2)))]
8274   "ix86_binary_operator_ok (AND, QImode, operands)
8275    && ix86_match_ccmode (insn,
8276                          GET_CODE (operands[2]) == CONST_INT
8277                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8278 {
8279   if (which_alternative == 2)
8280     {
8281       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8282         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8283       return "and{l}\t{%2, %k0|%k0, %2}";
8284     }
8285   return "and{b}\t{%2, %0|%0, %2}";
8286 }
8287   [(set_attr "type" "alu")
8288    (set_attr "mode" "QI,QI,SI")])
8289
8290 (define_insn "*andqi_2"
8291   [(set (reg FLAGS_REG)
8292         (compare (and:QI
8293                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8294                    (match_operand:QI 2 "general_operand" "qim,qi"))
8295                  (const_int 0)))
8296    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8297         (and:QI (match_dup 1) (match_dup 2)))]
8298   "ix86_match_ccmode (insn, CCNOmode)
8299    && ix86_binary_operator_ok (AND, QImode, operands)"
8300   "and{b}\t{%2, %0|%0, %2}"
8301   [(set_attr "type" "alu")
8302    (set_attr "mode" "QI")])
8303
8304 (define_insn "*andqi_2_slp"
8305   [(set (reg FLAGS_REG)
8306         (compare (and:QI
8307                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8308                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8309                  (const_int 0)))
8310    (set (strict_low_part (match_dup 0))
8311         (and:QI (match_dup 0) (match_dup 1)))]
8312   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8313    && ix86_match_ccmode (insn, CCNOmode)
8314    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8315   "and{b}\t{%1, %0|%0, %1}"
8316   [(set_attr "type" "alu1")
8317    (set_attr "mode" "QI")])
8318
8319 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8320 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8321 ;; for a QImode operand, which of course failed.
8322
8323 (define_insn "andqi_ext_0"
8324   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325                          (const_int 8)
8326                          (const_int 8))
8327         (and:SI 
8328           (zero_extract:SI
8329             (match_operand 1 "ext_register_operand" "0")
8330             (const_int 8)
8331             (const_int 8))
8332           (match_operand 2 "const_int_operand" "n")))
8333    (clobber (reg:CC FLAGS_REG))]
8334   ""
8335   "and{b}\t{%2, %h0|%h0, %2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "length_immediate" "1")
8338    (set_attr "mode" "QI")])
8339
8340 ;; Generated by peephole translating test to and.  This shows up
8341 ;; often in fp comparisons.
8342
8343 (define_insn "*andqi_ext_0_cc"
8344   [(set (reg FLAGS_REG)
8345         (compare
8346           (and:SI
8347             (zero_extract:SI
8348               (match_operand 1 "ext_register_operand" "0")
8349               (const_int 8)
8350               (const_int 8))
8351             (match_operand 2 "const_int_operand" "n"))
8352           (const_int 0)))
8353    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8354                          (const_int 8)
8355                          (const_int 8))
8356         (and:SI 
8357           (zero_extract:SI
8358             (match_dup 1)
8359             (const_int 8)
8360             (const_int 8))
8361           (match_dup 2)))]
8362   "ix86_match_ccmode (insn, CCNOmode)"
8363   "and{b}\t{%2, %h0|%h0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "length_immediate" "1")
8366    (set_attr "mode" "QI")])
8367
8368 (define_insn "*andqi_ext_1"
8369   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370                          (const_int 8)
8371                          (const_int 8))
8372         (and:SI 
8373           (zero_extract:SI
8374             (match_operand 1 "ext_register_operand" "0")
8375             (const_int 8)
8376             (const_int 8))
8377           (zero_extend:SI
8378             (match_operand:QI 2 "general_operand" "Qm"))))
8379    (clobber (reg:CC FLAGS_REG))]
8380   "!TARGET_64BIT"
8381   "and{b}\t{%2, %h0|%h0, %2}"
8382   [(set_attr "type" "alu")
8383    (set_attr "length_immediate" "0")
8384    (set_attr "mode" "QI")])
8385
8386 (define_insn "*andqi_ext_1_rex64"
8387   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388                          (const_int 8)
8389                          (const_int 8))
8390         (and:SI 
8391           (zero_extract:SI
8392             (match_operand 1 "ext_register_operand" "0")
8393             (const_int 8)
8394             (const_int 8))
8395           (zero_extend:SI
8396             (match_operand 2 "ext_register_operand" "Q"))))
8397    (clobber (reg:CC FLAGS_REG))]
8398   "TARGET_64BIT"
8399   "and{b}\t{%2, %h0|%h0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "length_immediate" "0")
8402    (set_attr "mode" "QI")])
8403
8404 (define_insn "*andqi_ext_2"
8405   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406                          (const_int 8)
8407                          (const_int 8))
8408         (and:SI
8409           (zero_extract:SI
8410             (match_operand 1 "ext_register_operand" "%0")
8411             (const_int 8)
8412             (const_int 8))
8413           (zero_extract:SI
8414             (match_operand 2 "ext_register_operand" "Q")
8415             (const_int 8)
8416             (const_int 8))))
8417    (clobber (reg:CC FLAGS_REG))]
8418   ""
8419   "and{b}\t{%h2, %h0|%h0, %h2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "length_immediate" "0")
8422    (set_attr "mode" "QI")])
8423
8424 ;; Convert wide AND instructions with immediate operand to shorter QImode
8425 ;; equivalents when possible.
8426 ;; Don't do the splitting with memory operands, since it introduces risk
8427 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8428 ;; for size, but that can (should?) be handled by generic code instead.
8429 (define_split
8430   [(set (match_operand 0 "register_operand" "")
8431         (and (match_operand 1 "register_operand" "")
8432              (match_operand 2 "const_int_operand" "")))
8433    (clobber (reg:CC FLAGS_REG))]
8434    "reload_completed
8435     && QI_REG_P (operands[0])
8436     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8437     && !(~INTVAL (operands[2]) & ~(255 << 8))
8438     && GET_MODE (operands[0]) != QImode"
8439   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8440                    (and:SI (zero_extract:SI (match_dup 1)
8441                                             (const_int 8) (const_int 8))
8442                            (match_dup 2)))
8443               (clobber (reg:CC FLAGS_REG))])]
8444   "operands[0] = gen_lowpart (SImode, operands[0]);
8445    operands[1] = gen_lowpart (SImode, operands[1]);
8446    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8447
8448 ;; Since AND can be encoded with sign extended immediate, this is only
8449 ;; profitable when 7th bit is not set.
8450 (define_split
8451   [(set (match_operand 0 "register_operand" "")
8452         (and (match_operand 1 "general_operand" "")
8453              (match_operand 2 "const_int_operand" "")))
8454    (clobber (reg:CC FLAGS_REG))]
8455    "reload_completed
8456     && ANY_QI_REG_P (operands[0])
8457     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458     && !(~INTVAL (operands[2]) & ~255)
8459     && !(INTVAL (operands[2]) & 128)
8460     && GET_MODE (operands[0]) != QImode"
8461   [(parallel [(set (strict_low_part (match_dup 0))
8462                    (and:QI (match_dup 1)
8463                            (match_dup 2)))
8464               (clobber (reg:CC FLAGS_REG))])]
8465   "operands[0] = gen_lowpart (QImode, operands[0]);
8466    operands[1] = gen_lowpart (QImode, operands[1]);
8467    operands[2] = gen_lowpart (QImode, operands[2]);")
8468 \f
8469 ;; Logical inclusive OR instructions
8470
8471 ;; %%% This used to optimize known byte-wide and operations to memory.
8472 ;; If this is considered useful, it should be done with splitters.
8473
8474 (define_expand "iordi3"
8475   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8476         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8477                 (match_operand:DI 2 "x86_64_general_operand" "")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_64BIT"
8480   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8481
8482 (define_insn "*iordi_1_rex64"
8483   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8484         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8485                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "TARGET_64BIT
8488    && ix86_binary_operator_ok (IOR, DImode, operands)"
8489   "or{q}\t{%2, %0|%0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "mode" "DI")])
8492
8493 (define_insn "*iordi_2_rex64"
8494   [(set (reg FLAGS_REG)
8495         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8496                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8497                  (const_int 0)))
8498    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8499         (ior:DI (match_dup 1) (match_dup 2)))]
8500   "TARGET_64BIT
8501    && ix86_match_ccmode (insn, CCNOmode)
8502    && ix86_binary_operator_ok (IOR, DImode, operands)"
8503   "or{q}\t{%2, %0|%0, %2}"
8504   [(set_attr "type" "alu")
8505    (set_attr "mode" "DI")])
8506
8507 (define_insn "*iordi_3_rex64"
8508   [(set (reg FLAGS_REG)
8509         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8510                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8511                  (const_int 0)))
8512    (clobber (match_scratch:DI 0 "=r"))]
8513   "TARGET_64BIT
8514    && ix86_match_ccmode (insn, CCNOmode)
8515    && ix86_binary_operator_ok (IOR, DImode, operands)"
8516   "or{q}\t{%2, %0|%0, %2}"
8517   [(set_attr "type" "alu")
8518    (set_attr "mode" "DI")])
8519
8520
8521 (define_expand "iorsi3"
8522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8523         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8524                 (match_operand:SI 2 "general_operand" "")))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8528
8529 (define_insn "*iorsi_1"
8530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8531         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8532                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8533    (clobber (reg:CC FLAGS_REG))]
8534   "ix86_binary_operator_ok (IOR, SImode, operands)"
8535   "or{l}\t{%2, %0|%0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "mode" "SI")])
8538
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 (define_insn "*iorsi_1_zext"
8541   [(set (match_operand:DI 0 "register_operand" "=rm")
8542         (zero_extend:DI
8543           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544                   (match_operand:SI 2 "general_operand" "rim"))))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8547   "or{l}\t{%2, %k0|%k0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "SI")])
8550
8551 (define_insn "*iorsi_1_zext_imm"
8552   [(set (match_operand:DI 0 "register_operand" "=rm")
8553         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8554                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8555    (clobber (reg:CC FLAGS_REG))]
8556   "TARGET_64BIT"
8557   "or{l}\t{%2, %k0|%k0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "SI")])
8560
8561 (define_insn "*iorsi_2"
8562   [(set (reg FLAGS_REG)
8563         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564                          (match_operand:SI 2 "general_operand" "rim,ri"))
8565                  (const_int 0)))
8566    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567         (ior:SI (match_dup 1) (match_dup 2)))]
8568   "ix86_match_ccmode (insn, CCNOmode)
8569    && ix86_binary_operator_ok (IOR, SImode, operands)"
8570   "or{l}\t{%2, %0|%0, %2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "SI")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 ;; ??? Special case for immediate operand is missing - it is tricky.
8576 (define_insn "*iorsi_2_zext"
8577   [(set (reg FLAGS_REG)
8578         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579                          (match_operand:SI 2 "general_operand" "rim"))
8580                  (const_int 0)))
8581    (set (match_operand:DI 0 "register_operand" "=r")
8582         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8583   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (IOR, SImode, operands)"
8585   "or{l}\t{%2, %k0|%k0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "SI")])
8588
8589 (define_insn "*iorsi_2_zext_imm"
8590   [(set (reg FLAGS_REG)
8591         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8592                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8593                  (const_int 0)))
8594    (set (match_operand:DI 0 "register_operand" "=r")
8595         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8596   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8597    && ix86_binary_operator_ok (IOR, SImode, operands)"
8598   "or{l}\t{%2, %k0|%k0, %2}"
8599   [(set_attr "type" "alu")
8600    (set_attr "mode" "SI")])
8601
8602 (define_insn "*iorsi_3"
8603   [(set (reg FLAGS_REG)
8604         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8605                          (match_operand:SI 2 "general_operand" "rim"))
8606                  (const_int 0)))
8607    (clobber (match_scratch:SI 0 "=r"))]
8608   "ix86_match_ccmode (insn, CCNOmode)
8609    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8610   "or{l}\t{%2, %0|%0, %2}"
8611   [(set_attr "type" "alu")
8612    (set_attr "mode" "SI")])
8613
8614 (define_expand "iorhi3"
8615   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8616         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8617                 (match_operand:HI 2 "general_operand" "")))
8618    (clobber (reg:CC FLAGS_REG))]
8619   "TARGET_HIMODE_MATH"
8620   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8621
8622 (define_insn "*iorhi_1"
8623   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8624         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8625                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "ix86_binary_operator_ok (IOR, HImode, operands)"
8628   "or{w}\t{%2, %0|%0, %2}"
8629   [(set_attr "type" "alu")
8630    (set_attr "mode" "HI")])
8631
8632 (define_insn "*iorhi_2"
8633   [(set (reg FLAGS_REG)
8634         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635                          (match_operand:HI 2 "general_operand" "rim,ri"))
8636                  (const_int 0)))
8637    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638         (ior:HI (match_dup 1) (match_dup 2)))]
8639   "ix86_match_ccmode (insn, CCNOmode)
8640    && ix86_binary_operator_ok (IOR, HImode, operands)"
8641   "or{w}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "HI")])
8644
8645 (define_insn "*iorhi_3"
8646   [(set (reg FLAGS_REG)
8647         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8648                          (match_operand:HI 2 "general_operand" "rim"))
8649                  (const_int 0)))
8650    (clobber (match_scratch:HI 0 "=r"))]
8651   "ix86_match_ccmode (insn, CCNOmode)
8652    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8653   "or{w}\t{%2, %0|%0, %2}"
8654   [(set_attr "type" "alu")
8655    (set_attr "mode" "HI")])
8656
8657 (define_expand "iorqi3"
8658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8659         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8660                 (match_operand:QI 2 "general_operand" "")))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "TARGET_QIMODE_MATH"
8663   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8664
8665 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8666 (define_insn "*iorqi_1"
8667   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8668         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "ix86_binary_operator_ok (IOR, QImode, operands)"
8672   "@
8673    or{b}\t{%2, %0|%0, %2}
8674    or{b}\t{%2, %0|%0, %2}
8675    or{l}\t{%k2, %k0|%k0, %k2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "QI,QI,SI")])
8678
8679 (define_insn "*iorqi_1_slp"
8680   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8681         (ior:QI (match_dup 0)
8682                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8683    (clobber (reg:CC FLAGS_REG))]
8684   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8686   "or{b}\t{%1, %0|%0, %1}"
8687   [(set_attr "type" "alu1")
8688    (set_attr "mode" "QI")])
8689
8690 (define_insn "*iorqi_2"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8693                          (match_operand:QI 2 "general_operand" "qim,qi"))
8694                  (const_int 0)))
8695    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8696         (ior:QI (match_dup 1) (match_dup 2)))]
8697   "ix86_match_ccmode (insn, CCNOmode)
8698    && ix86_binary_operator_ok (IOR, QImode, operands)"
8699   "or{b}\t{%2, %0|%0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "QI")])
8702
8703 (define_insn "*iorqi_2_slp"
8704   [(set (reg FLAGS_REG)
8705         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8706                          (match_operand:QI 1 "general_operand" "qim,qi"))
8707                  (const_int 0)))
8708    (set (strict_low_part (match_dup 0))
8709         (ior:QI (match_dup 0) (match_dup 1)))]
8710   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8711    && ix86_match_ccmode (insn, CCNOmode)
8712    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8713   "or{b}\t{%1, %0|%0, %1}"
8714   [(set_attr "type" "alu1")
8715    (set_attr "mode" "QI")])
8716
8717 (define_insn "*iorqi_3"
8718   [(set (reg FLAGS_REG)
8719         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8720                          (match_operand:QI 2 "general_operand" "qim"))
8721                  (const_int 0)))
8722    (clobber (match_scratch:QI 0 "=q"))]
8723   "ix86_match_ccmode (insn, CCNOmode)
8724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725   "or{b}\t{%2, %0|%0, %2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "mode" "QI")])
8728
8729 (define_insn "iorqi_ext_0"
8730   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8731                          (const_int 8)
8732                          (const_int 8))
8733         (ior:SI 
8734           (zero_extract:SI
8735             (match_operand 1 "ext_register_operand" "0")
8736             (const_int 8)
8737             (const_int 8))
8738           (match_operand 2 "const_int_operand" "n")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8741   "or{b}\t{%2, %h0|%h0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "length_immediate" "1")
8744    (set_attr "mode" "QI")])
8745
8746 (define_insn "*iorqi_ext_1"
8747   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8748                          (const_int 8)
8749                          (const_int 8))
8750         (ior:SI 
8751           (zero_extract:SI
8752             (match_operand 1 "ext_register_operand" "0")
8753             (const_int 8)
8754             (const_int 8))
8755           (zero_extend:SI
8756             (match_operand:QI 2 "general_operand" "Qm"))))
8757    (clobber (reg:CC FLAGS_REG))]
8758   "!TARGET_64BIT
8759    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8760   "or{b}\t{%2, %h0|%h0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "length_immediate" "0")
8763    (set_attr "mode" "QI")])
8764
8765 (define_insn "*iorqi_ext_1_rex64"
8766   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767                          (const_int 8)
8768                          (const_int 8))
8769         (ior:SI 
8770           (zero_extract:SI
8771             (match_operand 1 "ext_register_operand" "0")
8772             (const_int 8)
8773             (const_int 8))
8774           (zero_extend:SI
8775             (match_operand 2 "ext_register_operand" "Q"))))
8776    (clobber (reg:CC FLAGS_REG))]
8777   "TARGET_64BIT
8778    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8779   "or{b}\t{%2, %h0|%h0, %2}"
8780   [(set_attr "type" "alu")
8781    (set_attr "length_immediate" "0")
8782    (set_attr "mode" "QI")])
8783
8784 (define_insn "*iorqi_ext_2"
8785   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786                          (const_int 8)
8787                          (const_int 8))
8788         (ior:SI 
8789           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8790                            (const_int 8)
8791                            (const_int 8))
8792           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8793                            (const_int 8)
8794                            (const_int 8))))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8797   "ior{b}\t{%h2, %h0|%h0, %h2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "length_immediate" "0")
8800    (set_attr "mode" "QI")])
8801
8802 (define_split
8803   [(set (match_operand 0 "register_operand" "")
8804         (ior (match_operand 1 "register_operand" "")
8805              (match_operand 2 "const_int_operand" "")))
8806    (clobber (reg:CC FLAGS_REG))]
8807    "reload_completed
8808     && QI_REG_P (operands[0])
8809     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8810     && !(INTVAL (operands[2]) & ~(255 << 8))
8811     && GET_MODE (operands[0]) != QImode"
8812   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8813                    (ior:SI (zero_extract:SI (match_dup 1)
8814                                             (const_int 8) (const_int 8))
8815                            (match_dup 2)))
8816               (clobber (reg:CC FLAGS_REG))])]
8817   "operands[0] = gen_lowpart (SImode, operands[0]);
8818    operands[1] = gen_lowpart (SImode, operands[1]);
8819    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8820
8821 ;; Since OR can be encoded with sign extended immediate, this is only
8822 ;; profitable when 7th bit is set.
8823 (define_split
8824   [(set (match_operand 0 "register_operand" "")
8825         (ior (match_operand 1 "general_operand" "")
8826              (match_operand 2 "const_int_operand" "")))
8827    (clobber (reg:CC FLAGS_REG))]
8828    "reload_completed
8829     && ANY_QI_REG_P (operands[0])
8830     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831     && !(INTVAL (operands[2]) & ~255)
8832     && (INTVAL (operands[2]) & 128)
8833     && GET_MODE (operands[0]) != QImode"
8834   [(parallel [(set (strict_low_part (match_dup 0))
8835                    (ior:QI (match_dup 1)
8836                            (match_dup 2)))
8837               (clobber (reg:CC FLAGS_REG))])]
8838   "operands[0] = gen_lowpart (QImode, operands[0]);
8839    operands[1] = gen_lowpart (QImode, operands[1]);
8840    operands[2] = gen_lowpart (QImode, operands[2]);")
8841 \f
8842 ;; Logical XOR instructions
8843
8844 ;; %%% This used to optimize known byte-wide and operations to memory.
8845 ;; If this is considered useful, it should be done with splitters.
8846
8847 (define_expand "xordi3"
8848   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8849         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8850                 (match_operand:DI 2 "x86_64_general_operand" "")))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "TARGET_64BIT"
8853   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8854
8855 (define_insn "*xordi_1_rex64"
8856   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8857         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8858                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8859    (clobber (reg:CC FLAGS_REG))]
8860   "TARGET_64BIT
8861    && ix86_binary_operator_ok (XOR, DImode, operands)"
8862   "@
8863    xor{q}\t{%2, %0|%0, %2}
8864    xor{q}\t{%2, %0|%0, %2}"
8865   [(set_attr "type" "alu")
8866    (set_attr "mode" "DI,DI")])
8867
8868 (define_insn "*xordi_2_rex64"
8869   [(set (reg FLAGS_REG)
8870         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8871                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8872                  (const_int 0)))
8873    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8874         (xor:DI (match_dup 1) (match_dup 2)))]
8875   "TARGET_64BIT
8876    && ix86_match_ccmode (insn, CCNOmode)
8877    && ix86_binary_operator_ok (XOR, DImode, operands)"
8878   "@
8879    xor{q}\t{%2, %0|%0, %2}
8880    xor{q}\t{%2, %0|%0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "mode" "DI,DI")])
8883
8884 (define_insn "*xordi_3_rex64"
8885   [(set (reg FLAGS_REG)
8886         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8888                  (const_int 0)))
8889    (clobber (match_scratch:DI 0 "=r"))]
8890   "TARGET_64BIT
8891    && ix86_match_ccmode (insn, CCNOmode)
8892    && ix86_binary_operator_ok (XOR, DImode, operands)"
8893   "xor{q}\t{%2, %0|%0, %2}"
8894   [(set_attr "type" "alu")
8895    (set_attr "mode" "DI")])
8896
8897 (define_expand "xorsi3"
8898   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8899         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8900                 (match_operand:SI 2 "general_operand" "")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   ""
8903   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8904
8905 (define_insn "*xorsi_1"
8906   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8907         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8908                 (match_operand:SI 2 "general_operand" "ri,rm")))
8909    (clobber (reg:CC FLAGS_REG))]
8910   "ix86_binary_operator_ok (XOR, SImode, operands)"
8911   "xor{l}\t{%2, %0|%0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "SI")])
8914
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 ;; Add speccase for immediates
8917 (define_insn "*xorsi_1_zext"
8918   [(set (match_operand:DI 0 "register_operand" "=r")
8919         (zero_extend:DI
8920           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921                   (match_operand:SI 2 "general_operand" "rim"))))
8922    (clobber (reg:CC FLAGS_REG))]
8923   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8924   "xor{l}\t{%2, %k0|%k0, %2}"
8925   [(set_attr "type" "alu")
8926    (set_attr "mode" "SI")])
8927
8928 (define_insn "*xorsi_1_zext_imm"
8929   [(set (match_operand:DI 0 "register_operand" "=r")
8930         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8934   "xor{l}\t{%2, %k0|%k0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "SI")])
8937
8938 (define_insn "*xorsi_2"
8939   [(set (reg FLAGS_REG)
8940         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941                          (match_operand:SI 2 "general_operand" "rim,ri"))
8942                  (const_int 0)))
8943    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944         (xor:SI (match_dup 1) (match_dup 2)))]
8945   "ix86_match_ccmode (insn, CCNOmode)
8946    && ix86_binary_operator_ok (XOR, SImode, operands)"
8947   "xor{l}\t{%2, %0|%0, %2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "mode" "SI")])
8950
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*xorsi_2_zext"
8954   [(set (reg FLAGS_REG)
8955         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956                          (match_operand:SI 2 "general_operand" "rim"))
8957                  (const_int 0)))
8958    (set (match_operand:DI 0 "register_operand" "=r")
8959         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961    && ix86_binary_operator_ok (XOR, SImode, operands)"
8962   "xor{l}\t{%2, %k0|%k0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "SI")])
8965
8966 (define_insn "*xorsi_2_zext_imm"
8967   [(set (reg FLAGS_REG)
8968         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8970                  (const_int 0)))
8971    (set (match_operand:DI 0 "register_operand" "=r")
8972         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974    && ix86_binary_operator_ok (XOR, SImode, operands)"
8975   "xor{l}\t{%2, %k0|%k0, %2}"
8976   [(set_attr "type" "alu")
8977    (set_attr "mode" "SI")])
8978
8979 (define_insn "*xorsi_3"
8980   [(set (reg FLAGS_REG)
8981         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982                          (match_operand:SI 2 "general_operand" "rim"))
8983                  (const_int 0)))
8984    (clobber (match_scratch:SI 0 "=r"))]
8985   "ix86_match_ccmode (insn, CCNOmode)
8986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987   "xor{l}\t{%2, %0|%0, %2}"
8988   [(set_attr "type" "alu")
8989    (set_attr "mode" "SI")])
8990
8991 (define_expand "xorhi3"
8992   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994                 (match_operand:HI 2 "general_operand" "")))
8995    (clobber (reg:CC FLAGS_REG))]
8996   "TARGET_HIMODE_MATH"
8997   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8998
8999 (define_insn "*xorhi_1"
9000   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "ix86_binary_operator_ok (XOR, HImode, operands)"
9005   "xor{w}\t{%2, %0|%0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "HI")])
9008
9009 (define_insn "*xorhi_2"
9010   [(set (reg FLAGS_REG)
9011         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012                          (match_operand:HI 2 "general_operand" "rim,ri"))
9013                  (const_int 0)))
9014    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015         (xor:HI (match_dup 1) (match_dup 2)))]
9016   "ix86_match_ccmode (insn, CCNOmode)
9017    && ix86_binary_operator_ok (XOR, HImode, operands)"
9018   "xor{w}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "HI")])
9021
9022 (define_insn "*xorhi_3"
9023   [(set (reg FLAGS_REG)
9024         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025                          (match_operand:HI 2 "general_operand" "rim"))
9026                  (const_int 0)))
9027    (clobber (match_scratch:HI 0 "=r"))]
9028   "ix86_match_ccmode (insn, CCNOmode)
9029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030   "xor{w}\t{%2, %0|%0, %2}"
9031   [(set_attr "type" "alu")
9032    (set_attr "mode" "HI")])
9033
9034 (define_expand "xorqi3"
9035   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037                 (match_operand:QI 2 "general_operand" "")))
9038    (clobber (reg:CC FLAGS_REG))]
9039   "TARGET_QIMODE_MATH"
9040   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9041
9042 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9043 (define_insn "*xorqi_1"
9044   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047    (clobber (reg:CC FLAGS_REG))]
9048   "ix86_binary_operator_ok (XOR, QImode, operands)"
9049   "@
9050    xor{b}\t{%2, %0|%0, %2}
9051    xor{b}\t{%2, %0|%0, %2}
9052    xor{l}\t{%k2, %k0|%k0, %k2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "QI,QI,SI")])
9055
9056 (define_insn "*xorqi_1_slp"
9057   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9058         (xor:QI (match_dup 0)
9059                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9060    (clobber (reg:CC FLAGS_REG))]
9061   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063   "xor{b}\t{%1, %0|%0, %1}"
9064   [(set_attr "type" "alu1")
9065    (set_attr "mode" "QI")])
9066
9067 (define_insn "xorqi_ext_0"
9068   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9069                          (const_int 8)
9070                          (const_int 8))
9071         (xor:SI 
9072           (zero_extract:SI
9073             (match_operand 1 "ext_register_operand" "0")
9074             (const_int 8)
9075             (const_int 8))
9076           (match_operand 2 "const_int_operand" "n")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9079   "xor{b}\t{%2, %h0|%h0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "length_immediate" "1")
9082    (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_ext_1"
9085   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9086                          (const_int 8)
9087                          (const_int 8))
9088         (xor:SI 
9089           (zero_extract:SI
9090             (match_operand 1 "ext_register_operand" "0")
9091             (const_int 8)
9092             (const_int 8))
9093           (zero_extend:SI
9094             (match_operand:QI 2 "general_operand" "Qm"))))
9095    (clobber (reg:CC FLAGS_REG))]
9096   "!TARGET_64BIT
9097    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9098   "xor{b}\t{%2, %h0|%h0, %2}"
9099   [(set_attr "type" "alu")
9100    (set_attr "length_immediate" "0")
9101    (set_attr "mode" "QI")])
9102
9103 (define_insn "*xorqi_ext_1_rex64"
9104   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9105                          (const_int 8)
9106                          (const_int 8))
9107         (xor:SI 
9108           (zero_extract:SI
9109             (match_operand 1 "ext_register_operand" "0")
9110             (const_int 8)
9111             (const_int 8))
9112           (zero_extend:SI
9113             (match_operand 2 "ext_register_operand" "Q"))))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "TARGET_64BIT
9116    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9117   "xor{b}\t{%2, %h0|%h0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "length_immediate" "0")
9120    (set_attr "mode" "QI")])
9121
9122 (define_insn "*xorqi_ext_2"
9123   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9124                          (const_int 8)
9125                          (const_int 8))
9126         (xor:SI 
9127           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9128                            (const_int 8)
9129                            (const_int 8))
9130           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9131                            (const_int 8)
9132                            (const_int 8))))
9133    (clobber (reg:CC FLAGS_REG))]
9134   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9135   "xor{b}\t{%h2, %h0|%h0, %h2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "length_immediate" "0")
9138    (set_attr "mode" "QI")])
9139
9140 (define_insn "*xorqi_cc_1"
9141   [(set (reg FLAGS_REG)
9142         (compare
9143           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9144                   (match_operand:QI 2 "general_operand" "qim,qi"))
9145           (const_int 0)))
9146    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9147         (xor:QI (match_dup 1) (match_dup 2)))]
9148   "ix86_match_ccmode (insn, CCNOmode)
9149    && ix86_binary_operator_ok (XOR, QImode, operands)"
9150   "xor{b}\t{%2, %0|%0, %2}"
9151   [(set_attr "type" "alu")
9152    (set_attr "mode" "QI")])
9153
9154 (define_insn "*xorqi_2_slp"
9155   [(set (reg FLAGS_REG)
9156         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9157                          (match_operand:QI 1 "general_operand" "qim,qi"))
9158                  (const_int 0)))
9159    (set (strict_low_part (match_dup 0))
9160         (xor:QI (match_dup 0) (match_dup 1)))]
9161   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9162    && ix86_match_ccmode (insn, CCNOmode)
9163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164   "xor{b}\t{%1, %0|%0, %1}"
9165   [(set_attr "type" "alu1")
9166    (set_attr "mode" "QI")])
9167
9168 (define_insn "*xorqi_cc_2"
9169   [(set (reg FLAGS_REG)
9170         (compare
9171           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9172                   (match_operand:QI 2 "general_operand" "qim"))
9173           (const_int 0)))
9174    (clobber (match_scratch:QI 0 "=q"))]
9175   "ix86_match_ccmode (insn, CCNOmode)
9176    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9177   "xor{b}\t{%2, %0|%0, %2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "mode" "QI")])
9180
9181 (define_insn "*xorqi_cc_ext_1"
9182   [(set (reg FLAGS_REG)
9183         (compare
9184           (xor:SI
9185             (zero_extract:SI
9186               (match_operand 1 "ext_register_operand" "0")
9187               (const_int 8)
9188               (const_int 8))
9189             (match_operand:QI 2 "general_operand" "qmn"))
9190           (const_int 0)))
9191    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9192                          (const_int 8)
9193                          (const_int 8))
9194         (xor:SI 
9195           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9196           (match_dup 2)))]
9197   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9198   "xor{b}\t{%2, %h0|%h0, %2}"
9199   [(set_attr "type" "alu")
9200    (set_attr "mode" "QI")])
9201
9202 (define_insn "*xorqi_cc_ext_1_rex64"
9203   [(set (reg FLAGS_REG)
9204         (compare
9205           (xor:SI
9206             (zero_extract:SI
9207               (match_operand 1 "ext_register_operand" "0")
9208               (const_int 8)
9209               (const_int 8))
9210             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9211           (const_int 0)))
9212    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI 
9216           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9217           (match_dup 2)))]
9218   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219   "xor{b}\t{%2, %h0|%h0, %2}"
9220   [(set_attr "type" "alu")
9221    (set_attr "mode" "QI")])
9222
9223 (define_expand "xorqi_cc_ext_1"
9224   [(parallel [
9225      (set (reg:CCNO FLAGS_REG)
9226           (compare:CCNO
9227             (xor:SI
9228               (zero_extract:SI
9229                 (match_operand 1 "ext_register_operand" "")
9230                 (const_int 8)
9231                 (const_int 8))
9232               (match_operand:QI 2 "general_operand" ""))
9233             (const_int 0)))
9234      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9235                            (const_int 8)
9236                            (const_int 8))
9237           (xor:SI 
9238             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9239             (match_dup 2)))])]
9240   ""
9241   "")
9242
9243 (define_split
9244   [(set (match_operand 0 "register_operand" "")
9245         (xor (match_operand 1 "register_operand" "")
9246              (match_operand 2 "const_int_operand" "")))
9247    (clobber (reg:CC FLAGS_REG))]
9248    "reload_completed
9249     && QI_REG_P (operands[0])
9250     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9251     && !(INTVAL (operands[2]) & ~(255 << 8))
9252     && GET_MODE (operands[0]) != QImode"
9253   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9254                    (xor:SI (zero_extract:SI (match_dup 1)
9255                                             (const_int 8) (const_int 8))
9256                            (match_dup 2)))
9257               (clobber (reg:CC FLAGS_REG))])]
9258   "operands[0] = gen_lowpart (SImode, operands[0]);
9259    operands[1] = gen_lowpart (SImode, operands[1]);
9260    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9261
9262 ;; Since XOR can be encoded with sign extended immediate, this is only
9263 ;; profitable when 7th bit is set.
9264 (define_split
9265   [(set (match_operand 0 "register_operand" "")
9266         (xor (match_operand 1 "general_operand" "")
9267              (match_operand 2 "const_int_operand" "")))
9268    (clobber (reg:CC FLAGS_REG))]
9269    "reload_completed
9270     && ANY_QI_REG_P (operands[0])
9271     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272     && !(INTVAL (operands[2]) & ~255)
9273     && (INTVAL (operands[2]) & 128)
9274     && GET_MODE (operands[0]) != QImode"
9275   [(parallel [(set (strict_low_part (match_dup 0))
9276                    (xor:QI (match_dup 1)
9277                            (match_dup 2)))
9278               (clobber (reg:CC FLAGS_REG))])]
9279   "operands[0] = gen_lowpart (QImode, operands[0]);
9280    operands[1] = gen_lowpart (QImode, operands[1]);
9281    operands[2] = gen_lowpart (QImode, operands[2]);")
9282 \f
9283 ;; Negation instructions
9284
9285 (define_expand "negti2"
9286   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9287                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9288               (clobber (reg:CC FLAGS_REG))])]
9289   "TARGET_64BIT"
9290   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9291
9292 (define_insn "*negti2_1"
9293   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9294         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9295    (clobber (reg:CC FLAGS_REG))]
9296   "TARGET_64BIT
9297    && ix86_unary_operator_ok (NEG, TImode, operands)"
9298   "#")
9299
9300 (define_split
9301   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9302         (neg:TI (match_operand:TI 1 "general_operand" "")))
9303    (clobber (reg:CC FLAGS_REG))]
9304   "TARGET_64BIT && reload_completed"
9305   [(parallel
9306     [(set (reg:CCZ FLAGS_REG)
9307           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9308      (set (match_dup 0) (neg:DI (match_dup 2)))])
9309    (parallel
9310     [(set (match_dup 1)
9311           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9312                             (match_dup 3))
9313                    (const_int 0)))
9314      (clobber (reg:CC FLAGS_REG))])
9315    (parallel
9316     [(set (match_dup 1)
9317           (neg:DI (match_dup 1)))
9318      (clobber (reg:CC FLAGS_REG))])]
9319   "split_ti (operands+1, 1, operands+2, operands+3);
9320    split_ti (operands+0, 1, operands+0, operands+1);")
9321
9322 (define_expand "negdi2"
9323   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325               (clobber (reg:CC FLAGS_REG))])]
9326   ""
9327   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9328
9329 (define_insn "*negdi2_1"
9330   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "!TARGET_64BIT
9334    && ix86_unary_operator_ok (NEG, DImode, operands)"
9335   "#")
9336
9337 (define_split
9338   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339         (neg:DI (match_operand:DI 1 "general_operand" "")))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "!TARGET_64BIT && reload_completed"
9342   [(parallel
9343     [(set (reg:CCZ FLAGS_REG)
9344           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345      (set (match_dup 0) (neg:SI (match_dup 2)))])
9346    (parallel
9347     [(set (match_dup 1)
9348           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9349                             (match_dup 3))
9350                    (const_int 0)))
9351      (clobber (reg:CC FLAGS_REG))])
9352    (parallel
9353     [(set (match_dup 1)
9354           (neg:SI (match_dup 1)))
9355      (clobber (reg:CC FLAGS_REG))])]
9356   "split_di (operands+1, 1, operands+2, operands+3);
9357    split_di (operands+0, 1, operands+0, operands+1);")
9358
9359 (define_insn "*negdi2_1_rex64"
9360   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9364   "neg{q}\t%0"
9365   [(set_attr "type" "negnot")
9366    (set_attr "mode" "DI")])
9367
9368 ;; The problem with neg is that it does not perform (compare x 0),
9369 ;; it really performs (compare 0 x), which leaves us with the zero
9370 ;; flag being the only useful item.
9371
9372 (define_insn "*negdi2_cmpz_rex64"
9373   [(set (reg:CCZ FLAGS_REG)
9374         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9375                      (const_int 0)))
9376    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377         (neg:DI (match_dup 1)))]
9378   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9379   "neg{q}\t%0"
9380   [(set_attr "type" "negnot")
9381    (set_attr "mode" "DI")])
9382
9383
9384 (define_expand "negsi2"
9385   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387               (clobber (reg:CC FLAGS_REG))])]
9388   ""
9389   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9390
9391 (define_insn "*negsi2_1"
9392   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "ix86_unary_operator_ok (NEG, SImode, operands)"
9396   "neg{l}\t%0"
9397   [(set_attr "type" "negnot")
9398    (set_attr "mode" "SI")])
9399
9400 ;; Combine is quite creative about this pattern.
9401 (define_insn "*negsi2_1_zext"
9402   [(set (match_operand:DI 0 "register_operand" "=r")
9403         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9404                                         (const_int 32)))
9405                      (const_int 32)))
9406    (clobber (reg:CC FLAGS_REG))]
9407   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9408   "neg{l}\t%k0"
9409   [(set_attr "type" "negnot")
9410    (set_attr "mode" "SI")])
9411
9412 ;; The problem with neg is that it does not perform (compare x 0),
9413 ;; it really performs (compare 0 x), which leaves us with the zero
9414 ;; flag being the only useful item.
9415
9416 (define_insn "*negsi2_cmpz"
9417   [(set (reg:CCZ FLAGS_REG)
9418         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9419                      (const_int 0)))
9420    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421         (neg:SI (match_dup 1)))]
9422   "ix86_unary_operator_ok (NEG, SImode, operands)"
9423   "neg{l}\t%0"
9424   [(set_attr "type" "negnot")
9425    (set_attr "mode" "SI")])
9426
9427 (define_insn "*negsi2_cmpz_zext"
9428   [(set (reg:CCZ FLAGS_REG)
9429         (compare:CCZ (lshiftrt:DI
9430                        (neg:DI (ashift:DI
9431                                  (match_operand:DI 1 "register_operand" "0")
9432                                  (const_int 32)))
9433                        (const_int 32))
9434                      (const_int 0)))
9435    (set (match_operand:DI 0 "register_operand" "=r")
9436         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9437                                         (const_int 32)))
9438                      (const_int 32)))]
9439   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9440   "neg{l}\t%k0"
9441   [(set_attr "type" "negnot")
9442    (set_attr "mode" "SI")])
9443
9444 (define_expand "neghi2"
9445   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447               (clobber (reg:CC FLAGS_REG))])]
9448   "TARGET_HIMODE_MATH"
9449   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9450
9451 (define_insn "*neghi2_1"
9452   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "ix86_unary_operator_ok (NEG, HImode, operands)"
9456   "neg{w}\t%0"
9457   [(set_attr "type" "negnot")
9458    (set_attr "mode" "HI")])
9459
9460 (define_insn "*neghi2_cmpz"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9463                      (const_int 0)))
9464    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465         (neg:HI (match_dup 1)))]
9466   "ix86_unary_operator_ok (NEG, HImode, operands)"
9467   "neg{w}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "HI")])
9470
9471 (define_expand "negqi2"
9472   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474               (clobber (reg:CC FLAGS_REG))])]
9475   "TARGET_QIMODE_MATH"
9476   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9477
9478 (define_insn "*negqi2_1"
9479   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481    (clobber (reg:CC FLAGS_REG))]
9482   "ix86_unary_operator_ok (NEG, QImode, operands)"
9483   "neg{b}\t%0"
9484   [(set_attr "type" "negnot")
9485    (set_attr "mode" "QI")])
9486
9487 (define_insn "*negqi2_cmpz"
9488   [(set (reg:CCZ FLAGS_REG)
9489         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9490                      (const_int 0)))
9491    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492         (neg:QI (match_dup 1)))]
9493   "ix86_unary_operator_ok (NEG, QImode, operands)"
9494   "neg{b}\t%0"
9495   [(set_attr "type" "negnot")
9496    (set_attr "mode" "QI")])
9497
9498 ;; Changing of sign for FP values is doable using integer unit too.
9499
9500 (define_expand "negsf2"
9501   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503   "TARGET_80387 || TARGET_SSE_MATH"
9504   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9505
9506 (define_expand "abssf2"
9507   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509   "TARGET_80387 || TARGET_SSE_MATH"
9510   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9511
9512 (define_insn "*absnegsf2_mixed"
9513   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9514         (match_operator:SF 3 "absneg_operator"
9515           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9516    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9517    (clobber (reg:CC FLAGS_REG))]
9518   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9519    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9520   "#")
9521
9522 (define_insn "*absnegsf2_sse"
9523   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9524         (match_operator:SF 3 "absneg_operator"
9525           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9526    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9527    (clobber (reg:CC FLAGS_REG))]
9528   "TARGET_SSE_MATH
9529    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9530   "#")
9531
9532 (define_insn "*absnegsf2_i387"
9533   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9534         (match_operator:SF 3 "absneg_operator"
9535           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9536    (use (match_operand 2 "" ""))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "TARGET_80387 && !TARGET_SSE_MATH
9539    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9540   "#")
9541
9542 (define_expand "copysignsf3"
9543   [(match_operand:SF 0 "register_operand" "")
9544    (match_operand:SF 1 "nonmemory_operand" "")
9545    (match_operand:SF 2 "register_operand" "")]
9546   "TARGET_SSE_MATH"
9547 {
9548   ix86_expand_copysign (operands);
9549   DONE;
9550 })
9551
9552 (define_insn_and_split "copysignsf3_const"
9553   [(set (match_operand:SF 0 "register_operand"          "=x")
9554         (unspec:SF
9555           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9556            (match_operand:SF 2 "register_operand"       "0")
9557            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9558           UNSPEC_COPYSIGN))]
9559   "TARGET_SSE_MATH"
9560   "#"
9561   "&& reload_completed"
9562   [(const_int 0)]
9563 {
9564   ix86_split_copysign_const (operands);
9565   DONE;
9566 })
9567
9568 (define_insn "copysignsf3_var"
9569   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9570         (unspec:SF
9571           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9572            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9573            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9574            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9575           UNSPEC_COPYSIGN))
9576    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9577   "TARGET_SSE_MATH"
9578   "#")
9579
9580 (define_split
9581   [(set (match_operand:SF 0 "register_operand" "")
9582         (unspec:SF
9583           [(match_operand:SF 2 "register_operand" "")
9584            (match_operand:SF 3 "register_operand" "")
9585            (match_operand:V4SF 4 "" "")
9586            (match_operand:V4SF 5 "" "")]
9587           UNSPEC_COPYSIGN))
9588    (clobber (match_scratch:V4SF 1 ""))]
9589   "TARGET_SSE_MATH && reload_completed"
9590   [(const_int 0)]
9591 {
9592   ix86_split_copysign_var (operands);
9593   DONE;
9594 })
9595
9596 (define_expand "negdf2"
9597   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9601
9602 (define_expand "absdf2"
9603   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9607
9608 (define_insn "*absnegdf2_mixed"
9609   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9610         (match_operator:DF 3 "absneg_operator"
9611           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9612    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9613    (clobber (reg:CC FLAGS_REG))]
9614   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9615    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9616   "#")
9617
9618 (define_insn "*absnegdf2_sse"
9619   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9620         (match_operator:DF 3 "absneg_operator"
9621           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9622    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9623    (clobber (reg:CC FLAGS_REG))]
9624   "TARGET_SSE2 && TARGET_SSE_MATH
9625    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9626   "#")
9627
9628 (define_insn "*absnegdf2_i387"
9629   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9630         (match_operator:DF 3 "absneg_operator"
9631           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9632    (use (match_operand 2 "" ""))
9633    (clobber (reg:CC FLAGS_REG))]
9634   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9635    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9636   "#")
9637
9638 (define_expand "copysigndf3"
9639   [(match_operand:DF 0 "register_operand" "")
9640    (match_operand:DF 1 "nonmemory_operand" "")
9641    (match_operand:DF 2 "register_operand" "")]
9642   "TARGET_SSE2 && TARGET_SSE_MATH"
9643 {
9644   ix86_expand_copysign (operands);
9645   DONE;
9646 })
9647
9648 (define_insn_and_split "copysigndf3_const"
9649   [(set (match_operand:DF 0 "register_operand"          "=x")
9650         (unspec:DF
9651           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9652            (match_operand:DF 2 "register_operand"       "0")
9653            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9654           UNSPEC_COPYSIGN))]
9655   "TARGET_SSE2 && TARGET_SSE_MATH"
9656   "#"
9657   "&& reload_completed"
9658   [(const_int 0)]
9659 {
9660   ix86_split_copysign_const (operands);
9661   DONE;
9662 })
9663
9664 (define_insn "copysigndf3_var"
9665   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9666         (unspec:DF
9667           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9668            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9669            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9670            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9671           UNSPEC_COPYSIGN))
9672    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9673   "TARGET_SSE2 && TARGET_SSE_MATH"
9674   "#")
9675
9676 (define_split
9677   [(set (match_operand:DF 0 "register_operand" "")
9678         (unspec:DF
9679           [(match_operand:DF 2 "register_operand" "")
9680            (match_operand:DF 3 "register_operand" "")
9681            (match_operand:V2DF 4 "" "")
9682            (match_operand:V2DF 5 "" "")]
9683           UNSPEC_COPYSIGN))
9684    (clobber (match_scratch:V2DF 1 ""))]
9685   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9686   [(const_int 0)]
9687 {
9688   ix86_split_copysign_var (operands);
9689   DONE;
9690 })
9691
9692 (define_expand "negxf2"
9693   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387"
9696   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9697
9698 (define_expand "absxf2"
9699   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701   "TARGET_80387"
9702   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9703
9704 (define_insn "*absnegxf2_i387"
9705   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9706         (match_operator:XF 3 "absneg_operator"
9707           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9708    (use (match_operand 2 "" ""))
9709    (clobber (reg:CC FLAGS_REG))]
9710   "TARGET_80387
9711    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9712   "#")
9713
9714 ;; Splitters for fp abs and neg.
9715
9716 (define_split
9717   [(set (match_operand 0 "fp_register_operand" "")
9718         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9719    (use (match_operand 2 "" ""))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "reload_completed"
9722   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9723
9724 (define_split
9725   [(set (match_operand 0 "register_operand" "")
9726         (match_operator 3 "absneg_operator"
9727           [(match_operand 1 "register_operand" "")]))
9728    (use (match_operand 2 "nonimmediate_operand" ""))
9729    (clobber (reg:CC FLAGS_REG))]
9730   "reload_completed && SSE_REG_P (operands[0])"
9731   [(set (match_dup 0) (match_dup 3))]
9732 {
9733   enum machine_mode mode = GET_MODE (operands[0]);
9734   enum machine_mode vmode = GET_MODE (operands[2]);
9735   rtx tmp;
9736   
9737   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9738   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9739   if (operands_match_p (operands[0], operands[2]))
9740     {
9741       tmp = operands[1];
9742       operands[1] = operands[2];
9743       operands[2] = tmp;
9744     }
9745   if (GET_CODE (operands[3]) == ABS)
9746     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9747   else
9748     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9749   operands[3] = tmp;
9750 })
9751
9752 (define_split
9753   [(set (match_operand:SF 0 "register_operand" "")
9754         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9755    (use (match_operand:V4SF 2 "" ""))
9756    (clobber (reg:CC FLAGS_REG))]
9757   "reload_completed"
9758   [(parallel [(set (match_dup 0) (match_dup 1))
9759               (clobber (reg:CC FLAGS_REG))])]
9760
9761   rtx tmp;
9762   operands[0] = gen_lowpart (SImode, operands[0]);
9763   if (GET_CODE (operands[1]) == ABS)
9764     {
9765       tmp = gen_int_mode (0x7fffffff, SImode);
9766       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9767     }
9768   else
9769     {
9770       tmp = gen_int_mode (0x80000000, SImode);
9771       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9772     }
9773   operands[1] = tmp;
9774 })
9775
9776 (define_split
9777   [(set (match_operand:DF 0 "register_operand" "")
9778         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9779    (use (match_operand 2 "" ""))
9780    (clobber (reg:CC FLAGS_REG))]
9781   "reload_completed"
9782   [(parallel [(set (match_dup 0) (match_dup 1))
9783               (clobber (reg:CC FLAGS_REG))])]
9784 {
9785   rtx tmp;
9786   if (TARGET_64BIT)
9787     {
9788       tmp = gen_lowpart (DImode, operands[0]);
9789       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9790       operands[0] = tmp;
9791
9792       if (GET_CODE (operands[1]) == ABS)
9793         tmp = const0_rtx;
9794       else
9795         tmp = gen_rtx_NOT (DImode, tmp);
9796     }
9797   else
9798     {
9799       operands[0] = gen_highpart (SImode, operands[0]);
9800       if (GET_CODE (operands[1]) == ABS)
9801         {
9802           tmp = gen_int_mode (0x7fffffff, SImode);
9803           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9804         }
9805       else
9806         {
9807           tmp = gen_int_mode (0x80000000, SImode);
9808           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9809         }
9810     }
9811   operands[1] = tmp;
9812 })
9813
9814 (define_split
9815   [(set (match_operand:XF 0 "register_operand" "")
9816         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9817    (use (match_operand 2 "" ""))
9818    (clobber (reg:CC FLAGS_REG))]
9819   "reload_completed"
9820   [(parallel [(set (match_dup 0) (match_dup 1))
9821               (clobber (reg:CC FLAGS_REG))])]
9822 {
9823   rtx tmp;
9824   operands[0] = gen_rtx_REG (SImode,
9825                              true_regnum (operands[0])
9826                              + (TARGET_64BIT ? 1 : 2));
9827   if (GET_CODE (operands[1]) == ABS)
9828     {
9829       tmp = GEN_INT (0x7fff);
9830       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9831     }
9832   else
9833     {
9834       tmp = GEN_INT (0x8000);
9835       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9836     }
9837   operands[1] = tmp;
9838 })
9839
9840 (define_split
9841   [(set (match_operand 0 "memory_operand" "")
9842         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9843    (use (match_operand 2 "" ""))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "reload_completed"
9846   [(parallel [(set (match_dup 0) (match_dup 1))
9847               (clobber (reg:CC FLAGS_REG))])]
9848 {
9849   enum machine_mode mode = GET_MODE (operands[0]);
9850   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9851   rtx tmp;
9852
9853   operands[0] = adjust_address (operands[0], QImode, size - 1);
9854   if (GET_CODE (operands[1]) == ABS)
9855     {
9856       tmp = gen_int_mode (0x7f, QImode);
9857       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9858     }
9859   else
9860     {
9861       tmp = gen_int_mode (0x80, QImode);
9862       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9863     }
9864   operands[1] = tmp;
9865 })
9866
9867 ;; Conditionalize these after reload. If they match before reload, we 
9868 ;; lose the clobber and ability to use integer instructions.
9869
9870 (define_insn "*negsf2_1"
9871   [(set (match_operand:SF 0 "register_operand" "=f")
9872         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9873   "TARGET_80387 && reload_completed"
9874   "fchs"
9875   [(set_attr "type" "fsgn")
9876    (set_attr "mode" "SF")])
9877
9878 (define_insn "*negdf2_1"
9879   [(set (match_operand:DF 0 "register_operand" "=f")
9880         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9881   "TARGET_80387 && reload_completed"
9882   "fchs"
9883   [(set_attr "type" "fsgn")
9884    (set_attr "mode" "DF")])
9885
9886 (define_insn "*negxf2_1"
9887   [(set (match_operand:XF 0 "register_operand" "=f")
9888         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9889   "TARGET_80387 && reload_completed"
9890   "fchs"
9891   [(set_attr "type" "fsgn")
9892    (set_attr "mode" "XF")])
9893
9894 (define_insn "*abssf2_1"
9895   [(set (match_operand:SF 0 "register_operand" "=f")
9896         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9897   "TARGET_80387 && reload_completed"
9898   "fabs"
9899   [(set_attr "type" "fsgn")
9900    (set_attr "mode" "SF")])
9901
9902 (define_insn "*absdf2_1"
9903   [(set (match_operand:DF 0 "register_operand" "=f")
9904         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9905   "TARGET_80387 && reload_completed"
9906   "fabs"
9907   [(set_attr "type" "fsgn")
9908    (set_attr "mode" "DF")])
9909
9910 (define_insn "*absxf2_1"
9911   [(set (match_operand:XF 0 "register_operand" "=f")
9912         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9913   "TARGET_80387 && reload_completed"
9914   "fabs"
9915   [(set_attr "type" "fsgn")
9916    (set_attr "mode" "DF")])
9917
9918 (define_insn "*negextendsfdf2"
9919   [(set (match_operand:DF 0 "register_operand" "=f")
9920         (neg:DF (float_extend:DF
9921                   (match_operand:SF 1 "register_operand" "0"))))]
9922   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "DF")])
9926
9927 (define_insn "*negextenddfxf2"
9928   [(set (match_operand:XF 0 "register_operand" "=f")
9929         (neg:XF (float_extend:XF
9930                   (match_operand:DF 1 "register_operand" "0"))))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "XF")])
9935
9936 (define_insn "*negextendsfxf2"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (float_extend:XF
9939                   (match_operand:SF 1 "register_operand" "0"))))]
9940   "TARGET_80387"
9941   "fchs"
9942   [(set_attr "type" "fsgn")
9943    (set_attr "mode" "XF")])
9944
9945 (define_insn "*absextendsfdf2"
9946   [(set (match_operand:DF 0 "register_operand" "=f")
9947         (abs:DF (float_extend:DF
9948                   (match_operand:SF 1 "register_operand" "0"))))]
9949   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9950   "fabs"
9951   [(set_attr "type" "fsgn")
9952    (set_attr "mode" "DF")])
9953
9954 (define_insn "*absextenddfxf2"
9955   [(set (match_operand:XF 0 "register_operand" "=f")
9956         (abs:XF (float_extend:XF
9957           (match_operand:DF 1 "register_operand" "0"))))]
9958   "TARGET_80387"
9959   "fabs"
9960   [(set_attr "type" "fsgn")
9961    (set_attr "mode" "XF")])
9962
9963 (define_insn "*absextendsfxf2"
9964   [(set (match_operand:XF 0 "register_operand" "=f")
9965         (abs:XF (float_extend:XF
9966           (match_operand:SF 1 "register_operand" "0"))))]
9967   "TARGET_80387"
9968   "fabs"
9969   [(set_attr "type" "fsgn")
9970    (set_attr "mode" "XF")])
9971 \f
9972 ;; One complement instructions
9973
9974 (define_expand "one_cmpldi2"
9975   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9976         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9977   "TARGET_64BIT"
9978   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9979
9980 (define_insn "*one_cmpldi2_1_rex64"
9981   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9983   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9984   "not{q}\t%0"
9985   [(set_attr "type" "negnot")
9986    (set_attr "mode" "DI")])
9987
9988 (define_insn "*one_cmpldi2_2_rex64"
9989   [(set (reg FLAGS_REG)
9990         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9991                  (const_int 0)))
9992    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9993         (not:DI (match_dup 1)))]
9994   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9995    && ix86_unary_operator_ok (NOT, DImode, operands)"
9996   "#"
9997   [(set_attr "type" "alu1")
9998    (set_attr "mode" "DI")])
9999
10000 (define_split
10001   [(set (match_operand 0 "flags_reg_operand" "")
10002         (match_operator 2 "compare_operator"
10003           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10004            (const_int 0)]))
10005    (set (match_operand:DI 1 "nonimmediate_operand" "")
10006         (not:DI (match_dup 3)))]
10007   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10008   [(parallel [(set (match_dup 0)
10009                    (match_op_dup 2
10010                      [(xor:DI (match_dup 3) (const_int -1))
10011                       (const_int 0)]))
10012               (set (match_dup 1)
10013                    (xor:DI (match_dup 3) (const_int -1)))])]
10014   "")
10015
10016 (define_expand "one_cmplsi2"
10017   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10018         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10019   ""
10020   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10021
10022 (define_insn "*one_cmplsi2_1"
10023   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10025   "ix86_unary_operator_ok (NOT, SImode, operands)"
10026   "not{l}\t%0"
10027   [(set_attr "type" "negnot")
10028    (set_attr "mode" "SI")])
10029
10030 ;; ??? Currently never generated - xor is used instead.
10031 (define_insn "*one_cmplsi2_1_zext"
10032   [(set (match_operand:DI 0 "register_operand" "=r")
10033         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10034   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10035   "not{l}\t%k0"
10036   [(set_attr "type" "negnot")
10037    (set_attr "mode" "SI")])
10038
10039 (define_insn "*one_cmplsi2_2"
10040   [(set (reg FLAGS_REG)
10041         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10042                  (const_int 0)))
10043    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10044         (not:SI (match_dup 1)))]
10045   "ix86_match_ccmode (insn, CCNOmode)
10046    && ix86_unary_operator_ok (NOT, SImode, operands)"
10047   "#"
10048   [(set_attr "type" "alu1")
10049    (set_attr "mode" "SI")])
10050
10051 (define_split
10052   [(set (match_operand 0 "flags_reg_operand" "")
10053         (match_operator 2 "compare_operator"
10054           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10055            (const_int 0)]))
10056    (set (match_operand:SI 1 "nonimmediate_operand" "")
10057         (not:SI (match_dup 3)))]
10058   "ix86_match_ccmode (insn, CCNOmode)"
10059   [(parallel [(set (match_dup 0)
10060                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10061                                     (const_int 0)]))
10062               (set (match_dup 1)
10063                    (xor:SI (match_dup 3) (const_int -1)))])]
10064   "")
10065
10066 ;; ??? Currently never generated - xor is used instead.
10067 (define_insn "*one_cmplsi2_2_zext"
10068   [(set (reg FLAGS_REG)
10069         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10070                  (const_int 0)))
10071    (set (match_operand:DI 0 "register_operand" "=r")
10072         (zero_extend:DI (not:SI (match_dup 1))))]
10073   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10074    && ix86_unary_operator_ok (NOT, SImode, operands)"
10075   "#"
10076   [(set_attr "type" "alu1")
10077    (set_attr "mode" "SI")])
10078
10079 (define_split
10080   [(set (match_operand 0 "flags_reg_operand" "")
10081         (match_operator 2 "compare_operator"
10082           [(not:SI (match_operand:SI 3 "register_operand" ""))
10083            (const_int 0)]))
10084    (set (match_operand:DI 1 "register_operand" "")
10085         (zero_extend:DI (not:SI (match_dup 3))))]
10086   "ix86_match_ccmode (insn, CCNOmode)"
10087   [(parallel [(set (match_dup 0)
10088                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10089                                     (const_int 0)]))
10090               (set (match_dup 1)
10091                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10092   "")
10093
10094 (define_expand "one_cmplhi2"
10095   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10096         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10097   "TARGET_HIMODE_MATH"
10098   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10099
10100 (define_insn "*one_cmplhi2_1"
10101   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10103   "ix86_unary_operator_ok (NOT, HImode, operands)"
10104   "not{w}\t%0"
10105   [(set_attr "type" "negnot")
10106    (set_attr "mode" "HI")])
10107
10108 (define_insn "*one_cmplhi2_2"
10109   [(set (reg FLAGS_REG)
10110         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10111                  (const_int 0)))
10112    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10113         (not:HI (match_dup 1)))]
10114   "ix86_match_ccmode (insn, CCNOmode)
10115    && ix86_unary_operator_ok (NEG, HImode, operands)"
10116   "#"
10117   [(set_attr "type" "alu1")
10118    (set_attr "mode" "HI")])
10119
10120 (define_split
10121   [(set (match_operand 0 "flags_reg_operand" "")
10122         (match_operator 2 "compare_operator"
10123           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10124            (const_int 0)]))
10125    (set (match_operand:HI 1 "nonimmediate_operand" "")
10126         (not:HI (match_dup 3)))]
10127   "ix86_match_ccmode (insn, CCNOmode)"
10128   [(parallel [(set (match_dup 0)
10129                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10130                                     (const_int 0)]))
10131               (set (match_dup 1)
10132                    (xor:HI (match_dup 3) (const_int -1)))])]
10133   "")
10134
10135 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10136 (define_expand "one_cmplqi2"
10137   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10138         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10139   "TARGET_QIMODE_MATH"
10140   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10141
10142 (define_insn "*one_cmplqi2_1"
10143   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10144         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10145   "ix86_unary_operator_ok (NOT, QImode, operands)"
10146   "@
10147    not{b}\t%0
10148    not{l}\t%k0"
10149   [(set_attr "type" "negnot")
10150    (set_attr "mode" "QI,SI")])
10151
10152 (define_insn "*one_cmplqi2_2"
10153   [(set (reg FLAGS_REG)
10154         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10155                  (const_int 0)))
10156    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10157         (not:QI (match_dup 1)))]
10158   "ix86_match_ccmode (insn, CCNOmode)
10159    && ix86_unary_operator_ok (NOT, QImode, operands)"
10160   "#"
10161   [(set_attr "type" "alu1")
10162    (set_attr "mode" "QI")])
10163
10164 (define_split
10165   [(set (match_operand 0 "flags_reg_operand" "")
10166         (match_operator 2 "compare_operator"
10167           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10168            (const_int 0)]))
10169    (set (match_operand:QI 1 "nonimmediate_operand" "")
10170         (not:QI (match_dup 3)))]
10171   "ix86_match_ccmode (insn, CCNOmode)"
10172   [(parallel [(set (match_dup 0)
10173                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10174                                     (const_int 0)]))
10175               (set (match_dup 1)
10176                    (xor:QI (match_dup 3) (const_int -1)))])]
10177   "")
10178 \f
10179 ;; Arithmetic shift instructions
10180
10181 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10182 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10183 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10184 ;; from the assembler input.
10185 ;;
10186 ;; This instruction shifts the target reg/mem as usual, but instead of
10187 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10188 ;; is a left shift double, bits are taken from the high order bits of
10189 ;; reg, else if the insn is a shift right double, bits are taken from the
10190 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10191 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10192 ;;
10193 ;; Since sh[lr]d does not change the `reg' operand, that is done
10194 ;; separately, making all shifts emit pairs of shift double and normal
10195 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10196 ;; support a 63 bit shift, each shift where the count is in a reg expands
10197 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10198 ;;
10199 ;; If the shift count is a constant, we need never emit more than one
10200 ;; shift pair, instead using moves and sign extension for counts greater
10201 ;; than 31.
10202
10203 (define_expand "ashlti3"
10204   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10205                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10206                               (match_operand:QI 2 "nonmemory_operand" "")))
10207               (clobber (reg:CC FLAGS_REG))])]
10208   "TARGET_64BIT"
10209 {
10210   if (! immediate_operand (operands[2], QImode))
10211     {
10212       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10213       DONE;
10214     }
10215   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10216   DONE;
10217 })
10218
10219 (define_insn "ashlti3_1"
10220   [(set (match_operand:TI 0 "register_operand" "=r")
10221         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10222                    (match_operand:QI 2 "register_operand" "c")))
10223    (clobber (match_scratch:DI 3 "=&r"))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "TARGET_64BIT"
10226   "#"
10227   [(set_attr "type" "multi")])
10228
10229 (define_insn "*ashlti3_2"
10230   [(set (match_operand:TI 0 "register_operand" "=r")
10231         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10232                    (match_operand:QI 2 "immediate_operand" "O")))
10233    (clobber (reg:CC FLAGS_REG))]
10234   "TARGET_64BIT"
10235   "#"
10236   [(set_attr "type" "multi")])
10237
10238 (define_split
10239   [(set (match_operand:TI 0 "register_operand" "")
10240         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10241                    (match_operand:QI 2 "register_operand" "")))
10242    (clobber (match_scratch:DI 3 ""))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "TARGET_64BIT && reload_completed"
10245   [(const_int 0)]
10246   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10247
10248 (define_split
10249   [(set (match_operand:TI 0 "register_operand" "")
10250         (ashift:TI (match_operand:TI 1 "register_operand" "")
10251                    (match_operand:QI 2 "immediate_operand" "")))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "TARGET_64BIT && reload_completed"
10254   [(const_int 0)]
10255   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10256
10257 (define_insn "x86_64_shld"
10258   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10259         (ior:DI (ashift:DI (match_dup 0)
10260                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10261                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10262                   (minus:QI (const_int 64) (match_dup 2)))))
10263    (clobber (reg:CC FLAGS_REG))]
10264   "TARGET_64BIT"
10265   "@
10266    shld{q}\t{%2, %1, %0|%0, %1, %2}
10267    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10268   [(set_attr "type" "ishift")
10269    (set_attr "prefix_0f" "1")
10270    (set_attr "mode" "DI")
10271    (set_attr "athlon_decode" "vector")])
10272
10273 (define_expand "x86_64_shift_adj"
10274   [(set (reg:CCZ FLAGS_REG)
10275         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10276                              (const_int 64))
10277                      (const_int 0)))
10278    (set (match_operand:DI 0 "register_operand" "")
10279         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280                          (match_operand:DI 1 "register_operand" "")
10281                          (match_dup 0)))
10282    (set (match_dup 1)
10283         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284                          (match_operand:DI 3 "register_operand" "r")
10285                          (match_dup 1)))]
10286   "TARGET_64BIT"
10287   "")
10288
10289 (define_expand "ashldi3"
10290   [(set (match_operand:DI 0 "shiftdi_operand" "")
10291         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10292                    (match_operand:QI 2 "nonmemory_operand" "")))]
10293   ""
10294   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10295
10296 (define_insn "*ashldi3_1_rex64"
10297   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10298         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10299                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10302 {
10303   switch (get_attr_type (insn))
10304     {
10305     case TYPE_ALU:
10306       gcc_assert (operands[2] == const1_rtx);
10307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10308       return "add{q}\t{%0, %0|%0, %0}";
10309
10310     case TYPE_LEA:
10311       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10312       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10313       operands[1] = gen_rtx_MULT (DImode, operands[1],
10314                                   GEN_INT (1 << INTVAL (operands[2])));
10315       return "lea{q}\t{%a1, %0|%0, %a1}";
10316
10317     default:
10318       if (REG_P (operands[2]))
10319         return "sal{q}\t{%b2, %0|%0, %b2}";
10320       else if (operands[2] == const1_rtx
10321                && (TARGET_SHIFT1 || optimize_size))
10322         return "sal{q}\t%0";
10323       else
10324         return "sal{q}\t{%2, %0|%0, %2}";
10325     }
10326 }
10327   [(set (attr "type")
10328      (cond [(eq_attr "alternative" "1")
10329               (const_string "lea")
10330             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10331                           (const_int 0))
10332                       (match_operand 0 "register_operand" ""))
10333                  (match_operand 2 "const1_operand" ""))
10334               (const_string "alu")
10335            ]
10336            (const_string "ishift")))
10337    (set_attr "mode" "DI")])
10338
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10340 (define_split
10341   [(set (match_operand:DI 0 "register_operand" "")
10342         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10343                    (match_operand:QI 2 "immediate_operand" "")))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_64BIT && reload_completed
10346    && true_regnum (operands[0]) != true_regnum (operands[1])"
10347   [(set (match_dup 0)
10348         (mult:DI (match_dup 1)
10349                  (match_dup 2)))]
10350   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10351
10352 ;; This pattern can't accept a variable shift count, since shifts by
10353 ;; zero don't affect the flags.  We assume that shifts by constant
10354 ;; zero are optimized away.
10355 (define_insn "*ashldi3_cmp_rex64"
10356   [(set (reg FLAGS_REG)
10357         (compare
10358           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10359                      (match_operand:QI 2 "immediate_operand" "e"))
10360           (const_int 0)))
10361    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362         (ashift:DI (match_dup 1) (match_dup 2)))]
10363   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10364    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10365 {
10366   switch (get_attr_type (insn))
10367     {
10368     case TYPE_ALU:
10369       gcc_assert (operands[2] == const1_rtx);
10370       return "add{q}\t{%0, %0|%0, %0}";
10371
10372     default:
10373       if (REG_P (operands[2]))
10374         return "sal{q}\t{%b2, %0|%0, %b2}";
10375       else if (operands[2] == const1_rtx
10376                && (TARGET_SHIFT1 || optimize_size))
10377         return "sal{q}\t%0";
10378       else
10379         return "sal{q}\t{%2, %0|%0, %2}";
10380     }
10381 }
10382   [(set (attr "type")
10383      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10384                           (const_int 0))
10385                       (match_operand 0 "register_operand" ""))
10386                  (match_operand 2 "const1_operand" ""))
10387               (const_string "alu")
10388            ]
10389            (const_string "ishift")))
10390    (set_attr "mode" "DI")])
10391
10392 (define_insn "*ashldi3_1"
10393   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10394         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10395                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "!TARGET_64BIT"
10398   "#"
10399   [(set_attr "type" "multi")])
10400
10401 ;; By default we don't ask for a scratch register, because when DImode
10402 ;; values are manipulated, registers are already at a premium.  But if
10403 ;; we have one handy, we won't turn it away.
10404 (define_peephole2
10405   [(match_scratch:SI 3 "r")
10406    (parallel [(set (match_operand:DI 0 "register_operand" "")
10407                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10408                               (match_operand:QI 2 "nonmemory_operand" "")))
10409               (clobber (reg:CC FLAGS_REG))])
10410    (match_dup 3)]
10411   "!TARGET_64BIT && TARGET_CMOVE"
10412   [(const_int 0)]
10413   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10414
10415 (define_split
10416   [(set (match_operand:DI 0 "register_operand" "")
10417         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10418                    (match_operand:QI 2 "nonmemory_operand" "")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10421                      ? flow2_completed : reload_completed)"
10422   [(const_int 0)]
10423   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10424
10425 (define_insn "x86_shld_1"
10426   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10427         (ior:SI (ashift:SI (match_dup 0)
10428                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10429                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10430                   (minus:QI (const_int 32) (match_dup 2)))))
10431    (clobber (reg:CC FLAGS_REG))]
10432   ""
10433   "@
10434    shld{l}\t{%2, %1, %0|%0, %1, %2}
10435    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10436   [(set_attr "type" "ishift")
10437    (set_attr "prefix_0f" "1")
10438    (set_attr "mode" "SI")
10439    (set_attr "pent_pair" "np")
10440    (set_attr "athlon_decode" "vector")])
10441
10442 (define_expand "x86_shift_adj_1"
10443   [(set (reg:CCZ FLAGS_REG)
10444         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10445                              (const_int 32))
10446                      (const_int 0)))
10447    (set (match_operand:SI 0 "register_operand" "")
10448         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10449                          (match_operand:SI 1 "register_operand" "")
10450                          (match_dup 0)))
10451    (set (match_dup 1)
10452         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10453                          (match_operand:SI 3 "register_operand" "r")
10454                          (match_dup 1)))]
10455   "TARGET_CMOVE"
10456   "")
10457
10458 (define_expand "x86_shift_adj_2"
10459   [(use (match_operand:SI 0 "register_operand" ""))
10460    (use (match_operand:SI 1 "register_operand" ""))
10461    (use (match_operand:QI 2 "register_operand" ""))]
10462   ""
10463 {
10464   rtx label = gen_label_rtx ();
10465   rtx tmp;
10466
10467   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10468
10469   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10470   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10471   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10472                               gen_rtx_LABEL_REF (VOIDmode, label),
10473                               pc_rtx);
10474   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10475   JUMP_LABEL (tmp) = label;
10476
10477   emit_move_insn (operands[0], operands[1]);
10478   ix86_expand_clear (operands[1]);
10479
10480   emit_label (label);
10481   LABEL_NUSES (label) = 1;
10482
10483   DONE;
10484 })
10485
10486 (define_expand "ashlsi3"
10487   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10489                    (match_operand:QI 2 "nonmemory_operand" "")))
10490    (clobber (reg:CC FLAGS_REG))]
10491   ""
10492   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10493
10494 (define_insn "*ashlsi3_1"
10495   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10496         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10497                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10498    (clobber (reg:CC FLAGS_REG))]
10499   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10500 {
10501   switch (get_attr_type (insn))
10502     {
10503     case TYPE_ALU:
10504       gcc_assert (operands[2] == const1_rtx);
10505       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10506       return "add{l}\t{%0, %0|%0, %0}";
10507
10508     case TYPE_LEA:
10509       return "#";
10510
10511     default:
10512       if (REG_P (operands[2]))
10513         return "sal{l}\t{%b2, %0|%0, %b2}";
10514       else if (operands[2] == const1_rtx
10515                && (TARGET_SHIFT1 || optimize_size))
10516         return "sal{l}\t%0";
10517       else
10518         return "sal{l}\t{%2, %0|%0, %2}";
10519     }
10520 }
10521   [(set (attr "type")
10522      (cond [(eq_attr "alternative" "1")
10523               (const_string "lea")
10524             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10525                           (const_int 0))
10526                       (match_operand 0 "register_operand" ""))
10527                  (match_operand 2 "const1_operand" ""))
10528               (const_string "alu")
10529            ]
10530            (const_string "ishift")))
10531    (set_attr "mode" "SI")])
10532
10533 ;; Convert lea to the lea pattern to avoid flags dependency.
10534 (define_split
10535   [(set (match_operand 0 "register_operand" "")
10536         (ashift (match_operand 1 "index_register_operand" "")
10537                 (match_operand:QI 2 "const_int_operand" "")))
10538    (clobber (reg:CC FLAGS_REG))]
10539   "reload_completed
10540    && true_regnum (operands[0]) != true_regnum (operands[1])
10541    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10542   [(const_int 0)]
10543 {
10544   rtx pat;
10545   enum machine_mode mode = GET_MODE (operands[0]);
10546
10547   if (GET_MODE_SIZE (mode) < 4)
10548     operands[0] = gen_lowpart (SImode, operands[0]);
10549   if (mode != Pmode)
10550     operands[1] = gen_lowpart (Pmode, operands[1]);
10551   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10552
10553   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10554   if (Pmode != SImode)
10555     pat = gen_rtx_SUBREG (SImode, pat, 0);
10556   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10557   DONE;
10558 })
10559
10560 ;; Rare case of shifting RSP is handled by generating move and shift
10561 (define_split
10562   [(set (match_operand 0 "register_operand" "")
10563         (ashift (match_operand 1 "register_operand" "")
10564                 (match_operand:QI 2 "const_int_operand" "")))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "reload_completed
10567    && true_regnum (operands[0]) != true_regnum (operands[1])"
10568   [(const_int 0)]
10569 {
10570   rtx pat, clob;
10571   emit_move_insn (operands[1], operands[0]);
10572   pat = gen_rtx_SET (VOIDmode, operands[0],
10573                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10574                                      operands[0], operands[2]));
10575   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10576   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10577   DONE;
10578 })
10579
10580 (define_insn "*ashlsi3_1_zext"
10581   [(set (match_operand:DI 0 "register_operand" "=r,r")
10582         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10583                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10584    (clobber (reg:CC FLAGS_REG))]
10585   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10586 {
10587   switch (get_attr_type (insn))
10588     {
10589     case TYPE_ALU:
10590       gcc_assert (operands[2] == const1_rtx);
10591       return "add{l}\t{%k0, %k0|%k0, %k0}";
10592
10593     case TYPE_LEA:
10594       return "#";
10595
10596     default:
10597       if (REG_P (operands[2]))
10598         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10599       else if (operands[2] == const1_rtx
10600                && (TARGET_SHIFT1 || optimize_size))
10601         return "sal{l}\t%k0";
10602       else
10603         return "sal{l}\t{%2, %k0|%k0, %2}";
10604     }
10605 }
10606   [(set (attr "type")
10607      (cond [(eq_attr "alternative" "1")
10608               (const_string "lea")
10609             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10610                      (const_int 0))
10611                  (match_operand 2 "const1_operand" ""))
10612               (const_string "alu")
10613            ]
10614            (const_string "ishift")))
10615    (set_attr "mode" "SI")])
10616
10617 ;; Convert lea to the lea pattern to avoid flags dependency.
10618 (define_split
10619   [(set (match_operand:DI 0 "register_operand" "")
10620         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10621                                 (match_operand:QI 2 "const_int_operand" ""))))
10622    (clobber (reg:CC FLAGS_REG))]
10623   "TARGET_64BIT && reload_completed
10624    && true_regnum (operands[0]) != true_regnum (operands[1])"
10625   [(set (match_dup 0) (zero_extend:DI
10626                         (subreg:SI (mult:SI (match_dup 1)
10627                                             (match_dup 2)) 0)))]
10628 {
10629   operands[1] = gen_lowpart (Pmode, operands[1]);
10630   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10631 })
10632
10633 ;; This pattern can't accept a variable shift count, since shifts by
10634 ;; zero don't affect the flags.  We assume that shifts by constant
10635 ;; zero are optimized away.
10636 (define_insn "*ashlsi3_cmp"
10637   [(set (reg FLAGS_REG)
10638         (compare
10639           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10640                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10641           (const_int 0)))
10642    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10643         (ashift:SI (match_dup 1) (match_dup 2)))]
10644   "ix86_match_ccmode (insn, CCGOCmode)
10645    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10646 {
10647   switch (get_attr_type (insn))
10648     {
10649     case TYPE_ALU:
10650       gcc_assert (operands[2] == const1_rtx);
10651       return "add{l}\t{%0, %0|%0, %0}";
10652
10653     default:
10654       if (REG_P (operands[2]))
10655         return "sal{l}\t{%b2, %0|%0, %b2}";
10656       else if (operands[2] == const1_rtx
10657                && (TARGET_SHIFT1 || optimize_size))
10658         return "sal{l}\t%0";
10659       else
10660         return "sal{l}\t{%2, %0|%0, %2}";
10661     }
10662 }
10663   [(set (attr "type")
10664      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10665                           (const_int 0))
10666                       (match_operand 0 "register_operand" ""))
10667                  (match_operand 2 "const1_operand" ""))
10668               (const_string "alu")
10669            ]
10670            (const_string "ishift")))
10671    (set_attr "mode" "SI")])
10672
10673 (define_insn "*ashlsi3_cmp_zext"
10674   [(set (reg FLAGS_REG)
10675         (compare
10676           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10677                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10678           (const_int 0)))
10679    (set (match_operand:DI 0 "register_operand" "=r")
10680         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10681   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10682    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10683 {
10684   switch (get_attr_type (insn))
10685     {
10686     case TYPE_ALU:
10687       gcc_assert (operands[2] == const1_rtx);
10688       return "add{l}\t{%k0, %k0|%k0, %k0}";
10689
10690     default:
10691       if (REG_P (operands[2]))
10692         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10693       else if (operands[2] == const1_rtx
10694                && (TARGET_SHIFT1 || optimize_size))
10695         return "sal{l}\t%k0";
10696       else
10697         return "sal{l}\t{%2, %k0|%k0, %2}";
10698     }
10699 }
10700   [(set (attr "type")
10701      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10702                      (const_int 0))
10703                  (match_operand 2 "const1_operand" ""))
10704               (const_string "alu")
10705            ]
10706            (const_string "ishift")))
10707    (set_attr "mode" "SI")])
10708
10709 (define_expand "ashlhi3"
10710   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10711         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10712                    (match_operand:QI 2 "nonmemory_operand" "")))
10713    (clobber (reg:CC FLAGS_REG))]
10714   "TARGET_HIMODE_MATH"
10715   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10716
10717 (define_insn "*ashlhi3_1_lea"
10718   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10719         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10720                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "!TARGET_PARTIAL_REG_STALL
10723    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10724 {
10725   switch (get_attr_type (insn))
10726     {
10727     case TYPE_LEA:
10728       return "#";
10729     case TYPE_ALU:
10730       gcc_assert (operands[2] == const1_rtx);
10731       return "add{w}\t{%0, %0|%0, %0}";
10732
10733     default:
10734       if (REG_P (operands[2]))
10735         return "sal{w}\t{%b2, %0|%0, %b2}";
10736       else if (operands[2] == const1_rtx
10737                && (TARGET_SHIFT1 || optimize_size))
10738         return "sal{w}\t%0";
10739       else
10740         return "sal{w}\t{%2, %0|%0, %2}";
10741     }
10742 }
10743   [(set (attr "type")
10744      (cond [(eq_attr "alternative" "1")
10745               (const_string "lea")
10746             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747                           (const_int 0))
10748                       (match_operand 0 "register_operand" ""))
10749                  (match_operand 2 "const1_operand" ""))
10750               (const_string "alu")
10751            ]
10752            (const_string "ishift")))
10753    (set_attr "mode" "HI,SI")])
10754
10755 (define_insn "*ashlhi3_1"
10756   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10758                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10759    (clobber (reg:CC FLAGS_REG))]
10760   "TARGET_PARTIAL_REG_STALL
10761    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10762 {
10763   switch (get_attr_type (insn))
10764     {
10765     case TYPE_ALU:
10766       gcc_assert (operands[2] == const1_rtx);
10767       return "add{w}\t{%0, %0|%0, %0}";
10768
10769     default:
10770       if (REG_P (operands[2]))
10771         return "sal{w}\t{%b2, %0|%0, %b2}";
10772       else if (operands[2] == const1_rtx
10773                && (TARGET_SHIFT1 || optimize_size))
10774         return "sal{w}\t%0";
10775       else
10776         return "sal{w}\t{%2, %0|%0, %2}";
10777     }
10778 }
10779   [(set (attr "type")
10780      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781                           (const_int 0))
10782                       (match_operand 0 "register_operand" ""))
10783                  (match_operand 2 "const1_operand" ""))
10784               (const_string "alu")
10785            ]
10786            (const_string "ishift")))
10787    (set_attr "mode" "HI")])
10788
10789 ;; This pattern can't accept a variable shift count, since shifts by
10790 ;; zero don't affect the flags.  We assume that shifts by constant
10791 ;; zero are optimized away.
10792 (define_insn "*ashlhi3_cmp"
10793   [(set (reg FLAGS_REG)
10794         (compare
10795           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10796                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10797           (const_int 0)))
10798    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10799         (ashift:HI (match_dup 1) (match_dup 2)))]
10800   "ix86_match_ccmode (insn, CCGOCmode)
10801    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10802 {
10803   switch (get_attr_type (insn))
10804     {
10805     case TYPE_ALU:
10806       gcc_assert (operands[2] == const1_rtx);
10807       return "add{w}\t{%0, %0|%0, %0}";
10808
10809     default:
10810       if (REG_P (operands[2]))
10811         return "sal{w}\t{%b2, %0|%0, %b2}";
10812       else if (operands[2] == const1_rtx
10813                && (TARGET_SHIFT1 || optimize_size))
10814         return "sal{w}\t%0";
10815       else
10816         return "sal{w}\t{%2, %0|%0, %2}";
10817     }
10818 }
10819   [(set (attr "type")
10820      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10821                           (const_int 0))
10822                       (match_operand 0 "register_operand" ""))
10823                  (match_operand 2 "const1_operand" ""))
10824               (const_string "alu")
10825            ]
10826            (const_string "ishift")))
10827    (set_attr "mode" "HI")])
10828
10829 (define_expand "ashlqi3"
10830   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10831         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10832                    (match_operand:QI 2 "nonmemory_operand" "")))
10833    (clobber (reg:CC FLAGS_REG))]
10834   "TARGET_QIMODE_MATH"
10835   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10836
10837 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10838
10839 (define_insn "*ashlqi3_1_lea"
10840   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10841         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10842                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10843    (clobber (reg:CC FLAGS_REG))]
10844   "!TARGET_PARTIAL_REG_STALL
10845    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10846 {
10847   switch (get_attr_type (insn))
10848     {
10849     case TYPE_LEA:
10850       return "#";
10851     case TYPE_ALU:
10852       gcc_assert (operands[2] == const1_rtx);
10853       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10854         return "add{l}\t{%k0, %k0|%k0, %k0}";
10855       else
10856         return "add{b}\t{%0, %0|%0, %0}";
10857
10858     default:
10859       if (REG_P (operands[2]))
10860         {
10861           if (get_attr_mode (insn) == MODE_SI)
10862             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10863           else
10864             return "sal{b}\t{%b2, %0|%0, %b2}";
10865         }
10866       else if (operands[2] == const1_rtx
10867                && (TARGET_SHIFT1 || optimize_size))
10868         {
10869           if (get_attr_mode (insn) == MODE_SI)
10870             return "sal{l}\t%0";
10871           else
10872             return "sal{b}\t%0";
10873         }
10874       else
10875         {
10876           if (get_attr_mode (insn) == MODE_SI)
10877             return "sal{l}\t{%2, %k0|%k0, %2}";
10878           else
10879             return "sal{b}\t{%2, %0|%0, %2}";
10880         }
10881     }
10882 }
10883   [(set (attr "type")
10884      (cond [(eq_attr "alternative" "2")
10885               (const_string "lea")
10886             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887                           (const_int 0))
10888                       (match_operand 0 "register_operand" ""))
10889                  (match_operand 2 "const1_operand" ""))
10890               (const_string "alu")
10891            ]
10892            (const_string "ishift")))
10893    (set_attr "mode" "QI,SI,SI")])
10894
10895 (define_insn "*ashlqi3_1"
10896   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10897         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10898                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10899    (clobber (reg:CC FLAGS_REG))]
10900   "TARGET_PARTIAL_REG_STALL
10901    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10902 {
10903   switch (get_attr_type (insn))
10904     {
10905     case TYPE_ALU:
10906       gcc_assert (operands[2] == const1_rtx);
10907       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10908         return "add{l}\t{%k0, %k0|%k0, %k0}";
10909       else
10910         return "add{b}\t{%0, %0|%0, %0}";
10911
10912     default:
10913       if (REG_P (operands[2]))
10914         {
10915           if (get_attr_mode (insn) == MODE_SI)
10916             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10917           else
10918             return "sal{b}\t{%b2, %0|%0, %b2}";
10919         }
10920       else if (operands[2] == const1_rtx
10921                && (TARGET_SHIFT1 || optimize_size))
10922         {
10923           if (get_attr_mode (insn) == MODE_SI)
10924             return "sal{l}\t%0";
10925           else
10926             return "sal{b}\t%0";
10927         }
10928       else
10929         {
10930           if (get_attr_mode (insn) == MODE_SI)
10931             return "sal{l}\t{%2, %k0|%k0, %2}";
10932           else
10933             return "sal{b}\t{%2, %0|%0, %2}";
10934         }
10935     }
10936 }
10937   [(set (attr "type")
10938      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10939                           (const_int 0))
10940                       (match_operand 0 "register_operand" ""))
10941                  (match_operand 2 "const1_operand" ""))
10942               (const_string "alu")
10943            ]
10944            (const_string "ishift")))
10945    (set_attr "mode" "QI,SI")])
10946
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags.  We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashlqi3_cmp"
10951   [(set (reg FLAGS_REG)
10952         (compare
10953           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10954                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10955           (const_int 0)))
10956    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10957         (ashift:QI (match_dup 1) (match_dup 2)))]
10958   "ix86_match_ccmode (insn, CCGOCmode)
10959    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10960 {
10961   switch (get_attr_type (insn))
10962     {
10963     case TYPE_ALU:
10964       gcc_assert (operands[2] == const1_rtx);
10965       return "add{b}\t{%0, %0|%0, %0}";
10966
10967     default:
10968       if (REG_P (operands[2]))
10969         return "sal{b}\t{%b2, %0|%0, %b2}";
10970       else if (operands[2] == const1_rtx
10971                && (TARGET_SHIFT1 || optimize_size))
10972         return "sal{b}\t%0";
10973       else
10974         return "sal{b}\t{%2, %0|%0, %2}";
10975     }
10976 }
10977   [(set (attr "type")
10978      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10979                           (const_int 0))
10980                       (match_operand 0 "register_operand" ""))
10981                  (match_operand 2 "const1_operand" ""))
10982               (const_string "alu")
10983            ]
10984            (const_string "ishift")))
10985    (set_attr "mode" "QI")])
10986
10987 ;; See comment above `ashldi3' about how this works.
10988
10989 (define_expand "ashrti3"
10990   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10991                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10992                                 (match_operand:QI 2 "nonmemory_operand" "")))
10993               (clobber (reg:CC FLAGS_REG))])]
10994   "TARGET_64BIT"
10995 {
10996   if (! immediate_operand (operands[2], QImode))
10997     {
10998       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10999       DONE;
11000     }
11001   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11002   DONE;
11003 })
11004
11005 (define_insn "ashrti3_1"
11006   [(set (match_operand:TI 0 "register_operand" "=r")
11007         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11008                      (match_operand:QI 2 "register_operand" "c")))
11009    (clobber (match_scratch:DI 3 "=&r"))
11010    (clobber (reg:CC FLAGS_REG))]
11011   "TARGET_64BIT"
11012   "#"
11013   [(set_attr "type" "multi")])
11014
11015 (define_insn "*ashrti3_2"
11016   [(set (match_operand:TI 0 "register_operand" "=r")
11017         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11018                      (match_operand:QI 2 "immediate_operand" "O")))
11019    (clobber (reg:CC FLAGS_REG))]
11020   "TARGET_64BIT"
11021   "#"
11022   [(set_attr "type" "multi")])
11023
11024 (define_split
11025   [(set (match_operand:TI 0 "register_operand" "")
11026         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027                      (match_operand:QI 2 "register_operand" "")))
11028    (clobber (match_scratch:DI 3 ""))
11029    (clobber (reg:CC FLAGS_REG))]
11030   "TARGET_64BIT && reload_completed"
11031   [(const_int 0)]
11032   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11033
11034 (define_split
11035   [(set (match_operand:TI 0 "register_operand" "")
11036         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11037                      (match_operand:QI 2 "immediate_operand" "")))
11038    (clobber (reg:CC FLAGS_REG))]
11039   "TARGET_64BIT && reload_completed"
11040   [(const_int 0)]
11041   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11042
11043 (define_insn "x86_64_shrd"
11044   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11045         (ior:DI (ashiftrt:DI (match_dup 0)
11046                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11047                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11048                   (minus:QI (const_int 64) (match_dup 2)))))
11049    (clobber (reg:CC FLAGS_REG))]
11050   "TARGET_64BIT"
11051   "@
11052    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11053    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11054   [(set_attr "type" "ishift")
11055    (set_attr "prefix_0f" "1")
11056    (set_attr "mode" "DI")
11057    (set_attr "athlon_decode" "vector")])
11058
11059 (define_expand "ashrdi3"
11060   [(set (match_operand:DI 0 "shiftdi_operand" "")
11061         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11062                      (match_operand:QI 2 "nonmemory_operand" "")))]
11063   ""
11064   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11065
11066 (define_insn "*ashrdi3_63_rex64"
11067   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11068         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11069                      (match_operand:DI 2 "const_int_operand" "i,i")))
11070    (clobber (reg:CC FLAGS_REG))]
11071   "TARGET_64BIT && INTVAL (operands[2]) == 63
11072    && (TARGET_USE_CLTD || optimize_size)
11073    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11074   "@
11075    {cqto|cqo}
11076    sar{q}\t{%2, %0|%0, %2}"
11077   [(set_attr "type" "imovx,ishift")
11078    (set_attr "prefix_0f" "0,*")
11079    (set_attr "length_immediate" "0,*")
11080    (set_attr "modrm" "0,1")
11081    (set_attr "mode" "DI")])
11082
11083 (define_insn "*ashrdi3_1_one_bit_rex64"
11084   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11085         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11086                      (match_operand:QI 2 "const1_operand" "")))
11087    (clobber (reg:CC FLAGS_REG))]
11088   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11089    && (TARGET_SHIFT1 || optimize_size)"
11090   "sar{q}\t%0"
11091   [(set_attr "type" "ishift")
11092    (set (attr "length") 
11093      (if_then_else (match_operand:DI 0 "register_operand" "") 
11094         (const_string "2")
11095         (const_string "*")))])
11096
11097 (define_insn "*ashrdi3_1_rex64"
11098   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11099         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11100                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11101    (clobber (reg:CC FLAGS_REG))]
11102   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11103   "@
11104    sar{q}\t{%2, %0|%0, %2}
11105    sar{q}\t{%b2, %0|%0, %b2}"
11106   [(set_attr "type" "ishift")
11107    (set_attr "mode" "DI")])
11108
11109 ;; This pattern can't accept a variable shift count, since shifts by
11110 ;; zero don't affect the flags.  We assume that shifts by constant
11111 ;; zero are optimized away.
11112 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11113   [(set (reg FLAGS_REG)
11114         (compare
11115           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11116                        (match_operand:QI 2 "const1_operand" ""))
11117           (const_int 0)))
11118    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11119         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11120   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11121    && (TARGET_SHIFT1 || optimize_size)
11122    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11123   "sar{q}\t%0"
11124   [(set_attr "type" "ishift")
11125    (set (attr "length") 
11126      (if_then_else (match_operand:DI 0 "register_operand" "") 
11127         (const_string "2")
11128         (const_string "*")))])
11129
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags.  We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrdi3_cmp_rex64"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11137                        (match_operand:QI 2 "const_int_operand" "n"))
11138           (const_int 0)))
11139    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11140         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11141   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11142    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11143   "sar{q}\t{%2, %0|%0, %2}"
11144   [(set_attr "type" "ishift")
11145    (set_attr "mode" "DI")])
11146
11147 (define_insn "*ashrdi3_1"
11148   [(set (match_operand:DI 0 "register_operand" "=r")
11149         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11150                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11151    (clobber (reg:CC FLAGS_REG))]
11152   "!TARGET_64BIT"
11153   "#"
11154   [(set_attr "type" "multi")])
11155
11156 ;; By default we don't ask for a scratch register, because when DImode
11157 ;; values are manipulated, registers are already at a premium.  But if
11158 ;; we have one handy, we won't turn it away.
11159 (define_peephole2
11160   [(match_scratch:SI 3 "r")
11161    (parallel [(set (match_operand:DI 0 "register_operand" "")
11162                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11163                                 (match_operand:QI 2 "nonmemory_operand" "")))
11164               (clobber (reg:CC FLAGS_REG))])
11165    (match_dup 3)]
11166   "!TARGET_64BIT && TARGET_CMOVE"
11167   [(const_int 0)]
11168   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11169
11170 (define_split
11171   [(set (match_operand:DI 0 "register_operand" "")
11172         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11173                      (match_operand:QI 2 "nonmemory_operand" "")))
11174    (clobber (reg:CC FLAGS_REG))]
11175   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11176                      ? flow2_completed : reload_completed)"
11177   [(const_int 0)]
11178   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11179
11180 (define_insn "x86_shrd_1"
11181   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11182         (ior:SI (ashiftrt:SI (match_dup 0)
11183                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11184                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11185                   (minus:QI (const_int 32) (match_dup 2)))))
11186    (clobber (reg:CC FLAGS_REG))]
11187   ""
11188   "@
11189    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11190    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11191   [(set_attr "type" "ishift")
11192    (set_attr "prefix_0f" "1")
11193    (set_attr "pent_pair" "np")
11194    (set_attr "mode" "SI")])
11195
11196 (define_expand "x86_shift_adj_3"
11197   [(use (match_operand:SI 0 "register_operand" ""))
11198    (use (match_operand:SI 1 "register_operand" ""))
11199    (use (match_operand:QI 2 "register_operand" ""))]
11200   ""
11201 {
11202   rtx label = gen_label_rtx ();
11203   rtx tmp;
11204
11205   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11206
11207   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11208   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11209   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11210                               gen_rtx_LABEL_REF (VOIDmode, label),
11211                               pc_rtx);
11212   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11213   JUMP_LABEL (tmp) = label;
11214
11215   emit_move_insn (operands[0], operands[1]);
11216   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11217
11218   emit_label (label);
11219   LABEL_NUSES (label) = 1;
11220
11221   DONE;
11222 })
11223
11224 (define_insn "ashrsi3_31"
11225   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11226         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11227                      (match_operand:SI 2 "const_int_operand" "i,i")))
11228    (clobber (reg:CC FLAGS_REG))]
11229   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11230    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11231   "@
11232    {cltd|cdq}
11233    sar{l}\t{%2, %0|%0, %2}"
11234   [(set_attr "type" "imovx,ishift")
11235    (set_attr "prefix_0f" "0,*")
11236    (set_attr "length_immediate" "0,*")
11237    (set_attr "modrm" "0,1")
11238    (set_attr "mode" "SI")])
11239
11240 (define_insn "*ashrsi3_31_zext"
11241   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11242         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11243                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11246    && INTVAL (operands[2]) == 31
11247    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11248   "@
11249    {cltd|cdq}
11250    sar{l}\t{%2, %k0|%k0, %2}"
11251   [(set_attr "type" "imovx,ishift")
11252    (set_attr "prefix_0f" "0,*")
11253    (set_attr "length_immediate" "0,*")
11254    (set_attr "modrm" "0,1")
11255    (set_attr "mode" "SI")])
11256
11257 (define_expand "ashrsi3"
11258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11259         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11260                      (match_operand:QI 2 "nonmemory_operand" "")))
11261    (clobber (reg:CC FLAGS_REG))]
11262   ""
11263   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11264
11265 (define_insn "*ashrsi3_1_one_bit"
11266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11267         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11268                      (match_operand:QI 2 "const1_operand" "")))
11269    (clobber (reg:CC FLAGS_REG))]
11270   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11271    && (TARGET_SHIFT1 || optimize_size)"
11272   "sar{l}\t%0"
11273   [(set_attr "type" "ishift")
11274    (set (attr "length") 
11275      (if_then_else (match_operand:SI 0 "register_operand" "") 
11276         (const_string "2")
11277         (const_string "*")))])
11278
11279 (define_insn "*ashrsi3_1_one_bit_zext"
11280   [(set (match_operand:DI 0 "register_operand" "=r")
11281         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11282                                      (match_operand:QI 2 "const1_operand" ""))))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11285    && (TARGET_SHIFT1 || optimize_size)"
11286   "sar{l}\t%k0"
11287   [(set_attr "type" "ishift")
11288    (set_attr "length" "2")])
11289
11290 (define_insn "*ashrsi3_1"
11291   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11292         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11293                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11296   "@
11297    sar{l}\t{%2, %0|%0, %2}
11298    sar{l}\t{%b2, %0|%0, %b2}"
11299   [(set_attr "type" "ishift")
11300    (set_attr "mode" "SI")])
11301
11302 (define_insn "*ashrsi3_1_zext"
11303   [(set (match_operand:DI 0 "register_operand" "=r,r")
11304         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11305                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11306    (clobber (reg:CC FLAGS_REG))]
11307   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11308   "@
11309    sar{l}\t{%2, %k0|%k0, %2}
11310    sar{l}\t{%b2, %k0|%k0, %b2}"
11311   [(set_attr "type" "ishift")
11312    (set_attr "mode" "SI")])
11313
11314 ;; This pattern can't accept a variable shift count, since shifts by
11315 ;; zero don't affect the flags.  We assume that shifts by constant
11316 ;; zero are optimized away.
11317 (define_insn "*ashrsi3_one_bit_cmp"
11318   [(set (reg FLAGS_REG)
11319         (compare
11320           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11321                        (match_operand:QI 2 "const1_operand" ""))
11322           (const_int 0)))
11323    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11324         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11325   "ix86_match_ccmode (insn, CCGOCmode)
11326    && (TARGET_SHIFT1 || optimize_size)
11327    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11328   "sar{l}\t%0"
11329   [(set_attr "type" "ishift")
11330    (set (attr "length") 
11331      (if_then_else (match_operand:SI 0 "register_operand" "") 
11332         (const_string "2")
11333         (const_string "*")))])
11334
11335 (define_insn "*ashrsi3_one_bit_cmp_zext"
11336   [(set (reg FLAGS_REG)
11337         (compare
11338           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11339                        (match_operand:QI 2 "const1_operand" ""))
11340           (const_int 0)))
11341    (set (match_operand:DI 0 "register_operand" "=r")
11342         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11343   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11344    && (TARGET_SHIFT1 || optimize_size)
11345    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11346   "sar{l}\t%k0"
11347   [(set_attr "type" "ishift")
11348    (set_attr "length" "2")])
11349
11350 ;; This pattern can't accept a variable shift count, since shifts by
11351 ;; zero don't affect the flags.  We assume that shifts by constant
11352 ;; zero are optimized away.
11353 (define_insn "*ashrsi3_cmp"
11354   [(set (reg FLAGS_REG)
11355         (compare
11356           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11357                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11358           (const_int 0)))
11359    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11360         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11361   "ix86_match_ccmode (insn, CCGOCmode)
11362    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363   "sar{l}\t{%2, %0|%0, %2}"
11364   [(set_attr "type" "ishift")
11365    (set_attr "mode" "SI")])
11366
11367 (define_insn "*ashrsi3_cmp_zext"
11368   [(set (reg FLAGS_REG)
11369         (compare
11370           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11371                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11372           (const_int 0)))
11373    (set (match_operand:DI 0 "register_operand" "=r")
11374         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11375   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11376    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11377   "sar{l}\t{%2, %k0|%k0, %2}"
11378   [(set_attr "type" "ishift")
11379    (set_attr "mode" "SI")])
11380
11381 (define_expand "ashrhi3"
11382   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11383         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11384                      (match_operand:QI 2 "nonmemory_operand" "")))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_HIMODE_MATH"
11387   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11388
11389 (define_insn "*ashrhi3_1_one_bit"
11390   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11391         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11392                      (match_operand:QI 2 "const1_operand" "")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11395    && (TARGET_SHIFT1 || optimize_size)"
11396   "sar{w}\t%0"
11397   [(set_attr "type" "ishift")
11398    (set (attr "length") 
11399      (if_then_else (match_operand 0 "register_operand" "") 
11400         (const_string "2")
11401         (const_string "*")))])
11402
11403 (define_insn "*ashrhi3_1"
11404   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11405         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11406                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11407    (clobber (reg:CC FLAGS_REG))]
11408   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11409   "@
11410    sar{w}\t{%2, %0|%0, %2}
11411    sar{w}\t{%b2, %0|%0, %b2}"
11412   [(set_attr "type" "ishift")
11413    (set_attr "mode" "HI")])
11414
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags.  We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*ashrhi3_one_bit_cmp"
11419   [(set (reg FLAGS_REG)
11420         (compare
11421           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11422                        (match_operand:QI 2 "const1_operand" ""))
11423           (const_int 0)))
11424    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11426   "ix86_match_ccmode (insn, CCGOCmode)
11427    && (TARGET_SHIFT1 || optimize_size)
11428    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11429   "sar{w}\t%0"
11430   [(set_attr "type" "ishift")
11431    (set (attr "length") 
11432      (if_then_else (match_operand 0 "register_operand" "") 
11433         (const_string "2")
11434         (const_string "*")))])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags.  We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*ashrhi3_cmp"
11440   [(set (reg FLAGS_REG)
11441         (compare
11442           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11443                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11444           (const_int 0)))
11445    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11446         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11447   "ix86_match_ccmode (insn, CCGOCmode)
11448    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11449   "sar{w}\t{%2, %0|%0, %2}"
11450   [(set_attr "type" "ishift")
11451    (set_attr "mode" "HI")])
11452
11453 (define_expand "ashrqi3"
11454   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11455         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11456                      (match_operand:QI 2 "nonmemory_operand" "")))
11457    (clobber (reg:CC FLAGS_REG))]
11458   "TARGET_QIMODE_MATH"
11459   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11460
11461 (define_insn "*ashrqi3_1_one_bit"
11462   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11463         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11464                      (match_operand:QI 2 "const1_operand" "")))
11465    (clobber (reg:CC FLAGS_REG))]
11466   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11467    && (TARGET_SHIFT1 || optimize_size)"
11468   "sar{b}\t%0"
11469   [(set_attr "type" "ishift")
11470    (set (attr "length") 
11471      (if_then_else (match_operand 0 "register_operand" "") 
11472         (const_string "2")
11473         (const_string "*")))])
11474
11475 (define_insn "*ashrqi3_1_one_bit_slp"
11476   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11477         (ashiftrt:QI (match_dup 0)
11478                      (match_operand:QI 1 "const1_operand" "")))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11481    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11482    && (TARGET_SHIFT1 || optimize_size)"
11483   "sar{b}\t%0"
11484   [(set_attr "type" "ishift1")
11485    (set (attr "length") 
11486      (if_then_else (match_operand 0 "register_operand" "") 
11487         (const_string "2")
11488         (const_string "*")))])
11489
11490 (define_insn "*ashrqi3_1"
11491   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11492         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11493                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11494    (clobber (reg:CC FLAGS_REG))]
11495   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11496   "@
11497    sar{b}\t{%2, %0|%0, %2}
11498    sar{b}\t{%b2, %0|%0, %b2}"
11499   [(set_attr "type" "ishift")
11500    (set_attr "mode" "QI")])
11501
11502 (define_insn "*ashrqi3_1_slp"
11503   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11504         (ashiftrt:QI (match_dup 0)
11505                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11506    (clobber (reg:CC FLAGS_REG))]
11507   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11508    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11509   "@
11510    sar{b}\t{%1, %0|%0, %1}
11511    sar{b}\t{%b1, %0|%0, %b1}"
11512   [(set_attr "type" "ishift1")
11513    (set_attr "mode" "QI")])
11514
11515 ;; This pattern can't accept a variable shift count, since shifts by
11516 ;; zero don't affect the flags.  We assume that shifts by constant
11517 ;; zero are optimized away.
11518 (define_insn "*ashrqi3_one_bit_cmp"
11519   [(set (reg FLAGS_REG)
11520         (compare
11521           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11522                        (match_operand:QI 2 "const1_operand" "I"))
11523           (const_int 0)))
11524    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11525         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11526   "ix86_match_ccmode (insn, CCGOCmode)
11527    && (TARGET_SHIFT1 || optimize_size)
11528    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11529   "sar{b}\t%0"
11530   [(set_attr "type" "ishift")
11531    (set (attr "length") 
11532      (if_then_else (match_operand 0 "register_operand" "") 
11533         (const_string "2")
11534         (const_string "*")))])
11535
11536 ;; This pattern can't accept a variable shift count, since shifts by
11537 ;; zero don't affect the flags.  We assume that shifts by constant
11538 ;; zero are optimized away.
11539 (define_insn "*ashrqi3_cmp"
11540   [(set (reg FLAGS_REG)
11541         (compare
11542           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11543                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11544           (const_int 0)))
11545    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11546         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11547   "ix86_match_ccmode (insn, CCGOCmode)
11548    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11549   "sar{b}\t{%2, %0|%0, %2}"
11550   [(set_attr "type" "ishift")
11551    (set_attr "mode" "QI")])
11552 \f
11553 ;; Logical shift instructions
11554
11555 ;; See comment above `ashldi3' about how this works.
11556
11557 (define_expand "lshrti3"
11558   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11559                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11560                                 (match_operand:QI 2 "nonmemory_operand" "")))
11561               (clobber (reg:CC FLAGS_REG))])]
11562   "TARGET_64BIT"
11563 {
11564   if (! immediate_operand (operands[2], QImode))
11565     {
11566       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11567       DONE;
11568     }
11569   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11570   DONE;
11571 })
11572
11573 (define_insn "lshrti3_1"
11574   [(set (match_operand:TI 0 "register_operand" "=r")
11575         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11576                      (match_operand:QI 2 "register_operand" "c")))
11577    (clobber (match_scratch:DI 3 "=&r"))
11578    (clobber (reg:CC FLAGS_REG))]
11579   "TARGET_64BIT"
11580   "#"
11581   [(set_attr "type" "multi")])
11582
11583 (define_insn "*lshrti3_2"
11584   [(set (match_operand:TI 0 "register_operand" "=r")
11585         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11586                      (match_operand:QI 2 "immediate_operand" "O")))
11587    (clobber (reg:CC FLAGS_REG))]
11588   "TARGET_64BIT"
11589   "#"
11590   [(set_attr "type" "multi")])
11591
11592 (define_split 
11593   [(set (match_operand:TI 0 "register_operand" "")
11594         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595                      (match_operand:QI 2 "register_operand" "")))
11596    (clobber (match_scratch:DI 3 ""))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "TARGET_64BIT && reload_completed"
11599   [(const_int 0)]
11600   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11601
11602 (define_split 
11603   [(set (match_operand:TI 0 "register_operand" "")
11604         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11605                      (match_operand:QI 2 "immediate_operand" "")))
11606    (clobber (reg:CC FLAGS_REG))]
11607   "TARGET_64BIT && reload_completed"
11608   [(const_int 0)]
11609   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11610
11611 (define_expand "lshrdi3"
11612   [(set (match_operand:DI 0 "shiftdi_operand" "")
11613         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11614                      (match_operand:QI 2 "nonmemory_operand" "")))]
11615   ""
11616   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11617
11618 (define_insn "*lshrdi3_1_one_bit_rex64"
11619   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11620         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11621                      (match_operand:QI 2 "const1_operand" "")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11624    && (TARGET_SHIFT1 || optimize_size)"
11625   "shr{q}\t%0"
11626   [(set_attr "type" "ishift")
11627    (set (attr "length") 
11628      (if_then_else (match_operand:DI 0 "register_operand" "") 
11629         (const_string "2")
11630         (const_string "*")))])
11631
11632 (define_insn "*lshrdi3_1_rex64"
11633   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11634         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11635                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11638   "@
11639    shr{q}\t{%2, %0|%0, %2}
11640    shr{q}\t{%b2, %0|%0, %b2}"
11641   [(set_attr "type" "ishift")
11642    (set_attr "mode" "DI")])
11643
11644 ;; This pattern can't accept a variable shift count, since shifts by
11645 ;; zero don't affect the flags.  We assume that shifts by constant
11646 ;; zero are optimized away.
11647 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11648   [(set (reg FLAGS_REG)
11649         (compare
11650           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11651                        (match_operand:QI 2 "const1_operand" ""))
11652           (const_int 0)))
11653    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11654         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11655   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11656    && (TARGET_SHIFT1 || optimize_size)
11657    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11658   "shr{q}\t%0"
11659   [(set_attr "type" "ishift")
11660    (set (attr "length") 
11661      (if_then_else (match_operand:DI 0 "register_operand" "") 
11662         (const_string "2")
11663         (const_string "*")))])
11664
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags.  We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrdi3_cmp_rex64"
11669   [(set (reg FLAGS_REG)
11670         (compare
11671           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11672                        (match_operand:QI 2 "const_int_operand" "e"))
11673           (const_int 0)))
11674    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11675         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11678   "shr{q}\t{%2, %0|%0, %2}"
11679   [(set_attr "type" "ishift")
11680    (set_attr "mode" "DI")])
11681
11682 (define_insn "*lshrdi3_1"
11683   [(set (match_operand:DI 0 "register_operand" "=r")
11684         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11685                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "!TARGET_64BIT"
11688   "#"
11689   [(set_attr "type" "multi")])
11690
11691 ;; By default we don't ask for a scratch register, because when DImode
11692 ;; values are manipulated, registers are already at a premium.  But if
11693 ;; we have one handy, we won't turn it away.
11694 (define_peephole2
11695   [(match_scratch:SI 3 "r")
11696    (parallel [(set (match_operand:DI 0 "register_operand" "")
11697                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11698                                 (match_operand:QI 2 "nonmemory_operand" "")))
11699               (clobber (reg:CC FLAGS_REG))])
11700    (match_dup 3)]
11701   "!TARGET_64BIT && TARGET_CMOVE"
11702   [(const_int 0)]
11703   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11704
11705 (define_split 
11706   [(set (match_operand:DI 0 "register_operand" "")
11707         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11708                      (match_operand:QI 2 "nonmemory_operand" "")))
11709    (clobber (reg:CC FLAGS_REG))]
11710   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11711                      ? flow2_completed : reload_completed)"
11712   [(const_int 0)]
11713   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11714
11715 (define_expand "lshrsi3"
11716   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11717         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11718                      (match_operand:QI 2 "nonmemory_operand" "")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   ""
11721   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11722
11723 (define_insn "*lshrsi3_1_one_bit"
11724   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11725         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11726                      (match_operand:QI 2 "const1_operand" "")))
11727    (clobber (reg:CC FLAGS_REG))]
11728   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11729    && (TARGET_SHIFT1 || optimize_size)"
11730   "shr{l}\t%0"
11731   [(set_attr "type" "ishift")
11732    (set (attr "length") 
11733      (if_then_else (match_operand:SI 0 "register_operand" "") 
11734         (const_string "2")
11735         (const_string "*")))])
11736
11737 (define_insn "*lshrsi3_1_one_bit_zext"
11738   [(set (match_operand:DI 0 "register_operand" "=r")
11739         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11740                      (match_operand:QI 2 "const1_operand" "")))
11741    (clobber (reg:CC FLAGS_REG))]
11742   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11743    && (TARGET_SHIFT1 || optimize_size)"
11744   "shr{l}\t%k0"
11745   [(set_attr "type" "ishift")
11746    (set_attr "length" "2")])
11747
11748 (define_insn "*lshrsi3_1"
11749   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752    (clobber (reg:CC FLAGS_REG))]
11753   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11754   "@
11755    shr{l}\t{%2, %0|%0, %2}
11756    shr{l}\t{%b2, %0|%0, %b2}"
11757   [(set_attr "type" "ishift")
11758    (set_attr "mode" "SI")])
11759
11760 (define_insn "*lshrsi3_1_zext"
11761   [(set (match_operand:DI 0 "register_operand" "=r,r")
11762         (zero_extend:DI
11763           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11764                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765    (clobber (reg:CC FLAGS_REG))]
11766   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11767   "@
11768    shr{l}\t{%2, %k0|%k0, %2}
11769    shr{l}\t{%b2, %k0|%k0, %b2}"
11770   [(set_attr "type" "ishift")
11771    (set_attr "mode" "SI")])
11772
11773 ;; This pattern can't accept a variable shift count, since shifts by
11774 ;; zero don't affect the flags.  We assume that shifts by constant
11775 ;; zero are optimized away.
11776 (define_insn "*lshrsi3_one_bit_cmp"
11777   [(set (reg FLAGS_REG)
11778         (compare
11779           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11780                        (match_operand:QI 2 "const1_operand" ""))
11781           (const_int 0)))
11782    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11783         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11784   "ix86_match_ccmode (insn, CCGOCmode)
11785    && (TARGET_SHIFT1 || optimize_size)
11786    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11787   "shr{l}\t%0"
11788   [(set_attr "type" "ishift")
11789    (set (attr "length") 
11790      (if_then_else (match_operand:SI 0 "register_operand" "") 
11791         (const_string "2")
11792         (const_string "*")))])
11793
11794 (define_insn "*lshrsi3_cmp_one_bit_zext"
11795   [(set (reg FLAGS_REG)
11796         (compare
11797           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11798                        (match_operand:QI 2 "const1_operand" ""))
11799           (const_int 0)))
11800    (set (match_operand:DI 0 "register_operand" "=r")
11801         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11802   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11803    && (TARGET_SHIFT1 || optimize_size)
11804    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11805   "shr{l}\t%k0"
11806   [(set_attr "type" "ishift")
11807    (set_attr "length" "2")])
11808
11809 ;; This pattern can't accept a variable shift count, since shifts by
11810 ;; zero don't affect the flags.  We assume that shifts by constant
11811 ;; zero are optimized away.
11812 (define_insn "*lshrsi3_cmp"
11813   [(set (reg FLAGS_REG)
11814         (compare
11815           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11816                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817           (const_int 0)))
11818    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11819         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11820   "ix86_match_ccmode (insn, CCGOCmode)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t{%2, %0|%0, %2}"
11823   [(set_attr "type" "ishift")
11824    (set_attr "mode" "SI")])
11825
11826 (define_insn "*lshrsi3_cmp_zext"
11827   [(set (reg FLAGS_REG)
11828         (compare
11829           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11830                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11831           (const_int 0)))
11832    (set (match_operand:DI 0 "register_operand" "=r")
11833         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11834   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11835    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11836   "shr{l}\t{%2, %k0|%k0, %2}"
11837   [(set_attr "type" "ishift")
11838    (set_attr "mode" "SI")])
11839
11840 (define_expand "lshrhi3"
11841   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11842         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11843                      (match_operand:QI 2 "nonmemory_operand" "")))
11844    (clobber (reg:CC FLAGS_REG))]
11845   "TARGET_HIMODE_MATH"
11846   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11847
11848 (define_insn "*lshrhi3_1_one_bit"
11849   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11851                      (match_operand:QI 2 "const1_operand" "")))
11852    (clobber (reg:CC FLAGS_REG))]
11853   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11854    && (TARGET_SHIFT1 || optimize_size)"
11855   "shr{w}\t%0"
11856   [(set_attr "type" "ishift")
11857    (set (attr "length") 
11858      (if_then_else (match_operand 0 "register_operand" "") 
11859         (const_string "2")
11860         (const_string "*")))])
11861
11862 (define_insn "*lshrhi3_1"
11863   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11864         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11865                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11868   "@
11869    shr{w}\t{%2, %0|%0, %2}
11870    shr{w}\t{%b2, %0|%0, %b2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "HI")])
11873
11874 ;; This pattern can't accept a variable shift count, since shifts by
11875 ;; zero don't affect the flags.  We assume that shifts by constant
11876 ;; zero are optimized away.
11877 (define_insn "*lshrhi3_one_bit_cmp"
11878   [(set (reg FLAGS_REG)
11879         (compare
11880           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11881                        (match_operand:QI 2 "const1_operand" ""))
11882           (const_int 0)))
11883    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11885   "ix86_match_ccmode (insn, CCGOCmode)
11886    && (TARGET_SHIFT1 || optimize_size)
11887    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11888   "shr{w}\t%0"
11889   [(set_attr "type" "ishift")
11890    (set (attr "length") 
11891      (if_then_else (match_operand:SI 0 "register_operand" "") 
11892         (const_string "2")
11893         (const_string "*")))])
11894
11895 ;; This pattern can't accept a variable shift count, since shifts by
11896 ;; zero don't affect the flags.  We assume that shifts by constant
11897 ;; zero are optimized away.
11898 (define_insn "*lshrhi3_cmp"
11899   [(set (reg FLAGS_REG)
11900         (compare
11901           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11902                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11903           (const_int 0)))
11904    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11905         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11906   "ix86_match_ccmode (insn, CCGOCmode)
11907    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11908   "shr{w}\t{%2, %0|%0, %2}"
11909   [(set_attr "type" "ishift")
11910    (set_attr "mode" "HI")])
11911
11912 (define_expand "lshrqi3"
11913   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11914         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11915                      (match_operand:QI 2 "nonmemory_operand" "")))
11916    (clobber (reg:CC FLAGS_REG))]
11917   "TARGET_QIMODE_MATH"
11918   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11919
11920 (define_insn "*lshrqi3_1_one_bit"
11921   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11922         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11923                      (match_operand:QI 2 "const1_operand" "")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11926    && (TARGET_SHIFT1 || optimize_size)"
11927   "shr{b}\t%0"
11928   [(set_attr "type" "ishift")
11929    (set (attr "length") 
11930      (if_then_else (match_operand 0 "register_operand" "") 
11931         (const_string "2")
11932         (const_string "*")))])
11933
11934 (define_insn "*lshrqi3_1_one_bit_slp"
11935   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11936         (lshiftrt:QI (match_dup 0)
11937                      (match_operand:QI 1 "const1_operand" "")))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11940    && (TARGET_SHIFT1 || optimize_size)"
11941   "shr{b}\t%0"
11942   [(set_attr "type" "ishift1")
11943    (set (attr "length") 
11944      (if_then_else (match_operand 0 "register_operand" "") 
11945         (const_string "2")
11946         (const_string "*")))])
11947
11948 (define_insn "*lshrqi3_1"
11949   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11950         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11951                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11952    (clobber (reg:CC FLAGS_REG))]
11953   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11954   "@
11955    shr{b}\t{%2, %0|%0, %2}
11956    shr{b}\t{%b2, %0|%0, %b2}"
11957   [(set_attr "type" "ishift")
11958    (set_attr "mode" "QI")])
11959
11960 (define_insn "*lshrqi3_1_slp"
11961   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11962         (lshiftrt:QI (match_dup 0)
11963                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11966    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11967   "@
11968    shr{b}\t{%1, %0|%0, %1}
11969    shr{b}\t{%b1, %0|%0, %b1}"
11970   [(set_attr "type" "ishift1")
11971    (set_attr "mode" "QI")])
11972
11973 ;; This pattern can't accept a variable shift count, since shifts by
11974 ;; zero don't affect the flags.  We assume that shifts by constant
11975 ;; zero are optimized away.
11976 (define_insn "*lshrqi2_one_bit_cmp"
11977   [(set (reg FLAGS_REG)
11978         (compare
11979           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11980                        (match_operand:QI 2 "const1_operand" ""))
11981           (const_int 0)))
11982    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11983         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11984   "ix86_match_ccmode (insn, CCGOCmode)
11985    && (TARGET_SHIFT1 || optimize_size)
11986    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11987   "shr{b}\t%0"
11988   [(set_attr "type" "ishift")
11989    (set (attr "length") 
11990      (if_then_else (match_operand:SI 0 "register_operand" "") 
11991         (const_string "2")
11992         (const_string "*")))])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*lshrqi2_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12002           (const_int 0)))
12003    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12005   "ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12007   "shr{b}\t{%2, %0|%0, %2}"
12008   [(set_attr "type" "ishift")
12009    (set_attr "mode" "QI")])
12010 \f
12011 ;; Rotate instructions
12012
12013 (define_expand "rotldi3"
12014   [(set (match_operand:DI 0 "shiftdi_operand" "")
12015         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12016                    (match_operand:QI 2 "nonmemory_operand" "")))
12017    (clobber (reg:CC FLAGS_REG))]
12018  ""
12019 {
12020   if (TARGET_64BIT)
12021     {
12022       ix86_expand_binary_operator (ROTATE, DImode, operands);
12023       DONE;
12024     }
12025   if (!const_1_to_31_operand (operands[2], VOIDmode))
12026     FAIL;
12027   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12028   DONE;
12029 })
12030
12031 ;; Implement rotation using two double-precision shift instructions
12032 ;; and a scratch register.   
12033 (define_insn_and_split "ix86_rotldi3"
12034  [(set (match_operand:DI 0 "register_operand" "=r")
12035        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12036                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12037   (clobber (reg:CC FLAGS_REG))
12038   (clobber (match_scratch:SI 3 "=&r"))]
12039  "!TARGET_64BIT"
12040  "" 
12041  "&& reload_completed"
12042  [(set (match_dup 3) (match_dup 4))
12043   (parallel
12044    [(set (match_dup 4)
12045          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12046                  (lshiftrt:SI (match_dup 5)
12047                               (minus:QI (const_int 32) (match_dup 2)))))
12048     (clobber (reg:CC FLAGS_REG))])
12049   (parallel
12050    [(set (match_dup 5)
12051          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12052                  (lshiftrt:SI (match_dup 3)
12053                               (minus:QI (const_int 32) (match_dup 2)))))
12054     (clobber (reg:CC FLAGS_REG))])]
12055  "split_di (operands, 1, operands + 4, operands + 5);")
12056  
12057 (define_insn "*rotlsi3_1_one_bit_rex64"
12058   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12059         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060                    (match_operand:QI 2 "const1_operand" "")))
12061    (clobber (reg:CC FLAGS_REG))]
12062   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12063    && (TARGET_SHIFT1 || optimize_size)"
12064   "rol{q}\t%0"
12065   [(set_attr "type" "rotate")
12066    (set (attr "length") 
12067      (if_then_else (match_operand:DI 0 "register_operand" "") 
12068         (const_string "2")
12069         (const_string "*")))])
12070
12071 (define_insn "*rotldi3_1_rex64"
12072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12073         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12074                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12077   "@
12078    rol{q}\t{%2, %0|%0, %2}
12079    rol{q}\t{%b2, %0|%0, %b2}"
12080   [(set_attr "type" "rotate")
12081    (set_attr "mode" "DI")])
12082
12083 (define_expand "rotlsi3"
12084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12085         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12086                    (match_operand:QI 2 "nonmemory_operand" "")))
12087    (clobber (reg:CC FLAGS_REG))]
12088   ""
12089   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12090
12091 (define_insn "*rotlsi3_1_one_bit"
12092   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12093         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12094                    (match_operand:QI 2 "const1_operand" "")))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12097    && (TARGET_SHIFT1 || optimize_size)"
12098   "rol{l}\t%0"
12099   [(set_attr "type" "rotate")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:SI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12104
12105 (define_insn "*rotlsi3_1_one_bit_zext"
12106   [(set (match_operand:DI 0 "register_operand" "=r")
12107         (zero_extend:DI
12108           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12109                      (match_operand:QI 2 "const1_operand" ""))))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12112    && (TARGET_SHIFT1 || optimize_size)"
12113   "rol{l}\t%k0"
12114   [(set_attr "type" "rotate")
12115    (set_attr "length" "2")])
12116
12117 (define_insn "*rotlsi3_1"
12118   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12119         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12120                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12123   "@
12124    rol{l}\t{%2, %0|%0, %2}
12125    rol{l}\t{%b2, %0|%0, %b2}"
12126   [(set_attr "type" "rotate")
12127    (set_attr "mode" "SI")])
12128
12129 (define_insn "*rotlsi3_1_zext"
12130   [(set (match_operand:DI 0 "register_operand" "=r,r")
12131         (zero_extend:DI
12132           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12133                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12136   "@
12137    rol{l}\t{%2, %k0|%k0, %2}
12138    rol{l}\t{%b2, %k0|%k0, %b2}"
12139   [(set_attr "type" "rotate")
12140    (set_attr "mode" "SI")])
12141
12142 (define_expand "rotlhi3"
12143   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12144         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12145                    (match_operand:QI 2 "nonmemory_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "TARGET_HIMODE_MATH"
12148   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12149
12150 (define_insn "*rotlhi3_1_one_bit"
12151   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12152         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12153                    (match_operand:QI 2 "const1_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12156    && (TARGET_SHIFT1 || optimize_size)"
12157   "rol{w}\t%0"
12158   [(set_attr "type" "rotate")
12159    (set (attr "length") 
12160      (if_then_else (match_operand 0 "register_operand" "") 
12161         (const_string "2")
12162         (const_string "*")))])
12163
12164 (define_insn "*rotlhi3_1"
12165   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12166         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12167                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12170   "@
12171    rol{w}\t{%2, %0|%0, %2}
12172    rol{w}\t{%b2, %0|%0, %b2}"
12173   [(set_attr "type" "rotate")
12174    (set_attr "mode" "HI")])
12175
12176 (define_expand "rotlqi3"
12177   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12178         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12179                    (match_operand:QI 2 "nonmemory_operand" "")))
12180    (clobber (reg:CC FLAGS_REG))]
12181   "TARGET_QIMODE_MATH"
12182   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12183
12184 (define_insn "*rotlqi3_1_one_bit_slp"
12185   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12186         (rotate:QI (match_dup 0)
12187                    (match_operand:QI 1 "const1_operand" "")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12190    && (TARGET_SHIFT1 || optimize_size)"
12191   "rol{b}\t%0"
12192   [(set_attr "type" "rotate1")
12193    (set (attr "length") 
12194      (if_then_else (match_operand 0 "register_operand" "") 
12195         (const_string "2")
12196         (const_string "*")))])
12197
12198 (define_insn "*rotlqi3_1_one_bit"
12199   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12200         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12201                    (match_operand:QI 2 "const1_operand" "")))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12204    && (TARGET_SHIFT1 || optimize_size)"
12205   "rol{b}\t%0"
12206   [(set_attr "type" "rotate")
12207    (set (attr "length") 
12208      (if_then_else (match_operand 0 "register_operand" "") 
12209         (const_string "2")
12210         (const_string "*")))])
12211
12212 (define_insn "*rotlqi3_1_slp"
12213   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12214         (rotate:QI (match_dup 0)
12215                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12216    (clobber (reg:CC FLAGS_REG))]
12217   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12219   "@
12220    rol{b}\t{%1, %0|%0, %1}
12221    rol{b}\t{%b1, %0|%0, %b1}"
12222   [(set_attr "type" "rotate1")
12223    (set_attr "mode" "QI")])
12224
12225 (define_insn "*rotlqi3_1"
12226   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12227         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12228                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12229    (clobber (reg:CC FLAGS_REG))]
12230   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12231   "@
12232    rol{b}\t{%2, %0|%0, %2}
12233    rol{b}\t{%b2, %0|%0, %b2}"
12234   [(set_attr "type" "rotate")
12235    (set_attr "mode" "QI")])
12236
12237 (define_expand "rotrdi3"
12238   [(set (match_operand:DI 0 "shiftdi_operand" "")
12239         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12240                    (match_operand:QI 2 "nonmemory_operand" "")))
12241    (clobber (reg:CC FLAGS_REG))]
12242  ""
12243 {
12244   if (TARGET_64BIT)
12245     {
12246       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12247       DONE;
12248     }
12249   if (!const_1_to_31_operand (operands[2], VOIDmode))
12250     FAIL;
12251   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12252   DONE;
12253 })
12254   
12255 ;; Implement rotation using two double-precision shift instructions
12256 ;; and a scratch register.   
12257 (define_insn_and_split "ix86_rotrdi3"
12258  [(set (match_operand:DI 0 "register_operand" "=r")
12259        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12260                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12261   (clobber (reg:CC FLAGS_REG))
12262   (clobber (match_scratch:SI 3 "=&r"))]
12263  "!TARGET_64BIT"
12264  ""
12265  "&& reload_completed"
12266  [(set (match_dup 3) (match_dup 4))
12267   (parallel
12268    [(set (match_dup 4)
12269          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12270                  (ashift:SI (match_dup 5)
12271                             (minus:QI (const_int 32) (match_dup 2)))))
12272     (clobber (reg:CC FLAGS_REG))])
12273   (parallel
12274    [(set (match_dup 5)
12275          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12276                  (ashift:SI (match_dup 3)
12277                             (minus:QI (const_int 32) (match_dup 2)))))
12278     (clobber (reg:CC FLAGS_REG))])]
12279  "split_di (operands, 1, operands + 4, operands + 5);")
12280
12281 (define_insn "*rotrdi3_1_one_bit_rex64"
12282   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12283         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12284                      (match_operand:QI 2 "const1_operand" "")))
12285    (clobber (reg:CC FLAGS_REG))]
12286   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12287    && (TARGET_SHIFT1 || optimize_size)"
12288   "ror{q}\t%0"
12289   [(set_attr "type" "rotate")
12290    (set (attr "length") 
12291      (if_then_else (match_operand:DI 0 "register_operand" "") 
12292         (const_string "2")
12293         (const_string "*")))])
12294
12295 (define_insn "*rotrdi3_1_rex64"
12296   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12297         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12298                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12299    (clobber (reg:CC FLAGS_REG))]
12300   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12301   "@
12302    ror{q}\t{%2, %0|%0, %2}
12303    ror{q}\t{%b2, %0|%0, %b2}"
12304   [(set_attr "type" "rotate")
12305    (set_attr "mode" "DI")])
12306
12307 (define_expand "rotrsi3"
12308   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12309         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12310                      (match_operand:QI 2 "nonmemory_operand" "")))
12311    (clobber (reg:CC FLAGS_REG))]
12312   ""
12313   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12314
12315 (define_insn "*rotrsi3_1_one_bit"
12316   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12318                      (match_operand:QI 2 "const1_operand" "")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12321    && (TARGET_SHIFT1 || optimize_size)"
12322   "ror{l}\t%0"
12323   [(set_attr "type" "rotate")
12324    (set (attr "length") 
12325      (if_then_else (match_operand:SI 0 "register_operand" "") 
12326         (const_string "2")
12327         (const_string "*")))])
12328
12329 (define_insn "*rotrsi3_1_one_bit_zext"
12330   [(set (match_operand:DI 0 "register_operand" "=r")
12331         (zero_extend:DI
12332           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12333                        (match_operand:QI 2 "const1_operand" ""))))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12336    && (TARGET_SHIFT1 || optimize_size)"
12337   "ror{l}\t%k0"
12338   [(set_attr "type" "rotate")
12339    (set (attr "length") 
12340      (if_then_else (match_operand:SI 0 "register_operand" "") 
12341         (const_string "2")
12342         (const_string "*")))])
12343
12344 (define_insn "*rotrsi3_1"
12345   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12346         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12347                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12350   "@
12351    ror{l}\t{%2, %0|%0, %2}
12352    ror{l}\t{%b2, %0|%0, %b2}"
12353   [(set_attr "type" "rotate")
12354    (set_attr "mode" "SI")])
12355
12356 (define_insn "*rotrsi3_1_zext"
12357   [(set (match_operand:DI 0 "register_operand" "=r,r")
12358         (zero_extend:DI
12359           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12360                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12363   "@
12364    ror{l}\t{%2, %k0|%k0, %2}
12365    ror{l}\t{%b2, %k0|%k0, %b2}"
12366   [(set_attr "type" "rotate")
12367    (set_attr "mode" "SI")])
12368
12369 (define_expand "rotrhi3"
12370   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12371         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12372                      (match_operand:QI 2 "nonmemory_operand" "")))
12373    (clobber (reg:CC FLAGS_REG))]
12374   "TARGET_HIMODE_MATH"
12375   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12376
12377 (define_insn "*rotrhi3_one_bit"
12378   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12379         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12380                      (match_operand:QI 2 "const1_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12383    && (TARGET_SHIFT1 || optimize_size)"
12384   "ror{w}\t%0"
12385   [(set_attr "type" "rotate")
12386    (set (attr "length") 
12387      (if_then_else (match_operand 0 "register_operand" "") 
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*rotrhi3"
12392   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12393         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12394                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12397   "@
12398    ror{w}\t{%2, %0|%0, %2}
12399    ror{w}\t{%b2, %0|%0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "HI")])
12402
12403 (define_expand "rotrqi3"
12404   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12406                      (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_QIMODE_MATH"
12409   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12410
12411 (define_insn "*rotrqi3_1_one_bit"
12412   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12413         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12414                      (match_operand:QI 2 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "ror{b}\t%0"
12419   [(set_attr "type" "rotate")
12420    (set (attr "length") 
12421      (if_then_else (match_operand 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12424
12425 (define_insn "*rotrqi3_1_one_bit_slp"
12426   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12427         (rotatert:QI (match_dup 0)
12428                      (match_operand:QI 1 "const1_operand" "")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12431    && (TARGET_SHIFT1 || optimize_size)"
12432   "ror{b}\t%0"
12433   [(set_attr "type" "rotate1")
12434    (set (attr "length") 
12435      (if_then_else (match_operand 0 "register_operand" "") 
12436         (const_string "2")
12437         (const_string "*")))])
12438
12439 (define_insn "*rotrqi3_1"
12440   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12441         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12442                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12445   "@
12446    ror{b}\t{%2, %0|%0, %2}
12447    ror{b}\t{%b2, %0|%0, %b2}"
12448   [(set_attr "type" "rotate")
12449    (set_attr "mode" "QI")])
12450
12451 (define_insn "*rotrqi3_1_slp"
12452   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12453         (rotatert:QI (match_dup 0)
12454                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12455    (clobber (reg:CC FLAGS_REG))]
12456   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12457    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12458   "@
12459    ror{b}\t{%1, %0|%0, %1}
12460    ror{b}\t{%b1, %0|%0, %b1}"
12461   [(set_attr "type" "rotate1")
12462    (set_attr "mode" "QI")])
12463 \f
12464 ;; Bit set / bit test instructions
12465
12466 (define_expand "extv"
12467   [(set (match_operand:SI 0 "register_operand" "")
12468         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12469                          (match_operand:SI 2 "immediate_operand" "")
12470                          (match_operand:SI 3 "immediate_operand" "")))]
12471   ""
12472 {
12473   /* Handle extractions from %ah et al.  */
12474   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12475     FAIL;
12476
12477   /* From mips.md: extract_bit_field doesn't verify that our source
12478      matches the predicate, so check it again here.  */
12479   if (! ext_register_operand (operands[1], VOIDmode))
12480     FAIL;
12481 })
12482
12483 (define_expand "extzv"
12484   [(set (match_operand:SI 0 "register_operand" "")
12485         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12486                          (match_operand:SI 2 "immediate_operand" "")
12487                          (match_operand:SI 3 "immediate_operand" "")))]
12488   ""
12489 {
12490   /* Handle extractions from %ah et al.  */
12491   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12492     FAIL;
12493
12494   /* From mips.md: extract_bit_field doesn't verify that our source
12495      matches the predicate, so check it again here.  */
12496   if (! ext_register_operand (operands[1], VOIDmode))
12497     FAIL;
12498 })
12499
12500 (define_expand "insv"
12501   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12502                       (match_operand 1 "immediate_operand" "")
12503                       (match_operand 2 "immediate_operand" ""))
12504         (match_operand 3 "register_operand" ""))]
12505   ""
12506 {
12507   /* Handle extractions from %ah et al.  */
12508   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12509     FAIL;
12510
12511   /* From mips.md: insert_bit_field doesn't verify that our source
12512      matches the predicate, so check it again here.  */
12513   if (! ext_register_operand (operands[0], VOIDmode))
12514     FAIL;
12515
12516   if (TARGET_64BIT)
12517     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12518   else
12519     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12520
12521   DONE;
12522 })
12523
12524 ;; %%% bts, btr, btc, bt.
12525 ;; In general these instructions are *slow* when applied to memory,
12526 ;; since they enforce atomic operation.  When applied to registers,
12527 ;; it depends on the cpu implementation.  They're never faster than
12528 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12529 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12530 ;; within the instruction itself, so operating on bits in the high
12531 ;; 32-bits of a register becomes easier.
12532 ;;
12533 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12534 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12535 ;; negdf respectively, so they can never be disabled entirely.
12536
12537 (define_insn "*btsq"
12538   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12539                          (const_int 1)
12540                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12541         (const_int 1))
12542    (clobber (reg:CC FLAGS_REG))]
12543   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12544   "bts{q} %1,%0"
12545   [(set_attr "type" "alu1")])
12546
12547 (define_insn "*btrq"
12548   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12549                          (const_int 1)
12550                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12551         (const_int 0))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12554   "btr{q} %1,%0"
12555   [(set_attr "type" "alu1")])
12556
12557 (define_insn "*btcq"
12558   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12559                          (const_int 1)
12560                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12561         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12564   "btc{q} %1,%0"
12565   [(set_attr "type" "alu1")])
12566
12567 ;; Allow Nocona to avoid these instructions if a register is available.
12568
12569 (define_peephole2
12570   [(match_scratch:DI 2 "r")
12571    (parallel [(set (zero_extract:DI
12572                      (match_operand:DI 0 "register_operand" "")
12573                      (const_int 1)
12574                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12575                    (const_int 1))
12576               (clobber (reg:CC FLAGS_REG))])]
12577   "TARGET_64BIT && !TARGET_USE_BT"
12578   [(const_int 0)]
12579 {
12580   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12581   rtx op1;
12582
12583   if (HOST_BITS_PER_WIDE_INT >= 64)
12584     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12585   else if (i < HOST_BITS_PER_WIDE_INT)
12586     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12587   else
12588     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12589
12590   op1 = immed_double_const (lo, hi, DImode);
12591   if (i >= 31)
12592     {
12593       emit_move_insn (operands[2], op1);
12594       op1 = operands[2];
12595     }
12596
12597   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12598   DONE;
12599 })
12600
12601 (define_peephole2
12602   [(match_scratch:DI 2 "r")
12603    (parallel [(set (zero_extract:DI
12604                      (match_operand:DI 0 "register_operand" "")
12605                      (const_int 1)
12606                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12607                    (const_int 0))
12608               (clobber (reg:CC FLAGS_REG))])]
12609   "TARGET_64BIT && !TARGET_USE_BT"
12610   [(const_int 0)]
12611 {
12612   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12613   rtx op1;
12614
12615   if (HOST_BITS_PER_WIDE_INT >= 64)
12616     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12617   else if (i < HOST_BITS_PER_WIDE_INT)
12618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619   else
12620     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12621
12622   op1 = immed_double_const (~lo, ~hi, DImode);
12623   if (i >= 32)
12624     {
12625       emit_move_insn (operands[2], op1);
12626       op1 = operands[2];
12627     }
12628
12629   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12630   DONE;
12631 })
12632
12633 (define_peephole2
12634   [(match_scratch:DI 2 "r")
12635    (parallel [(set (zero_extract:DI
12636                      (match_operand:DI 0 "register_operand" "")
12637                      (const_int 1)
12638                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12639               (not:DI (zero_extract:DI
12640                         (match_dup 0) (const_int 1) (match_dup 1))))
12641               (clobber (reg:CC FLAGS_REG))])]
12642   "TARGET_64BIT && !TARGET_USE_BT"
12643   [(const_int 0)]
12644 {
12645   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12646   rtx op1;
12647
12648   if (HOST_BITS_PER_WIDE_INT >= 64)
12649     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12650   else if (i < HOST_BITS_PER_WIDE_INT)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else
12653     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12654
12655   op1 = immed_double_const (lo, hi, DImode);
12656   if (i >= 31)
12657     {
12658       emit_move_insn (operands[2], op1);
12659       op1 = operands[2];
12660     }
12661
12662   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12663   DONE;
12664 })
12665 \f
12666 ;; Store-flag instructions.
12667
12668 ;; For all sCOND expanders, also expand the compare or test insn that
12669 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12670
12671 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12672 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12673 ;; way, which can later delete the movzx if only QImode is needed.
12674
12675 (define_expand "seq"
12676   [(set (match_operand:QI 0 "register_operand" "")
12677         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12678   ""
12679   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12680
12681 (define_expand "sne"
12682   [(set (match_operand:QI 0 "register_operand" "")
12683         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12684   ""
12685   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sgt"
12688   [(set (match_operand:QI 0 "register_operand" "")
12689         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12690   ""
12691   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sgtu"
12694   [(set (match_operand:QI 0 "register_operand" "")
12695         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12696   ""
12697   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "slt"
12700   [(set (match_operand:QI 0 "register_operand" "")
12701         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12702   ""
12703   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "sltu"
12706   [(set (match_operand:QI 0 "register_operand" "")
12707         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12708   ""
12709   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "sge"
12712   [(set (match_operand:QI 0 "register_operand" "")
12713         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714   ""
12715   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sgeu"
12718   [(set (match_operand:QI 0 "register_operand" "")
12719         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720   ""
12721   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sle"
12724   [(set (match_operand:QI 0 "register_operand" "")
12725         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726   ""
12727   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sleu"
12730   [(set (match_operand:QI 0 "register_operand" "")
12731         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732   ""
12733   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sunordered"
12736   [(set (match_operand:QI 0 "register_operand" "")
12737         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738   "TARGET_80387 || TARGET_SSE"
12739   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sordered"
12742   [(set (match_operand:QI 0 "register_operand" "")
12743         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744   "TARGET_80387"
12745   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12746
12747 (define_expand "suneq"
12748   [(set (match_operand:QI 0 "register_operand" "")
12749         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750   "TARGET_80387 || TARGET_SSE"
12751   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12752
12753 (define_expand "sunge"
12754   [(set (match_operand:QI 0 "register_operand" "")
12755         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756   "TARGET_80387 || TARGET_SSE"
12757   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12758
12759 (define_expand "sungt"
12760   [(set (match_operand:QI 0 "register_operand" "")
12761         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762   "TARGET_80387 || TARGET_SSE"
12763   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12764
12765 (define_expand "sunle"
12766   [(set (match_operand:QI 0 "register_operand" "")
12767         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768   "TARGET_80387 || TARGET_SSE"
12769   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12770
12771 (define_expand "sunlt"
12772   [(set (match_operand:QI 0 "register_operand" "")
12773         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774   "TARGET_80387 || TARGET_SSE"
12775   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12776
12777 (define_expand "sltgt"
12778   [(set (match_operand:QI 0 "register_operand" "")
12779         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780   "TARGET_80387 || TARGET_SSE"
12781   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12782
12783 (define_insn "*setcc_1"
12784   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12785         (match_operator:QI 1 "ix86_comparison_operator"
12786           [(reg FLAGS_REG) (const_int 0)]))]
12787   ""
12788   "set%C1\t%0"
12789   [(set_attr "type" "setcc")
12790    (set_attr "mode" "QI")])
12791
12792 (define_insn "*setcc_2"
12793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12794         (match_operator:QI 1 "ix86_comparison_operator"
12795           [(reg FLAGS_REG) (const_int 0)]))]
12796   ""
12797   "set%C1\t%0"
12798   [(set_attr "type" "setcc")
12799    (set_attr "mode" "QI")])
12800
12801 ;; In general it is not safe to assume too much about CCmode registers,
12802 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12803 ;; conditions this is safe on x86, so help combine not create
12804 ;;
12805 ;;      seta    %al
12806 ;;      testb   %al, %al
12807 ;;      sete    %al
12808
12809 (define_split 
12810   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12811         (ne:QI (match_operator 1 "ix86_comparison_operator"
12812                  [(reg FLAGS_REG) (const_int 0)])
12813             (const_int 0)))]
12814   ""
12815   [(set (match_dup 0) (match_dup 1))]
12816 {
12817   PUT_MODE (operands[1], QImode);
12818 })
12819
12820 (define_split 
12821   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12822         (ne:QI (match_operator 1 "ix86_comparison_operator"
12823                  [(reg FLAGS_REG) (const_int 0)])
12824             (const_int 0)))]
12825   ""
12826   [(set (match_dup 0) (match_dup 1))]
12827 {
12828   PUT_MODE (operands[1], QImode);
12829 })
12830
12831 (define_split 
12832   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12833         (eq:QI (match_operator 1 "ix86_comparison_operator"
12834                  [(reg FLAGS_REG) (const_int 0)])
12835             (const_int 0)))]
12836   ""
12837   [(set (match_dup 0) (match_dup 1))]
12838 {
12839   rtx new_op1 = copy_rtx (operands[1]);
12840   operands[1] = new_op1;
12841   PUT_MODE (new_op1, QImode);
12842   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12843                                              GET_MODE (XEXP (new_op1, 0))));
12844
12845   /* Make sure that (a) the CCmode we have for the flags is strong
12846      enough for the reversed compare or (b) we have a valid FP compare.  */
12847   if (! ix86_comparison_operator (new_op1, VOIDmode))
12848     FAIL;
12849 })
12850
12851 (define_split 
12852   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12853         (eq:QI (match_operator 1 "ix86_comparison_operator"
12854                  [(reg FLAGS_REG) (const_int 0)])
12855             (const_int 0)))]
12856   ""
12857   [(set (match_dup 0) (match_dup 1))]
12858 {
12859   rtx new_op1 = copy_rtx (operands[1]);
12860   operands[1] = new_op1;
12861   PUT_MODE (new_op1, QImode);
12862   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12863                                              GET_MODE (XEXP (new_op1, 0))));
12864
12865   /* Make sure that (a) the CCmode we have for the flags is strong
12866      enough for the reversed compare or (b) we have a valid FP compare.  */
12867   if (! ix86_comparison_operator (new_op1, VOIDmode))
12868     FAIL;
12869 })
12870
12871 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12872 ;; subsequent logical operations are used to imitate conditional moves.
12873 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12874 ;; it directly.
12875
12876 (define_insn "*sse_setccsf"
12877   [(set (match_operand:SF 0 "register_operand" "=x")
12878         (match_operator:SF 1 "sse_comparison_operator"
12879           [(match_operand:SF 2 "register_operand" "0")
12880            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12881   "TARGET_SSE"
12882   "cmp%D1ss\t{%3, %0|%0, %3}"
12883   [(set_attr "type" "ssecmp")
12884    (set_attr "mode" "SF")])
12885
12886 (define_insn "*sse_setccdf"
12887   [(set (match_operand:DF 0 "register_operand" "=Y")
12888         (match_operator:DF 1 "sse_comparison_operator"
12889           [(match_operand:DF 2 "register_operand" "0")
12890            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12891   "TARGET_SSE2"
12892   "cmp%D1sd\t{%3, %0|%0, %3}"
12893   [(set_attr "type" "ssecmp")
12894    (set_attr "mode" "DF")])
12895 \f
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12898
12899 ;; For all bCOND expanders, also expand the compare or test insn that
12900 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12901
12902 (define_expand "beq"
12903   [(set (pc)
12904         (if_then_else (match_dup 1)
12905                       (label_ref (match_operand 0 "" ""))
12906                       (pc)))]
12907   ""
12908   "ix86_expand_branch (EQ, operands[0]); DONE;")
12909
12910 (define_expand "bne"
12911   [(set (pc)
12912         (if_then_else (match_dup 1)
12913                       (label_ref (match_operand 0 "" ""))
12914                       (pc)))]
12915   ""
12916   "ix86_expand_branch (NE, operands[0]); DONE;")
12917
12918 (define_expand "bgt"
12919   [(set (pc)
12920         (if_then_else (match_dup 1)
12921                       (label_ref (match_operand 0 "" ""))
12922                       (pc)))]
12923   ""
12924   "ix86_expand_branch (GT, operands[0]); DONE;")
12925
12926 (define_expand "bgtu"
12927   [(set (pc)
12928         (if_then_else (match_dup 1)
12929                       (label_ref (match_operand 0 "" ""))
12930                       (pc)))]
12931   ""
12932   "ix86_expand_branch (GTU, operands[0]); DONE;")
12933
12934 (define_expand "blt"
12935   [(set (pc)
12936         (if_then_else (match_dup 1)
12937                       (label_ref (match_operand 0 "" ""))
12938                       (pc)))]
12939   ""
12940   "ix86_expand_branch (LT, operands[0]); DONE;")
12941
12942 (define_expand "bltu"
12943   [(set (pc)
12944         (if_then_else (match_dup 1)
12945                       (label_ref (match_operand 0 "" ""))
12946                       (pc)))]
12947   ""
12948   "ix86_expand_branch (LTU, operands[0]); DONE;")
12949
12950 (define_expand "bge"
12951   [(set (pc)
12952         (if_then_else (match_dup 1)
12953                       (label_ref (match_operand 0 "" ""))
12954                       (pc)))]
12955   ""
12956   "ix86_expand_branch (GE, operands[0]); DONE;")
12957
12958 (define_expand "bgeu"
12959   [(set (pc)
12960         (if_then_else (match_dup 1)
12961                       (label_ref (match_operand 0 "" ""))
12962                       (pc)))]
12963   ""
12964   "ix86_expand_branch (GEU, operands[0]); DONE;")
12965
12966 (define_expand "ble"
12967   [(set (pc)
12968         (if_then_else (match_dup 1)
12969                       (label_ref (match_operand 0 "" ""))
12970                       (pc)))]
12971   ""
12972   "ix86_expand_branch (LE, operands[0]); DONE;")
12973
12974 (define_expand "bleu"
12975   [(set (pc)
12976         (if_then_else (match_dup 1)
12977                       (label_ref (match_operand 0 "" ""))
12978                       (pc)))]
12979   ""
12980   "ix86_expand_branch (LEU, operands[0]); DONE;")
12981
12982 (define_expand "bunordered"
12983   [(set (pc)
12984         (if_then_else (match_dup 1)
12985                       (label_ref (match_operand 0 "" ""))
12986                       (pc)))]
12987   "TARGET_80387 || TARGET_SSE_MATH"
12988   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12989
12990 (define_expand "bordered"
12991   [(set (pc)
12992         (if_then_else (match_dup 1)
12993                       (label_ref (match_operand 0 "" ""))
12994                       (pc)))]
12995   "TARGET_80387 || TARGET_SSE_MATH"
12996   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12997
12998 (define_expand "buneq"
12999   [(set (pc)
13000         (if_then_else (match_dup 1)
13001                       (label_ref (match_operand 0 "" ""))
13002                       (pc)))]
13003   "TARGET_80387 || TARGET_SSE_MATH"
13004   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13005
13006 (define_expand "bunge"
13007   [(set (pc)
13008         (if_then_else (match_dup 1)
13009                       (label_ref (match_operand 0 "" ""))
13010                       (pc)))]
13011   "TARGET_80387 || TARGET_SSE_MATH"
13012   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13013
13014 (define_expand "bungt"
13015   [(set (pc)
13016         (if_then_else (match_dup 1)
13017                       (label_ref (match_operand 0 "" ""))
13018                       (pc)))]
13019   "TARGET_80387 || TARGET_SSE_MATH"
13020   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13021
13022 (define_expand "bunle"
13023   [(set (pc)
13024         (if_then_else (match_dup 1)
13025                       (label_ref (match_operand 0 "" ""))
13026                       (pc)))]
13027   "TARGET_80387 || TARGET_SSE_MATH"
13028   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13029
13030 (define_expand "bunlt"
13031   [(set (pc)
13032         (if_then_else (match_dup 1)
13033                       (label_ref (match_operand 0 "" ""))
13034                       (pc)))]
13035   "TARGET_80387 || TARGET_SSE_MATH"
13036   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13037
13038 (define_expand "bltgt"
13039   [(set (pc)
13040         (if_then_else (match_dup 1)
13041                       (label_ref (match_operand 0 "" ""))
13042                       (pc)))]
13043   "TARGET_80387 || TARGET_SSE_MATH"
13044   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13045
13046 (define_insn "*jcc_1"
13047   [(set (pc)
13048         (if_then_else (match_operator 1 "ix86_comparison_operator"
13049                                       [(reg FLAGS_REG) (const_int 0)])
13050                       (label_ref (match_operand 0 "" ""))
13051                       (pc)))]
13052   ""
13053   "%+j%C1\t%l0"
13054   [(set_attr "type" "ibr")
13055    (set_attr "modrm" "0")
13056    (set (attr "length")
13057            (if_then_else (and (ge (minus (match_dup 0) (pc))
13058                                   (const_int -126))
13059                               (lt (minus (match_dup 0) (pc))
13060                                   (const_int 128)))
13061              (const_int 2)
13062              (const_int 6)))])
13063
13064 (define_insn "*jcc_2"
13065   [(set (pc)
13066         (if_then_else (match_operator 1 "ix86_comparison_operator"
13067                                       [(reg FLAGS_REG) (const_int 0)])
13068                       (pc)
13069                       (label_ref (match_operand 0 "" ""))))]
13070   ""
13071   "%+j%c1\t%l0"
13072   [(set_attr "type" "ibr")
13073    (set_attr "modrm" "0")
13074    (set (attr "length")
13075            (if_then_else (and (ge (minus (match_dup 0) (pc))
13076                                   (const_int -126))
13077                               (lt (minus (match_dup 0) (pc))
13078                                   (const_int 128)))
13079              (const_int 2)
13080              (const_int 6)))])
13081
13082 ;; In general it is not safe to assume too much about CCmode registers,
13083 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13084 ;; conditions this is safe on x86, so help combine not create
13085 ;;
13086 ;;      seta    %al
13087 ;;      testb   %al, %al
13088 ;;      je      Lfoo
13089
13090 (define_split 
13091   [(set (pc)
13092         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13093                                       [(reg FLAGS_REG) (const_int 0)])
13094                           (const_int 0))
13095                       (label_ref (match_operand 1 "" ""))
13096                       (pc)))]
13097   ""
13098   [(set (pc)
13099         (if_then_else (match_dup 0)
13100                       (label_ref (match_dup 1))
13101                       (pc)))]
13102 {
13103   PUT_MODE (operands[0], VOIDmode);
13104 })
13105   
13106 (define_split 
13107   [(set (pc)
13108         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13109                                       [(reg FLAGS_REG) (const_int 0)])
13110                           (const_int 0))
13111                       (label_ref (match_operand 1 "" ""))
13112                       (pc)))]
13113   ""
13114   [(set (pc)
13115         (if_then_else (match_dup 0)
13116                       (label_ref (match_dup 1))
13117                       (pc)))]
13118 {
13119   rtx new_op0 = copy_rtx (operands[0]);
13120   operands[0] = new_op0;
13121   PUT_MODE (new_op0, VOIDmode);
13122   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13123                                              GET_MODE (XEXP (new_op0, 0))));
13124
13125   /* Make sure that (a) the CCmode we have for the flags is strong
13126      enough for the reversed compare or (b) we have a valid FP compare.  */
13127   if (! ix86_comparison_operator (new_op0, VOIDmode))
13128     FAIL;
13129 })
13130
13131 ;; Define combination compare-and-branch fp compare instructions to use
13132 ;; during early optimization.  Splitting the operation apart early makes
13133 ;; for bad code when we want to reverse the operation.
13134
13135 (define_insn "*fp_jcc_1_mixed"
13136   [(set (pc)
13137         (if_then_else (match_operator 0 "comparison_operator"
13138                         [(match_operand 1 "register_operand" "f#x,x#f")
13139                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13140           (label_ref (match_operand 3 "" ""))
13141           (pc)))
13142    (clobber (reg:CCFP FPSR_REG))
13143    (clobber (reg:CCFP FLAGS_REG))]
13144   "TARGET_MIX_SSE_I387
13145    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13146    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13147    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13148   "#")
13149
13150 (define_insn "*fp_jcc_1_sse"
13151   [(set (pc)
13152         (if_then_else (match_operator 0 "comparison_operator"
13153                         [(match_operand 1 "register_operand" "x")
13154                          (match_operand 2 "nonimmediate_operand" "xm")])
13155           (label_ref (match_operand 3 "" ""))
13156           (pc)))
13157    (clobber (reg:CCFP FPSR_REG))
13158    (clobber (reg:CCFP FLAGS_REG))]
13159   "TARGET_SSE_MATH
13160    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13161    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13163   "#")
13164
13165 (define_insn "*fp_jcc_1_387"
13166   [(set (pc)
13167         (if_then_else (match_operator 0 "comparison_operator"
13168                         [(match_operand 1 "register_operand" "f")
13169                          (match_operand 2 "register_operand" "f")])
13170           (label_ref (match_operand 3 "" ""))
13171           (pc)))
13172    (clobber (reg:CCFP FPSR_REG))
13173    (clobber (reg:CCFP FLAGS_REG))]
13174   "TARGET_CMOVE && TARGET_80387
13175    && FLOAT_MODE_P (GET_MODE (operands[1]))
13176    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13177    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13178   "#")
13179
13180 (define_insn "*fp_jcc_2_mixed"
13181   [(set (pc)
13182         (if_then_else (match_operator 0 "comparison_operator"
13183                         [(match_operand 1 "register_operand" "f#x,x#f")
13184                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13185           (pc)
13186           (label_ref (match_operand 3 "" ""))))
13187    (clobber (reg:CCFP FPSR_REG))
13188    (clobber (reg:CCFP FLAGS_REG))]
13189   "TARGET_MIX_SSE_I387
13190    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13191    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13192    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13193   "#")
13194
13195 (define_insn "*fp_jcc_2_sse"
13196   [(set (pc)
13197         (if_then_else (match_operator 0 "comparison_operator"
13198                         [(match_operand 1 "register_operand" "x")
13199                          (match_operand 2 "nonimmediate_operand" "xm")])
13200           (pc)
13201           (label_ref (match_operand 3 "" ""))))
13202    (clobber (reg:CCFP FPSR_REG))
13203    (clobber (reg:CCFP FLAGS_REG))]
13204   "TARGET_SSE_MATH
13205    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13206    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13207    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13208   "#")
13209
13210 (define_insn "*fp_jcc_2_387"
13211   [(set (pc)
13212         (if_then_else (match_operator 0 "comparison_operator"
13213                         [(match_operand 1 "register_operand" "f")
13214                          (match_operand 2 "register_operand" "f")])
13215           (pc)
13216           (label_ref (match_operand 3 "" ""))))
13217    (clobber (reg:CCFP FPSR_REG))
13218    (clobber (reg:CCFP FLAGS_REG))]
13219   "TARGET_CMOVE && TARGET_80387
13220    && FLOAT_MODE_P (GET_MODE (operands[1]))
13221    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13222    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13223   "#")
13224
13225 (define_insn "*fp_jcc_3_387"
13226   [(set (pc)
13227         (if_then_else (match_operator 0 "comparison_operator"
13228                         [(match_operand 1 "register_operand" "f")
13229                          (match_operand 2 "nonimmediate_operand" "fm")])
13230           (label_ref (match_operand 3 "" ""))
13231           (pc)))
13232    (clobber (reg:CCFP FPSR_REG))
13233    (clobber (reg:CCFP FLAGS_REG))
13234    (clobber (match_scratch:HI 4 "=a"))]
13235   "TARGET_80387
13236    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13238    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13239    && SELECT_CC_MODE (GET_CODE (operands[0]),
13240                       operands[1], operands[2]) == CCFPmode
13241    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13242   "#")
13243
13244 (define_insn "*fp_jcc_4_387"
13245   [(set (pc)
13246         (if_then_else (match_operator 0 "comparison_operator"
13247                         [(match_operand 1 "register_operand" "f")
13248                          (match_operand 2 "nonimmediate_operand" "fm")])
13249           (pc)
13250           (label_ref (match_operand 3 "" ""))))
13251    (clobber (reg:CCFP FPSR_REG))
13252    (clobber (reg:CCFP FLAGS_REG))
13253    (clobber (match_scratch:HI 4 "=a"))]
13254   "TARGET_80387
13255    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13256    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13258    && SELECT_CC_MODE (GET_CODE (operands[0]),
13259                       operands[1], operands[2]) == CCFPmode
13260    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13261   "#")
13262
13263 (define_insn "*fp_jcc_5_387"
13264   [(set (pc)
13265         (if_then_else (match_operator 0 "comparison_operator"
13266                         [(match_operand 1 "register_operand" "f")
13267                          (match_operand 2 "register_operand" "f")])
13268           (label_ref (match_operand 3 "" ""))
13269           (pc)))
13270    (clobber (reg:CCFP FPSR_REG))
13271    (clobber (reg:CCFP FLAGS_REG))
13272    (clobber (match_scratch:HI 4 "=a"))]
13273   "TARGET_80387
13274    && FLOAT_MODE_P (GET_MODE (operands[1]))
13275    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13278
13279 (define_insn "*fp_jcc_6_387"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "register_operand" "f")])
13284           (pc)
13285           (label_ref (match_operand 3 "" ""))))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && FLOAT_MODE_P (GET_MODE (operands[1]))
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13293   "#")
13294
13295 (define_insn "*fp_jcc_7_387"
13296   [(set (pc)
13297         (if_then_else (match_operator 0 "comparison_operator"
13298                         [(match_operand 1 "register_operand" "f")
13299                          (match_operand 2 "const0_operand" "X")])
13300           (label_ref (match_operand 3 "" ""))
13301           (pc)))
13302    (clobber (reg:CCFP FPSR_REG))
13303    (clobber (reg:CCFP FLAGS_REG))
13304    (clobber (match_scratch:HI 4 "=a"))]
13305   "TARGET_80387
13306    && FLOAT_MODE_P (GET_MODE (operands[1]))
13307    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13308    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13309    && SELECT_CC_MODE (GET_CODE (operands[0]),
13310                       operands[1], operands[2]) == CCFPmode
13311    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13312   "#")
13313
13314 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13315 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13316 ;; with a precedence over other operators and is always put in the first
13317 ;; place. Swap condition and operands to match ficom instruction.
13318
13319 (define_insn "*fp_jcc_8<mode>_387"
13320   [(set (pc)
13321         (if_then_else (match_operator 0 "comparison_operator"
13322                         [(match_operator 1 "float_operator"
13323                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13324                            (match_operand 3 "register_operand" "f,f")])
13325           (label_ref (match_operand 4 "" ""))
13326           (pc)))
13327    (clobber (reg:CCFP FPSR_REG))
13328    (clobber (reg:CCFP FLAGS_REG))
13329    (clobber (match_scratch:HI 5 "=a,a"))]
13330   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13331    && FLOAT_MODE_P (GET_MODE (operands[3]))
13332    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13333    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13334    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13335    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13336   "#")
13337
13338 (define_split
13339   [(set (pc)
13340         (if_then_else (match_operator 0 "comparison_operator"
13341                         [(match_operand 1 "register_operand" "")
13342                          (match_operand 2 "nonimmediate_operand" "")])
13343           (match_operand 3 "" "")
13344           (match_operand 4 "" "")))
13345    (clobber (reg:CCFP FPSR_REG))
13346    (clobber (reg:CCFP FLAGS_REG))]
13347   "reload_completed"
13348   [(const_int 0)]
13349 {
13350   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13351                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13352   DONE;
13353 })
13354
13355 (define_split
13356   [(set (pc)
13357         (if_then_else (match_operator 0 "comparison_operator"
13358                         [(match_operand 1 "register_operand" "")
13359                          (match_operand 2 "general_operand" "")])
13360           (match_operand 3 "" "")
13361           (match_operand 4 "" "")))
13362    (clobber (reg:CCFP FPSR_REG))
13363    (clobber (reg:CCFP FLAGS_REG))
13364    (clobber (match_scratch:HI 5 "=a"))]
13365   "reload_completed"
13366   [(const_int 0)]
13367 {
13368   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13369                         operands[3], operands[4], operands[5], NULL_RTX);
13370   DONE;
13371 })
13372
13373 (define_split
13374   [(set (pc)
13375         (if_then_else (match_operator 0 "comparison_operator"
13376                         [(match_operator 1 "float_operator"
13377                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13378                            (match_operand 3 "register_operand" "")])
13379           (match_operand 4 "" "")
13380           (match_operand 5 "" "")))
13381    (clobber (reg:CCFP FPSR_REG))
13382    (clobber (reg:CCFP FLAGS_REG))
13383    (clobber (match_scratch:HI 6 "=a"))]
13384   "reload_completed"
13385   [(const_int 0)]
13386 {
13387   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13388   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13389                         operands[3], operands[7],
13390                         operands[4], operands[5], operands[6], NULL_RTX);
13391   DONE;
13392 })
13393
13394 ;; %%% Kill this when reload knows how to do it.
13395 (define_split
13396   [(set (pc)
13397         (if_then_else (match_operator 0 "comparison_operator"
13398                         [(match_operator 1 "float_operator"
13399                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13400                            (match_operand 3 "register_operand" "")])
13401           (match_operand 4 "" "")
13402           (match_operand 5 "" "")))
13403    (clobber (reg:CCFP FPSR_REG))
13404    (clobber (reg:CCFP FLAGS_REG))
13405    (clobber (match_scratch:HI 6 "=a"))]
13406   "reload_completed"
13407   [(const_int 0)]
13408 {
13409   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13410   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13411   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13412                         operands[3], operands[7],
13413                         operands[4], operands[5], operands[6], operands[2]);
13414   DONE;
13415 })
13416 \f
13417 ;; Unconditional and other jump instructions
13418
13419 (define_insn "jump"
13420   [(set (pc)
13421         (label_ref (match_operand 0 "" "")))]
13422   ""
13423   "jmp\t%l0"
13424   [(set_attr "type" "ibr")
13425    (set (attr "length")
13426            (if_then_else (and (ge (minus (match_dup 0) (pc))
13427                                   (const_int -126))
13428                               (lt (minus (match_dup 0) (pc))
13429                                   (const_int 128)))
13430              (const_int 2)
13431              (const_int 5)))
13432    (set_attr "modrm" "0")])
13433
13434 (define_expand "indirect_jump"
13435   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13436   ""
13437   "")
13438
13439 (define_insn "*indirect_jump"
13440   [(set (pc) (match_operand:SI 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_insn "*indirect_jump_rtx64"
13447   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13448   "TARGET_64BIT"
13449   "jmp\t%A0"
13450   [(set_attr "type" "ibr")
13451    (set_attr "length_immediate" "0")])
13452
13453 (define_expand "tablejump"
13454   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13455               (use (label_ref (match_operand 1 "" "")))])]
13456   ""
13457 {
13458   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13459      relative.  Convert the relative address to an absolute address.  */
13460   if (flag_pic)
13461     {
13462       rtx op0, op1;
13463       enum rtx_code code;
13464
13465       if (TARGET_64BIT)
13466         {
13467           code = PLUS;
13468           op0 = operands[0];
13469           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13470         }
13471       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13472         {
13473           code = PLUS;
13474           op0 = operands[0];
13475           op1 = pic_offset_table_rtx;
13476         }
13477       else
13478         {
13479           code = MINUS;
13480           op0 = pic_offset_table_rtx;
13481           op1 = operands[0];
13482         }
13483
13484       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13485                                          OPTAB_DIRECT);
13486     }
13487 })
13488
13489 (define_insn "*tablejump_1"
13490   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13491    (use (label_ref (match_operand 1 "" "")))]
13492   "!TARGET_64BIT"
13493   "jmp\t%A0"
13494   [(set_attr "type" "ibr")
13495    (set_attr "length_immediate" "0")])
13496
13497 (define_insn "*tablejump_1_rtx64"
13498   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13499    (use (label_ref (match_operand 1 "" "")))]
13500   "TARGET_64BIT"
13501   "jmp\t%A0"
13502   [(set_attr "type" "ibr")
13503    (set_attr "length_immediate" "0")])
13504 \f
13505 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13506
13507 (define_peephole2
13508   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13509    (set (match_operand:QI 1 "register_operand" "")
13510         (match_operator:QI 2 "ix86_comparison_operator"
13511           [(reg FLAGS_REG) (const_int 0)]))
13512    (set (match_operand 3 "q_regs_operand" "")
13513         (zero_extend (match_dup 1)))]
13514   "(peep2_reg_dead_p (3, operands[1])
13515     || operands_match_p (operands[1], operands[3]))
13516    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13517   [(set (match_dup 4) (match_dup 0))
13518    (set (strict_low_part (match_dup 5))
13519         (match_dup 2))]
13520 {
13521   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13522   operands[5] = gen_lowpart (QImode, operands[3]);
13523   ix86_expand_clear (operands[3]);
13524 })
13525
13526 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13527
13528 (define_peephole2
13529   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13530    (set (match_operand:QI 1 "register_operand" "")
13531         (match_operator:QI 2 "ix86_comparison_operator"
13532           [(reg FLAGS_REG) (const_int 0)]))
13533    (parallel [(set (match_operand 3 "q_regs_operand" "")
13534                    (zero_extend (match_dup 1)))
13535               (clobber (reg:CC FLAGS_REG))])]
13536   "(peep2_reg_dead_p (3, operands[1])
13537     || operands_match_p (operands[1], operands[3]))
13538    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13539   [(set (match_dup 4) (match_dup 0))
13540    (set (strict_low_part (match_dup 5))
13541         (match_dup 2))]
13542 {
13543   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13544   operands[5] = gen_lowpart (QImode, operands[3]);
13545   ix86_expand_clear (operands[3]);
13546 })
13547 \f
13548 ;; Call instructions.
13549
13550 ;; The predicates normally associated with named expanders are not properly
13551 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13552 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13553
13554 ;; Call subroutine returning no value.
13555
13556 (define_expand "call_pop"
13557   [(parallel [(call (match_operand:QI 0 "" "")
13558                     (match_operand:SI 1 "" ""))
13559               (set (reg:SI SP_REG)
13560                    (plus:SI (reg:SI SP_REG)
13561                             (match_operand:SI 3 "" "")))])]
13562   "!TARGET_64BIT"
13563 {
13564   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13565   DONE;
13566 })
13567
13568 (define_insn "*call_pop_0"
13569   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13570          (match_operand:SI 1 "" ""))
13571    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13572                             (match_operand:SI 2 "immediate_operand" "")))]
13573   "!TARGET_64BIT"
13574 {
13575   if (SIBLING_CALL_P (insn))
13576     return "jmp\t%P0";
13577   else
13578     return "call\t%P0";
13579 }
13580   [(set_attr "type" "call")])
13581   
13582 (define_insn "*call_pop_1"
13583   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13584          (match_operand:SI 1 "" ""))
13585    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13586                             (match_operand:SI 2 "immediate_operand" "i")))]
13587   "!TARGET_64BIT"
13588 {
13589   if (constant_call_address_operand (operands[0], Pmode))
13590     {
13591       if (SIBLING_CALL_P (insn))
13592         return "jmp\t%P0";
13593       else
13594         return "call\t%P0";
13595     }
13596   if (SIBLING_CALL_P (insn))
13597     return "jmp\t%A0";
13598   else
13599     return "call\t%A0";
13600 }
13601   [(set_attr "type" "call")])
13602
13603 (define_expand "call"
13604   [(call (match_operand:QI 0 "" "")
13605          (match_operand 1 "" ""))
13606    (use (match_operand 2 "" ""))]
13607   ""
13608 {
13609   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13610   DONE;
13611 })
13612
13613 (define_expand "sibcall"
13614   [(call (match_operand:QI 0 "" "")
13615          (match_operand 1 "" ""))
13616    (use (match_operand 2 "" ""))]
13617   ""
13618 {
13619   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13620   DONE;
13621 })
13622
13623 (define_insn "*call_0"
13624   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13625          (match_operand 1 "" ""))]
13626   ""
13627 {
13628   if (SIBLING_CALL_P (insn))
13629     return "jmp\t%P0";
13630   else
13631     return "call\t%P0";
13632 }
13633   [(set_attr "type" "call")])
13634
13635 (define_insn "*call_1"
13636   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13637          (match_operand 1 "" ""))]
13638   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13639 {
13640   if (constant_call_address_operand (operands[0], Pmode))
13641     return "call\t%P0";
13642   return "call\t%A0";
13643 }
13644   [(set_attr "type" "call")])
13645
13646 (define_insn "*sibcall_1"
13647   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13648          (match_operand 1 "" ""))]
13649   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13650 {
13651   if (constant_call_address_operand (operands[0], Pmode))
13652     return "jmp\t%P0";
13653   return "jmp\t%A0";
13654 }
13655   [(set_attr "type" "call")])
13656
13657 (define_insn "*call_1_rex64"
13658   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13659          (match_operand 1 "" ""))]
13660   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13661 {
13662   if (constant_call_address_operand (operands[0], Pmode))
13663     return "call\t%P0";
13664   return "call\t%A0";
13665 }
13666   [(set_attr "type" "call")])
13667
13668 (define_insn "*sibcall_1_rex64"
13669   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13670          (match_operand 1 "" ""))]
13671   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13672   "jmp\t%P0"
13673   [(set_attr "type" "call")])
13674
13675 (define_insn "*sibcall_1_rex64_v"
13676   [(call (mem:QI (reg:DI 40))
13677          (match_operand 0 "" ""))]
13678   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13679   "jmp\t*%%r11"
13680   [(set_attr "type" "call")])
13681
13682
13683 ;; Call subroutine, returning value in operand 0
13684
13685 (define_expand "call_value_pop"
13686   [(parallel [(set (match_operand 0 "" "")
13687                    (call (match_operand:QI 1 "" "")
13688                          (match_operand:SI 2 "" "")))
13689               (set (reg:SI SP_REG)
13690                    (plus:SI (reg:SI SP_REG)
13691                             (match_operand:SI 4 "" "")))])]
13692   "!TARGET_64BIT"
13693 {
13694   ix86_expand_call (operands[0], operands[1], operands[2],
13695                     operands[3], operands[4], 0);
13696   DONE;
13697 })
13698
13699 (define_expand "call_value"
13700   [(set (match_operand 0 "" "")
13701         (call (match_operand:QI 1 "" "")
13702               (match_operand:SI 2 "" "")))
13703    (use (match_operand:SI 3 "" ""))]
13704   ;; Operand 2 not used on the i386.
13705   ""
13706 {
13707   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13708   DONE;
13709 })
13710
13711 (define_expand "sibcall_value"
13712   [(set (match_operand 0 "" "")
13713         (call (match_operand:QI 1 "" "")
13714               (match_operand:SI 2 "" "")))
13715    (use (match_operand:SI 3 "" ""))]
13716   ;; Operand 2 not used on the i386.
13717   ""
13718 {
13719   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13720   DONE;
13721 })
13722
13723 ;; Call subroutine returning any type.
13724
13725 (define_expand "untyped_call"
13726   [(parallel [(call (match_operand 0 "" "")
13727                     (const_int 0))
13728               (match_operand 1 "" "")
13729               (match_operand 2 "" "")])]
13730   ""
13731 {
13732   int i;
13733
13734   /* In order to give reg-stack an easier job in validating two
13735      coprocessor registers as containing a possible return value,
13736      simply pretend the untyped call returns a complex long double
13737      value.  */
13738
13739   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13740                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13741                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13742                     NULL, 0);
13743
13744   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13745     {
13746       rtx set = XVECEXP (operands[2], 0, i);
13747       emit_move_insn (SET_DEST (set), SET_SRC (set));
13748     }
13749
13750   /* The optimizer does not know that the call sets the function value
13751      registers we stored in the result block.  We avoid problems by
13752      claiming that all hard registers are used and clobbered at this
13753      point.  */
13754   emit_insn (gen_blockage (const0_rtx));
13755
13756   DONE;
13757 })
13758 \f
13759 ;; Prologue and epilogue instructions
13760
13761 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13762 ;; all of memory.  This blocks insns from being moved across this point.
13763
13764 (define_insn "blockage"
13765   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13766   ""
13767   ""
13768   [(set_attr "length" "0")])
13769
13770 ;; Insn emitted into the body of a function to return from a function.
13771 ;; This is only done if the function's epilogue is known to be simple.
13772 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13773
13774 (define_expand "return"
13775   [(return)]
13776   "ix86_can_use_return_insn_p ()"
13777 {
13778   if (current_function_pops_args)
13779     {
13780       rtx popc = GEN_INT (current_function_pops_args);
13781       emit_jump_insn (gen_return_pop_internal (popc));
13782       DONE;
13783     }
13784 })
13785
13786 (define_insn "return_internal"
13787   [(return)]
13788   "reload_completed"
13789   "ret"
13790   [(set_attr "length" "1")
13791    (set_attr "length_immediate" "0")
13792    (set_attr "modrm" "0")])
13793
13794 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13795 ;; instruction Athlon and K8 have.
13796
13797 (define_insn "return_internal_long"
13798   [(return)
13799    (unspec [(const_int 0)] UNSPEC_REP)]
13800   "reload_completed"
13801   "rep {;} ret"
13802   [(set_attr "length" "1")
13803    (set_attr "length_immediate" "0")
13804    (set_attr "prefix_rep" "1")
13805    (set_attr "modrm" "0")])
13806
13807 (define_insn "return_pop_internal"
13808   [(return)
13809    (use (match_operand:SI 0 "const_int_operand" ""))]
13810   "reload_completed"
13811   "ret\t%0"
13812   [(set_attr "length" "3")
13813    (set_attr "length_immediate" "2")
13814    (set_attr "modrm" "0")])
13815
13816 (define_insn "return_indirect_internal"
13817   [(return)
13818    (use (match_operand:SI 0 "register_operand" "r"))]
13819   "reload_completed"
13820   "jmp\t%A0"
13821   [(set_attr "type" "ibr")
13822    (set_attr "length_immediate" "0")])
13823
13824 (define_insn "nop"
13825   [(const_int 0)]
13826   ""
13827   "nop"
13828   [(set_attr "length" "1")
13829    (set_attr "length_immediate" "0")
13830    (set_attr "modrm" "0")])
13831
13832 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13833 ;; branch prediction penalty for the third jump in a 16-byte
13834 ;; block on K8.
13835
13836 (define_insn "align"
13837   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13838   ""
13839 {
13840 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13841   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13842 #else
13843   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13844      The align insn is used to avoid 3 jump instructions in the row to improve
13845      branch prediction and the benefits hardly outweight the cost of extra 8
13846      nops on the average inserted by full alignment pseudo operation.  */
13847 #endif
13848   return "";
13849 }
13850   [(set_attr "length" "16")])
13851
13852 (define_expand "prologue"
13853   [(const_int 1)]
13854   ""
13855   "ix86_expand_prologue (); DONE;")
13856
13857 (define_insn "set_got"
13858   [(set (match_operand:SI 0 "register_operand" "=r")
13859         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13860    (clobber (reg:CC FLAGS_REG))]
13861   "!TARGET_64BIT"
13862   { return output_set_got (operands[0]); }
13863   [(set_attr "type" "multi")
13864    (set_attr "length" "12")])
13865
13866 (define_insn "set_got_rex64"
13867   [(set (match_operand:DI 0 "register_operand" "=r")
13868         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13869   "TARGET_64BIT"
13870   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13871   [(set_attr "type" "lea")
13872    (set_attr "length" "6")])
13873
13874 (define_expand "epilogue"
13875   [(const_int 1)]
13876   ""
13877   "ix86_expand_epilogue (1); DONE;")
13878
13879 (define_expand "sibcall_epilogue"
13880   [(const_int 1)]
13881   ""
13882   "ix86_expand_epilogue (0); DONE;")
13883
13884 (define_expand "eh_return"
13885   [(use (match_operand 0 "register_operand" ""))]
13886   ""
13887 {
13888   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13889
13890   /* Tricky bit: we write the address of the handler to which we will
13891      be returning into someone else's stack frame, one word below the
13892      stack address we wish to restore.  */
13893   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13894   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13895   tmp = gen_rtx_MEM (Pmode, tmp);
13896   emit_move_insn (tmp, ra);
13897
13898   if (Pmode == SImode)
13899     emit_jump_insn (gen_eh_return_si (sa));
13900   else
13901     emit_jump_insn (gen_eh_return_di (sa));
13902   emit_barrier ();
13903   DONE;
13904 })
13905
13906 (define_insn_and_split "eh_return_si"
13907   [(set (pc) 
13908         (unspec [(match_operand:SI 0 "register_operand" "c")]
13909                  UNSPEC_EH_RETURN))]
13910   "!TARGET_64BIT"
13911   "#"
13912   "reload_completed"
13913   [(const_int 1)]
13914   "ix86_expand_epilogue (2); DONE;")
13915
13916 (define_insn_and_split "eh_return_di"
13917   [(set (pc) 
13918         (unspec [(match_operand:DI 0 "register_operand" "c")]
13919                  UNSPEC_EH_RETURN))]
13920   "TARGET_64BIT"
13921   "#"
13922   "reload_completed"
13923   [(const_int 1)]
13924   "ix86_expand_epilogue (2); DONE;")
13925
13926 (define_insn "leave"
13927   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13928    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13929    (clobber (mem:BLK (scratch)))]
13930   "!TARGET_64BIT"
13931   "leave"
13932   [(set_attr "type" "leave")])
13933
13934 (define_insn "leave_rex64"
13935   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13936    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13937    (clobber (mem:BLK (scratch)))]
13938   "TARGET_64BIT"
13939   "leave"
13940   [(set_attr "type" "leave")])
13941 \f
13942 (define_expand "ffssi2"
13943   [(parallel
13944      [(set (match_operand:SI 0 "register_operand" "") 
13945            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13946       (clobber (match_scratch:SI 2 ""))
13947       (clobber (reg:CC FLAGS_REG))])]
13948   ""
13949   "")
13950
13951 (define_insn_and_split "*ffs_cmove"
13952   [(set (match_operand:SI 0 "register_operand" "=r") 
13953         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13954    (clobber (match_scratch:SI 2 "=&r"))
13955    (clobber (reg:CC FLAGS_REG))]
13956   "TARGET_CMOVE"
13957   "#"
13958   "&& reload_completed"
13959   [(set (match_dup 2) (const_int -1))
13960    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13961               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13962    (set (match_dup 0) (if_then_else:SI
13963                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13964                         (match_dup 2)
13965                         (match_dup 0)))
13966    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13967               (clobber (reg:CC FLAGS_REG))])]
13968   "")
13969
13970 (define_insn_and_split "*ffs_no_cmove"
13971   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13972         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13973    (clobber (match_scratch:SI 2 "=&q"))
13974    (clobber (reg:CC FLAGS_REG))]
13975   ""
13976   "#"
13977   "reload_completed"
13978   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13979               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13980    (set (strict_low_part (match_dup 3))
13981         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13982    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13983               (clobber (reg:CC FLAGS_REG))])
13984    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13985               (clobber (reg:CC FLAGS_REG))])
13986    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13987               (clobber (reg:CC FLAGS_REG))])]
13988 {
13989   operands[3] = gen_lowpart (QImode, operands[2]);
13990   ix86_expand_clear (operands[2]);
13991 })
13992
13993 (define_insn "*ffssi_1"
13994   [(set (reg:CCZ FLAGS_REG)
13995         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13996                      (const_int 0)))
13997    (set (match_operand:SI 0 "register_operand" "=r")
13998         (ctz:SI (match_dup 1)))]
13999   ""
14000   "bsf{l}\t{%1, %0|%0, %1}"
14001   [(set_attr "prefix_0f" "1")])
14002
14003 (define_expand "ffsdi2"
14004   [(parallel
14005      [(set (match_operand:DI 0 "register_operand" "") 
14006            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14007       (clobber (match_scratch:DI 2 ""))
14008       (clobber (reg:CC FLAGS_REG))])]
14009   "TARGET_64BIT && TARGET_CMOVE"
14010   "")
14011
14012 (define_insn_and_split "*ffs_rex64"
14013   [(set (match_operand:DI 0 "register_operand" "=r") 
14014         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14015    (clobber (match_scratch:DI 2 "=&r"))
14016    (clobber (reg:CC FLAGS_REG))]
14017   "TARGET_64BIT && TARGET_CMOVE"
14018   "#"
14019   "&& reload_completed"
14020   [(set (match_dup 2) (const_int -1))
14021    (parallel [(set (reg:CCZ FLAGS_REG)
14022                    (compare:CCZ (match_dup 1) (const_int 0)))
14023               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14024    (set (match_dup 0) (if_then_else:DI
14025                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14026                         (match_dup 2)
14027                         (match_dup 0)))
14028    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14029               (clobber (reg:CC FLAGS_REG))])]
14030   "")
14031
14032 (define_insn "*ffsdi_1"
14033   [(set (reg:CCZ FLAGS_REG)
14034         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14035                      (const_int 0)))
14036    (set (match_operand:DI 0 "register_operand" "=r")
14037         (ctz:DI (match_dup 1)))]
14038   "TARGET_64BIT"
14039   "bsf{q}\t{%1, %0|%0, %1}"
14040   [(set_attr "prefix_0f" "1")])
14041
14042 (define_insn "ctzsi2"
14043   [(set (match_operand:SI 0 "register_operand" "=r")
14044         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14045    (clobber (reg:CC FLAGS_REG))]
14046   ""
14047   "bsf{l}\t{%1, %0|%0, %1}"
14048   [(set_attr "prefix_0f" "1")])
14049
14050 (define_insn "ctzdi2"
14051   [(set (match_operand:DI 0 "register_operand" "=r")
14052         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14053    (clobber (reg:CC FLAGS_REG))]
14054   "TARGET_64BIT"
14055   "bsf{q}\t{%1, %0|%0, %1}"
14056   [(set_attr "prefix_0f" "1")])
14057
14058 (define_expand "clzsi2"
14059   [(parallel
14060      [(set (match_operand:SI 0 "register_operand" "")
14061            (minus:SI (const_int 31)
14062                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14063       (clobber (reg:CC FLAGS_REG))])
14064    (parallel
14065      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14066       (clobber (reg:CC FLAGS_REG))])]
14067   ""
14068   "")
14069
14070 (define_insn "*bsr"
14071   [(set (match_operand:SI 0 "register_operand" "=r")
14072         (minus:SI (const_int 31)
14073                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14074    (clobber (reg:CC FLAGS_REG))]
14075   ""
14076   "bsr{l}\t{%1, %0|%0, %1}"
14077   [(set_attr "prefix_0f" "1")])
14078
14079 (define_expand "clzdi2"
14080   [(parallel
14081      [(set (match_operand:DI 0 "register_operand" "")
14082            (minus:DI (const_int 63)
14083                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14084       (clobber (reg:CC FLAGS_REG))])
14085    (parallel
14086      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14087       (clobber (reg:CC FLAGS_REG))])]
14088   "TARGET_64BIT"
14089   "")
14090
14091 (define_insn "*bsr_rex64"
14092   [(set (match_operand:DI 0 "register_operand" "=r")
14093         (minus:DI (const_int 63)
14094                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14095    (clobber (reg:CC FLAGS_REG))]
14096   "TARGET_64BIT"
14097   "bsr{q}\t{%1, %0|%0, %1}"
14098   [(set_attr "prefix_0f" "1")])
14099 \f
14100 ;; Thread-local storage patterns for ELF.
14101 ;;
14102 ;; Note that these code sequences must appear exactly as shown
14103 ;; in order to allow linker relaxation.
14104
14105 (define_insn "*tls_global_dynamic_32_gnu"
14106   [(set (match_operand:SI 0 "register_operand" "=a")
14107         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14108                     (match_operand:SI 2 "tls_symbolic_operand" "")
14109                     (match_operand:SI 3 "call_insn_operand" "")]
14110                     UNSPEC_TLS_GD))
14111    (clobber (match_scratch:SI 4 "=d"))
14112    (clobber (match_scratch:SI 5 "=c"))
14113    (clobber (reg:CC FLAGS_REG))]
14114   "!TARGET_64BIT && TARGET_GNU_TLS"
14115   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14116   [(set_attr "type" "multi")
14117    (set_attr "length" "12")])
14118
14119 (define_insn "*tls_global_dynamic_32_sun"
14120   [(set (match_operand:SI 0 "register_operand" "=a")
14121         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14122                     (match_operand:SI 2 "tls_symbolic_operand" "")
14123                     (match_operand:SI 3 "call_insn_operand" "")]
14124                     UNSPEC_TLS_GD))
14125    (clobber (match_scratch:SI 4 "=d"))
14126    (clobber (match_scratch:SI 5 "=c"))
14127    (clobber (reg:CC FLAGS_REG))]
14128   "!TARGET_64BIT && TARGET_SUN_TLS"
14129   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14130         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14131   [(set_attr "type" "multi")
14132    (set_attr "length" "14")])
14133
14134 (define_expand "tls_global_dynamic_32"
14135   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14136                    (unspec:SI
14137                     [(match_dup 2)
14138                      (match_operand:SI 1 "tls_symbolic_operand" "")
14139                      (match_dup 3)]
14140                     UNSPEC_TLS_GD))
14141               (clobber (match_scratch:SI 4 ""))
14142               (clobber (match_scratch:SI 5 ""))
14143               (clobber (reg:CC FLAGS_REG))])]
14144   ""
14145 {
14146   if (flag_pic)
14147     operands[2] = pic_offset_table_rtx;
14148   else
14149     {
14150       operands[2] = gen_reg_rtx (Pmode);
14151       emit_insn (gen_set_got (operands[2]));
14152     }
14153   operands[3] = ix86_tls_get_addr ();
14154 })
14155
14156 (define_insn "*tls_global_dynamic_64"
14157   [(set (match_operand:DI 0 "register_operand" "=a")
14158         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14159                  (match_operand:DI 3 "" "")))
14160    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14161               UNSPEC_TLS_GD)]
14162   "TARGET_64BIT"
14163   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14164   [(set_attr "type" "multi")
14165    (set_attr "length" "16")])
14166
14167 (define_expand "tls_global_dynamic_64"
14168   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14169                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14170               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14171                          UNSPEC_TLS_GD)])]
14172   ""
14173 {
14174   operands[2] = ix86_tls_get_addr ();
14175 })
14176
14177 (define_insn "*tls_local_dynamic_base_32_gnu"
14178   [(set (match_operand:SI 0 "register_operand" "=a")
14179         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14180                     (match_operand:SI 2 "call_insn_operand" "")]
14181                    UNSPEC_TLS_LD_BASE))
14182    (clobber (match_scratch:SI 3 "=d"))
14183    (clobber (match_scratch:SI 4 "=c"))
14184    (clobber (reg:CC FLAGS_REG))]
14185   "!TARGET_64BIT && TARGET_GNU_TLS"
14186   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14187   [(set_attr "type" "multi")
14188    (set_attr "length" "11")])
14189
14190 (define_insn "*tls_local_dynamic_base_32_sun"
14191   [(set (match_operand:SI 0 "register_operand" "=a")
14192         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14193                     (match_operand:SI 2 "call_insn_operand" "")]
14194                    UNSPEC_TLS_LD_BASE))
14195    (clobber (match_scratch:SI 3 "=d"))
14196    (clobber (match_scratch:SI 4 "=c"))
14197    (clobber (reg:CC FLAGS_REG))]
14198   "!TARGET_64BIT && TARGET_SUN_TLS"
14199   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14200         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14201   [(set_attr "type" "multi")
14202    (set_attr "length" "13")])
14203
14204 (define_expand "tls_local_dynamic_base_32"
14205   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14206                    (unspec:SI [(match_dup 1) (match_dup 2)]
14207                               UNSPEC_TLS_LD_BASE))
14208               (clobber (match_scratch:SI 3 ""))
14209               (clobber (match_scratch:SI 4 ""))
14210               (clobber (reg:CC FLAGS_REG))])]
14211   ""
14212 {
14213   if (flag_pic)
14214     operands[1] = pic_offset_table_rtx;
14215   else
14216     {
14217       operands[1] = gen_reg_rtx (Pmode);
14218       emit_insn (gen_set_got (operands[1]));
14219     }
14220   operands[2] = ix86_tls_get_addr ();
14221 })
14222
14223 (define_insn "*tls_local_dynamic_base_64"
14224   [(set (match_operand:DI 0 "register_operand" "=a")
14225         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14226                  (match_operand:DI 2 "" "")))
14227    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14228   "TARGET_64BIT"
14229   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14230   [(set_attr "type" "multi")
14231    (set_attr "length" "12")])
14232
14233 (define_expand "tls_local_dynamic_base_64"
14234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14235                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14236               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14237   ""
14238 {
14239   operands[1] = ix86_tls_get_addr ();
14240 })
14241
14242 ;; Local dynamic of a single variable is a lose.  Show combine how
14243 ;; to convert that back to global dynamic.
14244
14245 (define_insn_and_split "*tls_local_dynamic_32_once"
14246   [(set (match_operand:SI 0 "register_operand" "=a")
14247         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14248                              (match_operand:SI 2 "call_insn_operand" "")]
14249                             UNSPEC_TLS_LD_BASE)
14250                  (const:SI (unspec:SI
14251                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14252                             UNSPEC_DTPOFF))))
14253    (clobber (match_scratch:SI 4 "=d"))
14254    (clobber (match_scratch:SI 5 "=c"))
14255    (clobber (reg:CC FLAGS_REG))]
14256   ""
14257   "#"
14258   ""
14259   [(parallel [(set (match_dup 0)
14260                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14261                               UNSPEC_TLS_GD))
14262               (clobber (match_dup 4))
14263               (clobber (match_dup 5))
14264               (clobber (reg:CC FLAGS_REG))])]
14265   "")
14266
14267 ;; Load and add the thread base pointer from %gs:0.
14268
14269 (define_insn "*load_tp_si"
14270   [(set (match_operand:SI 0 "register_operand" "=r")
14271         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14272   "!TARGET_64BIT"
14273   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14274   [(set_attr "type" "imov")
14275    (set_attr "modrm" "0")
14276    (set_attr "length" "7")
14277    (set_attr "memory" "load")
14278    (set_attr "imm_disp" "false")])
14279
14280 (define_insn "*add_tp_si"
14281   [(set (match_operand:SI 0 "register_operand" "=r")
14282         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14283                  (match_operand:SI 1 "register_operand" "0")))
14284    (clobber (reg:CC FLAGS_REG))]
14285   "!TARGET_64BIT"
14286   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14287   [(set_attr "type" "alu")
14288    (set_attr "modrm" "0")
14289    (set_attr "length" "7")
14290    (set_attr "memory" "load")
14291    (set_attr "imm_disp" "false")])
14292
14293 (define_insn "*load_tp_di"
14294   [(set (match_operand:DI 0 "register_operand" "=r")
14295         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14296   "TARGET_64BIT"
14297   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14298   [(set_attr "type" "imov")
14299    (set_attr "modrm" "0")
14300    (set_attr "length" "7")
14301    (set_attr "memory" "load")
14302    (set_attr "imm_disp" "false")])
14303
14304 (define_insn "*add_tp_di"
14305   [(set (match_operand:DI 0 "register_operand" "=r")
14306         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14307                  (match_operand:DI 1 "register_operand" "0")))
14308    (clobber (reg:CC FLAGS_REG))]
14309   "TARGET_64BIT"
14310   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14311   [(set_attr "type" "alu")
14312    (set_attr "modrm" "0")
14313    (set_attr "length" "7")
14314    (set_attr "memory" "load")
14315    (set_attr "imm_disp" "false")])
14316 \f
14317 ;; These patterns match the binary 387 instructions for addM3, subM3,
14318 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14319 ;; SFmode.  The first is the normal insn, the second the same insn but
14320 ;; with one operand a conversion, and the third the same insn but with
14321 ;; the other operand a conversion.  The conversion may be SFmode or
14322 ;; SImode if the target mode DFmode, but only SImode if the target mode
14323 ;; is SFmode.
14324
14325 ;; Gcc is slightly more smart about handling normal two address instructions
14326 ;; so use special patterns for add and mull.
14327
14328 (define_insn "*fop_sf_comm_mixed"
14329   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14330         (match_operator:SF 3 "binary_fp_operator"
14331                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14332                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14333   "TARGET_MIX_SSE_I387
14334    && COMMUTATIVE_ARITH_P (operands[3])
14335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14336   "* return output_387_binary_op (insn, operands);"
14337   [(set (attr "type") 
14338         (if_then_else (eq_attr "alternative" "1")
14339            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14340               (const_string "ssemul")
14341               (const_string "sseadd"))
14342            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14343               (const_string "fmul")
14344               (const_string "fop"))))
14345    (set_attr "mode" "SF")])
14346
14347 (define_insn "*fop_sf_comm_sse"
14348   [(set (match_operand:SF 0 "register_operand" "=x")
14349         (match_operator:SF 3 "binary_fp_operator"
14350                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14351                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14352   "TARGET_SSE_MATH
14353    && COMMUTATIVE_ARITH_P (operands[3])
14354    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14355   "* return output_387_binary_op (insn, operands);"
14356   [(set (attr "type") 
14357         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14358            (const_string "ssemul")
14359            (const_string "sseadd")))
14360    (set_attr "mode" "SF")])
14361
14362 (define_insn "*fop_sf_comm_i387"
14363   [(set (match_operand:SF 0 "register_operand" "=f")
14364         (match_operator:SF 3 "binary_fp_operator"
14365                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14366                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14367   "TARGET_80387
14368    && COMMUTATIVE_ARITH_P (operands[3])
14369    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14370   "* return output_387_binary_op (insn, operands);"
14371   [(set (attr "type") 
14372         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14373            (const_string "fmul")
14374            (const_string "fop")))
14375    (set_attr "mode" "SF")])
14376
14377 (define_insn "*fop_sf_1_mixed"
14378   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14379         (match_operator:SF 3 "binary_fp_operator"
14380                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14381                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14382   "TARGET_MIX_SSE_I387
14383    && !COMMUTATIVE_ARITH_P (operands[3])
14384    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14385   "* return output_387_binary_op (insn, operands);"
14386   [(set (attr "type") 
14387         (cond [(and (eq_attr "alternative" "2")
14388                     (match_operand:SF 3 "mult_operator" ""))
14389                  (const_string "ssemul")
14390                (and (eq_attr "alternative" "2")
14391                     (match_operand:SF 3 "div_operator" ""))
14392                  (const_string "ssediv")
14393                (eq_attr "alternative" "2")
14394                  (const_string "sseadd")
14395                (match_operand:SF 3 "mult_operator" "") 
14396                  (const_string "fmul")
14397                (match_operand:SF 3 "div_operator" "") 
14398                  (const_string "fdiv")
14399               ]
14400               (const_string "fop")))
14401    (set_attr "mode" "SF")])
14402
14403 (define_insn "*fop_sf_1_sse"
14404   [(set (match_operand:SF 0 "register_operand" "=x")
14405         (match_operator:SF 3 "binary_fp_operator"
14406                         [(match_operand:SF 1 "register_operand" "0")
14407                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14408   "TARGET_SSE_MATH
14409    && !COMMUTATIVE_ARITH_P (operands[3])"
14410   "* return output_387_binary_op (insn, operands);"
14411   [(set (attr "type") 
14412         (cond [(match_operand:SF 3 "mult_operator" "")
14413                  (const_string "ssemul")
14414                (match_operand:SF 3 "div_operator" "")
14415                  (const_string "ssediv")
14416               ]
14417               (const_string "sseadd")))
14418    (set_attr "mode" "SF")])
14419
14420 ;; This pattern is not fully shadowed by the pattern above.
14421 (define_insn "*fop_sf_1_i387"
14422   [(set (match_operand:SF 0 "register_operand" "=f,f")
14423         (match_operator:SF 3 "binary_fp_operator"
14424                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14425                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14426   "TARGET_80387 && !TARGET_SSE_MATH
14427    && !COMMUTATIVE_ARITH_P (operands[3])
14428    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14429   "* return output_387_binary_op (insn, operands);"
14430   [(set (attr "type") 
14431         (cond [(match_operand:SF 3 "mult_operator" "") 
14432                  (const_string "fmul")
14433                (match_operand:SF 3 "div_operator" "") 
14434                  (const_string "fdiv")
14435               ]
14436               (const_string "fop")))
14437    (set_attr "mode" "SF")])
14438
14439 ;; ??? Add SSE splitters for these!
14440 (define_insn "*fop_sf_2<mode>_i387"
14441   [(set (match_operand:SF 0 "register_operand" "=f,f")
14442         (match_operator:SF 3 "binary_fp_operator"
14443           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14444            (match_operand:SF 2 "register_operand" "0,0")]))]
14445   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14446   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14447   [(set (attr "type") 
14448         (cond [(match_operand:SF 3 "mult_operator" "") 
14449                  (const_string "fmul")
14450                (match_operand:SF 3 "div_operator" "") 
14451                  (const_string "fdiv")
14452               ]
14453               (const_string "fop")))
14454    (set_attr "fp_int_src" "true")
14455    (set_attr "mode" "<MODE>")])
14456
14457 (define_insn "*fop_sf_3<mode>_i387"
14458   [(set (match_operand:SF 0 "register_operand" "=f,f")
14459         (match_operator:SF 3 "binary_fp_operator"
14460           [(match_operand:SF 1 "register_operand" "0,0")
14461            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14462   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14463   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14464   [(set (attr "type") 
14465         (cond [(match_operand:SF 3 "mult_operator" "") 
14466                  (const_string "fmul")
14467                (match_operand:SF 3 "div_operator" "") 
14468                  (const_string "fdiv")
14469               ]
14470               (const_string "fop")))
14471    (set_attr "fp_int_src" "true")
14472    (set_attr "mode" "<MODE>")])
14473
14474 (define_insn "*fop_df_comm_mixed"
14475   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14476         (match_operator:DF 3 "binary_fp_operator"
14477                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14478                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14479   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14480    && COMMUTATIVE_ARITH_P (operands[3])
14481    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482   "* return output_387_binary_op (insn, operands);"
14483   [(set (attr "type") 
14484         (if_then_else (eq_attr "alternative" "1")
14485            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14486               (const_string "ssemul")
14487               (const_string "sseadd"))
14488            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14489               (const_string "fmul")
14490               (const_string "fop"))))
14491    (set_attr "mode" "DF")])
14492
14493 (define_insn "*fop_df_comm_sse"
14494   [(set (match_operand:DF 0 "register_operand" "=Y")
14495         (match_operator:DF 3 "binary_fp_operator"
14496                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14497                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14498   "TARGET_SSE2 && TARGET_SSE_MATH
14499    && COMMUTATIVE_ARITH_P (operands[3])
14500    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14501   "* return output_387_binary_op (insn, operands);"
14502   [(set (attr "type") 
14503         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14504            (const_string "ssemul")
14505            (const_string "sseadd")))
14506    (set_attr "mode" "DF")])
14507
14508 (define_insn "*fop_df_comm_i387"
14509   [(set (match_operand:DF 0 "register_operand" "=f")
14510         (match_operator:DF 3 "binary_fp_operator"
14511                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14512                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14513   "TARGET_80387
14514    && COMMUTATIVE_ARITH_P (operands[3])
14515    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14516   "* return output_387_binary_op (insn, operands);"
14517   [(set (attr "type") 
14518         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14519            (const_string "fmul")
14520            (const_string "fop")))
14521    (set_attr "mode" "DF")])
14522
14523 (define_insn "*fop_df_1_mixed"
14524   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14525         (match_operator:DF 3 "binary_fp_operator"
14526                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14527                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14528   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14529    && !COMMUTATIVE_ARITH_P (operands[3])
14530    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531   "* return output_387_binary_op (insn, operands);"
14532   [(set (attr "type") 
14533         (cond [(and (eq_attr "alternative" "2")
14534                     (match_operand:SF 3 "mult_operator" ""))
14535                  (const_string "ssemul")
14536                (and (eq_attr "alternative" "2")
14537                     (match_operand:SF 3 "div_operator" ""))
14538                  (const_string "ssediv")
14539                (eq_attr "alternative" "2")
14540                  (const_string "sseadd")
14541                (match_operand:DF 3 "mult_operator" "") 
14542                  (const_string "fmul")
14543                (match_operand:DF 3 "div_operator" "") 
14544                  (const_string "fdiv")
14545               ]
14546               (const_string "fop")))
14547    (set_attr "mode" "DF")])
14548
14549 (define_insn "*fop_df_1_sse"
14550   [(set (match_operand:DF 0 "register_operand" "=Y")
14551         (match_operator:DF 3 "binary_fp_operator"
14552                         [(match_operand:DF 1 "register_operand" "0")
14553                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14554   "TARGET_SSE2 && TARGET_SSE_MATH
14555    && !COMMUTATIVE_ARITH_P (operands[3])"
14556   "* return output_387_binary_op (insn, operands);"
14557   [(set_attr "mode" "DF")
14558    (set (attr "type") 
14559         (cond [(match_operand:SF 3 "mult_operator" "")
14560                  (const_string "ssemul")
14561                (match_operand:SF 3 "div_operator" "")
14562                  (const_string "ssediv")
14563               ]
14564               (const_string "sseadd")))])
14565
14566 ;; This pattern is not fully shadowed by the pattern above.
14567 (define_insn "*fop_df_1_i387"
14568   [(set (match_operand:DF 0 "register_operand" "=f,f")
14569         (match_operator:DF 3 "binary_fp_operator"
14570                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14571                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14572   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14573    && !COMMUTATIVE_ARITH_P (operands[3])
14574    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14575   "* return output_387_binary_op (insn, operands);"
14576   [(set (attr "type") 
14577         (cond [(match_operand:DF 3 "mult_operator" "") 
14578                  (const_string "fmul")
14579                (match_operand:DF 3 "div_operator" "")
14580                  (const_string "fdiv")
14581               ]
14582               (const_string "fop")))
14583    (set_attr "mode" "DF")])
14584
14585 ;; ??? Add SSE splitters for these!
14586 (define_insn "*fop_df_2<mode>_i387"
14587   [(set (match_operand:DF 0 "register_operand" "=f,f")
14588         (match_operator:DF 3 "binary_fp_operator"
14589            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14590             (match_operand:DF 2 "register_operand" "0,0")]))]
14591   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14592    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14593   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14594   [(set (attr "type") 
14595         (cond [(match_operand:DF 3 "mult_operator" "") 
14596                  (const_string "fmul")
14597                (match_operand:DF 3 "div_operator" "") 
14598                  (const_string "fdiv")
14599               ]
14600               (const_string "fop")))
14601    (set_attr "fp_int_src" "true")
14602    (set_attr "mode" "<MODE>")])
14603
14604 (define_insn "*fop_df_3<mode>_i387"
14605   [(set (match_operand:DF 0 "register_operand" "=f,f")
14606         (match_operator:DF 3 "binary_fp_operator"
14607            [(match_operand:DF 1 "register_operand" "0,0")
14608             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14609   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14610    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14611   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14612   [(set (attr "type") 
14613         (cond [(match_operand:DF 3 "mult_operator" "") 
14614                  (const_string "fmul")
14615                (match_operand:DF 3 "div_operator" "") 
14616                  (const_string "fdiv")
14617               ]
14618               (const_string "fop")))
14619    (set_attr "fp_int_src" "true")
14620    (set_attr "mode" "<MODE>")])
14621
14622 (define_insn "*fop_df_4_i387"
14623   [(set (match_operand:DF 0 "register_operand" "=f,f")
14624         (match_operator:DF 3 "binary_fp_operator"
14625            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14626             (match_operand:DF 2 "register_operand" "0,f")]))]
14627   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14628    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14629   "* return output_387_binary_op (insn, operands);"
14630   [(set (attr "type") 
14631         (cond [(match_operand:DF 3 "mult_operator" "") 
14632                  (const_string "fmul")
14633                (match_operand:DF 3 "div_operator" "") 
14634                  (const_string "fdiv")
14635               ]
14636               (const_string "fop")))
14637    (set_attr "mode" "SF")])
14638
14639 (define_insn "*fop_df_5_i387"
14640   [(set (match_operand:DF 0 "register_operand" "=f,f")
14641         (match_operator:DF 3 "binary_fp_operator"
14642           [(match_operand:DF 1 "register_operand" "0,f")
14643            (float_extend:DF
14644             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14645   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14646   "* return output_387_binary_op (insn, operands);"
14647   [(set (attr "type") 
14648         (cond [(match_operand:DF 3 "mult_operator" "") 
14649                  (const_string "fmul")
14650                (match_operand:DF 3 "div_operator" "") 
14651                  (const_string "fdiv")
14652               ]
14653               (const_string "fop")))
14654    (set_attr "mode" "SF")])
14655
14656 (define_insn "*fop_df_6_i387"
14657   [(set (match_operand:DF 0 "register_operand" "=f,f")
14658         (match_operator:DF 3 "binary_fp_operator"
14659           [(float_extend:DF
14660             (match_operand:SF 1 "register_operand" "0,f"))
14661            (float_extend:DF
14662             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14663   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14664   "* return output_387_binary_op (insn, operands);"
14665   [(set (attr "type") 
14666         (cond [(match_operand:DF 3 "mult_operator" "") 
14667                  (const_string "fmul")
14668                (match_operand:DF 3 "div_operator" "") 
14669                  (const_string "fdiv")
14670               ]
14671               (const_string "fop")))
14672    (set_attr "mode" "SF")])
14673
14674 (define_insn "*fop_xf_comm_i387"
14675   [(set (match_operand:XF 0 "register_operand" "=f")
14676         (match_operator:XF 3 "binary_fp_operator"
14677                         [(match_operand:XF 1 "register_operand" "%0")
14678                          (match_operand:XF 2 "register_operand" "f")]))]
14679   "TARGET_80387
14680    && COMMUTATIVE_ARITH_P (operands[3])"
14681   "* return output_387_binary_op (insn, operands);"
14682   [(set (attr "type") 
14683         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14684            (const_string "fmul")
14685            (const_string "fop")))
14686    (set_attr "mode" "XF")])
14687
14688 (define_insn "*fop_xf_1_i387"
14689   [(set (match_operand:XF 0 "register_operand" "=f,f")
14690         (match_operator:XF 3 "binary_fp_operator"
14691                         [(match_operand:XF 1 "register_operand" "0,f")
14692                          (match_operand:XF 2 "register_operand" "f,0")]))]
14693   "TARGET_80387
14694    && !COMMUTATIVE_ARITH_P (operands[3])"
14695   "* return output_387_binary_op (insn, operands);"
14696   [(set (attr "type") 
14697         (cond [(match_operand:XF 3 "mult_operator" "") 
14698                  (const_string "fmul")
14699                (match_operand:XF 3 "div_operator" "") 
14700                  (const_string "fdiv")
14701               ]
14702               (const_string "fop")))
14703    (set_attr "mode" "XF")])
14704
14705 (define_insn "*fop_xf_2<mode>_i387"
14706   [(set (match_operand:XF 0 "register_operand" "=f,f")
14707         (match_operator:XF 3 "binary_fp_operator"
14708            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14709             (match_operand:XF 2 "register_operand" "0,0")]))]
14710   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14711   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14712   [(set (attr "type") 
14713         (cond [(match_operand:XF 3 "mult_operator" "") 
14714                  (const_string "fmul")
14715                (match_operand:XF 3 "div_operator" "") 
14716                  (const_string "fdiv")
14717               ]
14718               (const_string "fop")))
14719    (set_attr "fp_int_src" "true")
14720    (set_attr "mode" "<MODE>")])
14721
14722 (define_insn "*fop_xf_3<mode>_i387"
14723   [(set (match_operand:XF 0 "register_operand" "=f,f")
14724         (match_operator:XF 3 "binary_fp_operator"
14725           [(match_operand:XF 1 "register_operand" "0,0")
14726            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14727   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14728   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14729   [(set (attr "type") 
14730         (cond [(match_operand:XF 3 "mult_operator" "") 
14731                  (const_string "fmul")
14732                (match_operand:XF 3 "div_operator" "") 
14733                  (const_string "fdiv")
14734               ]
14735               (const_string "fop")))
14736    (set_attr "fp_int_src" "true")
14737    (set_attr "mode" "<MODE>")])
14738
14739 (define_insn "*fop_xf_4_i387"
14740   [(set (match_operand:XF 0 "register_operand" "=f,f")
14741         (match_operator:XF 3 "binary_fp_operator"
14742            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14743             (match_operand:XF 2 "register_operand" "0,f")]))]
14744   "TARGET_80387"
14745   "* return output_387_binary_op (insn, operands);"
14746   [(set (attr "type") 
14747         (cond [(match_operand:XF 3 "mult_operator" "") 
14748                  (const_string "fmul")
14749                (match_operand:XF 3 "div_operator" "") 
14750                  (const_string "fdiv")
14751               ]
14752               (const_string "fop")))
14753    (set_attr "mode" "SF")])
14754
14755 (define_insn "*fop_xf_5_i387"
14756   [(set (match_operand:XF 0 "register_operand" "=f,f")
14757         (match_operator:XF 3 "binary_fp_operator"
14758           [(match_operand:XF 1 "register_operand" "0,f")
14759            (float_extend:XF
14760             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14761   "TARGET_80387"
14762   "* return output_387_binary_op (insn, operands);"
14763   [(set (attr "type") 
14764         (cond [(match_operand:XF 3 "mult_operator" "") 
14765                  (const_string "fmul")
14766                (match_operand:XF 3 "div_operator" "") 
14767                  (const_string "fdiv")
14768               ]
14769               (const_string "fop")))
14770    (set_attr "mode" "SF")])
14771
14772 (define_insn "*fop_xf_6_i387"
14773   [(set (match_operand:XF 0 "register_operand" "=f,f")
14774         (match_operator:XF 3 "binary_fp_operator"
14775           [(float_extend:XF
14776             (match_operand 1 "register_operand" "0,f"))
14777            (float_extend:XF
14778             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14779   "TARGET_80387"
14780   "* return output_387_binary_op (insn, operands);"
14781   [(set (attr "type") 
14782         (cond [(match_operand:XF 3 "mult_operator" "") 
14783                  (const_string "fmul")
14784                (match_operand:XF 3 "div_operator" "") 
14785                  (const_string "fdiv")
14786               ]
14787               (const_string "fop")))
14788    (set_attr "mode" "SF")])
14789
14790 (define_split
14791   [(set (match_operand 0 "register_operand" "")
14792         (match_operator 3 "binary_fp_operator"
14793            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14794             (match_operand 2 "register_operand" "")]))]
14795   "TARGET_80387 && reload_completed
14796    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14797   [(const_int 0)]
14798
14799   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14800   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14801   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14802                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14803                                           GET_MODE (operands[3]),
14804                                           operands[4],
14805                                           operands[2])));
14806   ix86_free_from_memory (GET_MODE (operands[1]));
14807   DONE;
14808 })
14809
14810 (define_split
14811   [(set (match_operand 0 "register_operand" "")
14812         (match_operator 3 "binary_fp_operator"
14813            [(match_operand 1 "register_operand" "")
14814             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14815   "TARGET_80387 && reload_completed
14816    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14817   [(const_int 0)]
14818 {
14819   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14820   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14821   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14822                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14823                                           GET_MODE (operands[3]),
14824                                           operands[1],
14825                                           operands[4])));
14826   ix86_free_from_memory (GET_MODE (operands[2]));
14827   DONE;
14828 })
14829 \f
14830 ;; FPU special functions.
14831
14832 (define_expand "sqrtsf2"
14833   [(set (match_operand:SF 0 "register_operand" "")
14834         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14835   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14836 {
14837   if (!TARGET_SSE_MATH)
14838     operands[1] = force_reg (SFmode, operands[1]);
14839 })
14840
14841 (define_insn "*sqrtsf2_mixed"
14842   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14843         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14844   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14845   "@
14846    fsqrt
14847    sqrtss\t{%1, %0|%0, %1}"
14848   [(set_attr "type" "fpspc,sse")
14849    (set_attr "mode" "SF,SF")
14850    (set_attr "athlon_decode" "direct,*")])
14851
14852 (define_insn "*sqrtsf2_sse"
14853   [(set (match_operand:SF 0 "register_operand" "=x")
14854         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14855   "TARGET_SSE_MATH"
14856   "sqrtss\t{%1, %0|%0, %1}"
14857   [(set_attr "type" "sse")
14858    (set_attr "mode" "SF")
14859    (set_attr "athlon_decode" "*")])
14860
14861 (define_insn "*sqrtsf2_i387"
14862   [(set (match_operand:SF 0 "register_operand" "=f")
14863         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14864   "TARGET_USE_FANCY_MATH_387"
14865   "fsqrt"
14866   [(set_attr "type" "fpspc")
14867    (set_attr "mode" "SF")
14868    (set_attr "athlon_decode" "direct")])
14869
14870 (define_expand "sqrtdf2"
14871   [(set (match_operand:DF 0 "register_operand" "")
14872         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14873   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14874 {
14875   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14876     operands[1] = force_reg (DFmode, operands[1]);
14877 })
14878
14879 (define_insn "*sqrtdf2_mixed"
14880   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14881         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14882   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14883   "@
14884    fsqrt
14885    sqrtsd\t{%1, %0|%0, %1}"
14886   [(set_attr "type" "fpspc,sse")
14887    (set_attr "mode" "DF,DF")
14888    (set_attr "athlon_decode" "direct,*")])
14889
14890 (define_insn "*sqrtdf2_sse"
14891   [(set (match_operand:DF 0 "register_operand" "=Y")
14892         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14893   "TARGET_SSE2 && TARGET_SSE_MATH"
14894   "sqrtsd\t{%1, %0|%0, %1}"
14895   [(set_attr "type" "sse")
14896    (set_attr "mode" "DF")
14897    (set_attr "athlon_decode" "*")])
14898
14899 (define_insn "*sqrtdf2_i387"
14900   [(set (match_operand:DF 0 "register_operand" "=f")
14901         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14902   "TARGET_USE_FANCY_MATH_387"
14903   "fsqrt"
14904   [(set_attr "type" "fpspc")
14905    (set_attr "mode" "DF")
14906    (set_attr "athlon_decode" "direct")])
14907
14908 (define_insn "*sqrtextendsfdf2_i387"
14909   [(set (match_operand:DF 0 "register_operand" "=f")
14910         (sqrt:DF (float_extend:DF
14911                   (match_operand:SF 1 "register_operand" "0"))))]
14912   "TARGET_USE_FANCY_MATH_387
14913    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14914   "fsqrt"
14915   [(set_attr "type" "fpspc")
14916    (set_attr "mode" "DF")
14917    (set_attr "athlon_decode" "direct")])
14918
14919 (define_insn "sqrtxf2"
14920   [(set (match_operand:XF 0 "register_operand" "=f")
14921         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14922   "TARGET_USE_FANCY_MATH_387 
14923    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14924   "fsqrt"
14925   [(set_attr "type" "fpspc")
14926    (set_attr "mode" "XF")
14927    (set_attr "athlon_decode" "direct")])
14928
14929 (define_insn "*sqrtextendsfxf2_i387"
14930   [(set (match_operand:XF 0 "register_operand" "=f")
14931         (sqrt:XF (float_extend:XF
14932                   (match_operand:SF 1 "register_operand" "0"))))]
14933   "TARGET_USE_FANCY_MATH_387"
14934   "fsqrt"
14935   [(set_attr "type" "fpspc")
14936    (set_attr "mode" "XF")
14937    (set_attr "athlon_decode" "direct")])
14938
14939 (define_insn "*sqrtextenddfxf2_i387"
14940   [(set (match_operand:XF 0 "register_operand" "=f")
14941         (sqrt:XF (float_extend:XF
14942                   (match_operand:DF 1 "register_operand" "0"))))]
14943   "TARGET_USE_FANCY_MATH_387"
14944   "fsqrt"
14945   [(set_attr "type" "fpspc")
14946    (set_attr "mode" "XF")
14947    (set_attr "athlon_decode" "direct")])
14948
14949 (define_insn "fpremxf4"
14950   [(set (match_operand:XF 0 "register_operand" "=f")
14951         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14952                     (match_operand:XF 3 "register_operand" "1")]
14953                    UNSPEC_FPREM_F))
14954    (set (match_operand:XF 1 "register_operand" "=u")
14955         (unspec:XF [(match_dup 2) (match_dup 3)]
14956                    UNSPEC_FPREM_U))
14957    (set (reg:CCFP FPSR_REG)
14958         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14959   "TARGET_USE_FANCY_MATH_387
14960    && flag_unsafe_math_optimizations"
14961   "fprem"
14962   [(set_attr "type" "fpspc")
14963    (set_attr "mode" "XF")])
14964
14965 (define_expand "fmodsf3"
14966   [(use (match_operand:SF 0 "register_operand" ""))
14967    (use (match_operand:SF 1 "register_operand" ""))
14968    (use (match_operand:SF 2 "register_operand" ""))]
14969   "TARGET_USE_FANCY_MATH_387
14970    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14971    && flag_unsafe_math_optimizations"
14972 {
14973   rtx label = gen_label_rtx ();
14974
14975   rtx op1 = gen_reg_rtx (XFmode);
14976   rtx op2 = gen_reg_rtx (XFmode);
14977
14978   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14979   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14980
14981   emit_label (label);
14982
14983   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14984   ix86_emit_fp_unordered_jump (label);
14985
14986   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14987   DONE;
14988 })
14989
14990 (define_expand "fmoddf3"
14991   [(use (match_operand:DF 0 "register_operand" ""))
14992    (use (match_operand:DF 1 "register_operand" ""))
14993    (use (match_operand:DF 2 "register_operand" ""))]
14994   "TARGET_USE_FANCY_MATH_387
14995    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14996    && flag_unsafe_math_optimizations"
14997 {
14998   rtx label = gen_label_rtx ();
14999
15000   rtx op1 = gen_reg_rtx (XFmode);
15001   rtx op2 = gen_reg_rtx (XFmode);
15002
15003   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15004   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15005
15006   emit_label (label);
15007
15008   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15009   ix86_emit_fp_unordered_jump (label);
15010
15011   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15012   DONE;
15013 })
15014
15015 (define_expand "fmodxf3"
15016   [(use (match_operand:XF 0 "register_operand" ""))
15017    (use (match_operand:XF 1 "register_operand" ""))
15018    (use (match_operand:XF 2 "register_operand" ""))]
15019   "TARGET_USE_FANCY_MATH_387
15020    && flag_unsafe_math_optimizations"
15021 {
15022   rtx label = gen_label_rtx ();
15023
15024   emit_label (label);
15025
15026   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15027                            operands[1], operands[2]));
15028   ix86_emit_fp_unordered_jump (label);
15029
15030   emit_move_insn (operands[0], operands[1]);
15031   DONE;
15032 })
15033
15034 (define_insn "fprem1xf4"
15035   [(set (match_operand:XF 0 "register_operand" "=f")
15036         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15037                     (match_operand:XF 3 "register_operand" "1")]
15038                    UNSPEC_FPREM1_F))
15039    (set (match_operand:XF 1 "register_operand" "=u")
15040         (unspec:XF [(match_dup 2) (match_dup 3)]
15041                    UNSPEC_FPREM1_U))
15042    (set (reg:CCFP FPSR_REG)
15043         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15044   "TARGET_USE_FANCY_MATH_387
15045    && flag_unsafe_math_optimizations"
15046   "fprem1"
15047   [(set_attr "type" "fpspc")
15048    (set_attr "mode" "XF")])
15049
15050 (define_expand "dremsf3"
15051   [(use (match_operand:SF 0 "register_operand" ""))
15052    (use (match_operand:SF 1 "register_operand" ""))
15053    (use (match_operand:SF 2 "register_operand" ""))]
15054   "TARGET_USE_FANCY_MATH_387
15055    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15056    && flag_unsafe_math_optimizations"
15057 {
15058   rtx label = gen_label_rtx ();
15059
15060   rtx op1 = gen_reg_rtx (XFmode);
15061   rtx op2 = gen_reg_rtx (XFmode);
15062
15063   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15064   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15065
15066   emit_label (label);
15067
15068   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15069   ix86_emit_fp_unordered_jump (label);
15070
15071   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15072   DONE;
15073 })
15074
15075 (define_expand "dremdf3"
15076   [(use (match_operand:DF 0 "register_operand" ""))
15077    (use (match_operand:DF 1 "register_operand" ""))
15078    (use (match_operand:DF 2 "register_operand" ""))]
15079   "TARGET_USE_FANCY_MATH_387
15080    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15081    && flag_unsafe_math_optimizations"
15082 {
15083   rtx label = gen_label_rtx ();
15084
15085   rtx op1 = gen_reg_rtx (XFmode);
15086   rtx op2 = gen_reg_rtx (XFmode);
15087
15088   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15089   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15090
15091   emit_label (label);
15092
15093   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15094   ix86_emit_fp_unordered_jump (label);
15095
15096   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15097   DONE;
15098 })
15099
15100 (define_expand "dremxf3"
15101   [(use (match_operand:XF 0 "register_operand" ""))
15102    (use (match_operand:XF 1 "register_operand" ""))
15103    (use (match_operand:XF 2 "register_operand" ""))]
15104   "TARGET_USE_FANCY_MATH_387
15105    && flag_unsafe_math_optimizations"
15106 {
15107   rtx label = gen_label_rtx ();
15108
15109   emit_label (label);
15110
15111   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15112                             operands[1], operands[2]));
15113   ix86_emit_fp_unordered_jump (label);
15114
15115   emit_move_insn (operands[0], operands[1]);
15116   DONE;
15117 })
15118
15119 (define_insn "*sindf2"
15120   [(set (match_operand:DF 0 "register_operand" "=f")
15121         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15124    && flag_unsafe_math_optimizations"
15125   "fsin"
15126   [(set_attr "type" "fpspc")
15127    (set_attr "mode" "DF")])
15128
15129 (define_insn "*sinsf2"
15130   [(set (match_operand:SF 0 "register_operand" "=f")
15131         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15132   "TARGET_USE_FANCY_MATH_387
15133    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15134    && flag_unsafe_math_optimizations"
15135   "fsin"
15136   [(set_attr "type" "fpspc")
15137    (set_attr "mode" "SF")])
15138
15139 (define_insn "*sinextendsfdf2"
15140   [(set (match_operand:DF 0 "register_operand" "=f")
15141         (unspec:DF [(float_extend:DF
15142                      (match_operand:SF 1 "register_operand" "0"))]
15143                    UNSPEC_SIN))]
15144   "TARGET_USE_FANCY_MATH_387
15145    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15146    && flag_unsafe_math_optimizations"
15147   "fsin"
15148   [(set_attr "type" "fpspc")
15149    (set_attr "mode" "DF")])
15150
15151 (define_insn "*sinxf2"
15152   [(set (match_operand:XF 0 "register_operand" "=f")
15153         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15154   "TARGET_USE_FANCY_MATH_387
15155    && flag_unsafe_math_optimizations"
15156   "fsin"
15157   [(set_attr "type" "fpspc")
15158    (set_attr "mode" "XF")])
15159
15160 (define_insn "*cosdf2"
15161   [(set (match_operand:DF 0 "register_operand" "=f")
15162         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15165    && flag_unsafe_math_optimizations"
15166   "fcos"
15167   [(set_attr "type" "fpspc")
15168    (set_attr "mode" "DF")])
15169
15170 (define_insn "*cossf2"
15171   [(set (match_operand:SF 0 "register_operand" "=f")
15172         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15175    && flag_unsafe_math_optimizations"
15176   "fcos"
15177   [(set_attr "type" "fpspc")
15178    (set_attr "mode" "SF")])
15179
15180 (define_insn "*cosextendsfdf2"
15181   [(set (match_operand:DF 0 "register_operand" "=f")
15182         (unspec:DF [(float_extend:DF
15183                      (match_operand:SF 1 "register_operand" "0"))]
15184                    UNSPEC_COS))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15187    && flag_unsafe_math_optimizations"
15188   "fcos"
15189   [(set_attr "type" "fpspc")
15190    (set_attr "mode" "DF")])
15191
15192 (define_insn "*cosxf2"
15193   [(set (match_operand:XF 0 "register_operand" "=f")
15194         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15195   "TARGET_USE_FANCY_MATH_387
15196    && flag_unsafe_math_optimizations"
15197   "fcos"
15198   [(set_attr "type" "fpspc")
15199    (set_attr "mode" "XF")])
15200
15201 ;; With sincos pattern defined, sin and cos builtin function will be
15202 ;; expanded to sincos pattern with one of its outputs left unused. 
15203 ;; Cse pass  will detected, if two sincos patterns can be combined,
15204 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15205 ;; depending on the unused output.
15206
15207 (define_insn "sincosdf3"
15208   [(set (match_operand:DF 0 "register_operand" "=f")
15209         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15210                    UNSPEC_SINCOS_COS))
15211    (set (match_operand:DF 1 "register_operand" "=u")
15212         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15213   "TARGET_USE_FANCY_MATH_387
15214    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15215    && flag_unsafe_math_optimizations"
15216   "fsincos"
15217   [(set_attr "type" "fpspc")
15218    (set_attr "mode" "DF")])
15219
15220 (define_split
15221   [(set (match_operand:DF 0 "register_operand" "")
15222         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15223                    UNSPEC_SINCOS_COS))
15224    (set (match_operand:DF 1 "register_operand" "")
15225         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15226   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15227    && !reload_completed && !reload_in_progress"
15228   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15229   "")
15230
15231 (define_split
15232   [(set (match_operand:DF 0 "register_operand" "")
15233         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15234                    UNSPEC_SINCOS_COS))
15235    (set (match_operand:DF 1 "register_operand" "")
15236         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15237   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15238    && !reload_completed && !reload_in_progress"
15239   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15240   "")
15241
15242 (define_insn "sincossf3"
15243   [(set (match_operand:SF 0 "register_operand" "=f")
15244         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15245                    UNSPEC_SINCOS_COS))
15246    (set (match_operand:SF 1 "register_operand" "=u")
15247         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15248   "TARGET_USE_FANCY_MATH_387
15249    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15250    && flag_unsafe_math_optimizations"
15251   "fsincos"
15252   [(set_attr "type" "fpspc")
15253    (set_attr "mode" "SF")])
15254
15255 (define_split
15256   [(set (match_operand:SF 0 "register_operand" "")
15257         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15258                    UNSPEC_SINCOS_COS))
15259    (set (match_operand:SF 1 "register_operand" "")
15260         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15261   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15262    && !reload_completed && !reload_in_progress"
15263   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15264   "")
15265
15266 (define_split
15267   [(set (match_operand:SF 0 "register_operand" "")
15268         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15269                    UNSPEC_SINCOS_COS))
15270    (set (match_operand:SF 1 "register_operand" "")
15271         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15272   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15273    && !reload_completed && !reload_in_progress"
15274   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15275   "")
15276
15277 (define_insn "*sincosextendsfdf3"
15278   [(set (match_operand:DF 0 "register_operand" "=f")
15279         (unspec:DF [(float_extend:DF
15280                      (match_operand:SF 2 "register_operand" "0"))]
15281                    UNSPEC_SINCOS_COS))
15282    (set (match_operand:DF 1 "register_operand" "=u")
15283         (unspec:DF [(float_extend:DF
15284                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15285   "TARGET_USE_FANCY_MATH_387
15286    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15287    && flag_unsafe_math_optimizations"
15288   "fsincos"
15289   [(set_attr "type" "fpspc")
15290    (set_attr "mode" "DF")])
15291
15292 (define_split
15293   [(set (match_operand:DF 0 "register_operand" "")
15294         (unspec:DF [(float_extend:DF
15295                      (match_operand:SF 2 "register_operand" ""))]
15296                    UNSPEC_SINCOS_COS))
15297    (set (match_operand:DF 1 "register_operand" "")
15298         (unspec:DF [(float_extend:DF
15299                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15300   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15301    && !reload_completed && !reload_in_progress"
15302   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15303                                    (match_dup 2))] UNSPEC_SIN))]
15304   "")
15305
15306 (define_split
15307   [(set (match_operand:DF 0 "register_operand" "")
15308         (unspec:DF [(float_extend:DF
15309                      (match_operand:SF 2 "register_operand" ""))]
15310                    UNSPEC_SINCOS_COS))
15311    (set (match_operand:DF 1 "register_operand" "")
15312         (unspec:DF [(float_extend:DF
15313                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15314   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15315    && !reload_completed && !reload_in_progress"
15316   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15317                                    (match_dup 2))] UNSPEC_COS))]
15318   "")
15319
15320 (define_insn "sincosxf3"
15321   [(set (match_operand:XF 0 "register_operand" "=f")
15322         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15323                    UNSPEC_SINCOS_COS))
15324    (set (match_operand:XF 1 "register_operand" "=u")
15325         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15326   "TARGET_USE_FANCY_MATH_387
15327    && flag_unsafe_math_optimizations"
15328   "fsincos"
15329   [(set_attr "type" "fpspc")
15330    (set_attr "mode" "XF")])
15331
15332 (define_split
15333   [(set (match_operand:XF 0 "register_operand" "")
15334         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15335                    UNSPEC_SINCOS_COS))
15336    (set (match_operand:XF 1 "register_operand" "")
15337         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15338   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15339    && !reload_completed && !reload_in_progress"
15340   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15341   "")
15342
15343 (define_split
15344   [(set (match_operand:XF 0 "register_operand" "")
15345         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15346                    UNSPEC_SINCOS_COS))
15347    (set (match_operand:XF 1 "register_operand" "")
15348         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15349   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15350    && !reload_completed && !reload_in_progress"
15351   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15352   "")
15353
15354 (define_insn "*tandf3_1"
15355   [(set (match_operand:DF 0 "register_operand" "=f")
15356         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15357                    UNSPEC_TAN_ONE))
15358    (set (match_operand:DF 1 "register_operand" "=u")
15359         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15360   "TARGET_USE_FANCY_MATH_387
15361    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15362    && flag_unsafe_math_optimizations"
15363   "fptan"
15364   [(set_attr "type" "fpspc")
15365    (set_attr "mode" "DF")])
15366
15367 ;; optimize sequence: fptan
15368 ;;                    fstp    %st(0)
15369 ;;                    fld1
15370 ;; into fptan insn.
15371
15372 (define_peephole2
15373   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15374                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15375                              UNSPEC_TAN_ONE))
15376              (set (match_operand:DF 1 "register_operand" "")
15377                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15378    (set (match_dup 0)
15379         (match_operand:DF 3 "immediate_operand" ""))]
15380   "standard_80387_constant_p (operands[3]) == 2"
15381   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15382              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15383   "")
15384
15385 (define_expand "tandf2"
15386   [(parallel [(set (match_dup 2)
15387                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15388                               UNSPEC_TAN_ONE))
15389               (set (match_operand:DF 0 "register_operand" "")
15390                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15391   "TARGET_USE_FANCY_MATH_387
15392    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15393    && flag_unsafe_math_optimizations"
15394 {
15395   operands[2] = gen_reg_rtx (DFmode);
15396 })
15397
15398 (define_insn "*tansf3_1"
15399   [(set (match_operand:SF 0 "register_operand" "=f")
15400         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15401                    UNSPEC_TAN_ONE))
15402    (set (match_operand:SF 1 "register_operand" "=u")
15403         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15406    && flag_unsafe_math_optimizations"
15407   "fptan"
15408   [(set_attr "type" "fpspc")
15409    (set_attr "mode" "SF")])
15410
15411 ;; optimize sequence: fptan
15412 ;;                    fstp    %st(0)
15413 ;;                    fld1
15414 ;; into fptan insn.
15415
15416 (define_peephole2
15417   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15418                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15419                              UNSPEC_TAN_ONE))
15420              (set (match_operand:SF 1 "register_operand" "")
15421                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15422    (set (match_dup 0)
15423         (match_operand:SF 3 "immediate_operand" ""))]
15424   "standard_80387_constant_p (operands[3]) == 2"
15425   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15426              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15427   "")
15428
15429 (define_expand "tansf2"
15430   [(parallel [(set (match_dup 2)
15431                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15432                               UNSPEC_TAN_ONE))
15433               (set (match_operand:SF 0 "register_operand" "")
15434                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15435   "TARGET_USE_FANCY_MATH_387
15436    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15437    && flag_unsafe_math_optimizations"
15438 {
15439   operands[2] = gen_reg_rtx (SFmode);
15440 })
15441
15442 (define_insn "*tanxf3_1"
15443   [(set (match_operand:XF 0 "register_operand" "=f")
15444         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15445                    UNSPEC_TAN_ONE))
15446    (set (match_operand:XF 1 "register_operand" "=u")
15447         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15448   "TARGET_USE_FANCY_MATH_387
15449    && flag_unsafe_math_optimizations"
15450   "fptan"
15451   [(set_attr "type" "fpspc")
15452    (set_attr "mode" "XF")])
15453
15454 ;; optimize sequence: fptan
15455 ;;                    fstp    %st(0)
15456 ;;                    fld1
15457 ;; into fptan insn.
15458
15459 (define_peephole2
15460   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15461                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15462                              UNSPEC_TAN_ONE))
15463              (set (match_operand:XF 1 "register_operand" "")
15464                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15465    (set (match_dup 0)
15466         (match_operand:XF 3 "immediate_operand" ""))]
15467   "standard_80387_constant_p (operands[3]) == 2"
15468   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15469              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15470   "")
15471
15472 (define_expand "tanxf2"
15473   [(parallel [(set (match_dup 2)
15474                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15475                               UNSPEC_TAN_ONE))
15476               (set (match_operand:XF 0 "register_operand" "")
15477                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15478   "TARGET_USE_FANCY_MATH_387
15479    && flag_unsafe_math_optimizations"
15480 {
15481   operands[2] = gen_reg_rtx (XFmode);
15482 })
15483
15484 (define_insn "atan2df3_1"
15485   [(set (match_operand:DF 0 "register_operand" "=f")
15486         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15487                     (match_operand:DF 1 "register_operand" "u")]
15488                    UNSPEC_FPATAN))
15489    (clobber (match_scratch:DF 3 "=1"))]
15490   "TARGET_USE_FANCY_MATH_387
15491    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15492    && flag_unsafe_math_optimizations"
15493   "fpatan"
15494   [(set_attr "type" "fpspc")
15495    (set_attr "mode" "DF")])
15496
15497 (define_expand "atan2df3"
15498   [(use (match_operand:DF 0 "register_operand" ""))
15499    (use (match_operand:DF 2 "register_operand" ""))
15500    (use (match_operand:DF 1 "register_operand" ""))]
15501   "TARGET_USE_FANCY_MATH_387
15502    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15503    && flag_unsafe_math_optimizations"
15504 {
15505   rtx copy = gen_reg_rtx (DFmode);
15506   emit_move_insn (copy, operands[1]);
15507   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15508   DONE;
15509 })
15510
15511 (define_expand "atandf2"
15512   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15513                    (unspec:DF [(match_dup 2)
15514                                (match_operand:DF 1 "register_operand" "")]
15515                     UNSPEC_FPATAN))
15516               (clobber (match_scratch:DF 3 ""))])]
15517   "TARGET_USE_FANCY_MATH_387
15518    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15519    && flag_unsafe_math_optimizations"
15520 {
15521   operands[2] = gen_reg_rtx (DFmode);
15522   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15523 })
15524
15525 (define_insn "atan2sf3_1"
15526   [(set (match_operand:SF 0 "register_operand" "=f")
15527         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15528                     (match_operand:SF 1 "register_operand" "u")]
15529                    UNSPEC_FPATAN))
15530    (clobber (match_scratch:SF 3 "=1"))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15533    && flag_unsafe_math_optimizations"
15534   "fpatan"
15535   [(set_attr "type" "fpspc")
15536    (set_attr "mode" "SF")])
15537
15538 (define_expand "atan2sf3"
15539   [(use (match_operand:SF 0 "register_operand" ""))
15540    (use (match_operand:SF 2 "register_operand" ""))
15541    (use (match_operand:SF 1 "register_operand" ""))]
15542   "TARGET_USE_FANCY_MATH_387
15543    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15544    && flag_unsafe_math_optimizations"
15545 {
15546   rtx copy = gen_reg_rtx (SFmode);
15547   emit_move_insn (copy, operands[1]);
15548   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15549   DONE;
15550 })
15551
15552 (define_expand "atansf2"
15553   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15554                    (unspec:SF [(match_dup 2)
15555                                (match_operand:SF 1 "register_operand" "")]
15556                     UNSPEC_FPATAN))
15557               (clobber (match_scratch:SF 3 ""))])]
15558   "TARGET_USE_FANCY_MATH_387
15559    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15560    && flag_unsafe_math_optimizations"
15561 {
15562   operands[2] = gen_reg_rtx (SFmode);
15563   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15564 })
15565
15566 (define_insn "atan2xf3_1"
15567   [(set (match_operand:XF 0 "register_operand" "=f")
15568         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15569                     (match_operand:XF 1 "register_operand" "u")]
15570                    UNSPEC_FPATAN))
15571    (clobber (match_scratch:XF 3 "=1"))]
15572   "TARGET_USE_FANCY_MATH_387
15573    && flag_unsafe_math_optimizations"
15574   "fpatan"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")])
15577
15578 (define_expand "atan2xf3"
15579   [(use (match_operand:XF 0 "register_operand" ""))
15580    (use (match_operand:XF 2 "register_operand" ""))
15581    (use (match_operand:XF 1 "register_operand" ""))]
15582   "TARGET_USE_FANCY_MATH_387
15583    && flag_unsafe_math_optimizations"
15584 {
15585   rtx copy = gen_reg_rtx (XFmode);
15586   emit_move_insn (copy, operands[1]);
15587   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15588   DONE;
15589 })
15590
15591 (define_expand "atanxf2"
15592   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15593                    (unspec:XF [(match_dup 2)
15594                                (match_operand:XF 1 "register_operand" "")]
15595                     UNSPEC_FPATAN))
15596               (clobber (match_scratch:XF 3 ""))])]
15597   "TARGET_USE_FANCY_MATH_387
15598    && flag_unsafe_math_optimizations"
15599 {
15600   operands[2] = gen_reg_rtx (XFmode);
15601   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15602 })
15603
15604 (define_expand "asindf2"
15605   [(set (match_dup 2)
15606         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15607    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15608    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15609    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15610    (parallel [(set (match_dup 7)
15611                    (unspec:XF [(match_dup 6) (match_dup 2)]
15612                               UNSPEC_FPATAN))
15613               (clobber (match_scratch:XF 8 ""))])
15614    (set (match_operand:DF 0 "register_operand" "")
15615         (float_truncate:DF (match_dup 7)))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15618    && flag_unsafe_math_optimizations"
15619 {
15620   int i;
15621
15622   for (i=2; i<8; i++)
15623     operands[i] = gen_reg_rtx (XFmode);
15624
15625   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15626 })
15627
15628 (define_expand "asinsf2"
15629   [(set (match_dup 2)
15630         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15631    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15632    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15633    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15634    (parallel [(set (match_dup 7)
15635                    (unspec:XF [(match_dup 6) (match_dup 2)]
15636                               UNSPEC_FPATAN))
15637               (clobber (match_scratch:XF 8 ""))])
15638    (set (match_operand:SF 0 "register_operand" "")
15639         (float_truncate:SF (match_dup 7)))]
15640   "TARGET_USE_FANCY_MATH_387
15641    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15642    && flag_unsafe_math_optimizations"
15643 {
15644   int i;
15645
15646   for (i=2; i<8; i++)
15647     operands[i] = gen_reg_rtx (XFmode);
15648
15649   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15650 })
15651
15652 (define_expand "asinxf2"
15653   [(set (match_dup 2)
15654         (mult:XF (match_operand:XF 1 "register_operand" "")
15655                  (match_dup 1)))
15656    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15657    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15658    (parallel [(set (match_operand:XF 0 "register_operand" "")
15659                    (unspec:XF [(match_dup 5) (match_dup 1)]
15660                               UNSPEC_FPATAN))
15661               (clobber (match_scratch:XF 6 ""))])]
15662   "TARGET_USE_FANCY_MATH_387
15663    && flag_unsafe_math_optimizations"
15664 {
15665   int i;
15666
15667   for (i=2; i<6; i++)
15668     operands[i] = gen_reg_rtx (XFmode);
15669
15670   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15671 })
15672
15673 (define_expand "acosdf2"
15674   [(set (match_dup 2)
15675         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15676    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15677    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15678    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15679    (parallel [(set (match_dup 7)
15680                    (unspec:XF [(match_dup 2) (match_dup 6)]
15681                               UNSPEC_FPATAN))
15682               (clobber (match_scratch:XF 8 ""))])
15683    (set (match_operand:DF 0 "register_operand" "")
15684         (float_truncate:DF (match_dup 7)))]
15685   "TARGET_USE_FANCY_MATH_387
15686    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15687    && flag_unsafe_math_optimizations"
15688 {
15689   int i;
15690
15691   for (i=2; i<8; i++)
15692     operands[i] = gen_reg_rtx (XFmode);
15693
15694   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15695 })
15696
15697 (define_expand "acossf2"
15698   [(set (match_dup 2)
15699         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15700    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15701    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15702    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15703    (parallel [(set (match_dup 7)
15704                    (unspec:XF [(match_dup 2) (match_dup 6)]
15705                               UNSPEC_FPATAN))
15706               (clobber (match_scratch:XF 8 ""))])
15707    (set (match_operand:SF 0 "register_operand" "")
15708         (float_truncate:SF (match_dup 7)))]
15709   "TARGET_USE_FANCY_MATH_387
15710    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15711    && flag_unsafe_math_optimizations"
15712 {
15713   int i;
15714
15715   for (i=2; i<8; i++)
15716     operands[i] = gen_reg_rtx (XFmode);
15717
15718   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15719 })
15720
15721 (define_expand "acosxf2"
15722   [(set (match_dup 2)
15723         (mult:XF (match_operand:XF 1 "register_operand" "")
15724                  (match_dup 1)))
15725    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15726    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15727    (parallel [(set (match_operand:XF 0 "register_operand" "")
15728                    (unspec:XF [(match_dup 1) (match_dup 5)]
15729                               UNSPEC_FPATAN))
15730               (clobber (match_scratch:XF 6 ""))])]
15731   "TARGET_USE_FANCY_MATH_387
15732    && flag_unsafe_math_optimizations"
15733 {
15734   int i;
15735
15736   for (i=2; i<6; i++)
15737     operands[i] = gen_reg_rtx (XFmode);
15738
15739   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15740 })
15741
15742 (define_insn "fyl2x_xf3"
15743   [(set (match_operand:XF 0 "register_operand" "=f")
15744         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15745                     (match_operand:XF 1 "register_operand" "u")]
15746                    UNSPEC_FYL2X))
15747    (clobber (match_scratch:XF 3 "=1"))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && flag_unsafe_math_optimizations"
15750   "fyl2x"
15751   [(set_attr "type" "fpspc")
15752    (set_attr "mode" "XF")])
15753
15754 (define_expand "logsf2"
15755   [(set (match_dup 2)
15756         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15757    (parallel [(set (match_dup 4)
15758                    (unspec:XF [(match_dup 2)
15759                                (match_dup 3)] UNSPEC_FYL2X))
15760               (clobber (match_scratch:XF 5 ""))])
15761    (set (match_operand:SF 0 "register_operand" "")
15762         (float_truncate:SF (match_dup 4)))]
15763   "TARGET_USE_FANCY_MATH_387
15764    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15765    && flag_unsafe_math_optimizations"
15766 {
15767   rtx temp;
15768
15769   operands[2] = gen_reg_rtx (XFmode);
15770   operands[3] = gen_reg_rtx (XFmode);
15771   operands[4] = gen_reg_rtx (XFmode);
15772
15773   temp = standard_80387_constant_rtx (4); /* fldln2 */
15774   emit_move_insn (operands[3], temp);
15775 })
15776
15777 (define_expand "logdf2"
15778   [(set (match_dup 2)
15779         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15780    (parallel [(set (match_dup 4)
15781                    (unspec:XF [(match_dup 2)
15782                                (match_dup 3)] UNSPEC_FYL2X))
15783               (clobber (match_scratch:XF 5 ""))])
15784    (set (match_operand:DF 0 "register_operand" "")
15785         (float_truncate:DF (match_dup 4)))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15788    && flag_unsafe_math_optimizations"
15789 {
15790   rtx temp;
15791
15792   operands[2] = gen_reg_rtx (XFmode);
15793   operands[3] = gen_reg_rtx (XFmode);
15794   operands[4] = gen_reg_rtx (XFmode);
15795
15796   temp = standard_80387_constant_rtx (4); /* fldln2 */
15797   emit_move_insn (operands[3], temp);
15798 })
15799
15800 (define_expand "logxf2"
15801   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15803                                (match_dup 2)] UNSPEC_FYL2X))
15804               (clobber (match_scratch:XF 3 ""))])]
15805   "TARGET_USE_FANCY_MATH_387
15806    && flag_unsafe_math_optimizations"
15807 {
15808   rtx temp;
15809
15810   operands[2] = gen_reg_rtx (XFmode);
15811   temp = standard_80387_constant_rtx (4); /* fldln2 */
15812   emit_move_insn (operands[2], temp);
15813 })
15814
15815 (define_expand "log10sf2"
15816   [(set (match_dup 2)
15817         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15818    (parallel [(set (match_dup 4)
15819                    (unspec:XF [(match_dup 2)
15820                                (match_dup 3)] UNSPEC_FYL2X))
15821               (clobber (match_scratch:XF 5 ""))])
15822    (set (match_operand:SF 0 "register_operand" "")
15823         (float_truncate:SF (match_dup 4)))]
15824   "TARGET_USE_FANCY_MATH_387
15825    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15826    && flag_unsafe_math_optimizations"
15827 {
15828   rtx temp;
15829
15830   operands[2] = gen_reg_rtx (XFmode);
15831   operands[3] = gen_reg_rtx (XFmode);
15832   operands[4] = gen_reg_rtx (XFmode);
15833
15834   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15835   emit_move_insn (operands[3], temp);
15836 })
15837
15838 (define_expand "log10df2"
15839   [(set (match_dup 2)
15840         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15841    (parallel [(set (match_dup 4)
15842                    (unspec:XF [(match_dup 2)
15843                                (match_dup 3)] UNSPEC_FYL2X))
15844               (clobber (match_scratch:XF 5 ""))])
15845    (set (match_operand:DF 0 "register_operand" "")
15846         (float_truncate:DF (match_dup 4)))]
15847   "TARGET_USE_FANCY_MATH_387
15848    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15849    && flag_unsafe_math_optimizations"
15850 {
15851   rtx temp;
15852
15853   operands[2] = gen_reg_rtx (XFmode);
15854   operands[3] = gen_reg_rtx (XFmode);
15855   operands[4] = gen_reg_rtx (XFmode);
15856
15857   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15858   emit_move_insn (operands[3], temp);
15859 })
15860
15861 (define_expand "log10xf2"
15862   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15863                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15864                                (match_dup 2)] UNSPEC_FYL2X))
15865               (clobber (match_scratch:XF 3 ""))])]
15866   "TARGET_USE_FANCY_MATH_387
15867    && flag_unsafe_math_optimizations"
15868 {
15869   rtx temp;
15870
15871   operands[2] = gen_reg_rtx (XFmode);
15872   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15873   emit_move_insn (operands[2], temp);
15874 })
15875
15876 (define_expand "log2sf2"
15877   [(set (match_dup 2)
15878         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15879    (parallel [(set (match_dup 4)
15880                    (unspec:XF [(match_dup 2)
15881                                (match_dup 3)] UNSPEC_FYL2X))
15882               (clobber (match_scratch:XF 5 ""))])
15883    (set (match_operand:SF 0 "register_operand" "")
15884         (float_truncate:SF (match_dup 4)))]
15885   "TARGET_USE_FANCY_MATH_387
15886    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15887    && flag_unsafe_math_optimizations"
15888 {
15889   operands[2] = gen_reg_rtx (XFmode);
15890   operands[3] = gen_reg_rtx (XFmode);
15891   operands[4] = gen_reg_rtx (XFmode);
15892
15893   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15894 })
15895
15896 (define_expand "log2df2"
15897   [(set (match_dup 2)
15898         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15899    (parallel [(set (match_dup 4)
15900                    (unspec:XF [(match_dup 2)
15901                                (match_dup 3)] UNSPEC_FYL2X))
15902               (clobber (match_scratch:XF 5 ""))])
15903    (set (match_operand:DF 0 "register_operand" "")
15904         (float_truncate:DF (match_dup 4)))]
15905   "TARGET_USE_FANCY_MATH_387
15906    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15907    && flag_unsafe_math_optimizations"
15908 {
15909   operands[2] = gen_reg_rtx (XFmode);
15910   operands[3] = gen_reg_rtx (XFmode);
15911   operands[4] = gen_reg_rtx (XFmode);
15912
15913   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15914 })
15915
15916 (define_expand "log2xf2"
15917   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15918                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15919                                (match_dup 2)] UNSPEC_FYL2X))
15920               (clobber (match_scratch:XF 3 ""))])]
15921   "TARGET_USE_FANCY_MATH_387
15922    && flag_unsafe_math_optimizations"
15923 {
15924   operands[2] = gen_reg_rtx (XFmode);
15925   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15926 })
15927
15928 (define_insn "fyl2xp1_xf3"
15929   [(set (match_operand:XF 0 "register_operand" "=f")
15930         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15931                     (match_operand:XF 1 "register_operand" "u")]
15932                    UNSPEC_FYL2XP1))
15933    (clobber (match_scratch:XF 3 "=1"))]
15934   "TARGET_USE_FANCY_MATH_387
15935    && flag_unsafe_math_optimizations"
15936   "fyl2xp1"
15937   [(set_attr "type" "fpspc")
15938    (set_attr "mode" "XF")])
15939
15940 (define_expand "log1psf2"
15941   [(use (match_operand:SF 0 "register_operand" ""))
15942    (use (match_operand:SF 1 "register_operand" ""))]
15943   "TARGET_USE_FANCY_MATH_387
15944    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15945    && flag_unsafe_math_optimizations"
15946 {
15947   rtx op0 = gen_reg_rtx (XFmode);
15948   rtx op1 = gen_reg_rtx (XFmode);
15949
15950   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15951   ix86_emit_i387_log1p (op0, op1);
15952   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15953   DONE;
15954 })
15955
15956 (define_expand "log1pdf2"
15957   [(use (match_operand:DF 0 "register_operand" ""))
15958    (use (match_operand:DF 1 "register_operand" ""))]
15959   "TARGET_USE_FANCY_MATH_387
15960    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15961    && flag_unsafe_math_optimizations"
15962 {
15963   rtx op0 = gen_reg_rtx (XFmode);
15964   rtx op1 = gen_reg_rtx (XFmode);
15965
15966   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15967   ix86_emit_i387_log1p (op0, op1);
15968   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15969   DONE;
15970 })
15971
15972 (define_expand "log1pxf2"
15973   [(use (match_operand:XF 0 "register_operand" ""))
15974    (use (match_operand:XF 1 "register_operand" ""))]
15975   "TARGET_USE_FANCY_MATH_387
15976    && flag_unsafe_math_optimizations"
15977 {
15978   ix86_emit_i387_log1p (operands[0], operands[1]);
15979   DONE;
15980 })
15981
15982 (define_insn "*fxtractxf3"
15983   [(set (match_operand:XF 0 "register_operand" "=f")
15984         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15985                    UNSPEC_XTRACT_FRACT))
15986    (set (match_operand:XF 1 "register_operand" "=u")
15987         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15988   "TARGET_USE_FANCY_MATH_387
15989    && flag_unsafe_math_optimizations"
15990   "fxtract"
15991   [(set_attr "type" "fpspc")
15992    (set_attr "mode" "XF")])
15993
15994 (define_expand "logbsf2"
15995   [(set (match_dup 2)
15996         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15997    (parallel [(set (match_dup 3)
15998                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15999               (set (match_dup 4)
16000                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16001    (set (match_operand:SF 0 "register_operand" "")
16002         (float_truncate:SF (match_dup 4)))]
16003   "TARGET_USE_FANCY_MATH_387
16004    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16005    && flag_unsafe_math_optimizations"
16006 {
16007   operands[2] = gen_reg_rtx (XFmode);
16008   operands[3] = gen_reg_rtx (XFmode);
16009   operands[4] = gen_reg_rtx (XFmode);
16010 })
16011
16012 (define_expand "logbdf2"
16013   [(set (match_dup 2)
16014         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16015    (parallel [(set (match_dup 3)
16016                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16017               (set (match_dup 4)
16018                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16019    (set (match_operand:DF 0 "register_operand" "")
16020         (float_truncate:DF (match_dup 4)))]
16021   "TARGET_USE_FANCY_MATH_387
16022    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16023    && flag_unsafe_math_optimizations"
16024 {
16025   operands[2] = gen_reg_rtx (XFmode);
16026   operands[3] = gen_reg_rtx (XFmode);
16027   operands[4] = gen_reg_rtx (XFmode);
16028 })
16029
16030 (define_expand "logbxf2"
16031   [(parallel [(set (match_dup 2)
16032                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16033                               UNSPEC_XTRACT_FRACT))
16034               (set (match_operand:XF 0 "register_operand" "")
16035                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16036   "TARGET_USE_FANCY_MATH_387
16037    && flag_unsafe_math_optimizations"
16038 {
16039   operands[2] = gen_reg_rtx (XFmode);
16040 })
16041
16042 (define_expand "ilogbsi2"
16043   [(parallel [(set (match_dup 2)
16044                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16045                               UNSPEC_XTRACT_FRACT))
16046               (set (match_operand:XF 3 "register_operand" "")
16047                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16048    (parallel [(set (match_operand:SI 0 "register_operand" "")
16049                    (fix:SI (match_dup 3)))
16050               (clobber (reg:CC FLAGS_REG))])]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations"
16054 {
16055   operands[2] = gen_reg_rtx (XFmode);
16056   operands[3] = gen_reg_rtx (XFmode);
16057 })
16058
16059 (define_insn "*f2xm1xf2"
16060   [(set (match_operand:XF 0 "register_operand" "=f")
16061         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16062          UNSPEC_F2XM1))]
16063   "TARGET_USE_FANCY_MATH_387
16064    && flag_unsafe_math_optimizations"
16065   "f2xm1"
16066   [(set_attr "type" "fpspc")
16067    (set_attr "mode" "XF")])
16068
16069 (define_insn "*fscalexf4"
16070   [(set (match_operand:XF 0 "register_operand" "=f")
16071         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16072                     (match_operand:XF 3 "register_operand" "1")]
16073                    UNSPEC_FSCALE_FRACT))
16074    (set (match_operand:XF 1 "register_operand" "=u")
16075         (unspec:XF [(match_dup 2) (match_dup 3)]
16076                    UNSPEC_FSCALE_EXP))]
16077   "TARGET_USE_FANCY_MATH_387
16078    && flag_unsafe_math_optimizations"
16079   "fscale"
16080   [(set_attr "type" "fpspc")
16081    (set_attr "mode" "XF")])
16082
16083 (define_expand "expsf2"
16084   [(set (match_dup 2)
16085         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16086    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16087    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16088    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16089    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16090    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16091    (parallel [(set (match_dup 10)
16092                    (unspec:XF [(match_dup 9) (match_dup 5)]
16093                               UNSPEC_FSCALE_FRACT))
16094               (set (match_dup 11)
16095                    (unspec:XF [(match_dup 9) (match_dup 5)]
16096                               UNSPEC_FSCALE_EXP))])
16097    (set (match_operand:SF 0 "register_operand" "")
16098         (float_truncate:SF (match_dup 10)))]
16099   "TARGET_USE_FANCY_MATH_387
16100    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16101    && flag_unsafe_math_optimizations"
16102 {
16103   rtx temp;
16104   int i;
16105
16106   for (i=2; i<12; i++)
16107     operands[i] = gen_reg_rtx (XFmode);
16108   temp = standard_80387_constant_rtx (5); /* fldl2e */
16109   emit_move_insn (operands[3], temp);
16110   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16111 })
16112
16113 (define_expand "expdf2"
16114   [(set (match_dup 2)
16115         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16116    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16117    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16118    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16119    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16120    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16121    (parallel [(set (match_dup 10)
16122                    (unspec:XF [(match_dup 9) (match_dup 5)]
16123                               UNSPEC_FSCALE_FRACT))
16124               (set (match_dup 11)
16125                    (unspec:XF [(match_dup 9) (match_dup 5)]
16126                               UNSPEC_FSCALE_EXP))])
16127    (set (match_operand:DF 0 "register_operand" "")
16128         (float_truncate:DF (match_dup 10)))]
16129   "TARGET_USE_FANCY_MATH_387
16130    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16131    && flag_unsafe_math_optimizations"
16132 {
16133   rtx temp;
16134   int i;
16135
16136   for (i=2; i<12; i++)
16137     operands[i] = gen_reg_rtx (XFmode);
16138   temp = standard_80387_constant_rtx (5); /* fldl2e */
16139   emit_move_insn (operands[3], temp);
16140   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16141 })
16142
16143 (define_expand "expxf2"
16144   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16145                                (match_dup 2)))
16146    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16147    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16148    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16149    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16150    (parallel [(set (match_operand:XF 0 "register_operand" "")
16151                    (unspec:XF [(match_dup 8) (match_dup 4)]
16152                               UNSPEC_FSCALE_FRACT))
16153               (set (match_dup 9)
16154                    (unspec:XF [(match_dup 8) (match_dup 4)]
16155                               UNSPEC_FSCALE_EXP))])]
16156   "TARGET_USE_FANCY_MATH_387
16157    && flag_unsafe_math_optimizations"
16158 {
16159   rtx temp;
16160   int i;
16161
16162   for (i=2; i<10; i++)
16163     operands[i] = gen_reg_rtx (XFmode);
16164   temp = standard_80387_constant_rtx (5); /* fldl2e */
16165   emit_move_insn (operands[2], temp);
16166   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16167 })
16168
16169 (define_expand "exp10sf2"
16170   [(set (match_dup 2)
16171         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16172    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16173    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16174    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16175    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16176    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16177    (parallel [(set (match_dup 10)
16178                    (unspec:XF [(match_dup 9) (match_dup 5)]
16179                               UNSPEC_FSCALE_FRACT))
16180               (set (match_dup 11)
16181                    (unspec:XF [(match_dup 9) (match_dup 5)]
16182                               UNSPEC_FSCALE_EXP))])
16183    (set (match_operand:SF 0 "register_operand" "")
16184         (float_truncate:SF (match_dup 10)))]
16185   "TARGET_USE_FANCY_MATH_387
16186    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16187    && flag_unsafe_math_optimizations"
16188 {
16189   rtx temp;
16190   int i;
16191
16192   for (i=2; i<12; i++)
16193     operands[i] = gen_reg_rtx (XFmode);
16194   temp = standard_80387_constant_rtx (6); /* fldl2t */
16195   emit_move_insn (operands[3], temp);
16196   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16197 })
16198
16199 (define_expand "exp10df2"
16200   [(set (match_dup 2)
16201         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16202    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16203    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16204    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16205    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16206    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16207    (parallel [(set (match_dup 10)
16208                    (unspec:XF [(match_dup 9) (match_dup 5)]
16209                               UNSPEC_FSCALE_FRACT))
16210               (set (match_dup 11)
16211                    (unspec:XF [(match_dup 9) (match_dup 5)]
16212                               UNSPEC_FSCALE_EXP))])
16213    (set (match_operand:DF 0 "register_operand" "")
16214         (float_truncate:DF (match_dup 10)))]
16215   "TARGET_USE_FANCY_MATH_387
16216    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16217    && flag_unsafe_math_optimizations"
16218 {
16219   rtx temp;
16220   int i;
16221
16222   for (i=2; i<12; i++)
16223     operands[i] = gen_reg_rtx (XFmode);
16224   temp = standard_80387_constant_rtx (6); /* fldl2t */
16225   emit_move_insn (operands[3], temp);
16226   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16227 })
16228
16229 (define_expand "exp10xf2"
16230   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16231                                (match_dup 2)))
16232    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16233    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16234    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16235    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16236    (parallel [(set (match_operand:XF 0 "register_operand" "")
16237                    (unspec:XF [(match_dup 8) (match_dup 4)]
16238                               UNSPEC_FSCALE_FRACT))
16239               (set (match_dup 9)
16240                    (unspec:XF [(match_dup 8) (match_dup 4)]
16241                               UNSPEC_FSCALE_EXP))])]
16242   "TARGET_USE_FANCY_MATH_387
16243    && flag_unsafe_math_optimizations"
16244 {
16245   rtx temp;
16246   int i;
16247
16248   for (i=2; i<10; i++)
16249     operands[i] = gen_reg_rtx (XFmode);
16250   temp = standard_80387_constant_rtx (6); /* fldl2t */
16251   emit_move_insn (operands[2], temp);
16252   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16253 })
16254
16255 (define_expand "exp2sf2"
16256   [(set (match_dup 2)
16257         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16258    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16259    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16260    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16261    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16262    (parallel [(set (match_dup 8)
16263                    (unspec:XF [(match_dup 7) (match_dup 3)]
16264                               UNSPEC_FSCALE_FRACT))
16265               (set (match_dup 9)
16266                    (unspec:XF [(match_dup 7) (match_dup 3)]
16267                               UNSPEC_FSCALE_EXP))])
16268    (set (match_operand:SF 0 "register_operand" "")
16269         (float_truncate:SF (match_dup 8)))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16272    && flag_unsafe_math_optimizations"
16273 {
16274   int i;
16275
16276   for (i=2; i<10; i++)
16277     operands[i] = gen_reg_rtx (XFmode);
16278   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16279 })
16280
16281 (define_expand "exp2df2"
16282   [(set (match_dup 2)
16283         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16284    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16285    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16286    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16287    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16288    (parallel [(set (match_dup 8)
16289                    (unspec:XF [(match_dup 7) (match_dup 3)]
16290                               UNSPEC_FSCALE_FRACT))
16291               (set (match_dup 9)
16292                    (unspec:XF [(match_dup 7) (match_dup 3)]
16293                               UNSPEC_FSCALE_EXP))])
16294    (set (match_operand:DF 0 "register_operand" "")
16295         (float_truncate:DF (match_dup 8)))]
16296   "TARGET_USE_FANCY_MATH_387
16297    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16298    && flag_unsafe_math_optimizations"
16299 {
16300   int i;
16301
16302   for (i=2; i<10; i++)
16303     operands[i] = gen_reg_rtx (XFmode);
16304   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16305 })
16306
16307 (define_expand "exp2xf2"
16308   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16309    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16310    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16311    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16312    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16313    (parallel [(set (match_operand:XF 0 "register_operand" "")
16314                    (unspec:XF [(match_dup 7) (match_dup 3)]
16315                               UNSPEC_FSCALE_FRACT))
16316               (set (match_dup 8)
16317                    (unspec:XF [(match_dup 7) (match_dup 3)]
16318                               UNSPEC_FSCALE_EXP))])]
16319   "TARGET_USE_FANCY_MATH_387
16320    && flag_unsafe_math_optimizations"
16321 {
16322   int i;
16323
16324   for (i=2; i<9; i++)
16325     operands[i] = gen_reg_rtx (XFmode);
16326   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16327 })
16328
16329 (define_expand "expm1df2"
16330   [(set (match_dup 2)
16331         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16332    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16333    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16334    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16335    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16336    (parallel [(set (match_dup 8)
16337                    (unspec:XF [(match_dup 7) (match_dup 5)]
16338                               UNSPEC_FSCALE_FRACT))
16339                    (set (match_dup 9)
16340                    (unspec:XF [(match_dup 7) (match_dup 5)]
16341                               UNSPEC_FSCALE_EXP))])
16342    (parallel [(set (match_dup 11)
16343                    (unspec:XF [(match_dup 10) (match_dup 9)]
16344                               UNSPEC_FSCALE_FRACT))
16345               (set (match_dup 12)
16346                    (unspec:XF [(match_dup 10) (match_dup 9)]
16347                               UNSPEC_FSCALE_EXP))])
16348    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16349    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16350    (set (match_operand:DF 0 "register_operand" "")
16351         (float_truncate:DF (match_dup 14)))]
16352   "TARGET_USE_FANCY_MATH_387
16353    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16354    && flag_unsafe_math_optimizations"
16355 {
16356   rtx temp;
16357   int i;
16358
16359   for (i=2; i<15; i++)
16360     operands[i] = gen_reg_rtx (XFmode);
16361   temp = standard_80387_constant_rtx (5); /* fldl2e */
16362   emit_move_insn (operands[3], temp);
16363   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16364 })
16365
16366 (define_expand "expm1sf2"
16367   [(set (match_dup 2)
16368         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16369    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16370    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16371    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16372    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16373    (parallel [(set (match_dup 8)
16374                    (unspec:XF [(match_dup 7) (match_dup 5)]
16375                               UNSPEC_FSCALE_FRACT))
16376                    (set (match_dup 9)
16377                    (unspec:XF [(match_dup 7) (match_dup 5)]
16378                               UNSPEC_FSCALE_EXP))])
16379    (parallel [(set (match_dup 11)
16380                    (unspec:XF [(match_dup 10) (match_dup 9)]
16381                               UNSPEC_FSCALE_FRACT))
16382               (set (match_dup 12)
16383                    (unspec:XF [(match_dup 10) (match_dup 9)]
16384                               UNSPEC_FSCALE_EXP))])
16385    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16386    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16387    (set (match_operand:SF 0 "register_operand" "")
16388         (float_truncate:SF (match_dup 14)))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16391    && flag_unsafe_math_optimizations"
16392 {
16393   rtx temp;
16394   int i;
16395
16396   for (i=2; i<15; i++)
16397     operands[i] = gen_reg_rtx (XFmode);
16398   temp = standard_80387_constant_rtx (5); /* fldl2e */
16399   emit_move_insn (operands[3], temp);
16400   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16401 })
16402
16403 (define_expand "expm1xf2"
16404   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16405                                (match_dup 2)))
16406    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16407    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16408    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16409    (parallel [(set (match_dup 7)
16410                    (unspec:XF [(match_dup 6) (match_dup 4)]
16411                               UNSPEC_FSCALE_FRACT))
16412                    (set (match_dup 8)
16413                    (unspec:XF [(match_dup 6) (match_dup 4)]
16414                               UNSPEC_FSCALE_EXP))])
16415    (parallel [(set (match_dup 10)
16416                    (unspec:XF [(match_dup 9) (match_dup 8)]
16417                               UNSPEC_FSCALE_FRACT))
16418               (set (match_dup 11)
16419                    (unspec:XF [(match_dup 9) (match_dup 8)]
16420                               UNSPEC_FSCALE_EXP))])
16421    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16422    (set (match_operand:XF 0 "register_operand" "")
16423         (plus:XF (match_dup 12) (match_dup 7)))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && flag_unsafe_math_optimizations"
16426 {
16427   rtx temp;
16428   int i;
16429
16430   for (i=2; i<13; i++)
16431     operands[i] = gen_reg_rtx (XFmode);
16432   temp = standard_80387_constant_rtx (5); /* fldl2e */
16433   emit_move_insn (operands[2], temp);
16434   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16435 })
16436
16437 (define_expand "ldexpdf3"
16438   [(set (match_dup 3)
16439         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16440    (set (match_dup 4)
16441         (float:XF (match_operand:SI 2 "register_operand" "")))
16442    (parallel [(set (match_dup 5)
16443                    (unspec:XF [(match_dup 3) (match_dup 4)]
16444                               UNSPEC_FSCALE_FRACT))
16445               (set (match_dup 6)
16446                    (unspec:XF [(match_dup 3) (match_dup 4)]
16447                               UNSPEC_FSCALE_EXP))])
16448    (set (match_operand:DF 0 "register_operand" "")
16449         (float_truncate:DF (match_dup 5)))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16452    && flag_unsafe_math_optimizations"
16453 {
16454   int i;
16455
16456   for (i=3; i<7; i++)
16457     operands[i] = gen_reg_rtx (XFmode);
16458 })
16459
16460 (define_expand "ldexpsf3"
16461   [(set (match_dup 3)
16462         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16463    (set (match_dup 4)
16464         (float:XF (match_operand:SI 2 "register_operand" "")))
16465    (parallel [(set (match_dup 5)
16466                    (unspec:XF [(match_dup 3) (match_dup 4)]
16467                               UNSPEC_FSCALE_FRACT))
16468               (set (match_dup 6)
16469                    (unspec:XF [(match_dup 3) (match_dup 4)]
16470                               UNSPEC_FSCALE_EXP))])
16471    (set (match_operand:SF 0 "register_operand" "")
16472         (float_truncate:SF (match_dup 5)))]
16473   "TARGET_USE_FANCY_MATH_387
16474    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations"
16476 {
16477   int i;
16478
16479   for (i=3; i<7; i++)
16480     operands[i] = gen_reg_rtx (XFmode);
16481 })
16482
16483 (define_expand "ldexpxf3"
16484   [(set (match_dup 3)
16485         (float:XF (match_operand:SI 2 "register_operand" "")))
16486    (parallel [(set (match_operand:XF 0 " register_operand" "")
16487                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16488                                (match_dup 3)]
16489                               UNSPEC_FSCALE_FRACT))
16490               (set (match_dup 4)
16491                    (unspec:XF [(match_dup 1) (match_dup 3)]
16492                               UNSPEC_FSCALE_EXP))])]
16493   "TARGET_USE_FANCY_MATH_387
16494    && flag_unsafe_math_optimizations"
16495 {
16496   int i;
16497
16498   for (i=3; i<5; i++)
16499     operands[i] = gen_reg_rtx (XFmode);
16500 })
16501 \f
16502
16503 (define_insn "frndintxf2"
16504   [(set (match_operand:XF 0 "register_operand" "=f")
16505         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16506          UNSPEC_FRNDINT))]
16507   "TARGET_USE_FANCY_MATH_387
16508    && flag_unsafe_math_optimizations"
16509   "frndint"
16510   [(set_attr "type" "fpspc")
16511    (set_attr "mode" "XF")])
16512
16513 (define_expand "rintdf2"
16514   [(use (match_operand:DF 0 "register_operand" ""))
16515    (use (match_operand:DF 1 "register_operand" ""))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16518    && flag_unsafe_math_optimizations"
16519 {
16520   rtx op0 = gen_reg_rtx (XFmode);
16521   rtx op1 = gen_reg_rtx (XFmode);
16522
16523   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16524   emit_insn (gen_frndintxf2 (op0, op1));
16525
16526   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16527   DONE;
16528 })
16529
16530 (define_expand "rintsf2"
16531   [(use (match_operand:SF 0 "register_operand" ""))
16532    (use (match_operand:SF 1 "register_operand" ""))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16535    && flag_unsafe_math_optimizations"
16536 {
16537   rtx op0 = gen_reg_rtx (XFmode);
16538   rtx op1 = gen_reg_rtx (XFmode);
16539
16540   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16541   emit_insn (gen_frndintxf2 (op0, op1));
16542
16543   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16544   DONE;
16545 })
16546
16547 (define_expand "rintxf2"
16548   [(use (match_operand:XF 0 "register_operand" ""))
16549    (use (match_operand:XF 1 "register_operand" ""))]
16550   "TARGET_USE_FANCY_MATH_387
16551    && flag_unsafe_math_optimizations"
16552 {
16553   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16554   DONE;
16555 })
16556
16557 (define_insn_and_split "*fistdi2_1"
16558   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16559         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16560          UNSPEC_FIST))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && flag_unsafe_math_optimizations
16563    && !(reload_completed || reload_in_progress)"
16564   "#"
16565   "&& 1"
16566   [(const_int 0)]
16567 {
16568   if (memory_operand (operands[0], VOIDmode))
16569     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16570   else
16571     {
16572       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16573       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16574                                          operands[2]));
16575     }
16576   DONE;
16577 }
16578   [(set_attr "type" "fpspc")
16579    (set_attr "mode" "DI")])
16580
16581 (define_insn "fistdi2"
16582   [(set (match_operand:DI 0 "memory_operand" "=m")
16583         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16584          UNSPEC_FIST))
16585    (clobber (match_scratch:XF 2 "=&1f"))]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations"
16588   "* return output_fix_trunc (insn, operands, 0);"
16589   [(set_attr "type" "fpspc")
16590    (set_attr "mode" "DI")])
16591
16592 (define_insn "fistdi2_with_temp"
16593   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16594         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16595          UNSPEC_FIST))
16596    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16597    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && flag_unsafe_math_optimizations"
16600   "#"
16601   [(set_attr "type" "fpspc")
16602    (set_attr "mode" "DI")])
16603
16604 (define_split 
16605   [(set (match_operand:DI 0 "register_operand" "")
16606         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16607          UNSPEC_FIST))
16608    (clobber (match_operand:DI 2 "memory_operand" ""))
16609    (clobber (match_scratch 3 ""))]
16610   "reload_completed"
16611   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16612               (clobber (match_dup 3))])
16613    (set (match_dup 0) (match_dup 2))]
16614   "")
16615
16616 (define_split 
16617   [(set (match_operand:DI 0 "memory_operand" "")
16618         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16619          UNSPEC_FIST))
16620    (clobber (match_operand:DI 2 "memory_operand" ""))
16621    (clobber (match_scratch 3 ""))]
16622   "reload_completed"
16623   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16624               (clobber (match_dup 3))])]
16625   "")
16626
16627 (define_insn_and_split "*fist<mode>2_1"
16628   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16629         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16630          UNSPEC_FIST))]
16631   "TARGET_USE_FANCY_MATH_387
16632    && flag_unsafe_math_optimizations
16633    && !(reload_completed || reload_in_progress)"
16634   "#"
16635   "&& 1"
16636   [(const_int 0)]
16637 {
16638   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16639   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16640                                         operands[2]));
16641   DONE;
16642 }
16643   [(set_attr "type" "fpspc")
16644    (set_attr "mode" "<MODE>")])
16645
16646 (define_insn "fist<mode>2"
16647   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16648         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16649          UNSPEC_FIST))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && flag_unsafe_math_optimizations"
16652   "* return output_fix_trunc (insn, operands, 0);"
16653   [(set_attr "type" "fpspc")
16654    (set_attr "mode" "<MODE>")])
16655
16656 (define_insn "fist<mode>2_with_temp"
16657   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16658         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16659          UNSPEC_FIST))
16660    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && flag_unsafe_math_optimizations"
16663   "#"
16664   [(set_attr "type" "fpspc")
16665    (set_attr "mode" "<MODE>")])
16666
16667 (define_split 
16668   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16669         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16670          UNSPEC_FIST))
16671    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16672   "reload_completed"
16673   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16674                        UNSPEC_FIST))
16675    (set (match_dup 0) (match_dup 2))]
16676   "")
16677
16678 (define_split 
16679   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16681          UNSPEC_FIST))
16682    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16683   "reload_completed"
16684   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16685                        UNSPEC_FIST))]
16686   "")
16687
16688 (define_expand "lrint<mode>2"
16689   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16690         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16691          UNSPEC_FIST))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16694    && flag_unsafe_math_optimizations"
16695   "")
16696
16697 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16698 (define_insn_and_split "frndintxf2_floor"
16699   [(set (match_operand:XF 0 "register_operand" "=f")
16700         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16701          UNSPEC_FRNDINT_FLOOR))
16702    (clobber (reg:CC FLAGS_REG))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && flag_unsafe_math_optimizations
16705    && !(reload_completed || reload_in_progress)"
16706   "#"
16707   "&& 1"
16708   [(const_int 0)]
16709 {
16710   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16711
16712   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16713   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16714
16715   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16716                                         operands[2], operands[3]));
16717   DONE;
16718 }
16719   [(set_attr "type" "frndint")
16720    (set_attr "i387_cw" "floor")
16721    (set_attr "mode" "XF")])
16722
16723 (define_insn "frndintxf2_floor_i387"
16724   [(set (match_operand:XF 0 "register_operand" "=f")
16725         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16726          UNSPEC_FRNDINT_FLOOR))
16727    (use (match_operand:HI 2 "memory_operand" "m"))
16728    (use (match_operand:HI 3 "memory_operand" "m"))]
16729   "TARGET_USE_FANCY_MATH_387
16730    && flag_unsafe_math_optimizations"
16731   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16732   [(set_attr "type" "frndint")
16733    (set_attr "i387_cw" "floor")
16734    (set_attr "mode" "XF")])
16735
16736 (define_expand "floorxf2"
16737   [(use (match_operand:XF 0 "register_operand" ""))
16738    (use (match_operand:XF 1 "register_operand" ""))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && flag_unsafe_math_optimizations"
16741 {
16742   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16743   DONE;
16744 })
16745
16746 (define_expand "floordf2"
16747   [(use (match_operand:DF 0 "register_operand" ""))
16748    (use (match_operand:DF 1 "register_operand" ""))]
16749   "TARGET_USE_FANCY_MATH_387
16750    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16751    && flag_unsafe_math_optimizations"
16752 {
16753   rtx op0 = gen_reg_rtx (XFmode);
16754   rtx op1 = gen_reg_rtx (XFmode);
16755
16756   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16757   emit_insn (gen_frndintxf2_floor (op0, op1));
16758
16759   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16760   DONE;
16761 })
16762
16763 (define_expand "floorsf2"
16764   [(use (match_operand:SF 0 "register_operand" ""))
16765    (use (match_operand:SF 1 "register_operand" ""))]
16766   "TARGET_USE_FANCY_MATH_387
16767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16768    && flag_unsafe_math_optimizations"
16769 {
16770   rtx op0 = gen_reg_rtx (XFmode);
16771   rtx op1 = gen_reg_rtx (XFmode);
16772
16773   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16774   emit_insn (gen_frndintxf2_floor (op0, op1));
16775
16776   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16777   DONE;
16778 })
16779
16780 (define_insn_and_split "*fist<mode>2_floor_1"
16781   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16782         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16783          UNSPEC_FIST_FLOOR))
16784    (clobber (reg:CC FLAGS_REG))]
16785   "TARGET_USE_FANCY_MATH_387
16786    && flag_unsafe_math_optimizations
16787    && !(reload_completed || reload_in_progress)"
16788   "#"
16789   "&& 1"
16790   [(const_int 0)]
16791 {
16792   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16793
16794   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16795   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16796   if (memory_operand (operands[0], VOIDmode))
16797     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16798                                       operands[2], operands[3]));
16799   else
16800     {
16801       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16802       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16803                                                   operands[2], operands[3],
16804                                                   operands[4]));
16805     }
16806   DONE;
16807 }
16808   [(set_attr "type" "fistp")
16809    (set_attr "i387_cw" "floor")
16810    (set_attr "mode" "<MODE>")])
16811
16812 (define_insn "fistdi2_floor"
16813   [(set (match_operand:DI 0 "memory_operand" "=m")
16814         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16815          UNSPEC_FIST_FLOOR))
16816    (use (match_operand:HI 2 "memory_operand" "m"))
16817    (use (match_operand:HI 3 "memory_operand" "m"))
16818    (clobber (match_scratch:XF 4 "=&1f"))]
16819   "TARGET_USE_FANCY_MATH_387
16820    && flag_unsafe_math_optimizations"
16821   "* return output_fix_trunc (insn, operands, 0);"
16822   [(set_attr "type" "fistp")
16823    (set_attr "i387_cw" "floor")
16824    (set_attr "mode" "DI")])
16825
16826 (define_insn "fistdi2_floor_with_temp"
16827   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16828         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16829          UNSPEC_FIST_FLOOR))
16830    (use (match_operand:HI 2 "memory_operand" "m,m"))
16831    (use (match_operand:HI 3 "memory_operand" "m,m"))
16832    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16833    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16834   "TARGET_USE_FANCY_MATH_387
16835    && flag_unsafe_math_optimizations"
16836   "#"
16837   [(set_attr "type" "fistp")
16838    (set_attr "i387_cw" "floor")
16839    (set_attr "mode" "DI")])
16840
16841 (define_split 
16842   [(set (match_operand:DI 0 "register_operand" "")
16843         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16844          UNSPEC_FIST_FLOOR))
16845    (use (match_operand:HI 2 "memory_operand" ""))
16846    (use (match_operand:HI 3 "memory_operand" ""))
16847    (clobber (match_operand:DI 4 "memory_operand" ""))
16848    (clobber (match_scratch 5 ""))]
16849   "reload_completed"
16850   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16851               (use (match_dup 2))
16852               (use (match_dup 3))
16853               (clobber (match_dup 5))])
16854    (set (match_dup 0) (match_dup 4))]
16855   "")
16856
16857 (define_split 
16858   [(set (match_operand:DI 0 "memory_operand" "")
16859         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16860          UNSPEC_FIST_FLOOR))
16861    (use (match_operand:HI 2 "memory_operand" ""))
16862    (use (match_operand:HI 3 "memory_operand" ""))
16863    (clobber (match_operand:DI 4 "memory_operand" ""))
16864    (clobber (match_scratch 5 ""))]
16865   "reload_completed"
16866   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16867               (use (match_dup 2))
16868               (use (match_dup 3))
16869               (clobber (match_dup 5))])]
16870   "")
16871
16872 (define_insn "fist<mode>2_floor"
16873   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16874         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16875          UNSPEC_FIST_FLOOR))
16876    (use (match_operand:HI 2 "memory_operand" "m"))
16877    (use (match_operand:HI 3 "memory_operand" "m"))]
16878   "TARGET_USE_FANCY_MATH_387
16879    && flag_unsafe_math_optimizations"
16880   "* return output_fix_trunc (insn, operands, 0);"
16881   [(set_attr "type" "fistp")
16882    (set_attr "i387_cw" "floor")
16883    (set_attr "mode" "<MODE>")])
16884
16885 (define_insn "fist<mode>2_floor_with_temp"
16886   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16887         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16888          UNSPEC_FIST_FLOOR))
16889    (use (match_operand:HI 2 "memory_operand" "m,m"))
16890    (use (match_operand:HI 3 "memory_operand" "m,m"))
16891    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16892   "TARGET_USE_FANCY_MATH_387
16893    && flag_unsafe_math_optimizations"
16894   "#"
16895   [(set_attr "type" "fistp")
16896    (set_attr "i387_cw" "floor")
16897    (set_attr "mode" "<MODE>")])
16898
16899 (define_split 
16900   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16901         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16902          UNSPEC_FIST_FLOOR))
16903    (use (match_operand:HI 2 "memory_operand" ""))
16904    (use (match_operand:HI 3 "memory_operand" ""))
16905    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16906   "reload_completed"
16907   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16908                                   UNSPEC_FIST_FLOOR))
16909               (use (match_dup 2))
16910               (use (match_dup 3))])
16911    (set (match_dup 0) (match_dup 4))]
16912   "")
16913
16914 (define_split 
16915   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16916         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16917          UNSPEC_FIST_FLOOR))
16918    (use (match_operand:HI 2 "memory_operand" ""))
16919    (use (match_operand:HI 3 "memory_operand" ""))
16920    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16921   "reload_completed"
16922   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16923                                   UNSPEC_FIST_FLOOR))
16924               (use (match_dup 2))
16925               (use (match_dup 3))])]
16926   "")
16927
16928 (define_expand "lfloor<mode>2"
16929   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16930                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16931                     UNSPEC_FIST_FLOOR))
16932               (clobber (reg:CC FLAGS_REG))])]
16933   "TARGET_USE_FANCY_MATH_387
16934    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16935    && flag_unsafe_math_optimizations"
16936   "")
16937
16938 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16939 (define_insn_and_split "frndintxf2_ceil"
16940   [(set (match_operand:XF 0 "register_operand" "=f")
16941         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16942          UNSPEC_FRNDINT_CEIL))
16943    (clobber (reg:CC FLAGS_REG))]
16944   "TARGET_USE_FANCY_MATH_387
16945    && flag_unsafe_math_optimizations
16946    && !(reload_completed || reload_in_progress)"
16947   "#"
16948   "&& 1"
16949   [(const_int 0)]
16950 {
16951   ix86_optimize_mode_switching[I387_CEIL] = 1;
16952
16953   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16954   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16955
16956   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16957                                        operands[2], operands[3]));
16958   DONE;
16959 }
16960   [(set_attr "type" "frndint")
16961    (set_attr "i387_cw" "ceil")
16962    (set_attr "mode" "XF")])
16963
16964 (define_insn "frndintxf2_ceil_i387"
16965   [(set (match_operand:XF 0 "register_operand" "=f")
16966         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16967          UNSPEC_FRNDINT_CEIL))
16968    (use (match_operand:HI 2 "memory_operand" "m"))
16969    (use (match_operand:HI 3 "memory_operand" "m"))]
16970   "TARGET_USE_FANCY_MATH_387
16971    && flag_unsafe_math_optimizations"
16972   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16973   [(set_attr "type" "frndint")
16974    (set_attr "i387_cw" "ceil")
16975    (set_attr "mode" "XF")])
16976
16977 (define_expand "ceilxf2"
16978   [(use (match_operand:XF 0 "register_operand" ""))
16979    (use (match_operand:XF 1 "register_operand" ""))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && flag_unsafe_math_optimizations"
16982 {
16983   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16984   DONE;
16985 })
16986
16987 (define_expand "ceildf2"
16988   [(use (match_operand:DF 0 "register_operand" ""))
16989    (use (match_operand:DF 1 "register_operand" ""))]
16990   "TARGET_USE_FANCY_MATH_387
16991    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16992    && flag_unsafe_math_optimizations"
16993 {
16994   rtx op0 = gen_reg_rtx (XFmode);
16995   rtx op1 = gen_reg_rtx (XFmode);
16996
16997   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16998   emit_insn (gen_frndintxf2_ceil (op0, op1));
16999
17000   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17001   DONE;
17002 })
17003
17004 (define_expand "ceilsf2"
17005   [(use (match_operand:SF 0 "register_operand" ""))
17006    (use (match_operand:SF 1 "register_operand" ""))]
17007   "TARGET_USE_FANCY_MATH_387
17008    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17009    && flag_unsafe_math_optimizations"
17010 {
17011   rtx op0 = gen_reg_rtx (XFmode);
17012   rtx op1 = gen_reg_rtx (XFmode);
17013
17014   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17015   emit_insn (gen_frndintxf2_ceil (op0, op1));
17016
17017   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17018   DONE;
17019 })
17020
17021 (define_insn_and_split "*fist<mode>2_ceil_1"
17022   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17023         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17024          UNSPEC_FIST_CEIL))
17025    (clobber (reg:CC FLAGS_REG))]
17026   "TARGET_USE_FANCY_MATH_387
17027    && flag_unsafe_math_optimizations
17028    && !(reload_completed || reload_in_progress)"
17029   "#"
17030   "&& 1"
17031   [(const_int 0)]
17032 {
17033   ix86_optimize_mode_switching[I387_CEIL] = 1;
17034
17035   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17036   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17037   if (memory_operand (operands[0], VOIDmode))
17038     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17039                                      operands[2], operands[3]));
17040   else
17041     {
17042       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17043       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17044                                                  operands[2], operands[3],
17045                                                  operands[4]));
17046     }
17047   DONE;
17048 }
17049   [(set_attr "type" "fistp")
17050    (set_attr "i387_cw" "ceil")
17051    (set_attr "mode" "<MODE>")])
17052
17053 (define_insn "fistdi2_ceil"
17054   [(set (match_operand:DI 0 "memory_operand" "=m")
17055         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17056          UNSPEC_FIST_CEIL))
17057    (use (match_operand:HI 2 "memory_operand" "m"))
17058    (use (match_operand:HI 3 "memory_operand" "m"))
17059    (clobber (match_scratch:XF 4 "=&1f"))]
17060   "TARGET_USE_FANCY_MATH_387
17061    && flag_unsafe_math_optimizations"
17062   "* return output_fix_trunc (insn, operands, 0);"
17063   [(set_attr "type" "fistp")
17064    (set_attr "i387_cw" "ceil")
17065    (set_attr "mode" "DI")])
17066
17067 (define_insn "fistdi2_ceil_with_temp"
17068   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17069         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17070          UNSPEC_FIST_CEIL))
17071    (use (match_operand:HI 2 "memory_operand" "m,m"))
17072    (use (match_operand:HI 3 "memory_operand" "m,m"))
17073    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17074    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17075   "TARGET_USE_FANCY_MATH_387
17076    && flag_unsafe_math_optimizations"
17077   "#"
17078   [(set_attr "type" "fistp")
17079    (set_attr "i387_cw" "ceil")
17080    (set_attr "mode" "DI")])
17081
17082 (define_split 
17083   [(set (match_operand:DI 0 "register_operand" "")
17084         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17085          UNSPEC_FIST_CEIL))
17086    (use (match_operand:HI 2 "memory_operand" ""))
17087    (use (match_operand:HI 3 "memory_operand" ""))
17088    (clobber (match_operand:DI 4 "memory_operand" ""))
17089    (clobber (match_scratch 5 ""))]
17090   "reload_completed"
17091   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17092               (use (match_dup 2))
17093               (use (match_dup 3))
17094               (clobber (match_dup 5))])
17095    (set (match_dup 0) (match_dup 4))]
17096   "")
17097
17098 (define_split 
17099   [(set (match_operand:DI 0 "memory_operand" "")
17100         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17101          UNSPEC_FIST_CEIL))
17102    (use (match_operand:HI 2 "memory_operand" ""))
17103    (use (match_operand:HI 3 "memory_operand" ""))
17104    (clobber (match_operand:DI 4 "memory_operand" ""))
17105    (clobber (match_scratch 5 ""))]
17106   "reload_completed"
17107   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17108               (use (match_dup 2))
17109               (use (match_dup 3))
17110               (clobber (match_dup 5))])]
17111   "")
17112
17113 (define_insn "fist<mode>2_ceil"
17114   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17115         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17116          UNSPEC_FIST_CEIL))
17117    (use (match_operand:HI 2 "memory_operand" "m"))
17118    (use (match_operand:HI 3 "memory_operand" "m"))]
17119   "TARGET_USE_FANCY_MATH_387
17120    && flag_unsafe_math_optimizations"
17121   "* return output_fix_trunc (insn, operands, 0);"
17122   [(set_attr "type" "fistp")
17123    (set_attr "i387_cw" "ceil")
17124    (set_attr "mode" "<MODE>")])
17125
17126 (define_insn "fist<mode>2_ceil_with_temp"
17127   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17128         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17129          UNSPEC_FIST_CEIL))
17130    (use (match_operand:HI 2 "memory_operand" "m,m"))
17131    (use (match_operand:HI 3 "memory_operand" "m,m"))
17132    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations"
17135   "#"
17136   [(set_attr "type" "fistp")
17137    (set_attr "i387_cw" "ceil")
17138    (set_attr "mode" "<MODE>")])
17139
17140 (define_split 
17141   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17142         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17143          UNSPEC_FIST_CEIL))
17144    (use (match_operand:HI 2 "memory_operand" ""))
17145    (use (match_operand:HI 3 "memory_operand" ""))
17146    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17147   "reload_completed"
17148   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17149                                   UNSPEC_FIST_CEIL))
17150               (use (match_dup 2))
17151               (use (match_dup 3))])
17152    (set (match_dup 0) (match_dup 4))]
17153   "")
17154
17155 (define_split 
17156   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17157         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17158          UNSPEC_FIST_CEIL))
17159    (use (match_operand:HI 2 "memory_operand" ""))
17160    (use (match_operand:HI 3 "memory_operand" ""))
17161    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17162   "reload_completed"
17163   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17164                                   UNSPEC_FIST_CEIL))
17165               (use (match_dup 2))
17166               (use (match_dup 3))])]
17167   "")
17168
17169 (define_expand "lceil<mode>2"
17170   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17171                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17172                     UNSPEC_FIST_CEIL))
17173               (clobber (reg:CC FLAGS_REG))])]
17174   "TARGET_USE_FANCY_MATH_387
17175    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17176    && flag_unsafe_math_optimizations"
17177   "")
17178
17179 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17180 (define_insn_and_split "frndintxf2_trunc"
17181   [(set (match_operand:XF 0 "register_operand" "=f")
17182         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17183          UNSPEC_FRNDINT_TRUNC))
17184    (clobber (reg:CC FLAGS_REG))]
17185   "TARGET_USE_FANCY_MATH_387
17186    && flag_unsafe_math_optimizations
17187    && !(reload_completed || reload_in_progress)"
17188   "#"
17189   "&& 1"
17190   [(const_int 0)]
17191 {
17192   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17193
17194   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17195   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17196
17197   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17198                                         operands[2], operands[3]));
17199   DONE;
17200 }
17201   [(set_attr "type" "frndint")
17202    (set_attr "i387_cw" "trunc")
17203    (set_attr "mode" "XF")])
17204
17205 (define_insn "frndintxf2_trunc_i387"
17206   [(set (match_operand:XF 0 "register_operand" "=f")
17207         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17208          UNSPEC_FRNDINT_TRUNC))
17209    (use (match_operand:HI 2 "memory_operand" "m"))
17210    (use (match_operand:HI 3 "memory_operand" "m"))]
17211   "TARGET_USE_FANCY_MATH_387
17212    && flag_unsafe_math_optimizations"
17213   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17214   [(set_attr "type" "frndint")
17215    (set_attr "i387_cw" "trunc")
17216    (set_attr "mode" "XF")])
17217
17218 (define_expand "btruncxf2"
17219   [(use (match_operand:XF 0 "register_operand" ""))
17220    (use (match_operand:XF 1 "register_operand" ""))]
17221   "TARGET_USE_FANCY_MATH_387
17222    && flag_unsafe_math_optimizations"
17223 {
17224   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17225   DONE;
17226 })
17227
17228 (define_expand "btruncdf2"
17229   [(use (match_operand:DF 0 "register_operand" ""))
17230    (use (match_operand:DF 1 "register_operand" ""))]
17231   "TARGET_USE_FANCY_MATH_387
17232    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17233    && flag_unsafe_math_optimizations"
17234 {
17235   rtx op0 = gen_reg_rtx (XFmode);
17236   rtx op1 = gen_reg_rtx (XFmode);
17237
17238   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17239   emit_insn (gen_frndintxf2_trunc (op0, op1));
17240
17241   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17242   DONE;
17243 })
17244
17245 (define_expand "btruncsf2"
17246   [(use (match_operand:SF 0 "register_operand" ""))
17247    (use (match_operand:SF 1 "register_operand" ""))]
17248   "TARGET_USE_FANCY_MATH_387
17249    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17250    && flag_unsafe_math_optimizations"
17251 {
17252   rtx op0 = gen_reg_rtx (XFmode);
17253   rtx op1 = gen_reg_rtx (XFmode);
17254
17255   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17256   emit_insn (gen_frndintxf2_trunc (op0, op1));
17257
17258   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17259   DONE;
17260 })
17261
17262 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17263 (define_insn_and_split "frndintxf2_mask_pm"
17264   [(set (match_operand:XF 0 "register_operand" "=f")
17265         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17266          UNSPEC_FRNDINT_MASK_PM))
17267    (clobber (reg:CC FLAGS_REG))]
17268   "TARGET_USE_FANCY_MATH_387
17269    && flag_unsafe_math_optimizations
17270    && !(reload_completed || reload_in_progress)"
17271   "#"
17272   "&& 1"
17273   [(const_int 0)]
17274 {
17275   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17276
17277   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17278   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17279
17280   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17281                                           operands[2], operands[3]));
17282   DONE;
17283 }
17284   [(set_attr "type" "frndint")
17285    (set_attr "i387_cw" "mask_pm")
17286    (set_attr "mode" "XF")])
17287
17288 (define_insn "frndintxf2_mask_pm_i387"
17289   [(set (match_operand:XF 0 "register_operand" "=f")
17290         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17291          UNSPEC_FRNDINT_MASK_PM))
17292    (use (match_operand:HI 2 "memory_operand" "m"))
17293    (use (match_operand:HI 3 "memory_operand" "m"))]
17294   "TARGET_USE_FANCY_MATH_387
17295    && flag_unsafe_math_optimizations"
17296   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17297   [(set_attr "type" "frndint")
17298    (set_attr "i387_cw" "mask_pm")
17299    (set_attr "mode" "XF")])
17300
17301 (define_expand "nearbyintxf2"
17302   [(use (match_operand:XF 0 "register_operand" ""))
17303    (use (match_operand:XF 1 "register_operand" ""))]
17304   "TARGET_USE_FANCY_MATH_387
17305    && flag_unsafe_math_optimizations"
17306 {
17307   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17308
17309   DONE;
17310 })
17311
17312 (define_expand "nearbyintdf2"
17313   [(use (match_operand:DF 0 "register_operand" ""))
17314    (use (match_operand:DF 1 "register_operand" ""))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17317    && flag_unsafe_math_optimizations"
17318 {
17319   rtx op0 = gen_reg_rtx (XFmode);
17320   rtx op1 = gen_reg_rtx (XFmode);
17321
17322   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17323   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17324
17325   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17326   DONE;
17327 })
17328
17329 (define_expand "nearbyintsf2"
17330   [(use (match_operand:SF 0 "register_operand" ""))
17331    (use (match_operand:SF 1 "register_operand" ""))]
17332   "TARGET_USE_FANCY_MATH_387
17333    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334    && flag_unsafe_math_optimizations"
17335 {
17336   rtx op0 = gen_reg_rtx (XFmode);
17337   rtx op1 = gen_reg_rtx (XFmode);
17338
17339   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17340   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17341
17342   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17343   DONE;
17344 })
17345
17346 \f
17347 ;; Block operation instructions
17348
17349 (define_insn "cld"
17350  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17351  ""
17352  "cld"
17353   [(set_attr "type" "cld")])
17354
17355 (define_expand "movmemsi"
17356   [(use (match_operand:BLK 0 "memory_operand" ""))
17357    (use (match_operand:BLK 1 "memory_operand" ""))
17358    (use (match_operand:SI 2 "nonmemory_operand" ""))
17359    (use (match_operand:SI 3 "const_int_operand" ""))]
17360   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17361 {
17362  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17363    DONE;
17364  else
17365    FAIL;
17366 })
17367
17368 (define_expand "movmemdi"
17369   [(use (match_operand:BLK 0 "memory_operand" ""))
17370    (use (match_operand:BLK 1 "memory_operand" ""))
17371    (use (match_operand:DI 2 "nonmemory_operand" ""))
17372    (use (match_operand:DI 3 "const_int_operand" ""))]
17373   "TARGET_64BIT"
17374 {
17375  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17376    DONE;
17377  else
17378    FAIL;
17379 })
17380
17381 ;; Most CPUs don't like single string operations
17382 ;; Handle this case here to simplify previous expander.
17383
17384 (define_expand "strmov"
17385   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17386    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17387    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17388               (clobber (reg:CC FLAGS_REG))])
17389    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17390               (clobber (reg:CC FLAGS_REG))])]
17391   ""
17392 {
17393   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17394
17395   /* If .md ever supports :P for Pmode, these can be directly
17396      in the pattern above.  */
17397   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17398   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17399
17400   if (TARGET_SINGLE_STRINGOP || optimize_size)
17401     {
17402       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17403                                       operands[2], operands[3],
17404                                       operands[5], operands[6]));
17405       DONE;
17406     }
17407
17408   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17409 })
17410
17411 (define_expand "strmov_singleop"
17412   [(parallel [(set (match_operand 1 "memory_operand" "")
17413                    (match_operand 3 "memory_operand" ""))
17414               (set (match_operand 0 "register_operand" "")
17415                    (match_operand 4 "" ""))
17416               (set (match_operand 2 "register_operand" "")
17417                    (match_operand 5 "" ""))
17418               (use (reg:SI DIRFLAG_REG))])]
17419   "TARGET_SINGLE_STRINGOP || optimize_size"
17420   "")
17421
17422 (define_insn "*strmovdi_rex_1"
17423   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17424         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17425    (set (match_operand:DI 0 "register_operand" "=D")
17426         (plus:DI (match_dup 2)
17427                  (const_int 8)))
17428    (set (match_operand:DI 1 "register_operand" "=S")
17429         (plus:DI (match_dup 3)
17430                  (const_int 8)))
17431    (use (reg:SI DIRFLAG_REG))]
17432   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17433   "movsq"
17434   [(set_attr "type" "str")
17435    (set_attr "mode" "DI")
17436    (set_attr "memory" "both")])
17437
17438 (define_insn "*strmovsi_1"
17439   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17440         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17441    (set (match_operand:SI 0 "register_operand" "=D")
17442         (plus:SI (match_dup 2)
17443                  (const_int 4)))
17444    (set (match_operand:SI 1 "register_operand" "=S")
17445         (plus:SI (match_dup 3)
17446                  (const_int 4)))
17447    (use (reg:SI DIRFLAG_REG))]
17448   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17449   "{movsl|movsd}"
17450   [(set_attr "type" "str")
17451    (set_attr "mode" "SI")
17452    (set_attr "memory" "both")])
17453
17454 (define_insn "*strmovsi_rex_1"
17455   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17456         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17457    (set (match_operand:DI 0 "register_operand" "=D")
17458         (plus:DI (match_dup 2)
17459                  (const_int 4)))
17460    (set (match_operand:DI 1 "register_operand" "=S")
17461         (plus:DI (match_dup 3)
17462                  (const_int 4)))
17463    (use (reg:SI DIRFLAG_REG))]
17464   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17465   "{movsl|movsd}"
17466   [(set_attr "type" "str")
17467    (set_attr "mode" "SI")
17468    (set_attr "memory" "both")])
17469
17470 (define_insn "*strmovhi_1"
17471   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17472         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17473    (set (match_operand:SI 0 "register_operand" "=D")
17474         (plus:SI (match_dup 2)
17475                  (const_int 2)))
17476    (set (match_operand:SI 1 "register_operand" "=S")
17477         (plus:SI (match_dup 3)
17478                  (const_int 2)))
17479    (use (reg:SI DIRFLAG_REG))]
17480   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17481   "movsw"
17482   [(set_attr "type" "str")
17483    (set_attr "memory" "both")
17484    (set_attr "mode" "HI")])
17485
17486 (define_insn "*strmovhi_rex_1"
17487   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17488         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17489    (set (match_operand:DI 0 "register_operand" "=D")
17490         (plus:DI (match_dup 2)
17491                  (const_int 2)))
17492    (set (match_operand:DI 1 "register_operand" "=S")
17493         (plus:DI (match_dup 3)
17494                  (const_int 2)))
17495    (use (reg:SI DIRFLAG_REG))]
17496   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17497   "movsw"
17498   [(set_attr "type" "str")
17499    (set_attr "memory" "both")
17500    (set_attr "mode" "HI")])
17501
17502 (define_insn "*strmovqi_1"
17503   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17504         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17505    (set (match_operand:SI 0 "register_operand" "=D")
17506         (plus:SI (match_dup 2)
17507                  (const_int 1)))
17508    (set (match_operand:SI 1 "register_operand" "=S")
17509         (plus:SI (match_dup 3)
17510                  (const_int 1)))
17511    (use (reg:SI DIRFLAG_REG))]
17512   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17513   "movsb"
17514   [(set_attr "type" "str")
17515    (set_attr "memory" "both")
17516    (set_attr "mode" "QI")])
17517
17518 (define_insn "*strmovqi_rex_1"
17519   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17520         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17521    (set (match_operand:DI 0 "register_operand" "=D")
17522         (plus:DI (match_dup 2)
17523                  (const_int 1)))
17524    (set (match_operand:DI 1 "register_operand" "=S")
17525         (plus:DI (match_dup 3)
17526                  (const_int 1)))
17527    (use (reg:SI DIRFLAG_REG))]
17528   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17529   "movsb"
17530   [(set_attr "type" "str")
17531    (set_attr "memory" "both")
17532    (set_attr "mode" "QI")])
17533
17534 (define_expand "rep_mov"
17535   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17536               (set (match_operand 0 "register_operand" "")
17537                    (match_operand 5 "" ""))
17538               (set (match_operand 2 "register_operand" "")
17539                    (match_operand 6 "" ""))
17540               (set (match_operand 1 "memory_operand" "")
17541                    (match_operand 3 "memory_operand" ""))
17542               (use (match_dup 4))
17543               (use (reg:SI DIRFLAG_REG))])]
17544   ""
17545   "")
17546
17547 (define_insn "*rep_movdi_rex64"
17548   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17549    (set (match_operand:DI 0 "register_operand" "=D") 
17550         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17551                             (const_int 3))
17552                  (match_operand:DI 3 "register_operand" "0")))
17553    (set (match_operand:DI 1 "register_operand" "=S") 
17554         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17555                  (match_operand:DI 4 "register_operand" "1")))
17556    (set (mem:BLK (match_dup 3))
17557         (mem:BLK (match_dup 4)))
17558    (use (match_dup 5))
17559    (use (reg:SI DIRFLAG_REG))]
17560   "TARGET_64BIT"
17561   "{rep\;movsq|rep movsq}"
17562   [(set_attr "type" "str")
17563    (set_attr "prefix_rep" "1")
17564    (set_attr "memory" "both")
17565    (set_attr "mode" "DI")])
17566
17567 (define_insn "*rep_movsi"
17568   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17569    (set (match_operand:SI 0 "register_operand" "=D") 
17570         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17571                             (const_int 2))
17572                  (match_operand:SI 3 "register_operand" "0")))
17573    (set (match_operand:SI 1 "register_operand" "=S") 
17574         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17575                  (match_operand:SI 4 "register_operand" "1")))
17576    (set (mem:BLK (match_dup 3))
17577         (mem:BLK (match_dup 4)))
17578    (use (match_dup 5))
17579    (use (reg:SI DIRFLAG_REG))]
17580   "!TARGET_64BIT"
17581   "{rep\;movsl|rep movsd}"
17582   [(set_attr "type" "str")
17583    (set_attr "prefix_rep" "1")
17584    (set_attr "memory" "both")
17585    (set_attr "mode" "SI")])
17586
17587 (define_insn "*rep_movsi_rex64"
17588   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17589    (set (match_operand:DI 0 "register_operand" "=D") 
17590         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17591                             (const_int 2))
17592                  (match_operand:DI 3 "register_operand" "0")))
17593    (set (match_operand:DI 1 "register_operand" "=S") 
17594         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17595                  (match_operand:DI 4 "register_operand" "1")))
17596    (set (mem:BLK (match_dup 3))
17597         (mem:BLK (match_dup 4)))
17598    (use (match_dup 5))
17599    (use (reg:SI DIRFLAG_REG))]
17600   "TARGET_64BIT"
17601   "{rep\;movsl|rep movsd}"
17602   [(set_attr "type" "str")
17603    (set_attr "prefix_rep" "1")
17604    (set_attr "memory" "both")
17605    (set_attr "mode" "SI")])
17606
17607 (define_insn "*rep_movqi"
17608   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17609    (set (match_operand:SI 0 "register_operand" "=D") 
17610         (plus:SI (match_operand:SI 3 "register_operand" "0")
17611                  (match_operand:SI 5 "register_operand" "2")))
17612    (set (match_operand:SI 1 "register_operand" "=S") 
17613         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17614    (set (mem:BLK (match_dup 3))
17615         (mem:BLK (match_dup 4)))
17616    (use (match_dup 5))
17617    (use (reg:SI DIRFLAG_REG))]
17618   "!TARGET_64BIT"
17619   "{rep\;movsb|rep movsb}"
17620   [(set_attr "type" "str")
17621    (set_attr "prefix_rep" "1")
17622    (set_attr "memory" "both")
17623    (set_attr "mode" "SI")])
17624
17625 (define_insn "*rep_movqi_rex64"
17626   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17627    (set (match_operand:DI 0 "register_operand" "=D") 
17628         (plus:DI (match_operand:DI 3 "register_operand" "0")
17629                  (match_operand:DI 5 "register_operand" "2")))
17630    (set (match_operand:DI 1 "register_operand" "=S") 
17631         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17632    (set (mem:BLK (match_dup 3))
17633         (mem:BLK (match_dup 4)))
17634    (use (match_dup 5))
17635    (use (reg:SI DIRFLAG_REG))]
17636   "TARGET_64BIT"
17637   "{rep\;movsb|rep movsb}"
17638   [(set_attr "type" "str")
17639    (set_attr "prefix_rep" "1")
17640    (set_attr "memory" "both")
17641    (set_attr "mode" "SI")])
17642
17643 (define_expand "setmemsi"
17644    [(use (match_operand:BLK 0 "memory_operand" ""))
17645     (use (match_operand:SI 1 "nonmemory_operand" ""))
17646     (use (match_operand 2 "const_int_operand" ""))
17647     (use (match_operand 3 "const_int_operand" ""))]
17648   ""
17649 {
17650  /* If value to set is not zero, use the library routine.  */
17651  if (operands[2] != const0_rtx)
17652    FAIL;
17653
17654  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17655    DONE;
17656  else
17657    FAIL;
17658 })
17659
17660 (define_expand "setmemdi"
17661    [(use (match_operand:BLK 0 "memory_operand" ""))
17662     (use (match_operand:DI 1 "nonmemory_operand" ""))
17663     (use (match_operand 2 "const_int_operand" ""))
17664     (use (match_operand 3 "const_int_operand" ""))]
17665   "TARGET_64BIT"
17666 {
17667  /* If value to set is not zero, use the library routine.  */
17668  if (operands[2] != const0_rtx)
17669    FAIL;
17670
17671  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17672    DONE;
17673  else
17674    FAIL;
17675 })
17676
17677 ;; Most CPUs don't like single string operations
17678 ;; Handle this case here to simplify previous expander.
17679
17680 (define_expand "strset"
17681   [(set (match_operand 1 "memory_operand" "")
17682         (match_operand 2 "register_operand" ""))
17683    (parallel [(set (match_operand 0 "register_operand" "")
17684                    (match_dup 3))
17685               (clobber (reg:CC FLAGS_REG))])]
17686   ""
17687 {
17688   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17689     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17690
17691   /* If .md ever supports :P for Pmode, this can be directly
17692      in the pattern above.  */
17693   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17694                               GEN_INT (GET_MODE_SIZE (GET_MODE
17695                                                       (operands[2]))));
17696   if (TARGET_SINGLE_STRINGOP || optimize_size)
17697     {
17698       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17699                                       operands[3]));
17700       DONE;
17701     }
17702 })
17703
17704 (define_expand "strset_singleop"
17705   [(parallel [(set (match_operand 1 "memory_operand" "")
17706                    (match_operand 2 "register_operand" ""))
17707               (set (match_operand 0 "register_operand" "")
17708                    (match_operand 3 "" ""))
17709               (use (reg:SI DIRFLAG_REG))])]
17710   "TARGET_SINGLE_STRINGOP || optimize_size"
17711   "")
17712
17713 (define_insn "*strsetdi_rex_1"
17714   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17715         (match_operand:DI 2 "register_operand" "a"))
17716    (set (match_operand:DI 0 "register_operand" "=D")
17717         (plus:DI (match_dup 1)
17718                  (const_int 8)))
17719    (use (reg:SI DIRFLAG_REG))]
17720   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17721   "stosq"
17722   [(set_attr "type" "str")
17723    (set_attr "memory" "store")
17724    (set_attr "mode" "DI")])
17725
17726 (define_insn "*strsetsi_1"
17727   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17728         (match_operand:SI 2 "register_operand" "a"))
17729    (set (match_operand:SI 0 "register_operand" "=D")
17730         (plus:SI (match_dup 1)
17731                  (const_int 4)))
17732    (use (reg:SI DIRFLAG_REG))]
17733   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17734   "{stosl|stosd}"
17735   [(set_attr "type" "str")
17736    (set_attr "memory" "store")
17737    (set_attr "mode" "SI")])
17738
17739 (define_insn "*strsetsi_rex_1"
17740   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17741         (match_operand:SI 2 "register_operand" "a"))
17742    (set (match_operand:DI 0 "register_operand" "=D")
17743         (plus:DI (match_dup 1)
17744                  (const_int 4)))
17745    (use (reg:SI DIRFLAG_REG))]
17746   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17747   "{stosl|stosd}"
17748   [(set_attr "type" "str")
17749    (set_attr "memory" "store")
17750    (set_attr "mode" "SI")])
17751
17752 (define_insn "*strsethi_1"
17753   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17754         (match_operand:HI 2 "register_operand" "a"))
17755    (set (match_operand:SI 0 "register_operand" "=D")
17756         (plus:SI (match_dup 1)
17757                  (const_int 2)))
17758    (use (reg:SI DIRFLAG_REG))]
17759   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17760   "stosw"
17761   [(set_attr "type" "str")
17762    (set_attr "memory" "store")
17763    (set_attr "mode" "HI")])
17764
17765 (define_insn "*strsethi_rex_1"
17766   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17767         (match_operand:HI 2 "register_operand" "a"))
17768    (set (match_operand:DI 0 "register_operand" "=D")
17769         (plus:DI (match_dup 1)
17770                  (const_int 2)))
17771    (use (reg:SI DIRFLAG_REG))]
17772   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17773   "stosw"
17774   [(set_attr "type" "str")
17775    (set_attr "memory" "store")
17776    (set_attr "mode" "HI")])
17777
17778 (define_insn "*strsetqi_1"
17779   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17780         (match_operand:QI 2 "register_operand" "a"))
17781    (set (match_operand:SI 0 "register_operand" "=D")
17782         (plus:SI (match_dup 1)
17783                  (const_int 1)))
17784    (use (reg:SI DIRFLAG_REG))]
17785   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17786   "stosb"
17787   [(set_attr "type" "str")
17788    (set_attr "memory" "store")
17789    (set_attr "mode" "QI")])
17790
17791 (define_insn "*strsetqi_rex_1"
17792   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17793         (match_operand:QI 2 "register_operand" "a"))
17794    (set (match_operand:DI 0 "register_operand" "=D")
17795         (plus:DI (match_dup 1)
17796                  (const_int 1)))
17797    (use (reg:SI DIRFLAG_REG))]
17798   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17799   "stosb"
17800   [(set_attr "type" "str")
17801    (set_attr "memory" "store")
17802    (set_attr "mode" "QI")])
17803
17804 (define_expand "rep_stos"
17805   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17806               (set (match_operand 0 "register_operand" "")
17807                    (match_operand 4 "" ""))
17808               (set (match_operand 2 "memory_operand" "") (const_int 0))
17809               (use (match_operand 3 "register_operand" ""))
17810               (use (match_dup 1))
17811               (use (reg:SI DIRFLAG_REG))])]
17812   ""
17813   "")
17814
17815 (define_insn "*rep_stosdi_rex64"
17816   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17817    (set (match_operand:DI 0 "register_operand" "=D") 
17818         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17819                             (const_int 3))
17820                  (match_operand:DI 3 "register_operand" "0")))
17821    (set (mem:BLK (match_dup 3))
17822         (const_int 0))
17823    (use (match_operand:DI 2 "register_operand" "a"))
17824    (use (match_dup 4))
17825    (use (reg:SI DIRFLAG_REG))]
17826   "TARGET_64BIT"
17827   "{rep\;stosq|rep stosq}"
17828   [(set_attr "type" "str")
17829    (set_attr "prefix_rep" "1")
17830    (set_attr "memory" "store")
17831    (set_attr "mode" "DI")])
17832
17833 (define_insn "*rep_stossi"
17834   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17835    (set (match_operand:SI 0 "register_operand" "=D") 
17836         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17837                             (const_int 2))
17838                  (match_operand:SI 3 "register_operand" "0")))
17839    (set (mem:BLK (match_dup 3))
17840         (const_int 0))
17841    (use (match_operand:SI 2 "register_operand" "a"))
17842    (use (match_dup 4))
17843    (use (reg:SI DIRFLAG_REG))]
17844   "!TARGET_64BIT"
17845   "{rep\;stosl|rep stosd}"
17846   [(set_attr "type" "str")
17847    (set_attr "prefix_rep" "1")
17848    (set_attr "memory" "store")
17849    (set_attr "mode" "SI")])
17850
17851 (define_insn "*rep_stossi_rex64"
17852   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17853    (set (match_operand:DI 0 "register_operand" "=D") 
17854         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17855                             (const_int 2))
17856                  (match_operand:DI 3 "register_operand" "0")))
17857    (set (mem:BLK (match_dup 3))
17858         (const_int 0))
17859    (use (match_operand:SI 2 "register_operand" "a"))
17860    (use (match_dup 4))
17861    (use (reg:SI DIRFLAG_REG))]
17862   "TARGET_64BIT"
17863   "{rep\;stosl|rep stosd}"
17864   [(set_attr "type" "str")
17865    (set_attr "prefix_rep" "1")
17866    (set_attr "memory" "store")
17867    (set_attr "mode" "SI")])
17868
17869 (define_insn "*rep_stosqi"
17870   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17871    (set (match_operand:SI 0 "register_operand" "=D") 
17872         (plus:SI (match_operand:SI 3 "register_operand" "0")
17873                  (match_operand:SI 4 "register_operand" "1")))
17874    (set (mem:BLK (match_dup 3))
17875         (const_int 0))
17876    (use (match_operand:QI 2 "register_operand" "a"))
17877    (use (match_dup 4))
17878    (use (reg:SI DIRFLAG_REG))]
17879   "!TARGET_64BIT"
17880   "{rep\;stosb|rep stosb}"
17881   [(set_attr "type" "str")
17882    (set_attr "prefix_rep" "1")
17883    (set_attr "memory" "store")
17884    (set_attr "mode" "QI")])
17885
17886 (define_insn "*rep_stosqi_rex64"
17887   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17888    (set (match_operand:DI 0 "register_operand" "=D") 
17889         (plus:DI (match_operand:DI 3 "register_operand" "0")
17890                  (match_operand:DI 4 "register_operand" "1")))
17891    (set (mem:BLK (match_dup 3))
17892         (const_int 0))
17893    (use (match_operand:QI 2 "register_operand" "a"))
17894    (use (match_dup 4))
17895    (use (reg:SI DIRFLAG_REG))]
17896   "TARGET_64BIT"
17897   "{rep\;stosb|rep stosb}"
17898   [(set_attr "type" "str")
17899    (set_attr "prefix_rep" "1")
17900    (set_attr "memory" "store")
17901    (set_attr "mode" "QI")])
17902
17903 (define_expand "cmpstrnsi"
17904   [(set (match_operand:SI 0 "register_operand" "")
17905         (compare:SI (match_operand:BLK 1 "general_operand" "")
17906                     (match_operand:BLK 2 "general_operand" "")))
17907    (use (match_operand 3 "general_operand" ""))
17908    (use (match_operand 4 "immediate_operand" ""))]
17909   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17910 {
17911   rtx addr1, addr2, out, outlow, count, countreg, align;
17912
17913   /* Can't use this if the user has appropriated esi or edi.  */
17914   if (global_regs[4] || global_regs[5])
17915     FAIL;
17916
17917   out = operands[0];
17918   if (GET_CODE (out) != REG)
17919     out = gen_reg_rtx (SImode);
17920
17921   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17922   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17923   if (addr1 != XEXP (operands[1], 0))
17924     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17925   if (addr2 != XEXP (operands[2], 0))
17926     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17927
17928   count = operands[3];
17929   countreg = ix86_zero_extend_to_Pmode (count);
17930
17931   /* %%% Iff we are testing strict equality, we can use known alignment
17932      to good advantage.  This may be possible with combine, particularly
17933      once cc0 is dead.  */
17934   align = operands[4];
17935
17936   emit_insn (gen_cld ());
17937   if (GET_CODE (count) == CONST_INT)
17938     {
17939       if (INTVAL (count) == 0)
17940         {
17941           emit_move_insn (operands[0], const0_rtx);
17942           DONE;
17943         }
17944       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17945                                      operands[1], operands[2]));
17946     }
17947   else
17948     {
17949       if (TARGET_64BIT)
17950         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17951       else
17952         emit_insn (gen_cmpsi_1 (countreg, countreg));
17953       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17954                                   operands[1], operands[2]));
17955     }
17956
17957   outlow = gen_lowpart (QImode, out);
17958   emit_insn (gen_cmpintqi (outlow));
17959   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17960
17961   if (operands[0] != out)
17962     emit_move_insn (operands[0], out);
17963
17964   DONE;
17965 })
17966
17967 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17968
17969 (define_expand "cmpintqi"
17970   [(set (match_dup 1)
17971         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17972    (set (match_dup 2)
17973         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17974    (parallel [(set (match_operand:QI 0 "register_operand" "")
17975                    (minus:QI (match_dup 1)
17976                              (match_dup 2)))
17977               (clobber (reg:CC FLAGS_REG))])]
17978   ""
17979   "operands[1] = gen_reg_rtx (QImode);
17980    operands[2] = gen_reg_rtx (QImode);")
17981
17982 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17983 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17984
17985 (define_expand "cmpstrnqi_nz_1"
17986   [(parallel [(set (reg:CC FLAGS_REG)
17987                    (compare:CC (match_operand 4 "memory_operand" "")
17988                                (match_operand 5 "memory_operand" "")))
17989               (use (match_operand 2 "register_operand" ""))
17990               (use (match_operand:SI 3 "immediate_operand" ""))
17991               (use (reg:SI DIRFLAG_REG))
17992               (clobber (match_operand 0 "register_operand" ""))
17993               (clobber (match_operand 1 "register_operand" ""))
17994               (clobber (match_dup 2))])]
17995   ""
17996   "")
17997
17998 (define_insn "*cmpstrnqi_nz_1"
17999   [(set (reg:CC FLAGS_REG)
18000         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18001                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18002    (use (match_operand:SI 6 "register_operand" "2"))
18003    (use (match_operand:SI 3 "immediate_operand" "i"))
18004    (use (reg:SI DIRFLAG_REG))
18005    (clobber (match_operand:SI 0 "register_operand" "=S"))
18006    (clobber (match_operand:SI 1 "register_operand" "=D"))
18007    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18008   "!TARGET_64BIT"
18009   "repz{\;| }cmpsb"
18010   [(set_attr "type" "str")
18011    (set_attr "mode" "QI")
18012    (set_attr "prefix_rep" "1")])
18013
18014 (define_insn "*cmpstrnqi_nz_rex_1"
18015   [(set (reg:CC FLAGS_REG)
18016         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18017                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18018    (use (match_operand:DI 6 "register_operand" "2"))
18019    (use (match_operand:SI 3 "immediate_operand" "i"))
18020    (use (reg:SI DIRFLAG_REG))
18021    (clobber (match_operand:DI 0 "register_operand" "=S"))
18022    (clobber (match_operand:DI 1 "register_operand" "=D"))
18023    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18024   "TARGET_64BIT"
18025   "repz{\;| }cmpsb"
18026   [(set_attr "type" "str")
18027    (set_attr "mode" "QI")
18028    (set_attr "prefix_rep" "1")])
18029
18030 ;; The same, but the count is not known to not be zero.
18031
18032 (define_expand "cmpstrnqi_1"
18033   [(parallel [(set (reg:CC FLAGS_REG)
18034                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18035                                      (const_int 0))
18036                   (compare:CC (match_operand 4 "memory_operand" "")
18037                               (match_operand 5 "memory_operand" ""))
18038                   (const_int 0)))
18039               (use (match_operand:SI 3 "immediate_operand" ""))
18040               (use (reg:CC FLAGS_REG))
18041               (use (reg:SI DIRFLAG_REG))
18042               (clobber (match_operand 0 "register_operand" ""))
18043               (clobber (match_operand 1 "register_operand" ""))
18044               (clobber (match_dup 2))])]
18045   ""
18046   "")
18047
18048 (define_insn "*cmpstrnqi_1"
18049   [(set (reg:CC FLAGS_REG)
18050         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18051                              (const_int 0))
18052           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18053                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18054           (const_int 0)))
18055    (use (match_operand:SI 3 "immediate_operand" "i"))
18056    (use (reg:CC FLAGS_REG))
18057    (use (reg:SI DIRFLAG_REG))
18058    (clobber (match_operand:SI 0 "register_operand" "=S"))
18059    (clobber (match_operand:SI 1 "register_operand" "=D"))
18060    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18061   "!TARGET_64BIT"
18062   "repz{\;| }cmpsb"
18063   [(set_attr "type" "str")
18064    (set_attr "mode" "QI")
18065    (set_attr "prefix_rep" "1")])
18066
18067 (define_insn "*cmpstrnqi_rex_1"
18068   [(set (reg:CC FLAGS_REG)
18069         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18070                              (const_int 0))
18071           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18072                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18073           (const_int 0)))
18074    (use (match_operand:SI 3 "immediate_operand" "i"))
18075    (use (reg:CC FLAGS_REG))
18076    (use (reg:SI DIRFLAG_REG))
18077    (clobber (match_operand:DI 0 "register_operand" "=S"))
18078    (clobber (match_operand:DI 1 "register_operand" "=D"))
18079    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18080   "TARGET_64BIT"
18081   "repz{\;| }cmpsb"
18082   [(set_attr "type" "str")
18083    (set_attr "mode" "QI")
18084    (set_attr "prefix_rep" "1")])
18085
18086 (define_expand "strlensi"
18087   [(set (match_operand:SI 0 "register_operand" "")
18088         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18089                     (match_operand:QI 2 "immediate_operand" "")
18090                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18091   ""
18092 {
18093  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18094    DONE;
18095  else
18096    FAIL;
18097 })
18098
18099 (define_expand "strlendi"
18100   [(set (match_operand:DI 0 "register_operand" "")
18101         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18102                     (match_operand:QI 2 "immediate_operand" "")
18103                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18104   ""
18105 {
18106  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18107    DONE;
18108  else
18109    FAIL;
18110 })
18111
18112 (define_expand "strlenqi_1"
18113   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18114               (use (reg:SI DIRFLAG_REG))
18115               (clobber (match_operand 1 "register_operand" ""))
18116               (clobber (reg:CC FLAGS_REG))])]
18117   ""
18118   "")
18119
18120 (define_insn "*strlenqi_1"
18121   [(set (match_operand:SI 0 "register_operand" "=&c")
18122         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18123                     (match_operand:QI 2 "register_operand" "a")
18124                     (match_operand:SI 3 "immediate_operand" "i")
18125                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18126    (use (reg:SI DIRFLAG_REG))
18127    (clobber (match_operand:SI 1 "register_operand" "=D"))
18128    (clobber (reg:CC FLAGS_REG))]
18129   "!TARGET_64BIT"
18130   "repnz{\;| }scasb"
18131   [(set_attr "type" "str")
18132    (set_attr "mode" "QI")
18133    (set_attr "prefix_rep" "1")])
18134
18135 (define_insn "*strlenqi_rex_1"
18136   [(set (match_operand:DI 0 "register_operand" "=&c")
18137         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18138                     (match_operand:QI 2 "register_operand" "a")
18139                     (match_operand:DI 3 "immediate_operand" "i")
18140                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18141    (use (reg:SI DIRFLAG_REG))
18142    (clobber (match_operand:DI 1 "register_operand" "=D"))
18143    (clobber (reg:CC FLAGS_REG))]
18144   "TARGET_64BIT"
18145   "repnz{\;| }scasb"
18146   [(set_attr "type" "str")
18147    (set_attr "mode" "QI")
18148    (set_attr "prefix_rep" "1")])
18149
18150 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18151 ;; handled in combine, but it is not currently up to the task.
18152 ;; When used for their truth value, the cmpstrn* expanders generate
18153 ;; code like this:
18154 ;;
18155 ;;   repz cmpsb
18156 ;;   seta       %al
18157 ;;   setb       %dl
18158 ;;   cmpb       %al, %dl
18159 ;;   jcc        label
18160 ;;
18161 ;; The intermediate three instructions are unnecessary.
18162
18163 ;; This one handles cmpstrn*_nz_1...
18164 (define_peephole2
18165   [(parallel[
18166      (set (reg:CC FLAGS_REG)
18167           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18168                       (mem:BLK (match_operand 5 "register_operand" ""))))
18169      (use (match_operand 6 "register_operand" ""))
18170      (use (match_operand:SI 3 "immediate_operand" ""))
18171      (use (reg:SI DIRFLAG_REG))
18172      (clobber (match_operand 0 "register_operand" ""))
18173      (clobber (match_operand 1 "register_operand" ""))
18174      (clobber (match_operand 2 "register_operand" ""))])
18175    (set (match_operand:QI 7 "register_operand" "")
18176         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18177    (set (match_operand:QI 8 "register_operand" "")
18178         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18179    (set (reg FLAGS_REG)
18180         (compare (match_dup 7) (match_dup 8)))
18181   ]
18182   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18183   [(parallel[
18184      (set (reg:CC FLAGS_REG)
18185           (compare:CC (mem:BLK (match_dup 4))
18186                       (mem:BLK (match_dup 5))))
18187      (use (match_dup 6))
18188      (use (match_dup 3))
18189      (use (reg:SI DIRFLAG_REG))
18190      (clobber (match_dup 0))
18191      (clobber (match_dup 1))
18192      (clobber (match_dup 2))])]
18193   "")
18194
18195 ;; ...and this one handles cmpstrn*_1.
18196 (define_peephole2
18197   [(parallel[
18198      (set (reg:CC FLAGS_REG)
18199           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18200                                (const_int 0))
18201             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18202                         (mem:BLK (match_operand 5 "register_operand" "")))
18203             (const_int 0)))
18204      (use (match_operand:SI 3 "immediate_operand" ""))
18205      (use (reg:CC FLAGS_REG))
18206      (use (reg:SI DIRFLAG_REG))
18207      (clobber (match_operand 0 "register_operand" ""))
18208      (clobber (match_operand 1 "register_operand" ""))
18209      (clobber (match_operand 2 "register_operand" ""))])
18210    (set (match_operand:QI 7 "register_operand" "")
18211         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18212    (set (match_operand:QI 8 "register_operand" "")
18213         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18214    (set (reg FLAGS_REG)
18215         (compare (match_dup 7) (match_dup 8)))
18216   ]
18217   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18218   [(parallel[
18219      (set (reg:CC FLAGS_REG)
18220           (if_then_else:CC (ne (match_dup 6)
18221                                (const_int 0))
18222             (compare:CC (mem:BLK (match_dup 4))
18223                         (mem:BLK (match_dup 5)))
18224             (const_int 0)))
18225      (use (match_dup 3))
18226      (use (reg:CC FLAGS_REG))
18227      (use (reg:SI DIRFLAG_REG))
18228      (clobber (match_dup 0))
18229      (clobber (match_dup 1))
18230      (clobber (match_dup 2))])]
18231   "")
18232
18233
18234 \f
18235 ;; Conditional move instructions.
18236
18237 (define_expand "movdicc"
18238   [(set (match_operand:DI 0 "register_operand" "")
18239         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18240                          (match_operand:DI 2 "general_operand" "")
18241                          (match_operand:DI 3 "general_operand" "")))]
18242   "TARGET_64BIT"
18243   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18244
18245 (define_insn "x86_movdicc_0_m1_rex64"
18246   [(set (match_operand:DI 0 "register_operand" "=r")
18247         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18248           (const_int -1)
18249           (const_int 0)))
18250    (clobber (reg:CC FLAGS_REG))]
18251   "TARGET_64BIT"
18252   "sbb{q}\t%0, %0"
18253   ; Since we don't have the proper number of operands for an alu insn,
18254   ; fill in all the blanks.
18255   [(set_attr "type" "alu")
18256    (set_attr "pent_pair" "pu")
18257    (set_attr "memory" "none")
18258    (set_attr "imm_disp" "false")
18259    (set_attr "mode" "DI")
18260    (set_attr "length_immediate" "0")])
18261
18262 (define_insn "*movdicc_c_rex64"
18263   [(set (match_operand:DI 0 "register_operand" "=r,r")
18264         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18265                                 [(reg FLAGS_REG) (const_int 0)])
18266                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18267                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18268   "TARGET_64BIT && TARGET_CMOVE
18269    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18270   "@
18271    cmov%O2%C1\t{%2, %0|%0, %2}
18272    cmov%O2%c1\t{%3, %0|%0, %3}"
18273   [(set_attr "type" "icmov")
18274    (set_attr "mode" "DI")])
18275
18276 (define_expand "movsicc"
18277   [(set (match_operand:SI 0 "register_operand" "")
18278         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18279                          (match_operand:SI 2 "general_operand" "")
18280                          (match_operand:SI 3 "general_operand" "")))]
18281   ""
18282   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18283
18284 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18285 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18286 ;; So just document what we're doing explicitly.
18287
18288 (define_insn "x86_movsicc_0_m1"
18289   [(set (match_operand:SI 0 "register_operand" "=r")
18290         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18291           (const_int -1)
18292           (const_int 0)))
18293    (clobber (reg:CC FLAGS_REG))]
18294   ""
18295   "sbb{l}\t%0, %0"
18296   ; Since we don't have the proper number of operands for an alu insn,
18297   ; fill in all the blanks.
18298   [(set_attr "type" "alu")
18299    (set_attr "pent_pair" "pu")
18300    (set_attr "memory" "none")
18301    (set_attr "imm_disp" "false")
18302    (set_attr "mode" "SI")
18303    (set_attr "length_immediate" "0")])
18304
18305 (define_insn "*movsicc_noc"
18306   [(set (match_operand:SI 0 "register_operand" "=r,r")
18307         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18308                                 [(reg FLAGS_REG) (const_int 0)])
18309                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18310                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18311   "TARGET_CMOVE
18312    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18313   "@
18314    cmov%O2%C1\t{%2, %0|%0, %2}
18315    cmov%O2%c1\t{%3, %0|%0, %3}"
18316   [(set_attr "type" "icmov")
18317    (set_attr "mode" "SI")])
18318
18319 (define_expand "movhicc"
18320   [(set (match_operand:HI 0 "register_operand" "")
18321         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18322                          (match_operand:HI 2 "general_operand" "")
18323                          (match_operand:HI 3 "general_operand" "")))]
18324   "TARGET_HIMODE_MATH"
18325   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18326
18327 (define_insn "*movhicc_noc"
18328   [(set (match_operand:HI 0 "register_operand" "=r,r")
18329         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18330                                 [(reg FLAGS_REG) (const_int 0)])
18331                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18332                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18333   "TARGET_CMOVE
18334    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18335   "@
18336    cmov%O2%C1\t{%2, %0|%0, %2}
18337    cmov%O2%c1\t{%3, %0|%0, %3}"
18338   [(set_attr "type" "icmov")
18339    (set_attr "mode" "HI")])
18340
18341 (define_expand "movqicc"
18342   [(set (match_operand:QI 0 "register_operand" "")
18343         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18344                          (match_operand:QI 2 "general_operand" "")
18345                          (match_operand:QI 3 "general_operand" "")))]
18346   "TARGET_QIMODE_MATH"
18347   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18348
18349 (define_insn_and_split "*movqicc_noc"
18350   [(set (match_operand:QI 0 "register_operand" "=r,r")
18351         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18352                                 [(match_operand 4 "flags_reg_operand" "")
18353                                  (const_int 0)])
18354                       (match_operand:QI 2 "register_operand" "r,0")
18355                       (match_operand:QI 3 "register_operand" "0,r")))]
18356   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18357   "#"
18358   "&& reload_completed"
18359   [(set (match_dup 0)
18360         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18361                       (match_dup 2)
18362                       (match_dup 3)))]
18363   "operands[0] = gen_lowpart (SImode, operands[0]);
18364    operands[2] = gen_lowpart (SImode, operands[2]);
18365    operands[3] = gen_lowpart (SImode, operands[3]);"
18366   [(set_attr "type" "icmov")
18367    (set_attr "mode" "SI")])
18368
18369 (define_expand "movsfcc"
18370   [(set (match_operand:SF 0 "register_operand" "")
18371         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18372                          (match_operand:SF 2 "register_operand" "")
18373                          (match_operand:SF 3 "register_operand" "")))]
18374   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18375   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18376
18377 (define_insn "*movsfcc_1_387"
18378   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18379         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18380                                 [(reg FLAGS_REG) (const_int 0)])
18381                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18382                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18383   "TARGET_80387 && TARGET_CMOVE
18384    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18385   "@
18386    fcmov%F1\t{%2, %0|%0, %2}
18387    fcmov%f1\t{%3, %0|%0, %3}
18388    cmov%O2%C1\t{%2, %0|%0, %2}
18389    cmov%O2%c1\t{%3, %0|%0, %3}"
18390   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18391    (set_attr "mode" "SF,SF,SI,SI")])
18392
18393 (define_expand "movdfcc"
18394   [(set (match_operand:DF 0 "register_operand" "")
18395         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18396                          (match_operand:DF 2 "register_operand" "")
18397                          (match_operand:DF 3 "register_operand" "")))]
18398   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18399   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18400
18401 (define_insn "*movdfcc_1"
18402   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18403         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18404                                 [(reg FLAGS_REG) (const_int 0)])
18405                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18406                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18407   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18408    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18409   "@
18410    fcmov%F1\t{%2, %0|%0, %2}
18411    fcmov%f1\t{%3, %0|%0, %3}
18412    #
18413    #"
18414   [(set_attr "type" "fcmov,fcmov,multi,multi")
18415    (set_attr "mode" "DF")])
18416
18417 (define_insn "*movdfcc_1_rex64"
18418   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18419         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18420                                 [(reg FLAGS_REG) (const_int 0)])
18421                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18422                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18423   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18424    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18425   "@
18426    fcmov%F1\t{%2, %0|%0, %2}
18427    fcmov%f1\t{%3, %0|%0, %3}
18428    cmov%O2%C1\t{%2, %0|%0, %2}
18429    cmov%O2%c1\t{%3, %0|%0, %3}"
18430   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18431    (set_attr "mode" "DF")])
18432
18433 (define_split
18434   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18435         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18436                                 [(match_operand 4 "flags_reg_operand" "")
18437                                  (const_int 0)])
18438                       (match_operand:DF 2 "nonimmediate_operand" "")
18439                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18440   "!TARGET_64BIT && reload_completed"
18441   [(set (match_dup 2)
18442         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18443                       (match_dup 5)
18444                       (match_dup 7)))
18445    (set (match_dup 3)
18446         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18447                       (match_dup 6)
18448                       (match_dup 8)))]
18449   "split_di (operands+2, 1, operands+5, operands+6);
18450    split_di (operands+3, 1, operands+7, operands+8);
18451    split_di (operands, 1, operands+2, operands+3);")
18452
18453 (define_expand "movxfcc"
18454   [(set (match_operand:XF 0 "register_operand" "")
18455         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18456                          (match_operand:XF 2 "register_operand" "")
18457                          (match_operand:XF 3 "register_operand" "")))]
18458   "TARGET_80387 && TARGET_CMOVE"
18459   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18460
18461 (define_insn "*movxfcc_1"
18462   [(set (match_operand:XF 0 "register_operand" "=f,f")
18463         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18464                                 [(reg FLAGS_REG) (const_int 0)])
18465                       (match_operand:XF 2 "register_operand" "f,0")
18466                       (match_operand:XF 3 "register_operand" "0,f")))]
18467   "TARGET_80387 && TARGET_CMOVE"
18468   "@
18469    fcmov%F1\t{%2, %0|%0, %2}
18470    fcmov%f1\t{%3, %0|%0, %3}"
18471   [(set_attr "type" "fcmov")
18472    (set_attr "mode" "XF")])
18473
18474 ;; These versions of the min/max patterns are intentionally ignorant of
18475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18477 ;; are undefined in this condition, we're certain this is correct.
18478
18479 (define_insn "sminsf3"
18480   [(set (match_operand:SF 0 "register_operand" "=x")
18481         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18482                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18483   "TARGET_SSE_MATH"
18484   "minss\t{%2, %0|%0, %2}"
18485   [(set_attr "type" "sseadd")
18486    (set_attr "mode" "SF")])
18487
18488 (define_insn "smaxsf3"
18489   [(set (match_operand:SF 0 "register_operand" "=x")
18490         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18491                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18492   "TARGET_SSE_MATH"
18493   "maxss\t{%2, %0|%0, %2}"
18494   [(set_attr "type" "sseadd")
18495    (set_attr "mode" "SF")])
18496
18497 (define_insn "smindf3"
18498   [(set (match_operand:DF 0 "register_operand" "=x")
18499         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18500                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18501   "TARGET_SSE2 && TARGET_SSE_MATH"
18502   "minsd\t{%2, %0|%0, %2}"
18503   [(set_attr "type" "sseadd")
18504    (set_attr "mode" "DF")])
18505
18506 (define_insn "smaxdf3"
18507   [(set (match_operand:DF 0 "register_operand" "=x")
18508         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18509                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18510   "TARGET_SSE2 && TARGET_SSE_MATH"
18511   "maxsd\t{%2, %0|%0, %2}"
18512   [(set_attr "type" "sseadd")
18513    (set_attr "mode" "DF")])
18514
18515 ;; These versions of the min/max patterns implement exactly the operations
18516 ;;   min = (op1 < op2 ? op1 : op2)
18517 ;;   max = (!(op1 < op2) ? op1 : op2)
18518 ;; Their operands are not commutative, and thus they may be used in the
18519 ;; presence of -0.0 and NaN.
18520
18521 (define_insn "*ieee_sminsf3"
18522   [(set (match_operand:SF 0 "register_operand" "=x")
18523         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18524                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18525                    UNSPEC_IEEE_MIN))]
18526   "TARGET_SSE_MATH"
18527   "minss\t{%2, %0|%0, %2}"
18528   [(set_attr "type" "sseadd")
18529    (set_attr "mode" "SF")])
18530
18531 (define_insn "*ieee_smaxsf3"
18532   [(set (match_operand:SF 0 "register_operand" "=x")
18533         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18534                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18535                    UNSPEC_IEEE_MAX))]
18536   "TARGET_SSE_MATH"
18537   "maxss\t{%2, %0|%0, %2}"
18538   [(set_attr "type" "sseadd")
18539    (set_attr "mode" "SF")])
18540
18541 (define_insn "*ieee_smindf3"
18542   [(set (match_operand:DF 0 "register_operand" "=x")
18543         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18544                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18545                    UNSPEC_IEEE_MIN))]
18546   "TARGET_SSE2 && TARGET_SSE_MATH"
18547   "minsd\t{%2, %0|%0, %2}"
18548   [(set_attr "type" "sseadd")
18549    (set_attr "mode" "DF")])
18550
18551 (define_insn "*ieee_smaxdf3"
18552   [(set (match_operand:DF 0 "register_operand" "=x")
18553         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18554                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18555                    UNSPEC_IEEE_MAX))]
18556   "TARGET_SSE2 && TARGET_SSE_MATH"
18557   "maxsd\t{%2, %0|%0, %2}"
18558   [(set_attr "type" "sseadd")
18559    (set_attr "mode" "DF")])
18560
18561 ;; Conditional addition patterns
18562 (define_expand "addqicc"
18563   [(match_operand:QI 0 "register_operand" "")
18564    (match_operand 1 "comparison_operator" "")
18565    (match_operand:QI 2 "register_operand" "")
18566    (match_operand:QI 3 "const_int_operand" "")]
18567   ""
18568   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18569
18570 (define_expand "addhicc"
18571   [(match_operand:HI 0 "register_operand" "")
18572    (match_operand 1 "comparison_operator" "")
18573    (match_operand:HI 2 "register_operand" "")
18574    (match_operand:HI 3 "const_int_operand" "")]
18575   ""
18576   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18577
18578 (define_expand "addsicc"
18579   [(match_operand:SI 0 "register_operand" "")
18580    (match_operand 1 "comparison_operator" "")
18581    (match_operand:SI 2 "register_operand" "")
18582    (match_operand:SI 3 "const_int_operand" "")]
18583   ""
18584   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18585
18586 (define_expand "adddicc"
18587   [(match_operand:DI 0 "register_operand" "")
18588    (match_operand 1 "comparison_operator" "")
18589    (match_operand:DI 2 "register_operand" "")
18590    (match_operand:DI 3 "const_int_operand" "")]
18591   "TARGET_64BIT"
18592   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18593
18594 \f
18595 ;; Misc patterns (?)
18596
18597 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18598 ;; Otherwise there will be nothing to keep
18599 ;; 
18600 ;; [(set (reg ebp) (reg esp))]
18601 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18602 ;;  (clobber (eflags)]
18603 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18604 ;;
18605 ;; in proper program order.
18606 (define_insn "pro_epilogue_adjust_stack_1"
18607   [(set (match_operand:SI 0 "register_operand" "=r,r")
18608         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18609                  (match_operand:SI 2 "immediate_operand" "i,i")))
18610    (clobber (reg:CC FLAGS_REG))
18611    (clobber (mem:BLK (scratch)))]
18612   "!TARGET_64BIT"
18613 {
18614   switch (get_attr_type (insn))
18615     {
18616     case TYPE_IMOV:
18617       return "mov{l}\t{%1, %0|%0, %1}";
18618
18619     case TYPE_ALU:
18620       if (GET_CODE (operands[2]) == CONST_INT
18621           && (INTVAL (operands[2]) == 128
18622               || (INTVAL (operands[2]) < 0
18623                   && INTVAL (operands[2]) != -128)))
18624         {
18625           operands[2] = GEN_INT (-INTVAL (operands[2]));
18626           return "sub{l}\t{%2, %0|%0, %2}";
18627         }
18628       return "add{l}\t{%2, %0|%0, %2}";
18629
18630     case TYPE_LEA:
18631       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18632       return "lea{l}\t{%a2, %0|%0, %a2}";
18633
18634     default:
18635       gcc_unreachable ();
18636     }
18637 }
18638   [(set (attr "type")
18639         (cond [(eq_attr "alternative" "0")
18640                  (const_string "alu")
18641                (match_operand:SI 2 "const0_operand" "")
18642                  (const_string "imov")
18643               ]
18644               (const_string "lea")))
18645    (set_attr "mode" "SI")])
18646
18647 (define_insn "pro_epilogue_adjust_stack_rex64"
18648   [(set (match_operand:DI 0 "register_operand" "=r,r")
18649         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18650                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18651    (clobber (reg:CC FLAGS_REG))
18652    (clobber (mem:BLK (scratch)))]
18653   "TARGET_64BIT"
18654 {
18655   switch (get_attr_type (insn))
18656     {
18657     case TYPE_IMOV:
18658       return "mov{q}\t{%1, %0|%0, %1}";
18659
18660     case TYPE_ALU:
18661       if (GET_CODE (operands[2]) == CONST_INT
18662           /* Avoid overflows.  */
18663           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18664           && (INTVAL (operands[2]) == 128
18665               || (INTVAL (operands[2]) < 0
18666                   && INTVAL (operands[2]) != -128)))
18667         {
18668           operands[2] = GEN_INT (-INTVAL (operands[2]));
18669           return "sub{q}\t{%2, %0|%0, %2}";
18670         }
18671       return "add{q}\t{%2, %0|%0, %2}";
18672
18673     case TYPE_LEA:
18674       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18675       return "lea{q}\t{%a2, %0|%0, %a2}";
18676
18677     default:
18678       gcc_unreachable ();
18679     }
18680 }
18681   [(set (attr "type")
18682         (cond [(eq_attr "alternative" "0")
18683                  (const_string "alu")
18684                (match_operand:DI 2 "const0_operand" "")
18685                  (const_string "imov")
18686               ]
18687               (const_string "lea")))
18688    (set_attr "mode" "DI")])
18689
18690 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18691   [(set (match_operand:DI 0 "register_operand" "=r,r")
18692         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18693                  (match_operand:DI 3 "immediate_operand" "i,i")))
18694    (use (match_operand:DI 2 "register_operand" "r,r"))
18695    (clobber (reg:CC FLAGS_REG))
18696    (clobber (mem:BLK (scratch)))]
18697   "TARGET_64BIT"
18698 {
18699   switch (get_attr_type (insn))
18700     {
18701     case TYPE_ALU:
18702       return "add{q}\t{%2, %0|%0, %2}";
18703
18704     case TYPE_LEA:
18705       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18706       return "lea{q}\t{%a2, %0|%0, %a2}";
18707
18708     default:
18709       gcc_unreachable ();
18710     }
18711 }
18712   [(set_attr "type" "alu,lea")
18713    (set_attr "mode" "DI")])
18714
18715 (define_expand "allocate_stack_worker"
18716   [(match_operand:SI 0 "register_operand" "")]
18717   "TARGET_STACK_PROBE"
18718 {
18719   if (reload_completed)
18720     {
18721       if (TARGET_64BIT)
18722         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18723       else
18724         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18725     }
18726   else
18727     {
18728       if (TARGET_64BIT)
18729         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18730       else
18731         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18732     }
18733   DONE;
18734 })
18735
18736 (define_insn "allocate_stack_worker_1"
18737   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18738     UNSPECV_STACK_PROBE)
18739    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18740    (clobber (match_scratch:SI 1 "=0"))
18741    (clobber (reg:CC FLAGS_REG))]
18742   "!TARGET_64BIT && TARGET_STACK_PROBE"
18743   "call\t__alloca"
18744   [(set_attr "type" "multi")
18745    (set_attr "length" "5")])
18746
18747 (define_expand "allocate_stack_worker_postreload"
18748   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18749                                     UNSPECV_STACK_PROBE)
18750               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18751               (clobber (match_dup 0))
18752               (clobber (reg:CC FLAGS_REG))])]
18753   ""
18754   "")
18755
18756 (define_insn "allocate_stack_worker_rex64"
18757   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18758     UNSPECV_STACK_PROBE)
18759    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18760    (clobber (match_scratch:DI 1 "=0"))
18761    (clobber (reg:CC FLAGS_REG))]
18762   "TARGET_64BIT && TARGET_STACK_PROBE"
18763   "call\t__alloca"
18764   [(set_attr "type" "multi")
18765    (set_attr "length" "5")])
18766
18767 (define_expand "allocate_stack_worker_rex64_postreload"
18768   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18769                                     UNSPECV_STACK_PROBE)
18770               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18771               (clobber (match_dup 0))
18772               (clobber (reg:CC FLAGS_REG))])]
18773   ""
18774   "")
18775
18776 (define_expand "allocate_stack"
18777   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18778                    (minus:SI (reg:SI SP_REG)
18779                              (match_operand:SI 1 "general_operand" "")))
18780               (clobber (reg:CC FLAGS_REG))])
18781    (parallel [(set (reg:SI SP_REG)
18782                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18783               (clobber (reg:CC FLAGS_REG))])]
18784   "TARGET_STACK_PROBE"
18785 {
18786 #ifdef CHECK_STACK_LIMIT
18787   if (GET_CODE (operands[1]) == CONST_INT
18788       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18789     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18790                            operands[1]));
18791   else 
18792 #endif
18793     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18794                                                             operands[1])));
18795
18796   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18797   DONE;
18798 })
18799
18800 (define_expand "builtin_setjmp_receiver"
18801   [(label_ref (match_operand 0 "" ""))]
18802   "!TARGET_64BIT && flag_pic"
18803 {
18804   emit_insn (gen_set_got (pic_offset_table_rtx));
18805   DONE;
18806 })
18807 \f
18808 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18809
18810 (define_split
18811   [(set (match_operand 0 "register_operand" "")
18812         (match_operator 3 "promotable_binary_operator"
18813            [(match_operand 1 "register_operand" "")
18814             (match_operand 2 "aligned_operand" "")]))
18815    (clobber (reg:CC FLAGS_REG))]
18816   "! TARGET_PARTIAL_REG_STALL && reload_completed
18817    && ((GET_MODE (operands[0]) == HImode 
18818         && ((!optimize_size && !TARGET_FAST_PREFIX)
18819             || GET_CODE (operands[2]) != CONST_INT
18820             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18821        || (GET_MODE (operands[0]) == QImode 
18822            && (TARGET_PROMOTE_QImode || optimize_size)))"
18823   [(parallel [(set (match_dup 0)
18824                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18825               (clobber (reg:CC FLAGS_REG))])]
18826   "operands[0] = gen_lowpart (SImode, operands[0]);
18827    operands[1] = gen_lowpart (SImode, operands[1]);
18828    if (GET_CODE (operands[3]) != ASHIFT)
18829      operands[2] = gen_lowpart (SImode, operands[2]);
18830    PUT_MODE (operands[3], SImode);")
18831
18832 ; Promote the QImode tests, as i386 has encoding of the AND
18833 ; instruction with 32-bit sign-extended immediate and thus the
18834 ; instruction size is unchanged, except in the %eax case for
18835 ; which it is increased by one byte, hence the ! optimize_size.
18836 (define_split
18837   [(set (match_operand 0 "flags_reg_operand" "")
18838         (match_operator 2 "compare_operator"
18839           [(and (match_operand 3 "aligned_operand" "")
18840                 (match_operand 4 "const_int_operand" ""))
18841            (const_int 0)]))
18842    (set (match_operand 1 "register_operand" "")
18843         (and (match_dup 3) (match_dup 4)))]
18844   "! TARGET_PARTIAL_REG_STALL && reload_completed
18845    /* Ensure that the operand will remain sign-extended immediate.  */
18846    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18847    && ! optimize_size
18848    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18849        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18850   [(parallel [(set (match_dup 0)
18851                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18852                                     (const_int 0)]))
18853               (set (match_dup 1)
18854                    (and:SI (match_dup 3) (match_dup 4)))])]
18855 {
18856   operands[4]
18857     = gen_int_mode (INTVAL (operands[4])
18858                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18859   operands[1] = gen_lowpart (SImode, operands[1]);
18860   operands[3] = gen_lowpart (SImode, operands[3]);
18861 })
18862
18863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18864 ; the TEST instruction with 32-bit sign-extended immediate and thus
18865 ; the instruction size would at least double, which is not what we
18866 ; want even with ! optimize_size.
18867 (define_split
18868   [(set (match_operand 0 "flags_reg_operand" "")
18869         (match_operator 1 "compare_operator"
18870           [(and (match_operand:HI 2 "aligned_operand" "")
18871                 (match_operand:HI 3 "const_int_operand" ""))
18872            (const_int 0)]))]
18873   "! TARGET_PARTIAL_REG_STALL && reload_completed
18874    /* Ensure that the operand will remain sign-extended immediate.  */
18875    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18876    && ! TARGET_FAST_PREFIX
18877    && ! optimize_size"
18878   [(set (match_dup 0)
18879         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18880                          (const_int 0)]))]
18881 {
18882   operands[3]
18883     = gen_int_mode (INTVAL (operands[3])
18884                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18885   operands[2] = gen_lowpart (SImode, operands[2]);
18886 })
18887
18888 (define_split
18889   [(set (match_operand 0 "register_operand" "")
18890         (neg (match_operand 1 "register_operand" "")))
18891    (clobber (reg:CC FLAGS_REG))]
18892   "! TARGET_PARTIAL_REG_STALL && reload_completed
18893    && (GET_MODE (operands[0]) == HImode
18894        || (GET_MODE (operands[0]) == QImode 
18895            && (TARGET_PROMOTE_QImode || optimize_size)))"
18896   [(parallel [(set (match_dup 0)
18897                    (neg:SI (match_dup 1)))
18898               (clobber (reg:CC FLAGS_REG))])]
18899   "operands[0] = gen_lowpart (SImode, operands[0]);
18900    operands[1] = gen_lowpart (SImode, operands[1]);")
18901
18902 (define_split
18903   [(set (match_operand 0 "register_operand" "")
18904         (not (match_operand 1 "register_operand" "")))]
18905   "! TARGET_PARTIAL_REG_STALL && reload_completed
18906    && (GET_MODE (operands[0]) == HImode
18907        || (GET_MODE (operands[0]) == QImode 
18908            && (TARGET_PROMOTE_QImode || optimize_size)))"
18909   [(set (match_dup 0)
18910         (not:SI (match_dup 1)))]
18911   "operands[0] = gen_lowpart (SImode, operands[0]);
18912    operands[1] = gen_lowpart (SImode, operands[1]);")
18913
18914 (define_split 
18915   [(set (match_operand 0 "register_operand" "")
18916         (if_then_else (match_operator 1 "comparison_operator" 
18917                                 [(reg FLAGS_REG) (const_int 0)])
18918                       (match_operand 2 "register_operand" "")
18919                       (match_operand 3 "register_operand" "")))]
18920   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18921    && (GET_MODE (operands[0]) == HImode
18922        || (GET_MODE (operands[0]) == QImode 
18923            && (TARGET_PROMOTE_QImode || optimize_size)))"
18924   [(set (match_dup 0)
18925         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18926   "operands[0] = gen_lowpart (SImode, operands[0]);
18927    operands[2] = gen_lowpart (SImode, operands[2]);
18928    operands[3] = gen_lowpart (SImode, operands[3]);")
18929                         
18930 \f
18931 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18932 ;; transform a complex memory operation into two memory to register operations.
18933
18934 ;; Don't push memory operands
18935 (define_peephole2
18936   [(set (match_operand:SI 0 "push_operand" "")
18937         (match_operand:SI 1 "memory_operand" ""))
18938    (match_scratch:SI 2 "r")]
18939   "!optimize_size && !TARGET_PUSH_MEMORY
18940    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18941   [(set (match_dup 2) (match_dup 1))
18942    (set (match_dup 0) (match_dup 2))]
18943   "")
18944
18945 (define_peephole2
18946   [(set (match_operand:DI 0 "push_operand" "")
18947         (match_operand:DI 1 "memory_operand" ""))
18948    (match_scratch:DI 2 "r")]
18949   "!optimize_size && !TARGET_PUSH_MEMORY
18950    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18951   [(set (match_dup 2) (match_dup 1))
18952    (set (match_dup 0) (match_dup 2))]
18953   "")
18954
18955 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18956 ;; SImode pushes.
18957 (define_peephole2
18958   [(set (match_operand:SF 0 "push_operand" "")
18959         (match_operand:SF 1 "memory_operand" ""))
18960    (match_scratch:SF 2 "r")]
18961   "!optimize_size && !TARGET_PUSH_MEMORY
18962    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18963   [(set (match_dup 2) (match_dup 1))
18964    (set (match_dup 0) (match_dup 2))]
18965   "")
18966
18967 (define_peephole2
18968   [(set (match_operand:HI 0 "push_operand" "")
18969         (match_operand:HI 1 "memory_operand" ""))
18970    (match_scratch:HI 2 "r")]
18971   "!optimize_size && !TARGET_PUSH_MEMORY
18972    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18973   [(set (match_dup 2) (match_dup 1))
18974    (set (match_dup 0) (match_dup 2))]
18975   "")
18976
18977 (define_peephole2
18978   [(set (match_operand:QI 0 "push_operand" "")
18979         (match_operand:QI 1 "memory_operand" ""))
18980    (match_scratch:QI 2 "q")]
18981   "!optimize_size && !TARGET_PUSH_MEMORY
18982    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18983   [(set (match_dup 2) (match_dup 1))
18984    (set (match_dup 0) (match_dup 2))]
18985   "")
18986
18987 ;; Don't move an immediate directly to memory when the instruction
18988 ;; gets too big.
18989 (define_peephole2
18990   [(match_scratch:SI 1 "r")
18991    (set (match_operand:SI 0 "memory_operand" "")
18992         (const_int 0))]
18993   "! optimize_size
18994    && ! TARGET_USE_MOV0
18995    && TARGET_SPLIT_LONG_MOVES
18996    && get_attr_length (insn) >= ix86_cost->large_insn
18997    && peep2_regno_dead_p (0, FLAGS_REG)"
18998   [(parallel [(set (match_dup 1) (const_int 0))
18999               (clobber (reg:CC FLAGS_REG))])
19000    (set (match_dup 0) (match_dup 1))]
19001   "")
19002
19003 (define_peephole2
19004   [(match_scratch:HI 1 "r")
19005    (set (match_operand:HI 0 "memory_operand" "")
19006         (const_int 0))]
19007   "! optimize_size
19008    && ! TARGET_USE_MOV0
19009    && TARGET_SPLIT_LONG_MOVES
19010    && get_attr_length (insn) >= ix86_cost->large_insn
19011    && peep2_regno_dead_p (0, FLAGS_REG)"
19012   [(parallel [(set (match_dup 2) (const_int 0))
19013               (clobber (reg:CC FLAGS_REG))])
19014    (set (match_dup 0) (match_dup 1))]
19015   "operands[2] = gen_lowpart (SImode, operands[1]);")
19016
19017 (define_peephole2
19018   [(match_scratch:QI 1 "q")
19019    (set (match_operand:QI 0 "memory_operand" "")
19020         (const_int 0))]
19021   "! optimize_size
19022    && ! TARGET_USE_MOV0
19023    && TARGET_SPLIT_LONG_MOVES
19024    && get_attr_length (insn) >= ix86_cost->large_insn
19025    && peep2_regno_dead_p (0, FLAGS_REG)"
19026   [(parallel [(set (match_dup 2) (const_int 0))
19027               (clobber (reg:CC FLAGS_REG))])
19028    (set (match_dup 0) (match_dup 1))]
19029   "operands[2] = gen_lowpart (SImode, operands[1]);")
19030
19031 (define_peephole2
19032   [(match_scratch:SI 2 "r")
19033    (set (match_operand:SI 0 "memory_operand" "")
19034         (match_operand:SI 1 "immediate_operand" ""))]
19035   "! optimize_size
19036    && get_attr_length (insn) >= ix86_cost->large_insn
19037    && TARGET_SPLIT_LONG_MOVES"
19038   [(set (match_dup 2) (match_dup 1))
19039    (set (match_dup 0) (match_dup 2))]
19040   "")
19041
19042 (define_peephole2
19043   [(match_scratch:HI 2 "r")
19044    (set (match_operand:HI 0 "memory_operand" "")
19045         (match_operand:HI 1 "immediate_operand" ""))]
19046   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19047   && TARGET_SPLIT_LONG_MOVES"
19048   [(set (match_dup 2) (match_dup 1))
19049    (set (match_dup 0) (match_dup 2))]
19050   "")
19051
19052 (define_peephole2
19053   [(match_scratch:QI 2 "q")
19054    (set (match_operand:QI 0 "memory_operand" "")
19055         (match_operand:QI 1 "immediate_operand" ""))]
19056   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19057   && TARGET_SPLIT_LONG_MOVES"
19058   [(set (match_dup 2) (match_dup 1))
19059    (set (match_dup 0) (match_dup 2))]
19060   "")
19061
19062 ;; Don't compare memory with zero, load and use a test instead.
19063 (define_peephole2
19064   [(set (match_operand 0 "flags_reg_operand" "")
19065         (match_operator 1 "compare_operator"
19066           [(match_operand:SI 2 "memory_operand" "")
19067            (const_int 0)]))
19068    (match_scratch:SI 3 "r")]
19069   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19070   [(set (match_dup 3) (match_dup 2))
19071    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19072   "")
19073
19074 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19075 ;; Don't split NOTs with a displacement operand, because resulting XOR
19076 ;; will not be pairable anyway.
19077 ;;
19078 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19079 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19080 ;; so this split helps here as well.
19081 ;;
19082 ;; Note: Can't do this as a regular split because we can't get proper
19083 ;; lifetime information then.
19084
19085 (define_peephole2
19086   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19087         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19088   "!optimize_size
19089    && peep2_regno_dead_p (0, FLAGS_REG)
19090    && ((TARGET_PENTIUM 
19091         && (GET_CODE (operands[0]) != MEM
19092             || !memory_displacement_operand (operands[0], SImode)))
19093        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19094   [(parallel [(set (match_dup 0)
19095                    (xor:SI (match_dup 1) (const_int -1)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "")
19098
19099 (define_peephole2
19100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19101         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19102   "!optimize_size
19103    && peep2_regno_dead_p (0, FLAGS_REG)
19104    && ((TARGET_PENTIUM 
19105         && (GET_CODE (operands[0]) != MEM
19106             || !memory_displacement_operand (operands[0], HImode)))
19107        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19108   [(parallel [(set (match_dup 0)
19109                    (xor:HI (match_dup 1) (const_int -1)))
19110               (clobber (reg:CC FLAGS_REG))])]
19111   "")
19112
19113 (define_peephole2
19114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19115         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19116   "!optimize_size
19117    && peep2_regno_dead_p (0, FLAGS_REG)
19118    && ((TARGET_PENTIUM 
19119         && (GET_CODE (operands[0]) != MEM
19120             || !memory_displacement_operand (operands[0], QImode)))
19121        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19122   [(parallel [(set (match_dup 0)
19123                    (xor:QI (match_dup 1) (const_int -1)))
19124               (clobber (reg:CC FLAGS_REG))])]
19125   "")
19126
19127 ;; Non pairable "test imm, reg" instructions can be translated to
19128 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19129 ;; byte opcode instead of two, have a short form for byte operands),
19130 ;; so do it for other CPUs as well.  Given that the value was dead,
19131 ;; this should not create any new dependencies.  Pass on the sub-word
19132 ;; versions if we're concerned about partial register stalls.
19133
19134 (define_peephole2
19135   [(set (match_operand 0 "flags_reg_operand" "")
19136         (match_operator 1 "compare_operator"
19137           [(and:SI (match_operand:SI 2 "register_operand" "")
19138                    (match_operand:SI 3 "immediate_operand" ""))
19139            (const_int 0)]))]
19140   "ix86_match_ccmode (insn, CCNOmode)
19141    && (true_regnum (operands[2]) != 0
19142        || (GET_CODE (operands[3]) == CONST_INT
19143            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19144    && peep2_reg_dead_p (1, operands[2])"
19145   [(parallel
19146      [(set (match_dup 0)
19147            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19148                             (const_int 0)]))
19149       (set (match_dup 2)
19150            (and:SI (match_dup 2) (match_dup 3)))])]
19151   "")
19152
19153 ;; We don't need to handle HImode case, because it will be promoted to SImode
19154 ;; on ! TARGET_PARTIAL_REG_STALL
19155
19156 (define_peephole2
19157   [(set (match_operand 0 "flags_reg_operand" "")
19158         (match_operator 1 "compare_operator"
19159           [(and:QI (match_operand:QI 2 "register_operand" "")
19160                    (match_operand:QI 3 "immediate_operand" ""))
19161            (const_int 0)]))]
19162   "! TARGET_PARTIAL_REG_STALL
19163    && ix86_match_ccmode (insn, CCNOmode)
19164    && true_regnum (operands[2]) != 0
19165    && peep2_reg_dead_p (1, operands[2])"
19166   [(parallel
19167      [(set (match_dup 0)
19168            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19169                             (const_int 0)]))
19170       (set (match_dup 2)
19171            (and:QI (match_dup 2) (match_dup 3)))])]
19172   "")
19173
19174 (define_peephole2
19175   [(set (match_operand 0 "flags_reg_operand" "")
19176         (match_operator 1 "compare_operator"
19177           [(and:SI
19178              (zero_extract:SI
19179                (match_operand 2 "ext_register_operand" "")
19180                (const_int 8)
19181                (const_int 8))
19182              (match_operand 3 "const_int_operand" ""))
19183            (const_int 0)]))]
19184   "! TARGET_PARTIAL_REG_STALL
19185    && ix86_match_ccmode (insn, CCNOmode)
19186    && true_regnum (operands[2]) != 0
19187    && peep2_reg_dead_p (1, operands[2])"
19188   [(parallel [(set (match_dup 0)
19189                    (match_op_dup 1
19190                      [(and:SI
19191                         (zero_extract:SI
19192                           (match_dup 2)
19193                           (const_int 8)
19194                           (const_int 8))
19195                         (match_dup 3))
19196                       (const_int 0)]))
19197               (set (zero_extract:SI (match_dup 2)
19198                                     (const_int 8)
19199                                     (const_int 8))
19200                    (and:SI 
19201                      (zero_extract:SI
19202                        (match_dup 2)
19203                        (const_int 8)
19204                        (const_int 8))
19205                      (match_dup 3)))])]
19206   "")
19207
19208 ;; Don't do logical operations with memory inputs.
19209 (define_peephole2
19210   [(match_scratch:SI 2 "r")
19211    (parallel [(set (match_operand:SI 0 "register_operand" "")
19212                    (match_operator:SI 3 "arith_or_logical_operator"
19213                      [(match_dup 0)
19214                       (match_operand:SI 1 "memory_operand" "")]))
19215               (clobber (reg:CC FLAGS_REG))])]
19216   "! optimize_size && ! TARGET_READ_MODIFY"
19217   [(set (match_dup 2) (match_dup 1))
19218    (parallel [(set (match_dup 0)
19219                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19220               (clobber (reg:CC FLAGS_REG))])]
19221   "")
19222
19223 (define_peephole2
19224   [(match_scratch:SI 2 "r")
19225    (parallel [(set (match_operand:SI 0 "register_operand" "")
19226                    (match_operator:SI 3 "arith_or_logical_operator"
19227                      [(match_operand:SI 1 "memory_operand" "")
19228                       (match_dup 0)]))
19229               (clobber (reg:CC FLAGS_REG))])]
19230   "! optimize_size && ! TARGET_READ_MODIFY"
19231   [(set (match_dup 2) (match_dup 1))
19232    (parallel [(set (match_dup 0)
19233                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19234               (clobber (reg:CC FLAGS_REG))])]
19235   "")
19236
19237 ; Don't do logical operations with memory outputs
19238 ;
19239 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19240 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19241 ; the same decoder scheduling characteristics as the original.
19242
19243 (define_peephole2
19244   [(match_scratch:SI 2 "r")
19245    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19246                    (match_operator:SI 3 "arith_or_logical_operator"
19247                      [(match_dup 0)
19248                       (match_operand:SI 1 "nonmemory_operand" "")]))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19251   [(set (match_dup 2) (match_dup 0))
19252    (parallel [(set (match_dup 2)
19253                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19254               (clobber (reg:CC FLAGS_REG))])
19255    (set (match_dup 0) (match_dup 2))]
19256   "")
19257
19258 (define_peephole2
19259   [(match_scratch:SI 2 "r")
19260    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19261                    (match_operator:SI 3 "arith_or_logical_operator"
19262                      [(match_operand:SI 1 "nonmemory_operand" "")
19263                       (match_dup 0)]))
19264               (clobber (reg:CC FLAGS_REG))])]
19265   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19266   [(set (match_dup 2) (match_dup 0))
19267    (parallel [(set (match_dup 2)
19268                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19269               (clobber (reg:CC FLAGS_REG))])
19270    (set (match_dup 0) (match_dup 2))]
19271   "")
19272
19273 ;; Attempt to always use XOR for zeroing registers.
19274 (define_peephole2
19275   [(set (match_operand 0 "register_operand" "")
19276         (match_operand 1 "const0_operand" ""))]
19277   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19278    && (! TARGET_USE_MOV0 || optimize_size)
19279    && GENERAL_REG_P (operands[0])
19280    && peep2_regno_dead_p (0, FLAGS_REG)"
19281   [(parallel [(set (match_dup 0) (const_int 0))
19282               (clobber (reg:CC FLAGS_REG))])]
19283 {
19284   operands[0] = gen_lowpart (word_mode, operands[0]);
19285 })
19286
19287 (define_peephole2
19288   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19289         (const_int 0))]
19290   "(GET_MODE (operands[0]) == QImode
19291     || GET_MODE (operands[0]) == HImode)
19292    && (! TARGET_USE_MOV0 || optimize_size)
19293    && peep2_regno_dead_p (0, FLAGS_REG)"
19294   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19295               (clobber (reg:CC FLAGS_REG))])])
19296
19297 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19298 (define_peephole2
19299   [(set (match_operand 0 "register_operand" "")
19300         (const_int -1))]
19301   "(GET_MODE (operands[0]) == HImode
19302     || GET_MODE (operands[0]) == SImode 
19303     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19304    && (optimize_size || TARGET_PENTIUM)
19305    && peep2_regno_dead_p (0, FLAGS_REG)"
19306   [(parallel [(set (match_dup 0) (const_int -1))
19307               (clobber (reg:CC FLAGS_REG))])]
19308   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19309                               operands[0]);")
19310
19311 ;; Attempt to convert simple leas to adds. These can be created by
19312 ;; move expanders.
19313 (define_peephole2
19314   [(set (match_operand:SI 0 "register_operand" "")
19315         (plus:SI (match_dup 0)
19316                  (match_operand:SI 1 "nonmemory_operand" "")))]
19317   "peep2_regno_dead_p (0, FLAGS_REG)"
19318   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19319               (clobber (reg:CC FLAGS_REG))])]
19320   "")
19321
19322 (define_peephole2
19323   [(set (match_operand:SI 0 "register_operand" "")
19324         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19325                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19326   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19327   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19328               (clobber (reg:CC FLAGS_REG))])]
19329   "operands[2] = gen_lowpart (SImode, operands[2]);")
19330
19331 (define_peephole2
19332   [(set (match_operand:DI 0 "register_operand" "")
19333         (plus:DI (match_dup 0)
19334                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19335   "peep2_regno_dead_p (0, FLAGS_REG)"
19336   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19337               (clobber (reg:CC FLAGS_REG))])]
19338   "")
19339
19340 (define_peephole2
19341   [(set (match_operand:SI 0 "register_operand" "")
19342         (mult:SI (match_dup 0)
19343                  (match_operand:SI 1 "const_int_operand" "")))]
19344   "exact_log2 (INTVAL (operands[1])) >= 0
19345    && peep2_regno_dead_p (0, FLAGS_REG)"
19346   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19347               (clobber (reg:CC FLAGS_REG))])]
19348   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19349
19350 (define_peephole2
19351   [(set (match_operand:DI 0 "register_operand" "")
19352         (mult:DI (match_dup 0)
19353                  (match_operand:DI 1 "const_int_operand" "")))]
19354   "exact_log2 (INTVAL (operands[1])) >= 0
19355    && peep2_regno_dead_p (0, FLAGS_REG)"
19356   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19357               (clobber (reg:CC FLAGS_REG))])]
19358   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19359
19360 (define_peephole2
19361   [(set (match_operand:SI 0 "register_operand" "")
19362         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19363                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19364   "exact_log2 (INTVAL (operands[2])) >= 0
19365    && REGNO (operands[0]) == REGNO (operands[1])
19366    && peep2_regno_dead_p (0, FLAGS_REG)"
19367   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19368               (clobber (reg:CC FLAGS_REG))])]
19369   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19370
19371 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19372 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19373 ;; many CPUs it is also faster, since special hardware to avoid esp
19374 ;; dependencies is present.
19375
19376 ;; While some of these conversions may be done using splitters, we use peepholes
19377 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19378
19379 ;; Convert prologue esp subtractions to push.
19380 ;; We need register to push.  In order to keep verify_flow_info happy we have
19381 ;; two choices
19382 ;; - use scratch and clobber it in order to avoid dependencies
19383 ;; - use already live register
19384 ;; We can't use the second way right now, since there is no reliable way how to
19385 ;; verify that given register is live.  First choice will also most likely in
19386 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19387 ;; call clobbered registers are dead.  We may want to use base pointer as an
19388 ;; alternative when no register is available later.
19389
19390 (define_peephole2
19391   [(match_scratch:SI 0 "r")
19392    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19393               (clobber (reg:CC FLAGS_REG))
19394               (clobber (mem:BLK (scratch)))])]
19395   "optimize_size || !TARGET_SUB_ESP_4"
19396   [(clobber (match_dup 0))
19397    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19398               (clobber (mem:BLK (scratch)))])])
19399
19400 (define_peephole2
19401   [(match_scratch:SI 0 "r")
19402    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19403               (clobber (reg:CC FLAGS_REG))
19404               (clobber (mem:BLK (scratch)))])]
19405   "optimize_size || !TARGET_SUB_ESP_8"
19406   [(clobber (match_dup 0))
19407    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19408    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19409               (clobber (mem:BLK (scratch)))])])
19410
19411 ;; Convert esp subtractions to push.
19412 (define_peephole2
19413   [(match_scratch:SI 0 "r")
19414    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19415               (clobber (reg:CC FLAGS_REG))])]
19416   "optimize_size || !TARGET_SUB_ESP_4"
19417   [(clobber (match_dup 0))
19418    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19419
19420 (define_peephole2
19421   [(match_scratch:SI 0 "r")
19422    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19423               (clobber (reg:CC FLAGS_REG))])]
19424   "optimize_size || !TARGET_SUB_ESP_8"
19425   [(clobber (match_dup 0))
19426    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19427    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19428
19429 ;; Convert epilogue deallocator to pop.
19430 (define_peephole2
19431   [(match_scratch:SI 0 "r")
19432    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19433               (clobber (reg:CC FLAGS_REG))
19434               (clobber (mem:BLK (scratch)))])]
19435   "optimize_size || !TARGET_ADD_ESP_4"
19436   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19437               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19438               (clobber (mem:BLK (scratch)))])]
19439   "")
19440
19441 ;; Two pops case is tricky, since pop causes dependency on destination register.
19442 ;; We use two registers if available.
19443 (define_peephole2
19444   [(match_scratch:SI 0 "r")
19445    (match_scratch:SI 1 "r")
19446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19447               (clobber (reg:CC FLAGS_REG))
19448               (clobber (mem:BLK (scratch)))])]
19449   "optimize_size || !TARGET_ADD_ESP_8"
19450   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19451               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19452               (clobber (mem:BLK (scratch)))])
19453    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19455   "")
19456
19457 (define_peephole2
19458   [(match_scratch:SI 0 "r")
19459    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19460               (clobber (reg:CC FLAGS_REG))
19461               (clobber (mem:BLK (scratch)))])]
19462   "optimize_size"
19463   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19464               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19465               (clobber (mem:BLK (scratch)))])
19466    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19467               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19468   "")
19469
19470 ;; Convert esp additions to pop.
19471 (define_peephole2
19472   [(match_scratch:SI 0 "r")
19473    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
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   "")
19479
19480 ;; Two pops case is tricky, since pop causes dependency on destination register.
19481 ;; We use two registers if available.
19482 (define_peephole2
19483   [(match_scratch:SI 0 "r")
19484    (match_scratch:SI 1 "r")
19485    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19486               (clobber (reg:CC FLAGS_REG))])]
19487   ""
19488   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19490    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19491               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19492   "")
19493
19494 (define_peephole2
19495   [(match_scratch:SI 0 "r")
19496    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19497               (clobber (reg:CC FLAGS_REG))])]
19498   "optimize_size"
19499   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19500               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19501    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19502               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19503   "")
19504 \f
19505 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19506 ;; required and register dies.  Similarly for 128 to plus -128.
19507 (define_peephole2
19508   [(set (match_operand 0 "flags_reg_operand" "")
19509         (match_operator 1 "compare_operator"
19510           [(match_operand 2 "register_operand" "")
19511            (match_operand 3 "const_int_operand" "")]))]
19512   "(INTVAL (operands[3]) == -1
19513     || INTVAL (operands[3]) == 1
19514     || INTVAL (operands[3]) == 128)
19515    && ix86_match_ccmode (insn, CCGCmode)
19516    && peep2_reg_dead_p (1, operands[2])"
19517   [(parallel [(set (match_dup 0)
19518                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19519               (clobber (match_dup 2))])]
19520   "")
19521 \f
19522 (define_peephole2
19523   [(match_scratch:DI 0 "r")
19524    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19525               (clobber (reg:CC FLAGS_REG))
19526               (clobber (mem:BLK (scratch)))])]
19527   "optimize_size || !TARGET_SUB_ESP_4"
19528   [(clobber (match_dup 0))
19529    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19530               (clobber (mem:BLK (scratch)))])])
19531
19532 (define_peephole2
19533   [(match_scratch:DI 0 "r")
19534    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19535               (clobber (reg:CC FLAGS_REG))
19536               (clobber (mem:BLK (scratch)))])]
19537   "optimize_size || !TARGET_SUB_ESP_8"
19538   [(clobber (match_dup 0))
19539    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19540    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19541               (clobber (mem:BLK (scratch)))])])
19542
19543 ;; Convert esp subtractions to push.
19544 (define_peephole2
19545   [(match_scratch:DI 0 "r")
19546    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19547               (clobber (reg:CC FLAGS_REG))])]
19548   "optimize_size || !TARGET_SUB_ESP_4"
19549   [(clobber (match_dup 0))
19550    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19551
19552 (define_peephole2
19553   [(match_scratch:DI 0 "r")
19554    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19555               (clobber (reg:CC FLAGS_REG))])]
19556   "optimize_size || !TARGET_SUB_ESP_8"
19557   [(clobber (match_dup 0))
19558    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19559    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19560
19561 ;; Convert epilogue deallocator to pop.
19562 (define_peephole2
19563   [(match_scratch:DI 0 "r")
19564    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19565               (clobber (reg:CC FLAGS_REG))
19566               (clobber (mem:BLK (scratch)))])]
19567   "optimize_size || !TARGET_ADD_ESP_4"
19568   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19569               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19570               (clobber (mem:BLK (scratch)))])]
19571   "")
19572
19573 ;; Two pops case is tricky, since pop causes dependency on destination register.
19574 ;; We use two registers if available.
19575 (define_peephole2
19576   [(match_scratch:DI 0 "r")
19577    (match_scratch:DI 1 "r")
19578    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19579               (clobber (reg:CC FLAGS_REG))
19580               (clobber (mem:BLK (scratch)))])]
19581   "optimize_size || !TARGET_ADD_ESP_8"
19582   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19583               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19584               (clobber (mem:BLK (scratch)))])
19585    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19586               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19587   "")
19588
19589 (define_peephole2
19590   [(match_scratch:DI 0 "r")
19591    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19592               (clobber (reg:CC FLAGS_REG))
19593               (clobber (mem:BLK (scratch)))])]
19594   "optimize_size"
19595   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19596               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19597               (clobber (mem:BLK (scratch)))])
19598    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19599               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19600   "")
19601
19602 ;; Convert esp additions to pop.
19603 (define_peephole2
19604   [(match_scratch:DI 0 "r")
19605    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
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   "")
19611
19612 ;; Two pops case is tricky, since pop causes dependency on destination register.
19613 ;; We use two registers if available.
19614 (define_peephole2
19615   [(match_scratch:DI 0 "r")
19616    (match_scratch:DI 1 "r")
19617    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19618               (clobber (reg:CC FLAGS_REG))])]
19619   ""
19620   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19621               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19622    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19623               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19624   "")
19625
19626 (define_peephole2
19627   [(match_scratch:DI 0 "r")
19628    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19629               (clobber (reg:CC FLAGS_REG))])]
19630   "optimize_size"
19631   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19633    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19634               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19635   "")
19636 \f
19637 ;; Convert imul by three, five and nine into lea
19638 (define_peephole2
19639   [(parallel
19640     [(set (match_operand:SI 0 "register_operand" "")
19641           (mult:SI (match_operand:SI 1 "register_operand" "")
19642                    (match_operand:SI 2 "const_int_operand" "")))
19643      (clobber (reg:CC FLAGS_REG))])]
19644   "INTVAL (operands[2]) == 3
19645    || INTVAL (operands[2]) == 5
19646    || INTVAL (operands[2]) == 9"
19647   [(set (match_dup 0)
19648         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19649                  (match_dup 1)))]
19650   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19651
19652 (define_peephole2
19653   [(parallel
19654     [(set (match_operand:SI 0 "register_operand" "")
19655           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19656                    (match_operand:SI 2 "const_int_operand" "")))
19657      (clobber (reg:CC FLAGS_REG))])]
19658   "!optimize_size 
19659    && (INTVAL (operands[2]) == 3
19660        || INTVAL (operands[2]) == 5
19661        || INTVAL (operands[2]) == 9)"
19662   [(set (match_dup 0) (match_dup 1))
19663    (set (match_dup 0)
19664         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19665                  (match_dup 0)))]
19666   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19667
19668 (define_peephole2
19669   [(parallel
19670     [(set (match_operand:DI 0 "register_operand" "")
19671           (mult:DI (match_operand:DI 1 "register_operand" "")
19672                    (match_operand:DI 2 "const_int_operand" "")))
19673      (clobber (reg:CC FLAGS_REG))])]
19674   "TARGET_64BIT
19675    && (INTVAL (operands[2]) == 3
19676        || INTVAL (operands[2]) == 5
19677        || INTVAL (operands[2]) == 9)"
19678   [(set (match_dup 0)
19679         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19680                  (match_dup 1)))]
19681   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19682
19683 (define_peephole2
19684   [(parallel
19685     [(set (match_operand:DI 0 "register_operand" "")
19686           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19687                    (match_operand:DI 2 "const_int_operand" "")))
19688      (clobber (reg:CC FLAGS_REG))])]
19689   "TARGET_64BIT
19690    && !optimize_size 
19691    && (INTVAL (operands[2]) == 3
19692        || INTVAL (operands[2]) == 5
19693        || INTVAL (operands[2]) == 9)"
19694   [(set (match_dup 0) (match_dup 1))
19695    (set (match_dup 0)
19696         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19697                  (match_dup 0)))]
19698   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19699
19700 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19701 ;; imul $32bit_imm, reg, reg is direct decoded.
19702 (define_peephole2
19703   [(match_scratch:DI 3 "r")
19704    (parallel [(set (match_operand:DI 0 "register_operand" "")
19705                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19706                             (match_operand:DI 2 "immediate_operand" "")))
19707               (clobber (reg:CC FLAGS_REG))])]
19708   "TARGET_K8 && !optimize_size
19709    && (GET_CODE (operands[2]) != CONST_INT
19710        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19711   [(set (match_dup 3) (match_dup 1))
19712    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19713               (clobber (reg:CC FLAGS_REG))])]
19714 "")
19715
19716 (define_peephole2
19717   [(match_scratch:SI 3 "r")
19718    (parallel [(set (match_operand:SI 0 "register_operand" "")
19719                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19720                             (match_operand:SI 2 "immediate_operand" "")))
19721               (clobber (reg:CC FLAGS_REG))])]
19722   "TARGET_K8 && !optimize_size
19723    && (GET_CODE (operands[2]) != CONST_INT
19724        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19725   [(set (match_dup 3) (match_dup 1))
19726    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19727               (clobber (reg:CC FLAGS_REG))])]
19728 "")
19729
19730 (define_peephole2
19731   [(match_scratch:SI 3 "r")
19732    (parallel [(set (match_operand:DI 0 "register_operand" "")
19733                    (zero_extend:DI
19734                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19735                               (match_operand:SI 2 "immediate_operand" ""))))
19736               (clobber (reg:CC FLAGS_REG))])]
19737   "TARGET_K8 && !optimize_size
19738    && (GET_CODE (operands[2]) != CONST_INT
19739        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19740   [(set (match_dup 3) (match_dup 1))
19741    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19742               (clobber (reg:CC FLAGS_REG))])]
19743 "")
19744
19745 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19746 ;; Convert it into imul reg, reg
19747 ;; It would be better to force assembler to encode instruction using long
19748 ;; immediate, but there is apparently no way to do so.
19749 (define_peephole2
19750   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19751                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19752                             (match_operand:DI 2 "const_int_operand" "")))
19753               (clobber (reg:CC FLAGS_REG))])
19754    (match_scratch:DI 3 "r")]
19755   "TARGET_K8 && !optimize_size
19756    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19757   [(set (match_dup 3) (match_dup 2))
19758    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19759               (clobber (reg:CC FLAGS_REG))])]
19760 {
19761   if (!rtx_equal_p (operands[0], operands[1]))
19762     emit_move_insn (operands[0], operands[1]);
19763 })
19764
19765 (define_peephole2
19766   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19767                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19768                             (match_operand:SI 2 "const_int_operand" "")))
19769               (clobber (reg:CC FLAGS_REG))])
19770    (match_scratch:SI 3 "r")]
19771   "TARGET_K8 && !optimize_size
19772    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19773   [(set (match_dup 3) (match_dup 2))
19774    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19775               (clobber (reg:CC FLAGS_REG))])]
19776 {
19777   if (!rtx_equal_p (operands[0], operands[1]))
19778     emit_move_insn (operands[0], operands[1]);
19779 })
19780
19781 (define_peephole2
19782   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19783                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19784                             (match_operand:HI 2 "immediate_operand" "")))
19785               (clobber (reg:CC FLAGS_REG))])
19786    (match_scratch:HI 3 "r")]
19787   "TARGET_K8 && !optimize_size"
19788   [(set (match_dup 3) (match_dup 2))
19789    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19790               (clobber (reg:CC FLAGS_REG))])]
19791 {
19792   if (!rtx_equal_p (operands[0], operands[1]))
19793     emit_move_insn (operands[0], operands[1]);
19794 })
19795
19796 ;; After splitting up read-modify operations, array accesses with memory
19797 ;; operands might end up in form:
19798 ;;  sall    $2, %eax
19799 ;;  movl    4(%esp), %edx
19800 ;;  addl    %edx, %eax
19801 ;; instead of pre-splitting:
19802 ;;  sall    $2, %eax
19803 ;;  addl    4(%esp), %eax
19804 ;; Turn it into:
19805 ;;  movl    4(%esp), %edx
19806 ;;  leal    (%edx,%eax,4), %eax
19807
19808 (define_peephole2
19809   [(parallel [(set (match_operand 0 "register_operand" "")
19810                    (ashift (match_operand 1 "register_operand" "")
19811                            (match_operand 2 "const_int_operand" "")))
19812                (clobber (reg:CC FLAGS_REG))])
19813    (set (match_operand 3 "register_operand")
19814         (match_operand 4 "x86_64_general_operand" ""))
19815    (parallel [(set (match_operand 5 "register_operand" "")
19816                    (plus (match_operand 6 "register_operand" "")
19817                          (match_operand 7 "register_operand" "")))
19818                    (clobber (reg:CC FLAGS_REG))])]
19819   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19820    /* Validate MODE for lea.  */
19821    && ((!TARGET_PARTIAL_REG_STALL
19822         && (GET_MODE (operands[0]) == QImode
19823             || GET_MODE (operands[0]) == HImode))
19824        || GET_MODE (operands[0]) == SImode 
19825        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19826    /* We reorder load and the shift.  */
19827    && !rtx_equal_p (operands[1], operands[3])
19828    && !reg_overlap_mentioned_p (operands[0], operands[4])
19829    /* Last PLUS must consist of operand 0 and 3.  */
19830    && !rtx_equal_p (operands[0], operands[3])
19831    && (rtx_equal_p (operands[3], operands[6])
19832        || rtx_equal_p (operands[3], operands[7]))
19833    && (rtx_equal_p (operands[0], operands[6])
19834        || rtx_equal_p (operands[0], operands[7]))
19835    /* The intermediate operand 0 must die or be same as output.  */
19836    && (rtx_equal_p (operands[0], operands[5])
19837        || peep2_reg_dead_p (3, operands[0]))"
19838   [(set (match_dup 3) (match_dup 4))
19839    (set (match_dup 0) (match_dup 1))]
19840 {
19841   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19842   int scale = 1 << INTVAL (operands[2]);
19843   rtx index = gen_lowpart (Pmode, operands[1]);
19844   rtx base = gen_lowpart (Pmode, operands[3]);
19845   rtx dest = gen_lowpart (mode, operands[5]);
19846
19847   operands[1] = gen_rtx_PLUS (Pmode, base,
19848                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19849   if (mode != Pmode)
19850     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19851   operands[0] = dest;
19852 })
19853 \f
19854 ;; Call-value patterns last so that the wildcard operand does not
19855 ;; disrupt insn-recog's switch tables.
19856
19857 (define_insn "*call_value_pop_0"
19858   [(set (match_operand 0 "" "")
19859         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19860               (match_operand:SI 2 "" "")))
19861    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19862                             (match_operand:SI 3 "immediate_operand" "")))]
19863   "!TARGET_64BIT"
19864 {
19865   if (SIBLING_CALL_P (insn))
19866     return "jmp\t%P1";
19867   else
19868     return "call\t%P1";
19869 }
19870   [(set_attr "type" "callv")])
19871
19872 (define_insn "*call_value_pop_1"
19873   [(set (match_operand 0 "" "")
19874         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19875               (match_operand:SI 2 "" "")))
19876    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19877                             (match_operand:SI 3 "immediate_operand" "i")))]
19878   "!TARGET_64BIT"
19879 {
19880   if (constant_call_address_operand (operands[1], Pmode))
19881     {
19882       if (SIBLING_CALL_P (insn))
19883         return "jmp\t%P1";
19884       else
19885         return "call\t%P1";
19886     }
19887   if (SIBLING_CALL_P (insn))
19888     return "jmp\t%A1";
19889   else
19890     return "call\t%A1";
19891 }
19892   [(set_attr "type" "callv")])
19893
19894 (define_insn "*call_value_0"
19895   [(set (match_operand 0 "" "")
19896         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19897               (match_operand:SI 2 "" "")))]
19898   "!TARGET_64BIT"
19899 {
19900   if (SIBLING_CALL_P (insn))
19901     return "jmp\t%P1";
19902   else
19903     return "call\t%P1";
19904 }
19905   [(set_attr "type" "callv")])
19906
19907 (define_insn "*call_value_0_rex64"
19908   [(set (match_operand 0 "" "")
19909         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19910               (match_operand:DI 2 "const_int_operand" "")))]
19911   "TARGET_64BIT"
19912 {
19913   if (SIBLING_CALL_P (insn))
19914     return "jmp\t%P1";
19915   else
19916     return "call\t%P1";
19917 }
19918   [(set_attr "type" "callv")])
19919
19920 (define_insn "*call_value_1"
19921   [(set (match_operand 0 "" "")
19922         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19923               (match_operand:SI 2 "" "")))]
19924   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19925 {
19926   if (constant_call_address_operand (operands[1], Pmode))
19927     return "call\t%P1";
19928   return "call\t%A1";
19929 }
19930   [(set_attr "type" "callv")])
19931
19932 (define_insn "*sibcall_value_1"
19933   [(set (match_operand 0 "" "")
19934         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19935               (match_operand:SI 2 "" "")))]
19936   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19937 {
19938   if (constant_call_address_operand (operands[1], Pmode))
19939     return "jmp\t%P1";
19940   return "jmp\t%A1";
19941 }
19942   [(set_attr "type" "callv")])
19943
19944 (define_insn "*call_value_1_rex64"
19945   [(set (match_operand 0 "" "")
19946         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19947               (match_operand:DI 2 "" "")))]
19948   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19949 {
19950   if (constant_call_address_operand (operands[1], Pmode))
19951     return "call\t%P1";
19952   return "call\t%A1";
19953 }
19954   [(set_attr "type" "callv")])
19955
19956 (define_insn "*sibcall_value_1_rex64"
19957   [(set (match_operand 0 "" "")
19958         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19959               (match_operand:DI 2 "" "")))]
19960   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19961   "jmp\t%P1"
19962   [(set_attr "type" "callv")])
19963
19964 (define_insn "*sibcall_value_1_rex64_v"
19965   [(set (match_operand 0 "" "")
19966         (call (mem:QI (reg:DI 40))
19967               (match_operand:DI 1 "" "")))]
19968   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19969   "jmp\t*%%r11"
19970   [(set_attr "type" "callv")])
19971 \f
19972 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19973 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19974 ;; caught for use by garbage collectors and the like.  Using an insn that
19975 ;; maps to SIGILL makes it more likely the program will rightfully die.
19976 ;; Keeping with tradition, "6" is in honor of #UD.
19977 (define_insn "trap"
19978   [(trap_if (const_int 1) (const_int 6))]
19979   ""
19980   ".word\t0x0b0f"
19981   [(set_attr "length" "2")])
19982
19983 (define_expand "sse_prologue_save"
19984   [(parallel [(set (match_operand:BLK 0 "" "")
19985                    (unspec:BLK [(reg:DI 21)
19986                                 (reg:DI 22)
19987                                 (reg:DI 23)
19988                                 (reg:DI 24)
19989                                 (reg:DI 25)
19990                                 (reg:DI 26)
19991                                 (reg:DI 27)
19992                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19993               (use (match_operand:DI 1 "register_operand" ""))
19994               (use (match_operand:DI 2 "immediate_operand" ""))
19995               (use (label_ref:DI (match_operand 3 "" "")))])]
19996   "TARGET_64BIT"
19997   "")
19998
19999 (define_insn "*sse_prologue_save_insn"
20000   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20001                           (match_operand:DI 4 "const_int_operand" "n")))
20002         (unspec:BLK [(reg:DI 21)
20003                      (reg:DI 22)
20004                      (reg:DI 23)
20005                      (reg:DI 24)
20006                      (reg:DI 25)
20007                      (reg:DI 26)
20008                      (reg:DI 27)
20009                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20010    (use (match_operand:DI 1 "register_operand" "r"))
20011    (use (match_operand:DI 2 "const_int_operand" "i"))
20012    (use (label_ref:DI (match_operand 3 "" "X")))]
20013   "TARGET_64BIT
20014    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20015    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20016   "*
20017 {
20018   int i;
20019   operands[0] = gen_rtx_MEM (Pmode,
20020                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20021   output_asm_insn (\"jmp\\t%A1\", operands);
20022   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20023     {
20024       operands[4] = adjust_address (operands[0], DImode, i*16);
20025       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20026       PUT_MODE (operands[4], TImode);
20027       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20028         output_asm_insn (\"rex\", operands);
20029       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20030     }
20031   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20032                              CODE_LABEL_NUMBER (operands[3]));
20033   RET;
20034 }
20035   "
20036   [(set_attr "type" "other")
20037    (set_attr "length_immediate" "0")
20038    (set_attr "length_address" "0")
20039    (set_attr "length" "135")
20040    (set_attr "memory" "store")
20041    (set_attr "modrm" "0")
20042    (set_attr "mode" "DI")])
20043
20044 (define_expand "prefetch"
20045   [(prefetch (match_operand 0 "address_operand" "")
20046              (match_operand:SI 1 "const_int_operand" "")
20047              (match_operand:SI 2 "const_int_operand" ""))]
20048   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20049 {
20050   int rw = INTVAL (operands[1]);
20051   int locality = INTVAL (operands[2]);
20052
20053   gcc_assert (rw == 0 || rw == 1);
20054   gcc_assert (locality >= 0 && locality <= 3);
20055   gcc_assert (GET_MODE (operands[0]) == Pmode
20056               || GET_MODE (operands[0]) == VOIDmode);
20057
20058   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20059      supported by SSE counterpart or the SSE prefetch is not available
20060      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20061      of locality.  */
20062   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20063     operands[2] = GEN_INT (3);
20064   else
20065     operands[1] = const0_rtx;
20066 })
20067
20068 (define_insn "*prefetch_sse"
20069   [(prefetch (match_operand:SI 0 "address_operand" "p")
20070              (const_int 0)
20071              (match_operand:SI 1 "const_int_operand" ""))]
20072   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20073 {
20074   static const char * const patterns[4] = {
20075    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20076   };
20077
20078   int locality = INTVAL (operands[1]);
20079   gcc_assert (locality >= 0 && locality <= 3);
20080
20081   return patterns[locality];  
20082 }
20083   [(set_attr "type" "sse")
20084    (set_attr "memory" "none")])
20085
20086 (define_insn "*prefetch_sse_rex"
20087   [(prefetch (match_operand:DI 0 "address_operand" "p")
20088              (const_int 0)
20089              (match_operand:SI 1 "const_int_operand" ""))]
20090   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20091 {
20092   static const char * const patterns[4] = {
20093    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20094   };
20095
20096   int locality = INTVAL (operands[1]);
20097   gcc_assert (locality >= 0 && locality <= 3);
20098
20099   return patterns[locality];  
20100 }
20101   [(set_attr "type" "sse")
20102    (set_attr "memory" "none")])
20103
20104 (define_insn "*prefetch_3dnow"
20105   [(prefetch (match_operand:SI 0 "address_operand" "p")
20106              (match_operand:SI 1 "const_int_operand" "n")
20107              (const_int 3))]
20108   "TARGET_3DNOW && !TARGET_64BIT"
20109 {
20110   if (INTVAL (operands[1]) == 0)
20111     return "prefetch\t%a0";
20112   else
20113     return "prefetchw\t%a0";
20114 }
20115   [(set_attr "type" "mmx")
20116    (set_attr "memory" "none")])
20117
20118 (define_insn "*prefetch_3dnow_rex"
20119   [(prefetch (match_operand:DI 0 "address_operand" "p")
20120              (match_operand:SI 1 "const_int_operand" "n")
20121              (const_int 3))]
20122   "TARGET_3DNOW && TARGET_64BIT"
20123 {
20124   if (INTVAL (operands[1]) == 0)
20125     return "prefetch\t%a0";
20126   else
20127     return "prefetchw\t%a0";
20128 }
20129   [(set_attr "type" "mmx")
20130    (set_attr "memory" "none")])
20131
20132 (define_expand "stack_protect_set"
20133   [(match_operand 0 "memory_operand" "")
20134    (match_operand 1 "memory_operand" "")]
20135   ""
20136 {
20137 #ifdef TARGET_THREAD_SSP_OFFSET
20138   if (TARGET_64BIT)
20139     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20140                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20141   else
20142     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20143                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20144 #else
20145   if (TARGET_64BIT)
20146     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20147   else
20148     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20149 #endif
20150   DONE;
20151 })
20152
20153 (define_insn "stack_protect_set_si"
20154   [(set (match_operand:SI 0 "memory_operand" "=m")
20155         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20156    (set (match_scratch:SI 2 "=&r") (const_int 0))
20157    (clobber (reg:CC FLAGS_REG))]
20158   ""
20159   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20160   [(set_attr "type" "multi")])
20161
20162 (define_insn "stack_protect_set_di"
20163   [(set (match_operand:DI 0 "memory_operand" "=m")
20164         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20165    (set (match_scratch:DI 2 "=&r") (const_int 0))
20166    (clobber (reg:CC FLAGS_REG))]
20167   "TARGET_64BIT"
20168   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20169   [(set_attr "type" "multi")])
20170
20171 (define_insn "stack_tls_protect_set_si"
20172   [(set (match_operand:SI 0 "memory_operand" "=m")
20173         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20174    (set (match_scratch:SI 2 "=&r") (const_int 0))
20175    (clobber (reg:CC FLAGS_REG))]
20176   ""
20177   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20178   [(set_attr "type" "multi")])
20179
20180 (define_insn "stack_tls_protect_set_di"
20181   [(set (match_operand:DI 0 "memory_operand" "=m")
20182         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20183    (set (match_scratch:DI 2 "=&r") (const_int 0))
20184    (clobber (reg:CC FLAGS_REG))]
20185   "TARGET_64BIT"
20186   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20187   [(set_attr "type" "multi")])
20188
20189 (define_expand "stack_protect_test"
20190   [(match_operand 0 "memory_operand" "")
20191    (match_operand 1 "memory_operand" "")
20192    (match_operand 2 "" "")]
20193   ""
20194 {
20195   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20196   ix86_compare_op0 = operands[0];
20197   ix86_compare_op1 = operands[1];
20198   ix86_compare_emitted = flags;
20199
20200 #ifdef TARGET_THREAD_SSP_OFFSET
20201   if (TARGET_64BIT)
20202     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20203                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20204   else
20205     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20206                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20207 #else
20208   if (TARGET_64BIT)
20209     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20210   else
20211     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20212 #endif
20213   emit_jump_insn (gen_beq (operands[2]));
20214   DONE;
20215 })
20216
20217 (define_insn "stack_protect_test_si"
20218   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20219         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20220                      (match_operand:SI 2 "memory_operand" "m")]
20221                     UNSPEC_SP_TEST))
20222    (clobber (match_scratch:SI 3 "=&r"))]
20223   ""
20224   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20225   [(set_attr "type" "multi")])
20226
20227 (define_insn "stack_protect_test_di"
20228   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20229         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20230                      (match_operand:DI 2 "memory_operand" "m")]
20231                     UNSPEC_SP_TEST))
20232    (clobber (match_scratch:DI 3 "=&r"))]
20233   "TARGET_64BIT"
20234   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20235   [(set_attr "type" "multi")])
20236
20237 (define_insn "stack_tls_protect_test_si"
20238   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20239         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20240                      (match_operand:SI 2 "const_int_operand" "i")]
20241                     UNSPEC_SP_TLS_TEST))
20242    (clobber (match_scratch:SI 3 "=r"))]
20243   ""
20244   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20245   [(set_attr "type" "multi")])
20246
20247 (define_insn "stack_tls_protect_test_di"
20248   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20249         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20250                      (match_operand:DI 2 "const_int_operand" "i")]
20251                     UNSPEC_SP_TLS_TEST))
20252    (clobber (match_scratch:DI 3 "=r"))]
20253   "TARGET_64BIT"
20254   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20255   [(set_attr "type" "multi")])
20256
20257 (include "sse.md")
20258 (include "mmx.md")
20259 (include "sync.md")