- Test m_pkthdr.fw_flags against DUMMYNET_MBUF_TAGGED before trying to locate
[dragonfly/netmp.git] / contrib / gcc-4.1 / gcc / config / i386 / i386.md
blob6350b5018137a88b58145b92495d0f946ab86842
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.
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.
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.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
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.
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.
51 ;; UNSPEC usage:
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)
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)
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
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)
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)
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
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)
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)
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)
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   ])
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   ])
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   ])
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178 ;; from i386.c.
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".
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")))
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"))
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"))
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")))
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")))
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)")))
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)))
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)))
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)))
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)))
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               (and (match_operand 0 "register_operand" "")
318                    (match_operand 1 "immediate_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "call")
321               (match_operand 0 "constant_call_address_operand" ""))
322              (const_int 0)
323          (and (eq_attr "type" "callv")
324               (match_operand 1 "constant_call_address_operand" ""))
325              (const_int 0)
326          ]
327          (const_int 1)))
329 ;; The (bounding maximum) length of an instruction in bytes.
330 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
331 ;; Later we may want to split them and compute proper length as for
332 ;; other insns.
333 (define_attr "length" ""
334   (cond [(eq_attr "type" "other,multi,fistp,frndint")
335            (const_int 16)
336          (eq_attr "type" "fcmp")
337            (const_int 4)
338          (eq_attr "unit" "i387")
339            (plus (const_int 2)
340                  (plus (attr "prefix_data16")
341                        (attr "length_address")))]
342          (plus (plus (attr "modrm")
343                      (plus (attr "prefix_0f")
344                            (plus (attr "prefix_rex")
345                                  (const_int 1))))
346                (plus (attr "prefix_rep")
347                      (plus (attr "prefix_data16")
348                            (plus (attr "length_immediate")
349                                  (attr "length_address")))))))
351 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
352 ;; `store' if there is a simple memory reference therein, or `unknown'
353 ;; if the instruction is complex.
355 (define_attr "memory" "none,load,store,both,unknown"
356   (cond [(eq_attr "type" "other,multi,str")
357            (const_string "unknown")
358          (eq_attr "type" "lea,fcmov,fpspc,cld")
359            (const_string "none")
360          (eq_attr "type" "fistp,leave")
361            (const_string "both")
362          (eq_attr "type" "frndint")
363            (const_string "load")
364          (eq_attr "type" "push")
365            (if_then_else (match_operand 1 "memory_operand" "")
366              (const_string "both")
367              (const_string "store"))
368          (eq_attr "type" "pop")
369            (if_then_else (match_operand 0 "memory_operand" "")
370              (const_string "both")
371              (const_string "load"))
372          (eq_attr "type" "setcc")
373            (if_then_else (match_operand 0 "memory_operand" "")
374              (const_string "store")
375              (const_string "none"))
376          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
377            (if_then_else (ior (match_operand 0 "memory_operand" "")
378                               (match_operand 1 "memory_operand" ""))
379              (const_string "load")
380              (const_string "none"))
381          (eq_attr "type" "ibr")
382            (if_then_else (match_operand 0 "memory_operand" "")
383              (const_string "load")
384              (const_string "none"))
385          (eq_attr "type" "call")
386            (if_then_else (match_operand 0 "constant_call_address_operand" "")
387              (const_string "none")
388              (const_string "load"))
389          (eq_attr "type" "callv")
390            (if_then_else (match_operand 1 "constant_call_address_operand" "")
391              (const_string "none")
392              (const_string "load"))
393          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
394               (match_operand 1 "memory_operand" ""))
395            (const_string "both")
396          (and (match_operand 0 "memory_operand" "")
397               (match_operand 1 "memory_operand" ""))
398            (const_string "both")
399          (match_operand 0 "memory_operand" "")
400            (const_string "store")
401          (match_operand 1 "memory_operand" "")
402            (const_string "load")
403          (and (eq_attr "type"
404                  "!alu1,negnot,ishift1,
405                    imov,imovx,icmp,test,
406                    fmov,fcmp,fsgn,
407                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
408                    mmx,mmxmov,mmxcmp,mmxcvt")
409               (match_operand 2 "memory_operand" ""))
410            (const_string "load")
411          (and (eq_attr "type" "icmov")
412               (match_operand 3 "memory_operand" ""))
413            (const_string "load")
414         ]
415         (const_string "none")))
417 ;; Indicates if an instruction has both an immediate and a displacement.
419 (define_attr "imm_disp" "false,true,unknown"
420   (cond [(eq_attr "type" "other,multi")
421            (const_string "unknown")
422          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
423               (and (match_operand 0 "memory_displacement_operand" "")
424                    (match_operand 1 "immediate_operand" "")))
425            (const_string "true")
426          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
427               (and (match_operand 0 "memory_displacement_operand" "")
428                    (match_operand 2 "immediate_operand" "")))
429            (const_string "true")
430         ]
431         (const_string "false")))
433 ;; Indicates if an FP operation has an integer source.
435 (define_attr "fp_int_src" "false,true"
436   (const_string "false"))
438 ;; Defines rounding mode of an FP operation.
440 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
441   (const_string "any"))
443 ;; Describe a user's asm statement.
444 (define_asm_attributes
445   [(set_attr "length" "128")
446    (set_attr "type" "multi")])
448 ;; All x87 floating point modes
449 (define_mode_macro X87MODEF [SF DF XF])
451 ;; All integer modes handled by x87 fisttp operator.
452 (define_mode_macro X87MODEI [HI SI DI])
454 ;; All integer modes handled by integer x87 operators.
455 (define_mode_macro X87MODEI12 [HI SI])
457 ;; All SSE floating point modes
458 (define_mode_macro SSEMODEF [SF DF])
460 ;; All integer modes handled by SSE cvtts?2si* operators.
461 (define_mode_macro SSEMODEI24 [SI DI])
464 ;; Scheduling descriptions
466 (include "pentium.md")
467 (include "ppro.md")
468 (include "k6.md")
469 (include "athlon.md")
472 ;; Operand and operator predicates
474 (include "predicates.md")
477 ;; Compare instructions.
479 ;; All compare insns have expanders that save the operands away without
480 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
481 ;; after the cmp) will actually emit the cmpM.
483 (define_expand "cmpti"
484   [(set (reg:CC FLAGS_REG)
485         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
486                     (match_operand:TI 1 "x86_64_general_operand" "")))]
487   "TARGET_64BIT"
489   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
490     operands[0] = force_reg (TImode, operands[0]);
491   ix86_compare_op0 = operands[0];
492   ix86_compare_op1 = operands[1];
493   DONE;
496 (define_expand "cmpdi"
497   [(set (reg:CC FLAGS_REG)
498         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
499                     (match_operand:DI 1 "x86_64_general_operand" "")))]
500   ""
502   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503     operands[0] = force_reg (DImode, operands[0]);
504   ix86_compare_op0 = operands[0];
505   ix86_compare_op1 = operands[1];
506   DONE;
509 (define_expand "cmpsi"
510   [(set (reg:CC FLAGS_REG)
511         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
512                     (match_operand:SI 1 "general_operand" "")))]
513   ""
515   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516     operands[0] = force_reg (SImode, operands[0]);
517   ix86_compare_op0 = operands[0];
518   ix86_compare_op1 = operands[1];
519   DONE;
522 (define_expand "cmphi"
523   [(set (reg:CC FLAGS_REG)
524         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
525                     (match_operand:HI 1 "general_operand" "")))]
526   ""
528   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529     operands[0] = force_reg (HImode, operands[0]);
530   ix86_compare_op0 = operands[0];
531   ix86_compare_op1 = operands[1];
532   DONE;
535 (define_expand "cmpqi"
536   [(set (reg:CC FLAGS_REG)
537         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
538                     (match_operand:QI 1 "general_operand" "")))]
539   "TARGET_QIMODE_MATH"
541   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542     operands[0] = force_reg (QImode, operands[0]);
543   ix86_compare_op0 = operands[0];
544   ix86_compare_op1 = operands[1];
545   DONE;
548 (define_insn "cmpdi_ccno_1_rex64"
549   [(set (reg FLAGS_REG)
550         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
551                  (match_operand:DI 1 "const0_operand" "n,n")))]
552   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
553   "@
554    test{q}\t{%0, %0|%0, %0}
555    cmp{q}\t{%1, %0|%0, %1}"
556   [(set_attr "type" "test,icmp")
557    (set_attr "length_immediate" "0,1")
558    (set_attr "mode" "DI")])
560 (define_insn "*cmpdi_minus_1_rex64"
561   [(set (reg FLAGS_REG)
562         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
563                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
564                  (const_int 0)))]
565   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
566   "cmp{q}\t{%1, %0|%0, %1}"
567   [(set_attr "type" "icmp")
568    (set_attr "mode" "DI")])
570 (define_expand "cmpdi_1_rex64"
571   [(set (reg:CC FLAGS_REG)
572         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
573                     (match_operand:DI 1 "general_operand" "")))]
574   "TARGET_64BIT"
575   "")
577 (define_insn "cmpdi_1_insn_rex64"
578   [(set (reg FLAGS_REG)
579         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
580                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
581   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
582   "cmp{q}\t{%1, %0|%0, %1}"
583   [(set_attr "type" "icmp")
584    (set_attr "mode" "DI")])
587 (define_insn "*cmpsi_ccno_1"
588   [(set (reg FLAGS_REG)
589         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
590                  (match_operand:SI 1 "const0_operand" "n,n")))]
591   "ix86_match_ccmode (insn, CCNOmode)"
592   "@
593    test{l}\t{%0, %0|%0, %0}
594    cmp{l}\t{%1, %0|%0, %1}"
595   [(set_attr "type" "test,icmp")
596    (set_attr "length_immediate" "0,1")
597    (set_attr "mode" "SI")])
599 (define_insn "*cmpsi_minus_1"
600   [(set (reg FLAGS_REG)
601         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
602                            (match_operand:SI 1 "general_operand" "ri,mr"))
603                  (const_int 0)))]
604   "ix86_match_ccmode (insn, CCGOCmode)"
605   "cmp{l}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "icmp")
607    (set_attr "mode" "SI")])
609 (define_expand "cmpsi_1"
610   [(set (reg:CC FLAGS_REG)
611         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
612                     (match_operand:SI 1 "general_operand" "ri,mr")))]
613   ""
614   "")
616 (define_insn "*cmpsi_1_insn"
617   [(set (reg FLAGS_REG)
618         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619                  (match_operand:SI 1 "general_operand" "ri,mr")))]
620   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
621     && ix86_match_ccmode (insn, CCmode)"
622   "cmp{l}\t{%1, %0|%0, %1}"
623   [(set_attr "type" "icmp")
624    (set_attr "mode" "SI")])
626 (define_insn "*cmphi_ccno_1"
627   [(set (reg FLAGS_REG)
628         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
629                  (match_operand:HI 1 "const0_operand" "n,n")))]
630   "ix86_match_ccmode (insn, CCNOmode)"
631   "@
632    test{w}\t{%0, %0|%0, %0}
633    cmp{w}\t{%1, %0|%0, %1}"
634   [(set_attr "type" "test,icmp")
635    (set_attr "length_immediate" "0,1")
636    (set_attr "mode" "HI")])
638 (define_insn "*cmphi_minus_1"
639   [(set (reg FLAGS_REG)
640         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
641                            (match_operand:HI 1 "general_operand" "ri,mr"))
642                  (const_int 0)))]
643   "ix86_match_ccmode (insn, CCGOCmode)"
644   "cmp{w}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "HI")])
648 (define_insn "*cmphi_1"
649   [(set (reg FLAGS_REG)
650         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
651                  (match_operand:HI 1 "general_operand" "ri,mr")))]
652   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
653    && ix86_match_ccmode (insn, CCmode)"
654   "cmp{w}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "icmp")
656    (set_attr "mode" "HI")])
658 (define_insn "*cmpqi_ccno_1"
659   [(set (reg FLAGS_REG)
660         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
661                  (match_operand:QI 1 "const0_operand" "n,n")))]
662   "ix86_match_ccmode (insn, CCNOmode)"
663   "@
664    test{b}\t{%0, %0|%0, %0}
665    cmp{b}\t{$0, %0|%0, 0}"
666   [(set_attr "type" "test,icmp")
667    (set_attr "length_immediate" "0,1")
668    (set_attr "mode" "QI")])
670 (define_insn "*cmpqi_1"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
673                  (match_operand:QI 1 "general_operand" "qi,mq")))]
674   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675     && ix86_match_ccmode (insn, CCmode)"
676   "cmp{b}\t{%1, %0|%0, %1}"
677   [(set_attr "type" "icmp")
678    (set_attr "mode" "QI")])
680 (define_insn "*cmpqi_minus_1"
681   [(set (reg FLAGS_REG)
682         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
683                            (match_operand:QI 1 "general_operand" "qi,mq"))
684                  (const_int 0)))]
685   "ix86_match_ccmode (insn, CCGOCmode)"
686   "cmp{b}\t{%1, %0|%0, %1}"
687   [(set_attr "type" "icmp")
688    (set_attr "mode" "QI")])
690 (define_insn "*cmpqi_ext_1"
691   [(set (reg FLAGS_REG)
692         (compare
693           (match_operand:QI 0 "general_operand" "Qm")
694           (subreg:QI
695             (zero_extract:SI
696               (match_operand 1 "ext_register_operand" "Q")
697               (const_int 8)
698               (const_int 8)) 0)))]
699   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
700   "cmp{b}\t{%h1, %0|%0, %h1}"
701   [(set_attr "type" "icmp")
702    (set_attr "mode" "QI")])
704 (define_insn "*cmpqi_ext_1_rex64"
705   [(set (reg FLAGS_REG)
706         (compare
707           (match_operand:QI 0 "register_operand" "Q")
708           (subreg:QI
709             (zero_extract:SI
710               (match_operand 1 "ext_register_operand" "Q")
711               (const_int 8)
712               (const_int 8)) 0)))]
713   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
714   "cmp{b}\t{%h1, %0|%0, %h1}"
715   [(set_attr "type" "icmp")
716    (set_attr "mode" "QI")])
718 (define_insn "*cmpqi_ext_2"
719   [(set (reg FLAGS_REG)
720         (compare
721           (subreg:QI
722             (zero_extract:SI
723               (match_operand 0 "ext_register_operand" "Q")
724               (const_int 8)
725               (const_int 8)) 0)
726           (match_operand:QI 1 "const0_operand" "n")))]
727   "ix86_match_ccmode (insn, CCNOmode)"
728   "test{b}\t%h0, %h0"
729   [(set_attr "type" "test")
730    (set_attr "length_immediate" "0")
731    (set_attr "mode" "QI")])
733 (define_expand "cmpqi_ext_3"
734   [(set (reg:CC FLAGS_REG)
735         (compare:CC
736           (subreg:QI
737             (zero_extract:SI
738               (match_operand 0 "ext_register_operand" "")
739               (const_int 8)
740               (const_int 8)) 0)
741           (match_operand:QI 1 "general_operand" "")))]
742   ""
743   "")
745 (define_insn "cmpqi_ext_3_insn"
746   [(set (reg FLAGS_REG)
747         (compare
748           (subreg:QI
749             (zero_extract:SI
750               (match_operand 0 "ext_register_operand" "Q")
751               (const_int 8)
752               (const_int 8)) 0)
753           (match_operand:QI 1 "general_operand" "Qmn")))]
754   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755   "cmp{b}\t{%1, %h0|%h0, %1}"
756   [(set_attr "type" "icmp")
757    (set_attr "mode" "QI")])
759 (define_insn "cmpqi_ext_3_insn_rex64"
760   [(set (reg FLAGS_REG)
761         (compare
762           (subreg:QI
763             (zero_extract:SI
764               (match_operand 0 "ext_register_operand" "Q")
765               (const_int 8)
766               (const_int 8)) 0)
767           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
768   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769   "cmp{b}\t{%1, %h0|%h0, %1}"
770   [(set_attr "type" "icmp")
771    (set_attr "mode" "QI")])
773 (define_insn "*cmpqi_ext_4"
774   [(set (reg FLAGS_REG)
775         (compare
776           (subreg:QI
777             (zero_extract:SI
778               (match_operand 0 "ext_register_operand" "Q")
779               (const_int 8)
780               (const_int 8)) 0)
781           (subreg:QI
782             (zero_extract:SI
783               (match_operand 1 "ext_register_operand" "Q")
784               (const_int 8)
785               (const_int 8)) 0)))]
786   "ix86_match_ccmode (insn, CCmode)"
787   "cmp{b}\t{%h1, %h0|%h0, %h1}"
788   [(set_attr "type" "icmp")
789    (set_attr "mode" "QI")])
791 ;; These implement float point compares.
792 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
793 ;; which would allow mix and match FP modes on the compares.  Which is what
794 ;; the old patterns did, but with many more of them.
796 (define_expand "cmpxf"
797   [(set (reg:CC FLAGS_REG)
798         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
799                     (match_operand:XF 1 "nonmemory_operand" "")))]
800   "TARGET_80387"
802   ix86_compare_op0 = operands[0];
803   ix86_compare_op1 = operands[1];
804   DONE;
807 (define_expand "cmpdf"
808   [(set (reg:CC FLAGS_REG)
809         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
810                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
811   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
813   ix86_compare_op0 = operands[0];
814   ix86_compare_op1 = operands[1];
815   DONE;
818 (define_expand "cmpsf"
819   [(set (reg:CC FLAGS_REG)
820         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
821                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
822   "TARGET_80387 || TARGET_SSE_MATH"
824   ix86_compare_op0 = operands[0];
825   ix86_compare_op1 = operands[1];
826   DONE;
829 ;; FP compares, step 1:
830 ;; Set the FP condition codes.
832 ;; CCFPmode     compare with exceptions
833 ;; CCFPUmode    compare with no exceptions
835 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
836 ;; used to manage the reg stack popping would not be preserved.
838 (define_insn "*cmpfp_0"
839   [(set (match_operand:HI 0 "register_operand" "=a")
840         (unspec:HI
841           [(compare:CCFP
842              (match_operand 1 "register_operand" "f")
843              (match_operand 2 "const0_operand" "X"))]
844         UNSPEC_FNSTSW))]
845   "TARGET_80387
846    && FLOAT_MODE_P (GET_MODE (operands[1]))
847    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
848   "* return output_fp_compare (insn, operands, 0, 0);"
849   [(set_attr "type" "multi")
850    (set_attr "unit" "i387")
851    (set (attr "mode")
852      (cond [(match_operand:SF 1 "" "")
853               (const_string "SF")
854             (match_operand:DF 1 "" "")
855               (const_string "DF")
856            ]
857            (const_string "XF")))])
859 (define_insn "*cmpfp_sf"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand:SF 1 "register_operand" "f")
864              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
865           UNSPEC_FNSTSW))]
866   "TARGET_80387"
867   "* return output_fp_compare (insn, operands, 0, 0);"
868   [(set_attr "type" "multi")
869    (set_attr "unit" "i387")
870    (set_attr "mode" "SF")])
872 (define_insn "*cmpfp_df"
873   [(set (match_operand:HI 0 "register_operand" "=a")
874         (unspec:HI
875           [(compare:CCFP
876              (match_operand:DF 1 "register_operand" "f")
877              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
878           UNSPEC_FNSTSW))]
879   "TARGET_80387"
880   "* return output_fp_compare (insn, operands, 0, 0);"
881   [(set_attr "type" "multi")
882    (set_attr "unit" "i387")
883    (set_attr "mode" "DF")])
885 (define_insn "*cmpfp_xf"
886   [(set (match_operand:HI 0 "register_operand" "=a")
887         (unspec:HI
888           [(compare:CCFP
889              (match_operand:XF 1 "register_operand" "f")
890              (match_operand:XF 2 "register_operand" "f"))]
891           UNSPEC_FNSTSW))]
892   "TARGET_80387"
893   "* return output_fp_compare (insn, operands, 0, 0);"
894   [(set_attr "type" "multi")
895    (set_attr "unit" "i387")
896    (set_attr "mode" "XF")])
898 (define_insn "*cmpfp_u"
899   [(set (match_operand:HI 0 "register_operand" "=a")
900         (unspec:HI
901           [(compare:CCFPU
902              (match_operand 1 "register_operand" "f")
903              (match_operand 2 "register_operand" "f"))]
904           UNSPEC_FNSTSW))]
905   "TARGET_80387
906    && FLOAT_MODE_P (GET_MODE (operands[1]))
907    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
908   "* return output_fp_compare (insn, operands, 0, 1);"
909   [(set_attr "type" "multi")
910    (set_attr "unit" "i387")
911    (set (attr "mode")
912      (cond [(match_operand:SF 1 "" "")
913               (const_string "SF")
914             (match_operand:DF 1 "" "")
915               (const_string "DF")
916            ]
917            (const_string "XF")))])
919 (define_insn "*cmpfp_<mode>"
920   [(set (match_operand:HI 0 "register_operand" "=a")
921         (unspec:HI
922           [(compare:CCFP
923              (match_operand 1 "register_operand" "f")
924              (match_operator 3 "float_operator"
925                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
926           UNSPEC_FNSTSW))]
927   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
928    && FLOAT_MODE_P (GET_MODE (operands[1]))
929    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
930   "* return output_fp_compare (insn, operands, 0, 0);"
931   [(set_attr "type" "multi")
932    (set_attr "unit" "i387")
933    (set_attr "fp_int_src" "true")
934    (set_attr "mode" "<MODE>")])
936 ;; FP compares, step 2
937 ;; Move the fpsw to ax.
939 (define_insn "x86_fnstsw_1"
940   [(set (match_operand:HI 0 "register_operand" "=a")
941         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
942   "TARGET_80387"
943   "fnstsw\t%0"
944   [(set_attr "length" "2")
945    (set_attr "mode" "SI")
946    (set_attr "unit" "i387")])
948 ;; FP compares, step 3
949 ;; Get ax into flags, general case.
951 (define_insn "x86_sahf_1"
952   [(set (reg:CC FLAGS_REG)
953         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
954   "!TARGET_64BIT"
955   "sahf"
956   [(set_attr "length" "1")
957    (set_attr "athlon_decode" "vector")
958    (set_attr "mode" "SI")])
960 ;; Pentium Pro can do steps 1 through 3 in one go.
962 (define_insn "*cmpfp_i_mixed"
963   [(set (reg:CCFP FLAGS_REG)
964         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
965                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
966   "TARGET_MIX_SSE_I387
967    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969   "* return output_fp_compare (insn, operands, 1, 0);"
970   [(set_attr "type" "fcmp,ssecomi")
971    (set (attr "mode")
972      (if_then_else (match_operand:SF 1 "" "")
973         (const_string "SF")
974         (const_string "DF")))
975    (set_attr "athlon_decode" "vector")])
977 (define_insn "*cmpfp_i_sse"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "x")
980                       (match_operand 1 "nonimmediate_operand" "xm")))]
981   "TARGET_SSE_MATH
982    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984   "* return output_fp_compare (insn, operands, 1, 0);"
985   [(set_attr "type" "ssecomi")
986    (set (attr "mode")
987      (if_then_else (match_operand:SF 1 "" "")
988         (const_string "SF")
989         (const_string "DF")))
990    (set_attr "athlon_decode" "vector")])
992 (define_insn "*cmpfp_i_i387"
993   [(set (reg:CCFP FLAGS_REG)
994         (compare:CCFP (match_operand 0 "register_operand" "f")
995                       (match_operand 1 "register_operand" "f")))]
996   "TARGET_80387 && TARGET_CMOVE
997    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
998    && FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp")
1002    (set (attr "mode")
1003      (cond [(match_operand:SF 1 "" "")
1004               (const_string "SF")
1005             (match_operand:DF 1 "" "")
1006               (const_string "DF")
1007            ]
1008            (const_string "XF")))
1009    (set_attr "athlon_decode" "vector")])
1011 (define_insn "*cmpfp_iu_mixed"
1012   [(set (reg:CCFPU FLAGS_REG)
1013         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1014                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1015   "TARGET_MIX_SSE_I387
1016    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018   "* return output_fp_compare (insn, operands, 1, 1);"
1019   [(set_attr "type" "fcmp,ssecomi")
1020    (set (attr "mode")
1021      (if_then_else (match_operand:SF 1 "" "")
1022         (const_string "SF")
1023         (const_string "DF")))
1024    (set_attr "athlon_decode" "vector")])
1026 (define_insn "*cmpfp_iu_sse"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "x")
1029                        (match_operand 1 "nonimmediate_operand" "xm")))]
1030   "TARGET_SSE_MATH
1031    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 1);"
1034   [(set_attr "type" "ssecomi")
1035    (set (attr "mode")
1036      (if_then_else (match_operand:SF 1 "" "")
1037         (const_string "SF")
1038         (const_string "DF")))
1039    (set_attr "athlon_decode" "vector")])
1041 (define_insn "*cmpfp_iu_387"
1042   [(set (reg:CCFPU FLAGS_REG)
1043         (compare:CCFPU (match_operand 0 "register_operand" "f")
1044                        (match_operand 1 "register_operand" "f")))]
1045   "TARGET_80387 && TARGET_CMOVE
1046    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1047    && FLOAT_MODE_P (GET_MODE (operands[0]))
1048    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1049   "* return output_fp_compare (insn, operands, 1, 1);"
1050   [(set_attr "type" "fcmp")
1051    (set (attr "mode")
1052      (cond [(match_operand:SF 1 "" "")
1053               (const_string "SF")
1054             (match_operand:DF 1 "" "")
1055               (const_string "DF")
1056            ]
1057            (const_string "XF")))
1058    (set_attr "athlon_decode" "vector")])
1060 ;; Move instructions.
1062 ;; General case of fullword move.
1064 (define_expand "movsi"
1065   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1066         (match_operand:SI 1 "general_operand" ""))]
1067   ""
1068   "ix86_expand_move (SImode, operands); DONE;")
1070 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1071 ;; general_operand.
1073 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1074 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1075 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1076 ;; targets without our curiosities, and it is just as easy to represent
1077 ;; this differently.
1079 (define_insn "*pushsi2"
1080   [(set (match_operand:SI 0 "push_operand" "=<")
1081         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1082   "!TARGET_64BIT"
1083   "push{l}\t%1"
1084   [(set_attr "type" "push")
1085    (set_attr "mode" "SI")])
1087 ;; For 64BIT abi we always round up to 8 bytes.
1088 (define_insn "*pushsi2_rex64"
1089   [(set (match_operand:SI 0 "push_operand" "=X")
1090         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1091   "TARGET_64BIT"
1092   "push{q}\t%q1"
1093   [(set_attr "type" "push")
1094    (set_attr "mode" "SI")])
1096 (define_insn "*pushsi2_prologue"
1097   [(set (match_operand:SI 0 "push_operand" "=<")
1098         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1099    (clobber (mem:BLK (scratch)))]
1100   "!TARGET_64BIT"
1101   "push{l}\t%1"
1102   [(set_attr "type" "push")
1103    (set_attr "mode" "SI")])
1105 (define_insn "*popsi1_epilogue"
1106   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1107         (mem:SI (reg:SI SP_REG)))
1108    (set (reg:SI SP_REG)
1109         (plus:SI (reg:SI SP_REG) (const_int 4)))
1110    (clobber (mem:BLK (scratch)))]
1111   "!TARGET_64BIT"
1112   "pop{l}\t%0"
1113   [(set_attr "type" "pop")
1114    (set_attr "mode" "SI")])
1116 (define_insn "popsi1"
1117   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1118         (mem:SI (reg:SI SP_REG)))
1119    (set (reg:SI SP_REG)
1120         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1121   "!TARGET_64BIT"
1122   "pop{l}\t%0"
1123   [(set_attr "type" "pop")
1124    (set_attr "mode" "SI")])
1126 (define_insn "*movsi_xor"
1127   [(set (match_operand:SI 0 "register_operand" "=r")
1128         (match_operand:SI 1 "const0_operand" "i"))
1129    (clobber (reg:CC FLAGS_REG))]
1130   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1131   "xor{l}\t{%0, %0|%0, %0}"
1132   [(set_attr "type" "alu1")
1133    (set_attr "mode" "SI")
1134    (set_attr "length_immediate" "0")])
1136 (define_insn "*movsi_or"
1137   [(set (match_operand:SI 0 "register_operand" "=r")
1138         (match_operand:SI 1 "immediate_operand" "i"))
1139    (clobber (reg:CC FLAGS_REG))]
1140   "reload_completed
1141    && operands[1] == constm1_rtx
1142    && (TARGET_PENTIUM || optimize_size)"
1144   operands[1] = constm1_rtx;
1145   return "or{l}\t{%1, %0|%0, %1}";
1147   [(set_attr "type" "alu1")
1148    (set_attr "mode" "SI")
1149    (set_attr "length_immediate" "1")])
1151 (define_insn "*movsi_1"
1152   [(set (match_operand:SI 0 "nonimmediate_operand"
1153                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1154         (match_operand:SI 1 "general_operand"
1155                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1156   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1158   switch (get_attr_type (insn))
1159     {
1160     case TYPE_SSELOG1:
1161       if (get_attr_mode (insn) == MODE_TI)
1162         return "pxor\t%0, %0";
1163       return "xorps\t%0, %0";
1165     case TYPE_SSEMOV:
1166       switch (get_attr_mode (insn))
1167         {
1168         case MODE_TI:
1169           return "movdqa\t{%1, %0|%0, %1}";
1170         case MODE_V4SF:
1171           return "movaps\t{%1, %0|%0, %1}";
1172         case MODE_SI:
1173           return "movd\t{%1, %0|%0, %1}";
1174         case MODE_SF:
1175           return "movss\t{%1, %0|%0, %1}";
1176         default:
1177           gcc_unreachable ();
1178         }
1180     case TYPE_MMXADD:
1181       return "pxor\t%0, %0";
1183     case TYPE_MMXMOV:
1184       if (get_attr_mode (insn) == MODE_DI)
1185         return "movq\t{%1, %0|%0, %1}";
1186       return "movd\t{%1, %0|%0, %1}";
1188     case TYPE_LEA:
1189       return "lea{l}\t{%1, %0|%0, %1}";
1191     default:
1192       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1193       return "mov{l}\t{%1, %0|%0, %1}";
1194     }
1196   [(set (attr "type")
1197      (cond [(eq_attr "alternative" "2")
1198               (const_string "mmxadd")
1199             (eq_attr "alternative" "3,4,5")
1200               (const_string "mmxmov")
1201             (eq_attr "alternative" "6")
1202               (const_string "sselog1")
1203             (eq_attr "alternative" "7,8,9,10,11")
1204               (const_string "ssemov")
1205             (match_operand:DI 1 "pic_32bit_operand" "")
1206               (const_string "lea")
1207            ]
1208            (const_string "imov")))
1209    (set (attr "mode")
1210      (cond [(eq_attr "alternative" "2,3")
1211               (const_string "DI")
1212             (eq_attr "alternative" "6,7")
1213               (if_then_else
1214                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1215                 (const_string "V4SF")
1216                 (const_string "TI"))
1217             (and (eq_attr "alternative" "8,9,10,11")
1218                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1219               (const_string "SF")
1220            ]
1221            (const_string "SI")))])
1223 ;; Stores and loads of ax to arbitrary constant address.
1224 ;; We fake an second form of instruction to force reload to load address
1225 ;; into register when rax is not available
1226 (define_insn "*movabssi_1_rex64"
1227   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1228         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1229   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1230   "@
1231    movabs{l}\t{%1, %P0|%P0, %1}
1232    mov{l}\t{%1, %a0|%a0, %1}"
1233   [(set_attr "type" "imov")
1234    (set_attr "modrm" "0,*")
1235    (set_attr "length_address" "8,0")
1236    (set_attr "length_immediate" "0,*")
1237    (set_attr "memory" "store")
1238    (set_attr "mode" "SI")])
1240 (define_insn "*movabssi_2_rex64"
1241   [(set (match_operand:SI 0 "register_operand" "=a,r")
1242         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1243   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1244   "@
1245    movabs{l}\t{%P1, %0|%0, %P1}
1246    mov{l}\t{%a1, %0|%0, %a1}"
1247   [(set_attr "type" "imov")
1248    (set_attr "modrm" "0,*")
1249    (set_attr "length_address" "8,0")
1250    (set_attr "length_immediate" "0")
1251    (set_attr "memory" "load")
1252    (set_attr "mode" "SI")])
1254 (define_insn "*swapsi"
1255   [(set (match_operand:SI 0 "register_operand" "+r")
1256         (match_operand:SI 1 "register_operand" "+r"))
1257    (set (match_dup 1)
1258         (match_dup 0))]
1259   ""
1260   "xchg{l}\t%1, %0"
1261   [(set_attr "type" "imov")
1262    (set_attr "mode" "SI")
1263    (set_attr "pent_pair" "np")
1264    (set_attr "athlon_decode" "vector")])
1266 (define_expand "movhi"
1267   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1268         (match_operand:HI 1 "general_operand" ""))]
1269   ""
1270   "ix86_expand_move (HImode, operands); DONE;")
1272 (define_insn "*pushhi2"
1273   [(set (match_operand:HI 0 "push_operand" "=X")
1274         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1275   "!TARGET_64BIT"
1276   "push{l}\t%k1"
1277   [(set_attr "type" "push")
1278    (set_attr "mode" "SI")])
1280 ;; For 64BIT abi we always round up to 8 bytes.
1281 (define_insn "*pushhi2_rex64"
1282   [(set (match_operand:HI 0 "push_operand" "=X")
1283         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1284   "TARGET_64BIT"
1285   "push{q}\t%q1"
1286   [(set_attr "type" "push")
1287    (set_attr "mode" "DI")])
1289 (define_insn "*movhi_1"
1290   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1291         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1292   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1294   switch (get_attr_type (insn))
1295     {
1296     case TYPE_IMOVX:
1297       /* movzwl is faster than movw on p2 due to partial word stalls,
1298          though not as fast as an aligned movl.  */
1299       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1300     default:
1301       if (get_attr_mode (insn) == MODE_SI)
1302         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1303       else
1304         return "mov{w}\t{%1, %0|%0, %1}";
1305     }
1307   [(set (attr "type")
1308      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1309               (const_string "imov")
1310             (and (eq_attr "alternative" "0")
1311                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1312                           (const_int 0))
1313                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1314                           (const_int 0))))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "1,2")
1317                  (match_operand:HI 1 "aligned_operand" ""))
1318               (const_string "imov")
1319             (and (ne (symbol_ref "TARGET_MOVX")
1320                      (const_int 0))
1321                  (eq_attr "alternative" "0,2"))
1322               (const_string "imovx")
1323            ]
1324            (const_string "imov")))
1325     (set (attr "mode")
1326       (cond [(eq_attr "type" "imovx")
1327                (const_string "SI")
1328              (and (eq_attr "alternative" "1,2")
1329                   (match_operand:HI 1 "aligned_operand" ""))
1330                (const_string "SI")
1331              (and (eq_attr "alternative" "0")
1332                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333                            (const_int 0))
1334                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1335                            (const_int 0))))
1336                (const_string "SI")
1337             ]
1338             (const_string "HI")))])
1340 ;; Stores and loads of ax to arbitrary constant address.
1341 ;; We fake an second form of instruction to force reload to load address
1342 ;; into register when rax is not available
1343 (define_insn "*movabshi_1_rex64"
1344   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1345         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1346   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1347   "@
1348    movabs{w}\t{%1, %P0|%P0, %1}
1349    mov{w}\t{%1, %a0|%a0, %1}"
1350   [(set_attr "type" "imov")
1351    (set_attr "modrm" "0,*")
1352    (set_attr "length_address" "8,0")
1353    (set_attr "length_immediate" "0,*")
1354    (set_attr "memory" "store")
1355    (set_attr "mode" "HI")])
1357 (define_insn "*movabshi_2_rex64"
1358   [(set (match_operand:HI 0 "register_operand" "=a,r")
1359         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1360   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1361   "@
1362    movabs{w}\t{%P1, %0|%0, %P1}
1363    mov{w}\t{%a1, %0|%0, %a1}"
1364   [(set_attr "type" "imov")
1365    (set_attr "modrm" "0,*")
1366    (set_attr "length_address" "8,0")
1367    (set_attr "length_immediate" "0")
1368    (set_attr "memory" "load")
1369    (set_attr "mode" "HI")])
1371 (define_insn "*swaphi_1"
1372   [(set (match_operand:HI 0 "register_operand" "+r")
1373         (match_operand:HI 1 "register_operand" "+r"))
1374    (set (match_dup 1)
1375         (match_dup 0))]
1376   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1377   "xchg{l}\t%k1, %k0"
1378   [(set_attr "type" "imov")
1379    (set_attr "mode" "SI")
1380    (set_attr "pent_pair" "np")
1381    (set_attr "athlon_decode" "vector")])
1383 (define_insn "*swaphi_2"
1384   [(set (match_operand:HI 0 "register_operand" "+r")
1385         (match_operand:HI 1 "register_operand" "+r"))
1386    (set (match_dup 1)
1387         (match_dup 0))]
1388   "TARGET_PARTIAL_REG_STALL"
1389   "xchg{w}\t%1, %0"
1390   [(set_attr "type" "imov")
1391    (set_attr "mode" "HI")
1392    (set_attr "pent_pair" "np")
1393    (set_attr "athlon_decode" "vector")])
1395 (define_expand "movstricthi"
1396   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1397         (match_operand:HI 1 "general_operand" ""))]
1398   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1400   /* Don't generate memory->memory moves, go through a register */
1401   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1402     operands[1] = force_reg (HImode, operands[1]);
1405 (define_insn "*movstricthi_1"
1406   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1407         (match_operand:HI 1 "general_operand" "rn,m"))]
1408   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1409    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1410   "mov{w}\t{%1, %0|%0, %1}"
1411   [(set_attr "type" "imov")
1412    (set_attr "mode" "HI")])
1414 (define_insn "*movstricthi_xor"
1415   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1416         (match_operand:HI 1 "const0_operand" "i"))
1417    (clobber (reg:CC FLAGS_REG))]
1418   "reload_completed
1419    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1420   "xor{w}\t{%0, %0|%0, %0}"
1421   [(set_attr "type" "alu1")
1422    (set_attr "mode" "HI")
1423    (set_attr "length_immediate" "0")])
1425 (define_expand "movqi"
1426   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1427         (match_operand:QI 1 "general_operand" ""))]
1428   ""
1429   "ix86_expand_move (QImode, operands); DONE;")
1431 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1432 ;; "push a byte".  But actually we use pushl, which has the effect
1433 ;; of rounding the amount pushed up to a word.
1435 (define_insn "*pushqi2"
1436   [(set (match_operand:QI 0 "push_operand" "=X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1438   "!TARGET_64BIT"
1439   "push{l}\t%k1"
1440   [(set_attr "type" "push")
1441    (set_attr "mode" "SI")])
1443 ;; For 64BIT abi we always round up to 8 bytes.
1444 (define_insn "*pushqi2_rex64"
1445   [(set (match_operand:QI 0 "push_operand" "=X")
1446         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1447   "TARGET_64BIT"
1448   "push{q}\t%q1"
1449   [(set_attr "type" "push")
1450    (set_attr "mode" "DI")])
1452 ;; Situation is quite tricky about when to choose full sized (SImode) move
1453 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1454 ;; partial register dependency machines (such as AMD Athlon), where QImode
1455 ;; moves issue extra dependency and for partial register stalls machines
1456 ;; that don't use QImode patterns (and QImode move cause stall on the next
1457 ;; instruction).
1459 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1460 ;; register stall machines with, where we use QImode instructions, since
1461 ;; partial register stall can be caused there.  Then we use movzx.
1462 (define_insn "*movqi_1"
1463   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1464         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1465   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1467   switch (get_attr_type (insn))
1468     {
1469     case TYPE_IMOVX:
1470       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1471       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1472     default:
1473       if (get_attr_mode (insn) == MODE_SI)
1474         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1475       else
1476         return "mov{b}\t{%1, %0|%0, %1}";
1477     }
1479   [(set (attr "type")
1480      (cond [(and (eq_attr "alternative" "5")
1481                  (not (match_operand:QI 1 "aligned_operand" "")))
1482               (const_string "imovx")
1483             (ne (symbol_ref "optimize_size") (const_int 0))
1484               (const_string "imov")
1485             (and (eq_attr "alternative" "3")
1486                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1487                           (const_int 0))
1488                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1489                           (const_int 0))))
1490               (const_string "imov")
1491             (eq_attr "alternative" "3,5")
1492               (const_string "imovx")
1493             (and (ne (symbol_ref "TARGET_MOVX")
1494                      (const_int 0))
1495                  (eq_attr "alternative" "2"))
1496               (const_string "imovx")
1497            ]
1498            (const_string "imov")))
1499    (set (attr "mode")
1500       (cond [(eq_attr "alternative" "3,4,5")
1501                (const_string "SI")
1502              (eq_attr "alternative" "6")
1503                (const_string "QI")
1504              (eq_attr "type" "imovx")
1505                (const_string "SI")
1506              (and (eq_attr "type" "imov")
1507                   (and (eq_attr "alternative" "0,1")
1508                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1509                            (const_int 0))))
1510                (const_string "SI")
1511              ;; Avoid partial register stalls when not using QImode arithmetic
1512              (and (eq_attr "type" "imov")
1513                   (and (eq_attr "alternative" "0,1")
1514                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1515                                 (const_int 0))
1516                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1517                                 (const_int 0)))))
1518                (const_string "SI")
1519            ]
1520            (const_string "QI")))])
1522 (define_expand "reload_outqi"
1523   [(parallel [(match_operand:QI 0 "" "=m")
1524               (match_operand:QI 1 "register_operand" "r")
1525               (match_operand:QI 2 "register_operand" "=&q")])]
1526   ""
1528   rtx op0, op1, op2;
1529   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1531   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1532   if (! q_regs_operand (op1, QImode))
1533     {
1534       emit_insn (gen_movqi (op2, op1));
1535       op1 = op2;
1536     }
1537   emit_insn (gen_movqi (op0, op1));
1538   DONE;
1541 (define_insn "*swapqi_1"
1542   [(set (match_operand:QI 0 "register_operand" "+r")
1543         (match_operand:QI 1 "register_operand" "+r"))
1544    (set (match_dup 1)
1545         (match_dup 0))]
1546   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1547   "xchg{l}\t%k1, %k0"
1548   [(set_attr "type" "imov")
1549    (set_attr "mode" "SI")
1550    (set_attr "pent_pair" "np")
1551    (set_attr "athlon_decode" "vector")])
1553 (define_insn "*swapqi_2"
1554   [(set (match_operand:QI 0 "register_operand" "+q")
1555         (match_operand:QI 1 "register_operand" "+q"))
1556    (set (match_dup 1)
1557         (match_dup 0))]
1558   "TARGET_PARTIAL_REG_STALL"
1559   "xchg{b}\t%1, %0"
1560   [(set_attr "type" "imov")
1561    (set_attr "mode" "QI")
1562    (set_attr "pent_pair" "np")
1563    (set_attr "athlon_decode" "vector")])
1565 (define_expand "movstrictqi"
1566   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1567         (match_operand:QI 1 "general_operand" ""))]
1568   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1570   /* Don't generate memory->memory moves, go through a register.  */
1571   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1572     operands[1] = force_reg (QImode, operands[1]);
1575 (define_insn "*movstrictqi_1"
1576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1577         (match_operand:QI 1 "general_operand" "*qn,m"))]
1578   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1580   "mov{b}\t{%1, %0|%0, %1}"
1581   [(set_attr "type" "imov")
1582    (set_attr "mode" "QI")])
1584 (define_insn "*movstrictqi_xor"
1585   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1586         (match_operand:QI 1 "const0_operand" "i"))
1587    (clobber (reg:CC FLAGS_REG))]
1588   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1589   "xor{b}\t{%0, %0|%0, %0}"
1590   [(set_attr "type" "alu1")
1591    (set_attr "mode" "QI")
1592    (set_attr "length_immediate" "0")])
1594 (define_insn "*movsi_extv_1"
1595   [(set (match_operand:SI 0 "register_operand" "=R")
1596         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1597                          (const_int 8)
1598                          (const_int 8)))]
1599   ""
1600   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1601   [(set_attr "type" "imovx")
1602    (set_attr "mode" "SI")])
1604 (define_insn "*movhi_extv_1"
1605   [(set (match_operand:HI 0 "register_operand" "=R")
1606         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   ""
1610   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1611   [(set_attr "type" "imovx")
1612    (set_attr "mode" "SI")])
1614 (define_insn "*movqi_extv_1"
1615   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1616         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   "!TARGET_64BIT"
1621   switch (get_attr_type (insn))
1622     {
1623     case TYPE_IMOVX:
1624       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1625     default:
1626       return "mov{b}\t{%h1, %0|%0, %h1}";
1627     }
1629   [(set (attr "type")
1630      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1631                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1632                              (ne (symbol_ref "TARGET_MOVX")
1633                                  (const_int 0))))
1634         (const_string "imovx")
1635         (const_string "imov")))
1636    (set (attr "mode")
1637      (if_then_else (eq_attr "type" "imovx")
1638         (const_string "SI")
1639         (const_string "QI")))])
1641 (define_insn "*movqi_extv_1_rex64"
1642   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1643         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   "TARGET_64BIT"
1648   switch (get_attr_type (insn))
1649     {
1650     case TYPE_IMOVX:
1651       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652     default:
1653       return "mov{b}\t{%h1, %0|%0, %h1}";
1654     }
1656   [(set (attr "type")
1657      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659                              (ne (symbol_ref "TARGET_MOVX")
1660                                  (const_int 0))))
1661         (const_string "imovx")
1662         (const_string "imov")))
1663    (set (attr "mode")
1664      (if_then_else (eq_attr "type" "imovx")
1665         (const_string "SI")
1666         (const_string "QI")))])
1668 ;; Stores and loads of ax to arbitrary constant address.
1669 ;; We fake an second form of instruction to force reload to load address
1670 ;; into register when rax is not available
1671 (define_insn "*movabsqi_1_rex64"
1672   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1673         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1674   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1675   "@
1676    movabs{b}\t{%1, %P0|%P0, %1}
1677    mov{b}\t{%1, %a0|%a0, %1}"
1678   [(set_attr "type" "imov")
1679    (set_attr "modrm" "0,*")
1680    (set_attr "length_address" "8,0")
1681    (set_attr "length_immediate" "0,*")
1682    (set_attr "memory" "store")
1683    (set_attr "mode" "QI")])
1685 (define_insn "*movabsqi_2_rex64"
1686   [(set (match_operand:QI 0 "register_operand" "=a,r")
1687         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1688   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1689   "@
1690    movabs{b}\t{%P1, %0|%0, %P1}
1691    mov{b}\t{%a1, %0|%0, %a1}"
1692   [(set_attr "type" "imov")
1693    (set_attr "modrm" "0,*")
1694    (set_attr "length_address" "8,0")
1695    (set_attr "length_immediate" "0")
1696    (set_attr "memory" "load")
1697    (set_attr "mode" "QI")])
1699 (define_insn "*movdi_extzv_1"
1700   [(set (match_operand:DI 0 "register_operand" "=R")
1701         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1702                          (const_int 8)
1703                          (const_int 8)))]
1704   "TARGET_64BIT"
1705   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1706   [(set_attr "type" "imovx")
1707    (set_attr "mode" "DI")])
1709 (define_insn "*movsi_extzv_1"
1710   [(set (match_operand:SI 0 "register_operand" "=R")
1711         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1712                          (const_int 8)
1713                          (const_int 8)))]
1714   ""
1715   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1716   [(set_attr "type" "imovx")
1717    (set_attr "mode" "SI")])
1719 (define_insn "*movqi_extzv_2"
1720   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1721         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1722                                     (const_int 8)
1723                                     (const_int 8)) 0))]
1724   "!TARGET_64BIT"
1726   switch (get_attr_type (insn))
1727     {
1728     case TYPE_IMOVX:
1729       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1730     default:
1731       return "mov{b}\t{%h1, %0|%0, %h1}";
1732     }
1734   [(set (attr "type")
1735      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1736                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1737                              (ne (symbol_ref "TARGET_MOVX")
1738                                  (const_int 0))))
1739         (const_string "imovx")
1740         (const_string "imov")))
1741    (set (attr "mode")
1742      (if_then_else (eq_attr "type" "imovx")
1743         (const_string "SI")
1744         (const_string "QI")))])
1746 (define_insn "*movqi_extzv_2_rex64"
1747   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1748         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1749                                     (const_int 8)
1750                                     (const_int 8)) 0))]
1751   "TARGET_64BIT"
1753   switch (get_attr_type (insn))
1754     {
1755     case TYPE_IMOVX:
1756       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1757     default:
1758       return "mov{b}\t{%h1, %0|%0, %h1}";
1759     }
1761   [(set (attr "type")
1762      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763                         (ne (symbol_ref "TARGET_MOVX")
1764                             (const_int 0)))
1765         (const_string "imovx")
1766         (const_string "imov")))
1767    (set (attr "mode")
1768      (if_then_else (eq_attr "type" "imovx")
1769         (const_string "SI")
1770         (const_string "QI")))])
1772 (define_insn "movsi_insv_1"
1773   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1774                          (const_int 8)
1775                          (const_int 8))
1776         (match_operand:SI 1 "general_operand" "Qmn"))]
1777   "!TARGET_64BIT"
1778   "mov{b}\t{%b1, %h0|%h0, %b1}"
1779   [(set_attr "type" "imov")
1780    (set_attr "mode" "QI")])
1782 (define_insn "movdi_insv_1_rex64"
1783   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1784                          (const_int 8)
1785                          (const_int 8))
1786         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1787   "TARGET_64BIT"
1788   "mov{b}\t{%b1, %h0|%h0, %b1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1792 (define_insn "*movqi_insv_2"
1793   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1794                          (const_int 8)
1795                          (const_int 8))
1796         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1797                      (const_int 8)))]
1798   ""
1799   "mov{b}\t{%h1, %h0|%h0, %h1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1803 (define_expand "movdi"
1804   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1805         (match_operand:DI 1 "general_operand" ""))]
1806   ""
1807   "ix86_expand_move (DImode, operands); DONE;")
1809 (define_insn "*pushdi"
1810   [(set (match_operand:DI 0 "push_operand" "=<")
1811         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1812   "!TARGET_64BIT"
1813   "#")
1815 (define_insn "*pushdi2_rex64"
1816   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1817         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1818   "TARGET_64BIT"
1819   "@
1820    push{q}\t%1
1821    #"
1822   [(set_attr "type" "push,multi")
1823    (set_attr "mode" "DI")])
1825 ;; Convert impossible pushes of immediate to existing instructions.
1826 ;; First try to get scratch register and go through it.  In case this
1827 ;; fails, push sign extended lower part first and then overwrite
1828 ;; upper part by 32bit move.
1829 (define_peephole2
1830   [(match_scratch:DI 2 "r")
1831    (set (match_operand:DI 0 "push_operand" "")
1832         (match_operand:DI 1 "immediate_operand" ""))]
1833   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1834    && !x86_64_immediate_operand (operands[1], DImode)"
1835   [(set (match_dup 2) (match_dup 1))
1836    (set (match_dup 0) (match_dup 2))]
1837   "")
1839 ;; We need to define this as both peepholer and splitter for case
1840 ;; peephole2 pass is not run.
1841 ;; "&& 1" is needed to keep it from matching the previous pattern.
1842 (define_peephole2
1843   [(set (match_operand:DI 0 "push_operand" "")
1844         (match_operand:DI 1 "immediate_operand" ""))]
1845   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1847   [(set (match_dup 0) (match_dup 1))
1848    (set (match_dup 2) (match_dup 3))]
1849   "split_di (operands + 1, 1, operands + 2, operands + 3);
1850    operands[1] = gen_lowpart (DImode, operands[2]);
1851    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1852                                                     GEN_INT (4)));
1853   ")
1855 (define_split
1856   [(set (match_operand:DI 0 "push_operand" "")
1857         (match_operand:DI 1 "immediate_operand" ""))]
1858   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1859                     ? flow2_completed : reload_completed)
1860    && !symbolic_operand (operands[1], DImode)
1861    && !x86_64_immediate_operand (operands[1], DImode)"
1862   [(set (match_dup 0) (match_dup 1))
1863    (set (match_dup 2) (match_dup 3))]
1864   "split_di (operands + 1, 1, operands + 2, operands + 3);
1865    operands[1] = gen_lowpart (DImode, operands[2]);
1866    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867                                                     GEN_INT (4)));
1868   ")
1870 (define_insn "*pushdi2_prologue_rex64"
1871   [(set (match_operand:DI 0 "push_operand" "=<")
1872         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1873    (clobber (mem:BLK (scratch)))]
1874   "TARGET_64BIT"
1875   "push{q}\t%1"
1876   [(set_attr "type" "push")
1877    (set_attr "mode" "DI")])
1879 (define_insn "*popdi1_epilogue_rex64"
1880   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881         (mem:DI (reg:DI SP_REG)))
1882    (set (reg:DI SP_REG)
1883         (plus:DI (reg:DI SP_REG) (const_int 8)))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "pop{q}\t%0"
1887   [(set_attr "type" "pop")
1888    (set_attr "mode" "DI")])
1890 (define_insn "popdi1"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1900 (define_insn "*movdi_xor_rex64"
1901   [(set (match_operand:DI 0 "register_operand" "=r")
1902         (match_operand:DI 1 "const0_operand" "i"))
1903    (clobber (reg:CC FLAGS_REG))]
1904   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1905    && reload_completed"
1906   "xor{l}\t{%k0, %k0|%k0, %k0}"
1907   [(set_attr "type" "alu1")
1908    (set_attr "mode" "SI")
1909    (set_attr "length_immediate" "0")])
1911 (define_insn "*movdi_or_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const_int_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1916    && reload_completed
1917    && operands[1] == constm1_rtx"
1919   operands[1] = constm1_rtx;
1920   return "or{q}\t{%1, %0|%0, %1}";
1922   [(set_attr "type" "alu1")
1923    (set_attr "mode" "DI")
1924    (set_attr "length_immediate" "1")])
1926 (define_insn "*movdi_2"
1927   [(set (match_operand:DI 0 "nonimmediate_operand"
1928                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1929         (match_operand:DI 1 "general_operand"
1930                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1931   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932   "@
1933    #
1934    #
1935    pxor\t%0, %0
1936    movq\t{%1, %0|%0, %1}
1937    movq\t{%1, %0|%0, %1}
1938    pxor\t%0, %0
1939    movq\t{%1, %0|%0, %1}
1940    movdqa\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    xorps\t%0, %0
1943    movlps\t{%1, %0|%0, %1}
1944    movaps\t{%1, %0|%0, %1}
1945    movlps\t{%1, %0|%0, %1}"
1946   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1947    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1949 (define_split
1950   [(set (match_operand:DI 0 "push_operand" "")
1951         (match_operand:DI 1 "general_operand" ""))]
1952   "!TARGET_64BIT && reload_completed
1953    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1954   [(const_int 0)]
1955   "ix86_split_long_move (operands); DONE;")
1957 ;; %%% This multiword shite has got to go.
1958 (define_split
1959   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1960         (match_operand:DI 1 "general_operand" ""))]
1961   "!TARGET_64BIT && reload_completed
1962    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1963    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1967 (define_insn "*movdi_1_rex64"
1968   [(set (match_operand:DI 0 "nonimmediate_operand"
1969                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1970         (match_operand:DI 1 "general_operand"
1971                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1972   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1974   switch (get_attr_type (insn))
1975     {
1976     case TYPE_SSECVT:
1977       if (which_alternative == 13)
1978         return "movq2dq\t{%1, %0|%0, %1}";
1979       else
1980         return "movdq2q\t{%1, %0|%0, %1}";
1981     case TYPE_SSEMOV:
1982       if (get_attr_mode (insn) == MODE_TI)
1983           return "movdqa\t{%1, %0|%0, %1}";
1984       /* FALLTHRU */
1985     case TYPE_MMXMOV:
1986       /* Moves from and into integer register is done using movd opcode with
1987          REX prefix.  */
1988       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1989           return "movd\t{%1, %0|%0, %1}";
1990       return "movq\t{%1, %0|%0, %1}";
1991     case TYPE_SSELOG1:
1992     case TYPE_MMXADD:
1993       return "pxor\t%0, %0";
1994     case TYPE_MULTI:
1995       return "#";
1996     case TYPE_LEA:
1997       return "lea{q}\t{%a1, %0|%0, %a1}";
1998     default:
1999       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000       if (get_attr_mode (insn) == MODE_SI)
2001         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002       else if (which_alternative == 2)
2003         return "movabs{q}\t{%1, %0|%0, %1}";
2004       else
2005         return "mov{q}\t{%1, %0|%0, %1}";
2006     }
2008   [(set (attr "type")
2009      (cond [(eq_attr "alternative" "5")
2010               (const_string "mmxadd")
2011             (eq_attr "alternative" "6,7,8")
2012               (const_string "mmxmov")
2013             (eq_attr "alternative" "9")
2014               (const_string "sselog1")
2015             (eq_attr "alternative" "10,11,12")
2016               (const_string "ssemov")
2017             (eq_attr "alternative" "13,14")
2018               (const_string "ssecvt")
2019             (eq_attr "alternative" "4")
2020               (const_string "multi")
2021             (match_operand:DI 1 "pic_32bit_operand" "")
2022               (const_string "lea")
2023            ]
2024            (const_string "imov")))
2025    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2026    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2027    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2029 ;; Stores and loads of ax to arbitrary constant address.
2030 ;; We fake an second form of instruction to force reload to load address
2031 ;; into register when rax is not available
2032 (define_insn "*movabsdi_1_rex64"
2033   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2034         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2035   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2036   "@
2037    movabs{q}\t{%1, %P0|%P0, %1}
2038    mov{q}\t{%1, %a0|%a0, %1}"
2039   [(set_attr "type" "imov")
2040    (set_attr "modrm" "0,*")
2041    (set_attr "length_address" "8,0")
2042    (set_attr "length_immediate" "0,*")
2043    (set_attr "memory" "store")
2044    (set_attr "mode" "DI")])
2046 (define_insn "*movabsdi_2_rex64"
2047   [(set (match_operand:DI 0 "register_operand" "=a,r")
2048         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2049   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2050   "@
2051    movabs{q}\t{%P1, %0|%0, %P1}
2052    mov{q}\t{%a1, %0|%0, %a1}"
2053   [(set_attr "type" "imov")
2054    (set_attr "modrm" "0,*")
2055    (set_attr "length_address" "8,0")
2056    (set_attr "length_immediate" "0")
2057    (set_attr "memory" "load")
2058    (set_attr "mode" "DI")])
2060 ;; Convert impossible stores of immediate to existing instructions.
2061 ;; First try to get scratch register and go through it.  In case this
2062 ;; fails, move by 32bit parts.
2063 (define_peephole2
2064   [(match_scratch:DI 2 "r")
2065    (set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "immediate_operand" ""))]
2067   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068    && !x86_64_immediate_operand (operands[1], DImode)"
2069   [(set (match_dup 2) (match_dup 1))
2070    (set (match_dup 0) (match_dup 2))]
2071   "")
2073 ;; We need to define this as both peepholer and splitter for case
2074 ;; peephole2 pass is not run.
2075 ;; "&& 1" is needed to keep it from matching the previous pattern.
2076 (define_peephole2
2077   [(set (match_operand:DI 0 "memory_operand" "")
2078         (match_operand:DI 1 "immediate_operand" ""))]
2079   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2081   [(set (match_dup 2) (match_dup 3))
2082    (set (match_dup 4) (match_dup 5))]
2083   "split_di (operands, 2, operands + 2, operands + 4);")
2085 (define_split
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2089                     ? flow2_completed : reload_completed)
2090    && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode)"
2092   [(set (match_dup 2) (match_dup 3))
2093    (set (match_dup 4) (match_dup 5))]
2094   "split_di (operands, 2, operands + 2, operands + 4);")
2096 (define_insn "*swapdi_rex64"
2097   [(set (match_operand:DI 0 "register_operand" "+r")
2098         (match_operand:DI 1 "register_operand" "+r"))
2099    (set (match_dup 1)
2100         (match_dup 0))]
2101   "TARGET_64BIT"
2102   "xchg{q}\t%1, %0"
2103   [(set_attr "type" "imov")
2104    (set_attr "mode" "DI")
2105    (set_attr "pent_pair" "np")
2106    (set_attr "athlon_decode" "vector")])
2108 (define_expand "movti"
2109   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2110         (match_operand:TI 1 "nonimmediate_operand" ""))]
2111   "TARGET_SSE || TARGET_64BIT"
2113   if (TARGET_64BIT)
2114     ix86_expand_move (TImode, operands);
2115   else
2116     ix86_expand_vector_move (TImode, operands);
2117   DONE;
2120 (define_insn "*movti_internal"
2121   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2122         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2123   "TARGET_SSE && !TARGET_64BIT
2124    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2126   switch (which_alternative)
2127     {
2128     case 0:
2129       if (get_attr_mode (insn) == MODE_V4SF)
2130         return "xorps\t%0, %0";
2131       else
2132         return "pxor\t%0, %0";
2133     case 1:
2134     case 2:
2135       if (get_attr_mode (insn) == MODE_V4SF)
2136         return "movaps\t{%1, %0|%0, %1}";
2137       else
2138         return "movdqa\t{%1, %0|%0, %1}";
2139     default:
2140       gcc_unreachable ();
2141     }
2143   [(set_attr "type" "ssemov,ssemov,ssemov")
2144    (set (attr "mode")
2145         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2146                  (const_string "V4SF")
2148                (eq_attr "alternative" "0,1")
2149                  (if_then_else
2150                    (ne (symbol_ref "optimize_size")
2151                        (const_int 0))
2152                    (const_string "V4SF")
2153                    (const_string "TI"))
2154                (eq_attr "alternative" "2")
2155                  (if_then_else
2156                    (ne (symbol_ref "optimize_size")
2157                        (const_int 0))
2158                    (const_string "V4SF")
2159                    (const_string "TI"))]
2160                (const_string "TI")))])
2162 (define_insn "*movti_rex64"
2163   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2164         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2165   "TARGET_64BIT
2166    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2168   switch (which_alternative)
2169     {
2170     case 0:
2171     case 1:
2172       return "#";
2173     case 2:
2174       if (get_attr_mode (insn) == MODE_V4SF)
2175         return "xorps\t%0, %0";
2176       else
2177         return "pxor\t%0, %0";
2178     case 3:
2179     case 4:
2180       if (get_attr_mode (insn) == MODE_V4SF)
2181         return "movaps\t{%1, %0|%0, %1}";
2182       else
2183         return "movdqa\t{%1, %0|%0, %1}";
2184     default:
2185       gcc_unreachable ();
2186     }
2188   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2189    (set (attr "mode")
2190         (cond [(eq_attr "alternative" "2,3")
2191                  (if_then_else
2192                    (ne (symbol_ref "optimize_size")
2193                        (const_int 0))
2194                    (const_string "V4SF")
2195                    (const_string "TI"))
2196                (eq_attr "alternative" "4")
2197                  (if_then_else
2198                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2199                             (const_int 0))
2200                         (ne (symbol_ref "optimize_size")
2201                             (const_int 0)))
2202                    (const_string "V4SF")
2203                    (const_string "TI"))]
2204                (const_string "DI")))])
2206 (define_split
2207   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2208         (match_operand:TI 1 "general_operand" ""))]
2209   "reload_completed && !SSE_REG_P (operands[0])
2210    && !SSE_REG_P (operands[1])"
2211   [(const_int 0)]
2212   "ix86_split_long_move (operands); DONE;")
2214 (define_expand "movsf"
2215   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2216         (match_operand:SF 1 "general_operand" ""))]
2217   ""
2218   "ix86_expand_move (SFmode, operands); DONE;")
2220 (define_insn "*pushsf"
2221   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2222         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2223   "!TARGET_64BIT"
2225   /* Anything else should be already split before reg-stack.  */
2226   gcc_assert (which_alternative == 1);
2227   return "push{l}\t%1";
2229   [(set_attr "type" "multi,push,multi")
2230    (set_attr "unit" "i387,*,*")
2231    (set_attr "mode" "SF,SI,SF")])
2233 (define_insn "*pushsf_rex64"
2234   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2235         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2236   "TARGET_64BIT"
2238   /* Anything else should be already split before reg-stack.  */
2239   gcc_assert (which_alternative == 1);
2240   return "push{q}\t%q1";
2242   [(set_attr "type" "multi,push,multi")
2243    (set_attr "unit" "i387,*,*")
2244    (set_attr "mode" "SF,DI,SF")])
2246 (define_split
2247   [(set (match_operand:SF 0 "push_operand" "")
2248         (match_operand:SF 1 "memory_operand" ""))]
2249   "reload_completed
2250    && GET_CODE (operands[1]) == MEM
2251    && constant_pool_reference_p (operands[1])"
2252   [(set (match_dup 0)
2253         (match_dup 1))]
2254   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2257 ;; %%% Kill this when call knows how to work this out.
2258 (define_split
2259   [(set (match_operand:SF 0 "push_operand" "")
2260         (match_operand:SF 1 "any_fp_register_operand" ""))]
2261   "!TARGET_64BIT"
2262   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2263    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2265 (define_split
2266   [(set (match_operand:SF 0 "push_operand" "")
2267         (match_operand:SF 1 "any_fp_register_operand" ""))]
2268   "TARGET_64BIT"
2269   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2270    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2272 (define_insn "*movsf_1"
2273   [(set (match_operand:SF 0 "nonimmediate_operand"
2274           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2275         (match_operand:SF 1 "general_operand"
2276           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2277   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2278    && (reload_in_progress || reload_completed
2279        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2280        || GET_CODE (operands[1]) != CONST_DOUBLE
2281        || memory_operand (operands[0], SFmode))" 
2283   switch (which_alternative)
2284     {
2285     case 0:
2286       return output_387_reg_move (insn, operands);
2288     case 1:
2289       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2290         return "fstp%z0\t%y0";
2291       else
2292         return "fst%z0\t%y0";
2294     case 2:
2295       return standard_80387_constant_opcode (operands[1]);
2297     case 3:
2298     case 4:
2299       return "mov{l}\t{%1, %0|%0, %1}";
2300     case 5:
2301       if (get_attr_mode (insn) == MODE_TI)
2302         return "pxor\t%0, %0";
2303       else
2304         return "xorps\t%0, %0";
2305     case 6:
2306       if (get_attr_mode (insn) == MODE_V4SF)
2307         return "movaps\t{%1, %0|%0, %1}";
2308       else
2309         return "movss\t{%1, %0|%0, %1}";
2310     case 7:
2311     case 8:
2312       return "movss\t{%1, %0|%0, %1}";
2314     case 9:
2315     case 10:
2316       return "movd\t{%1, %0|%0, %1}";
2318     case 11:
2319       return "movq\t{%1, %0|%0, %1}";
2321     default:
2322       gcc_unreachable ();
2323     }
2325   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2326    (set (attr "mode")
2327         (cond [(eq_attr "alternative" "3,4,9,10")
2328                  (const_string "SI")
2329                (eq_attr "alternative" "5")
2330                  (if_then_else
2331                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2332                                  (const_int 0))
2333                              (ne (symbol_ref "TARGET_SSE2")
2334                                  (const_int 0)))
2335                         (eq (symbol_ref "optimize_size")
2336                             (const_int 0)))
2337                    (const_string "TI")
2338                    (const_string "V4SF"))
2339                /* For architectures resolving dependencies on
2340                   whole SSE registers use APS move to break dependency
2341                   chains, otherwise use short move to avoid extra work. 
2343                   Do the same for architectures resolving dependencies on
2344                   the parts.  While in DF mode it is better to always handle
2345                   just register parts, the SF mode is different due to lack
2346                   of instructions to load just part of the register.  It is
2347                   better to maintain the whole registers in single format
2348                   to avoid problems on using packed logical operations.  */
2349                (eq_attr "alternative" "6")
2350                  (if_then_else
2351                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2352                             (const_int 0))
2353                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2354                             (const_int 0)))
2355                    (const_string "V4SF")
2356                    (const_string "SF"))
2357                (eq_attr "alternative" "11")
2358                  (const_string "DI")]
2359                (const_string "SF")))])
2361 (define_insn "*swapsf"
2362   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2363         (match_operand:SF 1 "fp_register_operand" "+f"))
2364    (set (match_dup 1)
2365         (match_dup 0))]
2366   "reload_completed || TARGET_80387"
2368   if (STACK_TOP_P (operands[0]))
2369     return "fxch\t%1";
2370   else
2371     return "fxch\t%0";
2373   [(set_attr "type" "fxch")
2374    (set_attr "mode" "SF")])
2376 (define_expand "movdf"
2377   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2378         (match_operand:DF 1 "general_operand" ""))]
2379   ""
2380   "ix86_expand_move (DFmode, operands); DONE;")
2382 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2383 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2384 ;; On the average, pushdf using integers can be still shorter.  Allow this
2385 ;; pattern for optimize_size too.
2387 (define_insn "*pushdf_nointeger"
2388   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2389         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2390   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2392   /* This insn should be already split before reg-stack.  */
2393   gcc_unreachable ();
2395   [(set_attr "type" "multi")
2396    (set_attr "unit" "i387,*,*,*")
2397    (set_attr "mode" "DF,SI,SI,DF")])
2399 (define_insn "*pushdf_integer"
2400   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2401         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2402   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2404   /* This insn should be already split before reg-stack.  */
2405   gcc_unreachable ();
2407   [(set_attr "type" "multi")
2408    (set_attr "unit" "i387,*,*")
2409    (set_attr "mode" "DF,SI,DF")])
2411 ;; %%% Kill this when call knows how to work this out.
2412 (define_split
2413   [(set (match_operand:DF 0 "push_operand" "")
2414         (match_operand:DF 1 "any_fp_register_operand" ""))]
2415   "!TARGET_64BIT && reload_completed"
2416   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2417    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2418   "")
2420 (define_split
2421   [(set (match_operand:DF 0 "push_operand" "")
2422         (match_operand:DF 1 "any_fp_register_operand" ""))]
2423   "TARGET_64BIT && reload_completed"
2424   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2425    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2426   "")
2428 (define_split
2429   [(set (match_operand:DF 0 "push_operand" "")
2430         (match_operand:DF 1 "general_operand" ""))]
2431   "reload_completed"
2432   [(const_int 0)]
2433   "ix86_split_long_move (operands); DONE;")
2435 ;; Moving is usually shorter when only FP registers are used. This separate
2436 ;; movdf pattern avoids the use of integer registers for FP operations
2437 ;; when optimizing for size.
2439 (define_insn "*movdf_nointeger"
2440   [(set (match_operand:DF 0 "nonimmediate_operand"
2441                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2442         (match_operand:DF 1 "general_operand"
2443                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2444   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2445    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2446    && (reload_in_progress || reload_completed
2447        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2448        || GET_CODE (operands[1]) != CONST_DOUBLE
2449        || memory_operand (operands[0], DFmode))" 
2451   switch (which_alternative)
2452     {
2453     case 0:
2454       return output_387_reg_move (insn, operands);
2456     case 1:
2457       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2458         return "fstp%z0\t%y0";
2459       else
2460         return "fst%z0\t%y0";
2462     case 2:
2463       return standard_80387_constant_opcode (operands[1]);
2465     case 3:
2466     case 4:
2467       return "#";
2468     case 5:
2469       switch (get_attr_mode (insn))
2470         {
2471         case MODE_V4SF:
2472           return "xorps\t%0, %0";
2473         case MODE_V2DF:
2474           return "xorpd\t%0, %0";
2475         case MODE_TI:
2476           return "pxor\t%0, %0";
2477         default:
2478           gcc_unreachable ();
2479         }
2480     case 6:
2481     case 7:
2482     case 8:
2483       switch (get_attr_mode (insn))
2484         {
2485         case MODE_V4SF:
2486           return "movaps\t{%1, %0|%0, %1}";
2487         case MODE_V2DF:
2488           return "movapd\t{%1, %0|%0, %1}";
2489         case MODE_TI:
2490           return "movdqa\t{%1, %0|%0, %1}";
2491         case MODE_DI:
2492           return "movq\t{%1, %0|%0, %1}";
2493         case MODE_DF:
2494           return "movsd\t{%1, %0|%0, %1}";
2495         case MODE_V1DF:
2496           return "movlpd\t{%1, %0|%0, %1}";
2497         case MODE_V2SF:
2498           return "movlps\t{%1, %0|%0, %1}";
2499         default:
2500           gcc_unreachable ();
2501         }
2503     default:
2504       gcc_unreachable ();
2505     }
2507   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2508    (set (attr "mode")
2509         (cond [(eq_attr "alternative" "0,1,2")
2510                  (const_string "DF")
2511                (eq_attr "alternative" "3,4")
2512                  (const_string "SI")
2514                /* For SSE1, we have many fewer alternatives.  */
2515                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2516                  (cond [(eq_attr "alternative" "5,6")
2517                           (const_string "V4SF")
2518                        ]
2519                    (const_string "V2SF"))
2521                /* xorps is one byte shorter.  */
2522                (eq_attr "alternative" "5")
2523                  (cond [(ne (symbol_ref "optimize_size")
2524                             (const_int 0))
2525                           (const_string "V4SF")
2526                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2527                             (const_int 0))
2528                           (const_string "TI")
2529                        ]
2530                        (const_string "V2DF"))
2532                /* For architectures resolving dependencies on
2533                   whole SSE registers use APD move to break dependency
2534                   chains, otherwise use short move to avoid extra work.
2536                   movaps encodes one byte shorter.  */
2537                (eq_attr "alternative" "6")
2538                  (cond
2539                    [(ne (symbol_ref "optimize_size")
2540                         (const_int 0))
2541                       (const_string "V4SF")
2542                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2543                         (const_int 0))
2544                       (const_string "V2DF")
2545                    ]
2546                    (const_string "DF"))
2547                /* For architectures resolving dependencies on register
2548                   parts we may avoid extra work to zero out upper part
2549                   of register.  */
2550                (eq_attr "alternative" "7")
2551                  (if_then_else
2552                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2553                        (const_int 0))
2554                    (const_string "V1DF")
2555                    (const_string "DF"))
2556               ]
2557               (const_string "DF")))])
2559 (define_insn "*movdf_integer"
2560   [(set (match_operand:DF 0 "nonimmediate_operand"
2561                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2562         (match_operand:DF 1 "general_operand"
2563                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2564   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2565    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2566    && (reload_in_progress || reload_completed
2567        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2568        || GET_CODE (operands[1]) != CONST_DOUBLE
2569        || memory_operand (operands[0], DFmode))" 
2571   switch (which_alternative)
2572     {
2573     case 0:
2574       return output_387_reg_move (insn, operands);
2576     case 1:
2577       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2578         return "fstp%z0\t%y0";
2579       else
2580         return "fst%z0\t%y0";
2582     case 2:
2583       return standard_80387_constant_opcode (operands[1]);
2585     case 3:
2586     case 4:
2587       return "#";
2589     case 5:
2590       switch (get_attr_mode (insn))
2591         {
2592         case MODE_V4SF:
2593           return "xorps\t%0, %0";
2594         case MODE_V2DF:
2595           return "xorpd\t%0, %0";
2596         case MODE_TI:
2597           return "pxor\t%0, %0";
2598         default:
2599           gcc_unreachable ();
2600         }
2601     case 6:
2602     case 7:
2603     case 8:
2604       switch (get_attr_mode (insn))
2605         {
2606         case MODE_V4SF:
2607           return "movaps\t{%1, %0|%0, %1}";
2608         case MODE_V2DF:
2609           return "movapd\t{%1, %0|%0, %1}";
2610         case MODE_TI:
2611           return "movdqa\t{%1, %0|%0, %1}";
2612         case MODE_DI:
2613           return "movq\t{%1, %0|%0, %1}";
2614         case MODE_DF:
2615           return "movsd\t{%1, %0|%0, %1}";
2616         case MODE_V1DF:
2617           return "movlpd\t{%1, %0|%0, %1}";
2618         case MODE_V2SF:
2619           return "movlps\t{%1, %0|%0, %1}";
2620         default:
2621           gcc_unreachable ();
2622         }
2624     default:
2625       gcc_unreachable();
2626     }
2628   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2629    (set (attr "mode")
2630         (cond [(eq_attr "alternative" "0,1,2")
2631                  (const_string "DF")
2632                (eq_attr "alternative" "3,4")
2633                  (const_string "SI")
2635                /* For SSE1, we have many fewer alternatives.  */
2636                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2637                  (cond [(eq_attr "alternative" "5,6")
2638                           (const_string "V4SF")
2639                        ]
2640                    (const_string "V2SF"))
2642                /* xorps is one byte shorter.  */
2643                (eq_attr "alternative" "5")
2644                  (cond [(ne (symbol_ref "optimize_size")
2645                             (const_int 0))
2646                           (const_string "V4SF")
2647                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2648                             (const_int 0))
2649                           (const_string "TI")
2650                        ]
2651                        (const_string "V2DF"))
2653                /* For architectures resolving dependencies on
2654                   whole SSE registers use APD move to break dependency
2655                   chains, otherwise use short move to avoid extra work.
2657                   movaps encodes one byte shorter.  */
2658                (eq_attr "alternative" "6")
2659                  (cond
2660                    [(ne (symbol_ref "optimize_size")
2661                         (const_int 0))
2662                       (const_string "V4SF")
2663                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2664                         (const_int 0))
2665                       (const_string "V2DF")
2666                    ]
2667                    (const_string "DF"))
2668                /* For architectures resolving dependencies on register
2669                   parts we may avoid extra work to zero out upper part
2670                   of register.  */
2671                (eq_attr "alternative" "7")
2672                  (if_then_else
2673                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2674                        (const_int 0))
2675                    (const_string "V1DF")
2676                    (const_string "DF"))
2677               ]
2678               (const_string "DF")))])
2680 (define_split
2681   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2682         (match_operand:DF 1 "general_operand" ""))]
2683   "reload_completed
2684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685    && ! (ANY_FP_REG_P (operands[0]) || 
2686          (GET_CODE (operands[0]) == SUBREG
2687           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2688    && ! (ANY_FP_REG_P (operands[1]) || 
2689          (GET_CODE (operands[1]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2691   [(const_int 0)]
2692   "ix86_split_long_move (operands); DONE;")
2694 (define_insn "*swapdf"
2695   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2696         (match_operand:DF 1 "fp_register_operand" "+f"))
2697    (set (match_dup 1)
2698         (match_dup 0))]
2699   "reload_completed || TARGET_80387"
2701   if (STACK_TOP_P (operands[0]))
2702     return "fxch\t%1";
2703   else
2704     return "fxch\t%0";
2706   [(set_attr "type" "fxch")
2707    (set_attr "mode" "DF")])
2709 (define_expand "movxf"
2710   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2711         (match_operand:XF 1 "general_operand" ""))]
2712   ""
2713   "ix86_expand_move (XFmode, operands); DONE;")
2715 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2716 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2717 ;; Pushing using integer instructions is longer except for constants
2718 ;; and direct memory references.
2719 ;; (assuming that any given constant is pushed only once, but this ought to be
2720 ;;  handled elsewhere).
2722 (define_insn "*pushxf_nointeger"
2723   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2724         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2725   "optimize_size"
2727   /* This insn should be already split before reg-stack.  */
2728   gcc_unreachable ();
2730   [(set_attr "type" "multi")
2731    (set_attr "unit" "i387,*,*")
2732    (set_attr "mode" "XF,SI,SI")])
2734 (define_insn "*pushxf_integer"
2735   [(set (match_operand:XF 0 "push_operand" "=<,<")
2736         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2737   "!optimize_size"
2739   /* This insn should be already split before reg-stack.  */
2740   gcc_unreachable ();
2742   [(set_attr "type" "multi")
2743    (set_attr "unit" "i387,*")
2744    (set_attr "mode" "XF,SI")])
2746 (define_split
2747   [(set (match_operand 0 "push_operand" "")
2748         (match_operand 1 "general_operand" ""))]
2749   "reload_completed
2750    && (GET_MODE (operands[0]) == XFmode
2751        || GET_MODE (operands[0]) == DFmode)
2752    && !ANY_FP_REG_P (operands[1])"
2753   [(const_int 0)]
2754   "ix86_split_long_move (operands); DONE;")
2756 (define_split
2757   [(set (match_operand:XF 0 "push_operand" "")
2758         (match_operand:XF 1 "any_fp_register_operand" ""))]
2759   "!TARGET_64BIT"
2760   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2761    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2762   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2764 (define_split
2765   [(set (match_operand:XF 0 "push_operand" "")
2766         (match_operand:XF 1 "any_fp_register_operand" ""))]
2767   "TARGET_64BIT"
2768   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2769    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2770   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772 ;; Do not use integer registers when optimizing for size
2773 (define_insn "*movxf_nointeger"
2774   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2775         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2776   "optimize_size
2777    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778    && (reload_in_progress || reload_completed
2779        || GET_CODE (operands[1]) != CONST_DOUBLE
2780        || memory_operand (operands[0], XFmode))" 
2782   switch (which_alternative)
2783     {
2784     case 0:
2785       return output_387_reg_move (insn, operands);
2787     case 1:
2788       /* There is no non-popping store to memory for XFmode.  So if
2789          we need one, follow the store with a load.  */
2790       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2791         return "fstp%z0\t%y0\;fld%z0\t%y0";
2792       else
2793         return "fstp%z0\t%y0";
2795     case 2:
2796       return standard_80387_constant_opcode (operands[1]);
2798     case 3: case 4:
2799       return "#";
2800     default:
2801       gcc_unreachable ();
2802     }
2804   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2805    (set_attr "mode" "XF,XF,XF,SI,SI")])
2807 (define_insn "*movxf_integer"
2808   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2809         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2810   "!optimize_size
2811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812    && (reload_in_progress || reload_completed
2813        || GET_CODE (operands[1]) != CONST_DOUBLE
2814        || memory_operand (operands[0], XFmode))" 
2816   switch (which_alternative)
2817     {
2818     case 0:
2819       return output_387_reg_move (insn, operands);
2821     case 1:
2822       /* There is no non-popping store to memory for XFmode.  So if
2823          we need one, follow the store with a load.  */
2824       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825         return "fstp%z0\t%y0\;fld%z0\t%y0";
2826       else
2827         return "fstp%z0\t%y0";
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2832     case 3: case 4:
2833       return "#";
2835     default:
2836       gcc_unreachable ();
2837     }
2839   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840    (set_attr "mode" "XF,XF,XF,SI,SI")])
2842 (define_split
2843   [(set (match_operand 0 "nonimmediate_operand" "")
2844         (match_operand 1 "general_operand" ""))]
2845   "reload_completed
2846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2847    && GET_MODE (operands[0]) == XFmode
2848    && ! (ANY_FP_REG_P (operands[0]) || 
2849          (GET_CODE (operands[0]) == SUBREG
2850           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2851    && ! (ANY_FP_REG_P (operands[1]) || 
2852          (GET_CODE (operands[1]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2854   [(const_int 0)]
2855   "ix86_split_long_move (operands); DONE;")
2857 (define_split
2858   [(set (match_operand 0 "register_operand" "")
2859         (match_operand 1 "memory_operand" ""))]
2860   "reload_completed
2861    && GET_CODE (operands[1]) == MEM
2862    && (GET_MODE (operands[0]) == XFmode
2863        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2864    && constant_pool_reference_p (operands[1])"
2865   [(set (match_dup 0) (match_dup 1))]
2867   rtx c = avoid_constant_pool_reference (operands[1]);
2868   rtx r = operands[0];
2870   if (GET_CODE (r) == SUBREG)
2871     r = SUBREG_REG (r);
2873   if (SSE_REG_P (r))
2874     {
2875       if (!standard_sse_constant_p (c))
2876         FAIL;
2877     }
2878   else if (FP_REG_P (r))
2879     {
2880       if (!standard_80387_constant_p (c))
2881         FAIL;
2882     }
2883   else if (MMX_REG_P (r))
2884     FAIL;
2886   operands[1] = c;
2889 (define_insn "swapxf"
2890   [(set (match_operand:XF 0 "register_operand" "+f")
2891         (match_operand:XF 1 "register_operand" "+f"))
2892    (set (match_dup 1)
2893         (match_dup 0))]
2894   "TARGET_80387"
2896   if (STACK_TOP_P (operands[0]))
2897     return "fxch\t%1";
2898   else
2899     return "fxch\t%0";
2901   [(set_attr "type" "fxch")
2902    (set_attr "mode" "XF")])
2904 (define_expand "movtf"
2905   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2906         (match_operand:TF 1 "nonimmediate_operand" ""))]
2907   "TARGET_64BIT"
2909   ix86_expand_move (TFmode, operands);
2910   DONE;
2913 (define_insn "*movtf_internal"
2914   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2915         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2916   "TARGET_64BIT
2917    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2919   switch (which_alternative)
2920     {
2921     case 0:
2922     case 1:
2923       return "#";
2924     case 2:
2925       if (get_attr_mode (insn) == MODE_V4SF)
2926         return "xorps\t%0, %0";
2927       else
2928         return "pxor\t%0, %0";
2929     case 3:
2930     case 4:
2931       if (get_attr_mode (insn) == MODE_V4SF)
2932         return "movaps\t{%1, %0|%0, %1}";
2933       else
2934         return "movdqa\t{%1, %0|%0, %1}";
2935     default:
2936       gcc_unreachable ();
2937     }
2939   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2940    (set (attr "mode")
2941         (cond [(eq_attr "alternative" "2,3")
2942                  (if_then_else
2943                    (ne (symbol_ref "optimize_size")
2944                        (const_int 0))
2945                    (const_string "V4SF")
2946                    (const_string "TI"))
2947                (eq_attr "alternative" "4")
2948                  (if_then_else
2949                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2950                             (const_int 0))
2951                         (ne (symbol_ref "optimize_size")
2952                             (const_int 0)))
2953                    (const_string "V4SF")
2954                    (const_string "TI"))]
2955                (const_string "DI")))])
2957 (define_split
2958   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2959         (match_operand:TF 1 "general_operand" ""))]
2960   "reload_completed && !SSE_REG_P (operands[0])
2961    && !SSE_REG_P (operands[1])"
2962   [(const_int 0)]
2963   "ix86_split_long_move (operands); DONE;")
2965 ;; Zero extension instructions
2967 (define_expand "zero_extendhisi2"
2968   [(set (match_operand:SI 0 "register_operand" "")
2969      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2970   ""
2972   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2973     {
2974       operands[1] = force_reg (HImode, operands[1]);
2975       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2976       DONE;
2977     }
2980 (define_insn "zero_extendhisi2_and"
2981   [(set (match_operand:SI 0 "register_operand" "=r")
2982      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2983    (clobber (reg:CC FLAGS_REG))]
2984   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2985   "#"
2986   [(set_attr "type" "alu1")
2987    (set_attr "mode" "SI")])
2989 (define_split
2990   [(set (match_operand:SI 0 "register_operand" "")
2991         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2992    (clobber (reg:CC FLAGS_REG))]
2993   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2995               (clobber (reg:CC FLAGS_REG))])]
2996   "")
2998 (define_insn "*zero_extendhisi2_movzwl"
2999   [(set (match_operand:SI 0 "register_operand" "=r")
3000      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3001   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3002   "movz{wl|x}\t{%1, %0|%0, %1}"
3003   [(set_attr "type" "imovx")
3004    (set_attr "mode" "SI")])
3006 (define_expand "zero_extendqihi2"
3007   [(parallel
3008     [(set (match_operand:HI 0 "register_operand" "")
3009        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3010      (clobber (reg:CC FLAGS_REG))])]
3011   ""
3012   "")
3014 (define_insn "*zero_extendqihi2_and"
3015   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3016      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3017    (clobber (reg:CC FLAGS_REG))]
3018   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3019   "#"
3020   [(set_attr "type" "alu1")
3021    (set_attr "mode" "HI")])
3023 (define_insn "*zero_extendqihi2_movzbw_and"
3024   [(set (match_operand:HI 0 "register_operand" "=r,r")
3025      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3026    (clobber (reg:CC FLAGS_REG))]
3027   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3028   "#"
3029   [(set_attr "type" "imovx,alu1")
3030    (set_attr "mode" "HI")])
3032 (define_insn "*zero_extendqihi2_movzbw"
3033   [(set (match_operand:HI 0 "register_operand" "=r")
3034      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3035   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3036   "movz{bw|x}\t{%1, %0|%0, %1}"
3037   [(set_attr "type" "imovx")
3038    (set_attr "mode" "HI")])
3040 ;; For the movzbw case strip only the clobber
3041 (define_split
3042   [(set (match_operand:HI 0 "register_operand" "")
3043         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3044    (clobber (reg:CC FLAGS_REG))]
3045   "reload_completed 
3046    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3047    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3048   [(set (match_operand:HI 0 "register_operand" "")
3049         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3051 ;; When source and destination does not overlap, clear destination
3052 ;; first and then do the movb
3053 (define_split
3054   [(set (match_operand:HI 0 "register_operand" "")
3055         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056    (clobber (reg:CC FLAGS_REG))]
3057   "reload_completed
3058    && ANY_QI_REG_P (operands[0])
3059    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3060    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3061   [(set (match_dup 0) (const_int 0))
3062    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3063   "operands[2] = gen_lowpart (QImode, operands[0]);")
3065 ;; Rest is handled by single and.
3066 (define_split
3067   [(set (match_operand:HI 0 "register_operand" "")
3068         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3069    (clobber (reg:CC FLAGS_REG))]
3070   "reload_completed
3071    && true_regnum (operands[0]) == true_regnum (operands[1])"
3072   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3073               (clobber (reg:CC FLAGS_REG))])]
3074   "")
3076 (define_expand "zero_extendqisi2"
3077   [(parallel
3078     [(set (match_operand:SI 0 "register_operand" "")
3079        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3080      (clobber (reg:CC FLAGS_REG))])]
3081   ""
3082   "")
3084 (define_insn "*zero_extendqisi2_and"
3085   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3086      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3087    (clobber (reg:CC FLAGS_REG))]
3088   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3089   "#"
3090   [(set_attr "type" "alu1")
3091    (set_attr "mode" "SI")])
3093 (define_insn "*zero_extendqisi2_movzbw_and"
3094   [(set (match_operand:SI 0 "register_operand" "=r,r")
3095      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3096    (clobber (reg:CC FLAGS_REG))]
3097   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3098   "#"
3099   [(set_attr "type" "imovx,alu1")
3100    (set_attr "mode" "SI")])
3102 (define_insn "*zero_extendqisi2_movzbw"
3103   [(set (match_operand:SI 0 "register_operand" "=r")
3104      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3105   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3106   "movz{bl|x}\t{%1, %0|%0, %1}"
3107   [(set_attr "type" "imovx")
3108    (set_attr "mode" "SI")])
3110 ;; For the movzbl case strip only the clobber
3111 (define_split
3112   [(set (match_operand:SI 0 "register_operand" "")
3113         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3114    (clobber (reg:CC FLAGS_REG))]
3115   "reload_completed 
3116    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3117    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3118   [(set (match_dup 0)
3119         (zero_extend:SI (match_dup 1)))])
3121 ;; When source and destination does not overlap, clear destination
3122 ;; first and then do the movb
3123 (define_split
3124   [(set (match_operand:SI 0 "register_operand" "")
3125         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126    (clobber (reg:CC FLAGS_REG))]
3127   "reload_completed
3128    && ANY_QI_REG_P (operands[0])
3129    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3130    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3131    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3132   [(set (match_dup 0) (const_int 0))
3133    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3134   "operands[2] = gen_lowpart (QImode, operands[0]);")
3136 ;; Rest is handled by single and.
3137 (define_split
3138   [(set (match_operand:SI 0 "register_operand" "")
3139         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3140    (clobber (reg:CC FLAGS_REG))]
3141   "reload_completed
3142    && true_regnum (operands[0]) == true_regnum (operands[1])"
3143   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3144               (clobber (reg:CC FLAGS_REG))])]
3145   "")
3147 ;; %%% Kill me once multi-word ops are sane.
3148 (define_expand "zero_extendsidi2"
3149   [(set (match_operand:DI 0 "register_operand" "=r")
3150      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3151   ""
3152   "if (!TARGET_64BIT)
3153      {
3154        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3155        DONE;
3156      }
3157   ")
3159 (define_insn "zero_extendsidi2_32"
3160   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3161         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3162    (clobber (reg:CC FLAGS_REG))]
3163   "!TARGET_64BIT"
3164   "@
3165    #
3166    #
3167    #
3168    movd\t{%1, %0|%0, %1}
3169    movd\t{%1, %0|%0, %1}"
3170   [(set_attr "mode" "SI,SI,SI,DI,TI")
3171    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3173 (define_insn "zero_extendsidi2_rex64"
3174   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3175      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3176   "TARGET_64BIT"
3177   "@
3178    mov\t{%k1, %k0|%k0, %k1}
3179    #
3180    movd\t{%1, %0|%0, %1}
3181    movd\t{%1, %0|%0, %1}"
3182   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3183    (set_attr "mode" "SI,DI,SI,SI")])
3185 (define_split
3186   [(set (match_operand:DI 0 "memory_operand" "")
3187      (zero_extend:DI (match_dup 0)))]
3188   "TARGET_64BIT"
3189   [(set (match_dup 4) (const_int 0))]
3190   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3192 (define_split 
3193   [(set (match_operand:DI 0 "register_operand" "")
3194         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3195    (clobber (reg:CC FLAGS_REG))]
3196   "!TARGET_64BIT && reload_completed
3197    && true_regnum (operands[0]) == true_regnum (operands[1])"
3198   [(set (match_dup 4) (const_int 0))]
3199   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3201 (define_split 
3202   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3203         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "!TARGET_64BIT && reload_completed
3206    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3207   [(set (match_dup 3) (match_dup 1))
3208    (set (match_dup 4) (const_int 0))]
3209   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3211 (define_insn "zero_extendhidi2"
3212   [(set (match_operand:DI 0 "register_operand" "=r")
3213      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3214   "TARGET_64BIT"
3215   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3216   [(set_attr "type" "imovx")
3217    (set_attr "mode" "DI")])
3219 (define_insn "zero_extendqidi2"
3220   [(set (match_operand:DI 0 "register_operand" "=r")
3221      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3222   "TARGET_64BIT"
3223   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3224   [(set_attr "type" "imovx")
3225    (set_attr "mode" "DI")])
3227 ;; Sign extension instructions
3229 (define_expand "extendsidi2"
3230   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3231                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3232               (clobber (reg:CC FLAGS_REG))
3233               (clobber (match_scratch:SI 2 ""))])]
3234   ""
3236   if (TARGET_64BIT)
3237     {
3238       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3239       DONE;
3240     }
3243 (define_insn "*extendsidi2_1"
3244   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3245         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3246    (clobber (reg:CC FLAGS_REG))
3247    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3248   "!TARGET_64BIT"
3249   "#")
3251 (define_insn "extendsidi2_rex64"
3252   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3253         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3254   "TARGET_64BIT"
3255   "@
3256    {cltq|cdqe}
3257    movs{lq|x}\t{%1,%0|%0, %1}"
3258   [(set_attr "type" "imovx")
3259    (set_attr "mode" "DI")
3260    (set_attr "prefix_0f" "0")
3261    (set_attr "modrm" "0,1")])
3263 (define_insn "extendhidi2"
3264   [(set (match_operand:DI 0 "register_operand" "=r")
3265         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3266   "TARGET_64BIT"
3267   "movs{wq|x}\t{%1,%0|%0, %1}"
3268   [(set_attr "type" "imovx")
3269    (set_attr "mode" "DI")])
3271 (define_insn "extendqidi2"
3272   [(set (match_operand:DI 0 "register_operand" "=r")
3273         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3274   "TARGET_64BIT"
3275   "movs{bq|x}\t{%1,%0|%0, %1}"
3276    [(set_attr "type" "imovx")
3277     (set_attr "mode" "DI")])
3279 ;; Extend to memory case when source register does die.
3280 (define_split 
3281   [(set (match_operand:DI 0 "memory_operand" "")
3282         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3283    (clobber (reg:CC FLAGS_REG))
3284    (clobber (match_operand:SI 2 "register_operand" ""))]
3285   "(reload_completed
3286     && dead_or_set_p (insn, operands[1])
3287     && !reg_mentioned_p (operands[1], operands[0]))"
3288   [(set (match_dup 3) (match_dup 1))
3289    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3290               (clobber (reg:CC FLAGS_REG))])
3291    (set (match_dup 4) (match_dup 1))]
3292   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3294 ;; Extend to memory case when source register does not die.
3295 (define_split 
3296   [(set (match_operand:DI 0 "memory_operand" "")
3297         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3298    (clobber (reg:CC FLAGS_REG))
3299    (clobber (match_operand:SI 2 "register_operand" ""))]
3300   "reload_completed"
3301   [(const_int 0)]
3303   split_di (&operands[0], 1, &operands[3], &operands[4]);
3305   emit_move_insn (operands[3], operands[1]);
3307   /* Generate a cltd if possible and doing so it profitable.  */
3308   if (true_regnum (operands[1]) == 0
3309       && true_regnum (operands[2]) == 1
3310       && (optimize_size || TARGET_USE_CLTD))
3311     {
3312       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3313     }
3314   else
3315     {
3316       emit_move_insn (operands[2], operands[1]);
3317       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3318     }
3319   emit_move_insn (operands[4], operands[2]);
3320   DONE;
3323 ;; Extend to register case.  Optimize case where source and destination
3324 ;; registers match and cases where we can use cltd.
3325 (define_split 
3326   [(set (match_operand:DI 0 "register_operand" "")
3327         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3328    (clobber (reg:CC FLAGS_REG))
3329    (clobber (match_scratch:SI 2 ""))]
3330   "reload_completed"
3331   [(const_int 0)]
3333   split_di (&operands[0], 1, &operands[3], &operands[4]);
3335   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3336     emit_move_insn (operands[3], operands[1]);
3338   /* Generate a cltd if possible and doing so it profitable.  */
3339   if (true_regnum (operands[3]) == 0
3340       && (optimize_size || TARGET_USE_CLTD))
3341     {
3342       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3343       DONE;
3344     }
3346   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3347     emit_move_insn (operands[4], operands[1]);
3349   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3350   DONE;
3353 (define_insn "extendhisi2"
3354   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3355         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3356   ""
3358   switch (get_attr_prefix_0f (insn))
3359     {
3360     case 0:
3361       return "{cwtl|cwde}";
3362     default:
3363       return "movs{wl|x}\t{%1,%0|%0, %1}";
3364     }
3366   [(set_attr "type" "imovx")
3367    (set_attr "mode" "SI")
3368    (set (attr "prefix_0f")
3369      ;; movsx is short decodable while cwtl is vector decoded.
3370      (if_then_else (and (eq_attr "cpu" "!k6")
3371                         (eq_attr "alternative" "0"))
3372         (const_string "0")
3373         (const_string "1")))
3374    (set (attr "modrm")
3375      (if_then_else (eq_attr "prefix_0f" "0")
3376         (const_string "0")
3377         (const_string "1")))])
3379 (define_insn "*extendhisi2_zext"
3380   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3381         (zero_extend:DI
3382           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3383   "TARGET_64BIT"
3385   switch (get_attr_prefix_0f (insn))
3386     {
3387     case 0:
3388       return "{cwtl|cwde}";
3389     default:
3390       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3391     }
3393   [(set_attr "type" "imovx")
3394    (set_attr "mode" "SI")
3395    (set (attr "prefix_0f")
3396      ;; movsx is short decodable while cwtl is vector decoded.
3397      (if_then_else (and (eq_attr "cpu" "!k6")
3398                         (eq_attr "alternative" "0"))
3399         (const_string "0")
3400         (const_string "1")))
3401    (set (attr "modrm")
3402      (if_then_else (eq_attr "prefix_0f" "0")
3403         (const_string "0")
3404         (const_string "1")))])
3406 (define_insn "extendqihi2"
3407   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3408         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3409   ""
3411   switch (get_attr_prefix_0f (insn))
3412     {
3413     case 0:
3414       return "{cbtw|cbw}";
3415     default:
3416       return "movs{bw|x}\t{%1,%0|%0, %1}";
3417     }
3419   [(set_attr "type" "imovx")
3420    (set_attr "mode" "HI")
3421    (set (attr "prefix_0f")
3422      ;; movsx is short decodable while cwtl is vector decoded.
3423      (if_then_else (and (eq_attr "cpu" "!k6")
3424                         (eq_attr "alternative" "0"))
3425         (const_string "0")
3426         (const_string "1")))
3427    (set (attr "modrm")
3428      (if_then_else (eq_attr "prefix_0f" "0")
3429         (const_string "0")
3430         (const_string "1")))])
3432 (define_insn "extendqisi2"
3433   [(set (match_operand:SI 0 "register_operand" "=r")
3434         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3435   ""
3436   "movs{bl|x}\t{%1,%0|%0, %1}"
3437    [(set_attr "type" "imovx")
3438     (set_attr "mode" "SI")])
3440 (define_insn "*extendqisi2_zext"
3441   [(set (match_operand:DI 0 "register_operand" "=r")
3442         (zero_extend:DI
3443           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3444   "TARGET_64BIT"
3445   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3446    [(set_attr "type" "imovx")
3447     (set_attr "mode" "SI")])
3449 ;; Conversions between float and double.
3451 ;; These are all no-ops in the model used for the 80387.  So just
3452 ;; emit moves.
3454 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3455 (define_insn "*dummy_extendsfdf2"
3456   [(set (match_operand:DF 0 "push_operand" "=<")
3457         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3458   "0"
3459   "#")
3461 (define_split
3462   [(set (match_operand:DF 0 "push_operand" "")
3463         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3464   "!TARGET_64BIT"
3465   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3466    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3468 (define_split
3469   [(set (match_operand:DF 0 "push_operand" "")
3470         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3471   "TARGET_64BIT"
3472   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3473    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3475 (define_insn "*dummy_extendsfxf2"
3476   [(set (match_operand:XF 0 "push_operand" "=<")
3477         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3478   "0"
3479   "#")
3481 (define_split
3482   [(set (match_operand:XF 0 "push_operand" "")
3483         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3484   ""
3485   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3486    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3487   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489 (define_split
3490   [(set (match_operand:XF 0 "push_operand" "")
3491         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3492   "TARGET_64BIT"
3493   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3494    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3495   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497 (define_split
3498   [(set (match_operand:XF 0 "push_operand" "")
3499         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3500   ""
3501   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3502    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3503   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505 (define_split
3506   [(set (match_operand:XF 0 "push_operand" "")
3507         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3508   "TARGET_64BIT"
3509   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3510    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3511   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513 (define_expand "extendsfdf2"
3514   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3515         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3516   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3518   /* ??? Needed for compress_float_constant since all fp constants
3519      are LEGITIMATE_CONSTANT_P.  */
3520   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523     operands[1] = force_reg (SFmode, operands[1]);
3526 (define_insn "*extendsfdf2_mixed"
3527   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3528         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3529   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3530    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3532   switch (which_alternative)
3533     {
3534     case 0:
3535       return output_387_reg_move (insn, operands);
3537     case 1:
3538       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3539         return "fstp%z0\t%y0";
3540       else
3541         return "fst%z0\t%y0";
3543     case 2:
3544       return "cvtss2sd\t{%1, %0|%0, %1}";
3546     default:
3547       gcc_unreachable ();
3548     }
3550   [(set_attr "type" "fmov,fmov,ssecvt")
3551    (set_attr "mode" "SF,XF,DF")])
3553 (define_insn "*extendsfdf2_sse"
3554   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3555         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3556   "TARGET_SSE2 && TARGET_SSE_MATH
3557    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3558   "cvtss2sd\t{%1, %0|%0, %1}"
3559   [(set_attr "type" "ssecvt")
3560    (set_attr "mode" "DF")])
3562 (define_insn "*extendsfdf2_i387"
3563   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3564         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3565   "TARGET_80387
3566    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3568   switch (which_alternative)
3569     {
3570     case 0:
3571       return output_387_reg_move (insn, operands);
3573     case 1:
3574       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3575         return "fstp%z0\t%y0";
3576       else
3577         return "fst%z0\t%y0";
3579     default:
3580       gcc_unreachable ();
3581     }
3583   [(set_attr "type" "fmov")
3584    (set_attr "mode" "SF,XF")])
3586 (define_expand "extendsfxf2"
3587   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3588         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3589   "TARGET_80387"
3591   /* ??? Needed for compress_float_constant since all fp constants
3592      are LEGITIMATE_CONSTANT_P.  */
3593   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3594     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3595   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3596     operands[1] = force_reg (SFmode, operands[1]);
3599 (define_insn "*extendsfxf2_i387"
3600   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3601         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3602   "TARGET_80387
3603    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3605   switch (which_alternative)
3606     {
3607     case 0:
3608       return output_387_reg_move (insn, operands);
3610     case 1:
3611       /* There is no non-popping store to memory for XFmode.  So if
3612          we need one, follow the store with a load.  */
3613       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614         return "fstp%z0\t%y0";
3615       else
3616         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3618     default:
3619       gcc_unreachable ();
3620     }
3622   [(set_attr "type" "fmov")
3623    (set_attr "mode" "SF,XF")])
3625 (define_expand "extenddfxf2"
3626   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3627         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3628   "TARGET_80387"
3630   /* ??? Needed for compress_float_constant since all fp constants
3631      are LEGITIMATE_CONSTANT_P.  */
3632   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3633     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3634   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3635     operands[1] = force_reg (DFmode, operands[1]);
3638 (define_insn "*extenddfxf2_i387"
3639   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3640         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3641   "TARGET_80387
3642    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3644   switch (which_alternative)
3645     {
3646     case 0:
3647       return output_387_reg_move (insn, operands);
3649     case 1:
3650       /* There is no non-popping store to memory for XFmode.  So if
3651          we need one, follow the store with a load.  */
3652       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3653         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3654       else
3655         return "fstp%z0\t%y0";
3657     default:
3658       gcc_unreachable ();
3659     }
3661   [(set_attr "type" "fmov")
3662    (set_attr "mode" "DF,XF")])
3664 ;; %%% This seems bad bad news.
3665 ;; This cannot output into an f-reg because there is no way to be sure
3666 ;; of truncating in that case.  Otherwise this is just like a simple move
3667 ;; insn.  So we pretend we can output to a reg in order to get better
3668 ;; register preferencing, but we really use a stack slot.
3670 ;; Conversion from DFmode to SFmode.
3672 (define_expand "truncdfsf2"
3673   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3674         (float_truncate:SF
3675           (match_operand:DF 1 "nonimmediate_operand" "")))]
3676   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3678   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3679     operands[1] = force_reg (DFmode, operands[1]);
3681   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3682     ;
3683   else if (flag_unsafe_math_optimizations)
3684     ;
3685   else
3686     {
3687       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3688       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3689       DONE;
3690     }
3693 (define_expand "truncdfsf2_with_temp"
3694   [(parallel [(set (match_operand:SF 0 "" "")
3695                    (float_truncate:SF (match_operand:DF 1 "" "")))
3696               (clobber (match_operand:SF 2 "" ""))])]
3697   "")
3699 (define_insn "*truncdfsf_fast_mixed"
3700   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3701         (float_truncate:SF
3702           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3703   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3705   switch (which_alternative)
3706     {
3707     case 0:
3708       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3709         return "fstp%z0\t%y0";
3710       else
3711         return "fst%z0\t%y0";
3712     case 1:
3713       return output_387_reg_move (insn, operands);
3714     case 2:
3715       return "cvtsd2ss\t{%1, %0|%0, %1}";
3716     default:
3717       gcc_unreachable ();
3718     }
3720   [(set_attr "type" "fmov,fmov,ssecvt")
3721    (set_attr "mode" "SF")])
3723 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3724 ;; because nothing we do here is unsafe.
3725 (define_insn "*truncdfsf_fast_sse"
3726   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3727         (float_truncate:SF
3728           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3729   "TARGET_SSE2 && TARGET_SSE_MATH"
3730   "cvtsd2ss\t{%1, %0|%0, %1}"
3731   [(set_attr "type" "ssecvt")
3732    (set_attr "mode" "SF")])
3734 (define_insn "*truncdfsf_fast_i387"
3735   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3736         (float_truncate:SF
3737           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3738   "TARGET_80387 && flag_unsafe_math_optimizations"
3739   "* return output_387_reg_move (insn, operands);"
3740   [(set_attr "type" "fmov")
3741    (set_attr "mode" "SF")])
3743 (define_insn "*truncdfsf_mixed"
3744   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3745         (float_truncate:SF
3746           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3747    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3748   "TARGET_MIX_SSE_I387"
3750   switch (which_alternative)
3751     {
3752     case 0:
3753       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754         return "fstp%z0\t%y0";
3755       else
3756         return "fst%z0\t%y0";
3757     case 1:
3758       return "#";
3759     case 2:
3760       return "cvtsd2ss\t{%1, %0|%0, %1}";
3761     default:
3762       gcc_unreachable ();
3763     }
3765   [(set_attr "type" "fmov,multi,ssecvt")
3766    (set_attr "unit" "*,i387,*")
3767    (set_attr "mode" "SF")])
3769 (define_insn "*truncdfsf_i387"
3770   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3771         (float_truncate:SF
3772           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3773    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3774   "TARGET_80387"
3776   switch (which_alternative)
3777     {
3778     case 0:
3779       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780         return "fstp%z0\t%y0";
3781       else
3782         return "fst%z0\t%y0";
3783     case 1:
3784       return "#";
3785     default:
3786       gcc_unreachable ();
3787     }
3789   [(set_attr "type" "fmov,multi")
3790    (set_attr "unit" "*,i387")
3791    (set_attr "mode" "SF")])
3793 (define_insn "*truncdfsf2_i387_1"
3794   [(set (match_operand:SF 0 "memory_operand" "=m")
3795         (float_truncate:SF
3796           (match_operand:DF 1 "register_operand" "f")))]
3797   "TARGET_80387
3798    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3799    && !TARGET_MIX_SSE_I387"
3801   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3802     return "fstp%z0\t%y0";
3803   else
3804     return "fst%z0\t%y0";
3806   [(set_attr "type" "fmov")
3807    (set_attr "mode" "SF")])
3809 (define_split
3810   [(set (match_operand:SF 0 "register_operand" "")
3811         (float_truncate:SF
3812          (match_operand:DF 1 "fp_register_operand" "")))
3813    (clobber (match_operand 2 "" ""))]
3814   "reload_completed"
3815   [(set (match_dup 2) (match_dup 1))
3816    (set (match_dup 0) (match_dup 2))]
3818   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3821 ;; Conversion from XFmode to SFmode.
3823 (define_expand "truncxfsf2"
3824   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3825                    (float_truncate:SF
3826                     (match_operand:XF 1 "register_operand" "")))
3827               (clobber (match_dup 2))])]
3828   "TARGET_80387"
3830   if (flag_unsafe_math_optimizations)
3831     {
3832       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3833       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3834       if (reg != operands[0])
3835         emit_move_insn (operands[0], reg);
3836       DONE;
3837     }
3838   else
3839     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3842 (define_insn "*truncxfsf2_mixed"
3843   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3844         (float_truncate:SF
3845          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3846    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3847   "TARGET_MIX_SSE_I387"
3849   gcc_assert (!which_alternative);
3850   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3851     return "fstp%z0\t%y0";
3852   else
3853     return "fst%z0\t%y0";
3855   [(set_attr "type" "fmov,multi,multi,multi")
3856    (set_attr "unit" "*,i387,i387,i387")
3857    (set_attr "mode" "SF")])
3859 (define_insn "truncxfsf2_i387_noop"
3860   [(set (match_operand:SF 0 "register_operand" "=f")
3861         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3862   "TARGET_80387 && flag_unsafe_math_optimizations"
3864   return output_387_reg_move (insn, operands);
3866   [(set_attr "type" "fmov")
3867    (set_attr "mode" "SF")])
3869 (define_insn "*truncxfsf2_i387"
3870   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3871         (float_truncate:SF
3872          (match_operand:XF 1 "register_operand" "f,f,f")))
3873    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3874   "TARGET_80387"
3876   gcc_assert (!which_alternative);
3877   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3878     return "fstp%z0\t%y0";
3879    else
3880      return "fst%z0\t%y0";
3882   [(set_attr "type" "fmov,multi,multi")
3883    (set_attr "unit" "*,i387,i387")
3884    (set_attr "mode" "SF")])
3886 (define_insn "*truncxfsf2_i387_1"
3887   [(set (match_operand:SF 0 "memory_operand" "=m")
3888         (float_truncate:SF
3889          (match_operand:XF 1 "register_operand" "f")))]
3890   "TARGET_80387"
3892   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3893     return "fstp%z0\t%y0";
3894   else
3895     return "fst%z0\t%y0";
3897   [(set_attr "type" "fmov")
3898    (set_attr "mode" "SF")])
3900 (define_split
3901   [(set (match_operand:SF 0 "register_operand" "")
3902         (float_truncate:SF
3903          (match_operand:XF 1 "register_operand" "")))
3904    (clobber (match_operand:SF 2 "memory_operand" ""))]
3905   "TARGET_80387 && reload_completed"
3906   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3907    (set (match_dup 0) (match_dup 2))]
3908   "")
3910 (define_split
3911   [(set (match_operand:SF 0 "memory_operand" "")
3912         (float_truncate:SF
3913          (match_operand:XF 1 "register_operand" "")))
3914    (clobber (match_operand:SF 2 "memory_operand" ""))]
3915   "TARGET_80387"
3916   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3917   "")
3919 ;; Conversion from XFmode to DFmode.
3921 (define_expand "truncxfdf2"
3922   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3923                    (float_truncate:DF
3924                     (match_operand:XF 1 "register_operand" "")))
3925               (clobber (match_dup 2))])]
3926   "TARGET_80387"
3928   if (flag_unsafe_math_optimizations)
3929     {
3930       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3931       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3932       if (reg != operands[0])
3933         emit_move_insn (operands[0], reg);
3934       DONE;
3935     }
3936   else
3937     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3940 (define_insn "*truncxfdf2_mixed"
3941   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3942         (float_truncate:DF
3943          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3944    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3945   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3947   gcc_assert (!which_alternative);
3948   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949     return "fstp%z0\t%y0";
3950   else
3951     return "fst%z0\t%y0";
3953   [(set_attr "type" "fmov,multi,multi,multi")
3954    (set_attr "unit" "*,i387,i387,i387")
3955    (set_attr "mode" "DF")])
3957 (define_insn "truncxfdf2_i387_noop"
3958   [(set (match_operand:DF 0 "register_operand" "=f")
3959         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3960   "TARGET_80387 && flag_unsafe_math_optimizations"
3962   return output_387_reg_move (insn, operands);
3964   [(set_attr "type" "fmov")
3965    (set_attr "mode" "DF")])
3967 (define_insn "*truncxfdf2_i387"
3968   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3969         (float_truncate:DF
3970          (match_operand:XF 1 "register_operand" "f,f,f")))
3971    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3972   "TARGET_80387"
3974   gcc_assert (!which_alternative);
3975   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3976     return "fstp%z0\t%y0";
3977   else
3978     return "fst%z0\t%y0";
3980   [(set_attr "type" "fmov,multi,multi")
3981    (set_attr "unit" "*,i387,i387")
3982    (set_attr "mode" "DF")])
3984 (define_insn "*truncxfdf2_i387_1"
3985   [(set (match_operand:DF 0 "memory_operand" "=m")
3986         (float_truncate:DF
3987           (match_operand:XF 1 "register_operand" "f")))]
3988   "TARGET_80387"
3990   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3991     return "fstp%z0\t%y0";
3992   else
3993     return "fst%z0\t%y0";
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "DF")])
3998 (define_split
3999   [(set (match_operand:DF 0 "register_operand" "")
4000         (float_truncate:DF
4001          (match_operand:XF 1 "register_operand" "")))
4002    (clobber (match_operand:DF 2 "memory_operand" ""))]
4003   "TARGET_80387 && reload_completed"
4004   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4005    (set (match_dup 0) (match_dup 2))]
4006   "")
4008 (define_split
4009   [(set (match_operand:DF 0 "memory_operand" "")
4010         (float_truncate:DF
4011          (match_operand:XF 1 "register_operand" "")))
4012    (clobber (match_operand:DF 2 "memory_operand" ""))]
4013   "TARGET_80387"
4014   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4015   "")
4017 ;; Signed conversion to DImode.
4019 (define_expand "fix_truncxfdi2"
4020   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4021                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4022               (clobber (reg:CC FLAGS_REG))])]
4023   "TARGET_80387"
4025   if (TARGET_FISTTP)
4026    {
4027      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4028      DONE;
4029    }
4032 (define_expand "fix_trunc<mode>di2"
4033   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4035               (clobber (reg:CC FLAGS_REG))])]
4036   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4038   if (TARGET_FISTTP
4039       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4040    {
4041      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4042      DONE;
4043    }
4044   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4045    {
4046      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4047      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4048      if (out != operands[0])
4049         emit_move_insn (operands[0], out);
4050      DONE;
4051    }
4054 ;; Signed conversion to SImode.
4056 (define_expand "fix_truncxfsi2"
4057   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4058                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4059               (clobber (reg:CC FLAGS_REG))])]
4060   "TARGET_80387"
4062   if (TARGET_FISTTP)
4063    {
4064      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4065      DONE;
4066    }
4069 (define_expand "fix_trunc<mode>si2"
4070   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4071                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4072               (clobber (reg:CC FLAGS_REG))])]
4073   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4075   if (TARGET_FISTTP
4076       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4077    {
4078      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4079      DONE;
4080    }
4081   if (SSE_FLOAT_MODE_P (<MODE>mode))
4082    {
4083      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4084      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4085      if (out != operands[0])
4086         emit_move_insn (operands[0], out);
4087      DONE;
4088    }
4091 ;; Signed conversion to HImode.
4093 (define_expand "fix_trunc<mode>hi2"
4094   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4095                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4096               (clobber (reg:CC FLAGS_REG))])]
4097   "TARGET_80387
4098    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4100   if (TARGET_FISTTP)
4101    {
4102      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4103      DONE;
4104    }
4107 ;; When SSE is available, it is always faster to use it!
4108 (define_insn "fix_truncsfdi_sse"
4109   [(set (match_operand:DI 0 "register_operand" "=r,r")
4110         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4111   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4112   "cvttss2si{q}\t{%1, %0|%0, %1}"
4113   [(set_attr "type" "sseicvt")
4114    (set_attr "mode" "SF")
4115    (set_attr "athlon_decode" "double,vector")])
4117 (define_insn "fix_truncdfdi_sse"
4118   [(set (match_operand:DI 0 "register_operand" "=r,r")
4119         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4120   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4121   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4122   [(set_attr "type" "sseicvt")
4123    (set_attr "mode" "DF")
4124    (set_attr "athlon_decode" "double,vector")])
4126 (define_insn "fix_truncsfsi_sse"
4127   [(set (match_operand:SI 0 "register_operand" "=r,r")
4128         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130   "cvttss2si\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "DF")
4133    (set_attr "athlon_decode" "double,vector")])
4135 (define_insn "fix_truncdfsi_sse"
4136   [(set (match_operand:SI 0 "register_operand" "=r,r")
4137         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139   "cvttsd2si\t{%1, %0|%0, %1}"
4140   [(set_attr "type" "sseicvt")
4141    (set_attr "mode" "DF")
4142    (set_attr "athlon_decode" "double,vector")])
4144 ;; Avoid vector decoded forms of the instruction.
4145 (define_peephole2
4146   [(match_scratch:DF 2 "Y")
4147    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4148         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4149   "TARGET_K8 && !optimize_size"
4150   [(set (match_dup 2) (match_dup 1))
4151    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4152   "")
4154 (define_peephole2
4155   [(match_scratch:SF 2 "x")
4156    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4157         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4158   "TARGET_K8 && !optimize_size"
4159   [(set (match_dup 2) (match_dup 1))
4160    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4161   "")
4163 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4164   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4165         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4166   "TARGET_FISTTP
4167    && FLOAT_MODE_P (GET_MODE (operands[1]))
4168    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4169          && (TARGET_64BIT || <MODE>mode != DImode))
4170         && TARGET_SSE_MATH)
4171    && !(reload_completed || reload_in_progress)"
4172   "#"
4173   "&& 1"
4174   [(const_int 0)]
4176   if (memory_operand (operands[0], VOIDmode))
4177     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4178   else
4179     {
4180       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4181       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4182                                                             operands[1],
4183                                                             operands[2]));
4184     }
4185   DONE;
4187   [(set_attr "type" "fisttp")
4188    (set_attr "mode" "<MODE>")])
4190 (define_insn "fix_trunc<mode>_i387_fisttp"
4191   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4192         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4193    (clobber (match_scratch:XF 2 "=&1f"))]
4194   "TARGET_FISTTP
4195    && FLOAT_MODE_P (GET_MODE (operands[1]))
4196    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4197          && (TARGET_64BIT || <MODE>mode != DImode))
4198         && TARGET_SSE_MATH)"
4199   "* return output_fix_trunc (insn, operands, 1);"
4200   [(set_attr "type" "fisttp")
4201    (set_attr "mode" "<MODE>")])
4203 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4204   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4205         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4206    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4207    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4208   "TARGET_FISTTP
4209    && FLOAT_MODE_P (GET_MODE (operands[1]))
4210    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4211         && (TARGET_64BIT || <MODE>mode != DImode))
4212         && TARGET_SSE_MATH)"
4213   "#"
4214   [(set_attr "type" "fisttp")
4215    (set_attr "mode" "<MODE>")])
4217 (define_split
4218   [(set (match_operand:X87MODEI 0 "register_operand" "")
4219         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4220    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4221    (clobber (match_scratch 3 ""))]
4222   "reload_completed"
4223   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4224               (clobber (match_dup 3))])
4225    (set (match_dup 0) (match_dup 2))]
4226   "")
4228 (define_split
4229   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4230         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4231    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4232    (clobber (match_scratch 3 ""))]
4233   "reload_completed"
4234   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4235               (clobber (match_dup 3))])]
4236   "")
4238 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4239 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4240 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4241 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4242 ;; function in i386.c.
4243 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4244   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4245         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4246    (clobber (reg:CC FLAGS_REG))]
4247   "TARGET_80387 && !TARGET_FISTTP
4248    && FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4250          && (TARGET_64BIT || <MODE>mode != DImode))
4251    && !(reload_completed || reload_in_progress)"
4252   "#"
4253   "&& 1"
4254   [(const_int 0)]
4256   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4258   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4259   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4260   if (memory_operand (operands[0], VOIDmode))
4261     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4262                                          operands[2], operands[3]));
4263   else
4264     {
4265       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4266       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4267                                                      operands[2], operands[3],
4268                                                      operands[4]));
4269     }
4270   DONE;
4272   [(set_attr "type" "fistp")
4273    (set_attr "i387_cw" "trunc")
4274    (set_attr "mode" "<MODE>")])
4276 (define_insn "fix_truncdi_i387"
4277   [(set (match_operand:DI 0 "memory_operand" "=m")
4278         (fix:DI (match_operand 1 "register_operand" "f")))
4279    (use (match_operand:HI 2 "memory_operand" "m"))
4280    (use (match_operand:HI 3 "memory_operand" "m"))
4281    (clobber (match_scratch:XF 4 "=&1f"))]
4282   "TARGET_80387 && !TARGET_FISTTP
4283    && FLOAT_MODE_P (GET_MODE (operands[1]))
4284    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4285   "* return output_fix_trunc (insn, operands, 0);"
4286   [(set_attr "type" "fistp")
4287    (set_attr "i387_cw" "trunc")
4288    (set_attr "mode" "DI")])
4290 (define_insn "fix_truncdi_i387_with_temp"
4291   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:DI (match_operand 1 "register_operand" "f,f")))
4293    (use (match_operand:HI 2 "memory_operand" "m,m"))
4294    (use (match_operand:HI 3 "memory_operand" "m,m"))
4295    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4296    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4297   "TARGET_80387 && !TARGET_FISTTP
4298    && FLOAT_MODE_P (GET_MODE (operands[1]))
4299    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4300   "#"
4301   [(set_attr "type" "fistp")
4302    (set_attr "i387_cw" "trunc")
4303    (set_attr "mode" "DI")])
4305 (define_split 
4306   [(set (match_operand:DI 0 "register_operand" "")
4307         (fix:DI (match_operand 1 "register_operand" "")))
4308    (use (match_operand:HI 2 "memory_operand" ""))
4309    (use (match_operand:HI 3 "memory_operand" ""))
4310    (clobber (match_operand:DI 4 "memory_operand" ""))
4311    (clobber (match_scratch 5 ""))]
4312   "reload_completed"
4313   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4314               (use (match_dup 2))
4315               (use (match_dup 3))
4316               (clobber (match_dup 5))])
4317    (set (match_dup 0) (match_dup 4))]
4318   "")
4320 (define_split 
4321   [(set (match_operand:DI 0 "memory_operand" "")
4322         (fix:DI (match_operand 1 "register_operand" "")))
4323    (use (match_operand:HI 2 "memory_operand" ""))
4324    (use (match_operand:HI 3 "memory_operand" ""))
4325    (clobber (match_operand:DI 4 "memory_operand" ""))
4326    (clobber (match_scratch 5 ""))]
4327   "reload_completed"
4328   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4329               (use (match_dup 2))
4330               (use (match_dup 3))
4331               (clobber (match_dup 5))])]
4332   "")
4334 (define_insn "fix_trunc<mode>_i387"
4335   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4336         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4337    (use (match_operand:HI 2 "memory_operand" "m"))
4338    (use (match_operand:HI 3 "memory_operand" "m"))]
4339   "TARGET_80387 && !TARGET_FISTTP
4340    && FLOAT_MODE_P (GET_MODE (operands[1]))
4341    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342   "* return output_fix_trunc (insn, operands, 0);"
4343   [(set_attr "type" "fistp")
4344    (set_attr "i387_cw" "trunc")
4345    (set_attr "mode" "<MODE>")])
4347 (define_insn "fix_trunc<mode>_i387_with_temp"
4348   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4349         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4350    (use (match_operand:HI 2 "memory_operand" "m,m"))
4351    (use (match_operand:HI 3 "memory_operand" "m,m"))
4352    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4353   "TARGET_80387 && !TARGET_FISTTP
4354    && FLOAT_MODE_P (GET_MODE (operands[1]))
4355    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356   "#"
4357   [(set_attr "type" "fistp")
4358    (set_attr "i387_cw" "trunc")
4359    (set_attr "mode" "<MODE>")])
4361 (define_split 
4362   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4363         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4364    (use (match_operand:HI 2 "memory_operand" ""))
4365    (use (match_operand:HI 3 "memory_operand" ""))
4366    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4367   "reload_completed"
4368   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4369               (use (match_dup 2))
4370               (use (match_dup 3))])
4371    (set (match_dup 0) (match_dup 4))]
4372   "")
4374 (define_split 
4375   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4376         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4377    (use (match_operand:HI 2 "memory_operand" ""))
4378    (use (match_operand:HI 3 "memory_operand" ""))
4379    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4380   "reload_completed"
4381   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4382               (use (match_dup 2))
4383               (use (match_dup 3))])]
4384   "")
4386 (define_insn "x86_fnstcw_1"
4387   [(set (match_operand:HI 0 "memory_operand" "=m")
4388         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4389   "TARGET_80387"
4390   "fnstcw\t%0"
4391   [(set_attr "length" "2")
4392    (set_attr "mode" "HI")
4393    (set_attr "unit" "i387")])
4395 (define_insn "x86_fldcw_1"
4396   [(set (reg:HI FPSR_REG)
4397         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4398   "TARGET_80387"
4399   "fldcw\t%0"
4400   [(set_attr "length" "2")
4401    (set_attr "mode" "HI")
4402    (set_attr "unit" "i387")
4403    (set_attr "athlon_decode" "vector")])
4405 ;; Conversion between fixed point and floating point.
4407 ;; Even though we only accept memory inputs, the backend _really_
4408 ;; wants to be able to do this between registers.
4410 (define_expand "floathisf2"
4411   [(set (match_operand:SF 0 "register_operand" "")
4412         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4413   "TARGET_80387 || TARGET_SSE_MATH"
4415   if (TARGET_SSE_MATH)
4416     {
4417       emit_insn (gen_floatsisf2 (operands[0],
4418                                  convert_to_mode (SImode, operands[1], 0)));
4419       DONE;
4420     }
4423 (define_insn "*floathisf2_i387"
4424   [(set (match_operand:SF 0 "register_operand" "=f,f")
4425         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4426   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4427   "@
4428    fild%z1\t%1
4429    #"
4430   [(set_attr "type" "fmov,multi")
4431    (set_attr "mode" "SF")
4432    (set_attr "unit" "*,i387")
4433    (set_attr "fp_int_src" "true")])
4435 (define_expand "floatsisf2"
4436   [(set (match_operand:SF 0 "register_operand" "")
4437         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4438   "TARGET_80387 || TARGET_SSE_MATH"
4439   "")
4441 (define_insn "*floatsisf2_mixed"
4442   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4443         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4444   "TARGET_MIX_SSE_I387"
4445   "@
4446    fild%z1\t%1
4447    #
4448    cvtsi2ss\t{%1, %0|%0, %1}
4449    cvtsi2ss\t{%1, %0|%0, %1}"
4450   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4451    (set_attr "mode" "SF")
4452    (set_attr "unit" "*,i387,*,*")
4453    (set_attr "athlon_decode" "*,*,vector,double")
4454    (set_attr "fp_int_src" "true")])
4456 (define_insn "*floatsisf2_sse"
4457   [(set (match_operand:SF 0 "register_operand" "=x,x")
4458         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4459   "TARGET_SSE_MATH"
4460   "cvtsi2ss\t{%1, %0|%0, %1}"
4461   [(set_attr "type" "sseicvt")
4462    (set_attr "mode" "SF")
4463    (set_attr "athlon_decode" "vector,double")
4464    (set_attr "fp_int_src" "true")])
4466 (define_insn "*floatsisf2_i387"
4467   [(set (match_operand:SF 0 "register_operand" "=f,f")
4468         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4469   "TARGET_80387"
4470   "@
4471    fild%z1\t%1
4472    #"
4473   [(set_attr "type" "fmov,multi")
4474    (set_attr "mode" "SF")
4475    (set_attr "unit" "*,i387")
4476    (set_attr "fp_int_src" "true")])
4478 (define_expand "floatdisf2"
4479   [(set (match_operand:SF 0 "register_operand" "")
4480         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4481   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4482   "")
4484 (define_insn "*floatdisf2_mixed"
4485   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4488   "@
4489    fild%z1\t%1
4490    #
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}
4492    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "unit" "*,i387,*,*")
4496    (set_attr "athlon_decode" "*,*,vector,double")
4497    (set_attr "fp_int_src" "true")])
4499 (define_insn "*floatdisf2_sse"
4500   [(set (match_operand:SF 0 "register_operand" "=x,x")
4501         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4502   "TARGET_64BIT && TARGET_SSE_MATH"
4503   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4504   [(set_attr "type" "sseicvt")
4505    (set_attr "mode" "SF")
4506    (set_attr "athlon_decode" "vector,double")
4507    (set_attr "fp_int_src" "true")])
4509 (define_insn "*floatdisf2_i387"
4510   [(set (match_operand:SF 0 "register_operand" "=f,f")
4511         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4512   "TARGET_80387"
4513   "@
4514    fild%z1\t%1
4515    #"
4516   [(set_attr "type" "fmov,multi")
4517    (set_attr "mode" "SF")
4518    (set_attr "unit" "*,i387")
4519    (set_attr "fp_int_src" "true")])
4521 (define_expand "floathidf2"
4522   [(set (match_operand:DF 0 "register_operand" "")
4523         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4524   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4526   if (TARGET_SSE2 && TARGET_SSE_MATH)
4527     {
4528       emit_insn (gen_floatsidf2 (operands[0],
4529                                  convert_to_mode (SImode, operands[1], 0)));
4530       DONE;
4531     }
4534 (define_insn "*floathidf2_i387"
4535   [(set (match_operand:DF 0 "register_operand" "=f,f")
4536         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4537   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4538   "@
4539    fild%z1\t%1
4540    #"
4541   [(set_attr "type" "fmov,multi")
4542    (set_attr "mode" "DF")
4543    (set_attr "unit" "*,i387")
4544    (set_attr "fp_int_src" "true")])
4546 (define_expand "floatsidf2"
4547   [(set (match_operand:DF 0 "register_operand" "")
4548         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4549   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4550   "")
4552 (define_insn "*floatsidf2_mixed"
4553   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4554         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4555   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4556   "@
4557    fild%z1\t%1
4558    #
4559    cvtsi2sd\t{%1, %0|%0, %1}
4560    cvtsi2sd\t{%1, %0|%0, %1}"
4561   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4562    (set_attr "mode" "DF")
4563    (set_attr "unit" "*,i387,*,*")
4564    (set_attr "athlon_decode" "*,*,double,direct")
4565    (set_attr "fp_int_src" "true")])
4567 (define_insn "*floatsidf2_sse"
4568   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4569         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4570   "TARGET_SSE2 && TARGET_SSE_MATH"
4571   "cvtsi2sd\t{%1, %0|%0, %1}"
4572   [(set_attr "type" "sseicvt")
4573    (set_attr "mode" "DF")
4574    (set_attr "athlon_decode" "double,direct")
4575    (set_attr "fp_int_src" "true")])
4577 (define_insn "*floatsidf2_i387"
4578   [(set (match_operand:DF 0 "register_operand" "=f,f")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4580   "TARGET_80387"
4581   "@
4582    fild%z1\t%1
4583    #"
4584   [(set_attr "type" "fmov,multi")
4585    (set_attr "mode" "DF")
4586    (set_attr "unit" "*,i387")
4587    (set_attr "fp_int_src" "true")])
4589 (define_expand "floatdidf2"
4590   [(set (match_operand:DF 0 "register_operand" "")
4591         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4593   "")
4595 (define_insn "*floatdidf2_mixed"
4596   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4597         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4598   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4599   "@
4600    fild%z1\t%1
4601    #
4602    cvtsi2sd{q}\t{%1, %0|%0, %1}
4603    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4604   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4605    (set_attr "mode" "DF")
4606    (set_attr "unit" "*,i387,*,*")
4607    (set_attr "athlon_decode" "*,*,double,direct")
4608    (set_attr "fp_int_src" "true")])
4610 (define_insn "*floatdidf2_sse"
4611   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4612         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4613   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4614   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4615   [(set_attr "type" "sseicvt")
4616    (set_attr "mode" "DF")
4617    (set_attr "athlon_decode" "double,direct")
4618    (set_attr "fp_int_src" "true")])
4620 (define_insn "*floatdidf2_i387"
4621   [(set (match_operand:DF 0 "register_operand" "=f,f")
4622         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4623   "TARGET_80387"
4624   "@
4625    fild%z1\t%1
4626    #"
4627   [(set_attr "type" "fmov,multi")
4628    (set_attr "mode" "DF")
4629    (set_attr "unit" "*,i387")
4630    (set_attr "fp_int_src" "true")])
4632 (define_insn "floathixf2"
4633   [(set (match_operand:XF 0 "register_operand" "=f,f")
4634         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4635   "TARGET_80387"
4636   "@
4637    fild%z1\t%1
4638    #"
4639   [(set_attr "type" "fmov,multi")
4640    (set_attr "mode" "XF")
4641    (set_attr "unit" "*,i387")
4642    (set_attr "fp_int_src" "true")])
4644 (define_insn "floatsixf2"
4645   [(set (match_operand:XF 0 "register_operand" "=f,f")
4646         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4647   "TARGET_80387"
4648   "@
4649    fild%z1\t%1
4650    #"
4651   [(set_attr "type" "fmov,multi")
4652    (set_attr "mode" "XF")
4653    (set_attr "unit" "*,i387")
4654    (set_attr "fp_int_src" "true")])
4656 (define_insn "floatdixf2"
4657   [(set (match_operand:XF 0 "register_operand" "=f,f")
4658         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4659   "TARGET_80387"
4660   "@
4661    fild%z1\t%1
4662    #"
4663   [(set_attr "type" "fmov,multi")
4664    (set_attr "mode" "XF")
4665    (set_attr "unit" "*,i387")
4666    (set_attr "fp_int_src" "true")])
4668 ;; %%% Kill these when reload knows how to do it.
4669 (define_split
4670   [(set (match_operand 0 "fp_register_operand" "")
4671         (float (match_operand 1 "register_operand" "")))]
4672   "reload_completed
4673    && TARGET_80387
4674    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4675   [(const_int 0)]
4677   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4678   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4679   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4680   ix86_free_from_memory (GET_MODE (operands[1]));
4681   DONE;
4684 (define_expand "floatunssisf2"
4685   [(use (match_operand:SF 0 "register_operand" ""))
4686    (use (match_operand:SI 1 "register_operand" ""))]
4687   "!TARGET_64BIT && TARGET_SSE_MATH"
4688   "x86_emit_floatuns (operands); DONE;")
4690 (define_expand "floatunsdisf2"
4691   [(use (match_operand:SF 0 "register_operand" ""))
4692    (use (match_operand:DI 1 "register_operand" ""))]
4693   "TARGET_64BIT && TARGET_SSE_MATH"
4694   "x86_emit_floatuns (operands); DONE;")
4696 (define_expand "floatunsdidf2"
4697   [(use (match_operand:DF 0 "register_operand" ""))
4698    (use (match_operand:DI 1 "register_operand" ""))]
4699   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700   "x86_emit_floatuns (operands); DONE;")
4702 ;; SSE extract/set expanders
4705 ;; Add instructions
4707 ;; %%% splits for addditi3
4709 (define_expand "addti3"
4710   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4711         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4712                  (match_operand:TI 2 "x86_64_general_operand" "")))
4713    (clobber (reg:CC FLAGS_REG))]
4714   "TARGET_64BIT"
4715   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4717 (define_insn "*addti3_1"
4718   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4720                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4721    (clobber (reg:CC FLAGS_REG))]
4722   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4723   "#")
4725 (define_split
4726   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4727         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4728                  (match_operand:TI 2 "general_operand" "")))
4729    (clobber (reg:CC FLAGS_REG))]
4730   "TARGET_64BIT && reload_completed"
4731   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4732                                           UNSPEC_ADD_CARRY))
4733               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4734    (parallel [(set (match_dup 3)
4735                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4736                                      (match_dup 4))
4737                             (match_dup 5)))
4738               (clobber (reg:CC FLAGS_REG))])]
4739   "split_ti (operands+0, 1, operands+0, operands+3);
4740    split_ti (operands+1, 1, operands+1, operands+4);
4741    split_ti (operands+2, 1, operands+2, operands+5);")
4743 ;; %%% splits for addsidi3
4744 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4746 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4748 (define_expand "adddi3"
4749   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4750         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4751                  (match_operand:DI 2 "x86_64_general_operand" "")))
4752    (clobber (reg:CC FLAGS_REG))]
4753   ""
4754   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4756 (define_insn "*adddi3_1"
4757   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4758         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4759                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4762   "#")
4764 (define_split
4765   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4766         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4767                  (match_operand:DI 2 "general_operand" "")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "!TARGET_64BIT && reload_completed"
4770   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771                                           UNSPEC_ADD_CARRY))
4772               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4773    (parallel [(set (match_dup 3)
4774                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4775                                      (match_dup 4))
4776                             (match_dup 5)))
4777               (clobber (reg:CC FLAGS_REG))])]
4778   "split_di (operands+0, 1, operands+0, operands+3);
4779    split_di (operands+1, 1, operands+1, operands+4);
4780    split_di (operands+2, 1, operands+2, operands+5);")
4782 (define_insn "adddi3_carry_rex64"
4783   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4784           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4785                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4786                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4787    (clobber (reg:CC FLAGS_REG))]
4788   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4789   "adc{q}\t{%2, %0|%0, %2}"
4790   [(set_attr "type" "alu")
4791    (set_attr "pent_pair" "pu")
4792    (set_attr "mode" "DI")])
4794 (define_insn "*adddi3_cc_rex64"
4795   [(set (reg:CC FLAGS_REG)
4796         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4798                    UNSPEC_ADD_CARRY))
4799    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4800         (plus:DI (match_dup 1) (match_dup 2)))]
4801   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4802   "add{q}\t{%2, %0|%0, %2}"
4803   [(set_attr "type" "alu")
4804    (set_attr "mode" "DI")])
4806 (define_insn "addqi3_carry"
4807   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4808           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4809                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4810                    (match_operand:QI 2 "general_operand" "qi,qm")))
4811    (clobber (reg:CC FLAGS_REG))]
4812   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4813   "adc{b}\t{%2, %0|%0, %2}"
4814   [(set_attr "type" "alu")
4815    (set_attr "pent_pair" "pu")
4816    (set_attr "mode" "QI")])
4818 (define_insn "addhi3_carry"
4819   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4820           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4821                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4822                    (match_operand:HI 2 "general_operand" "ri,rm")))
4823    (clobber (reg:CC FLAGS_REG))]
4824   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4825   "adc{w}\t{%2, %0|%0, %2}"
4826   [(set_attr "type" "alu")
4827    (set_attr "pent_pair" "pu")
4828    (set_attr "mode" "HI")])
4830 (define_insn "addsi3_carry"
4831   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4832           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4833                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4834                    (match_operand:SI 2 "general_operand" "ri,rm")))
4835    (clobber (reg:CC FLAGS_REG))]
4836   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4837   "adc{l}\t{%2, %0|%0, %2}"
4838   [(set_attr "type" "alu")
4839    (set_attr "pent_pair" "pu")
4840    (set_attr "mode" "SI")])
4842 (define_insn "*addsi3_carry_zext"
4843   [(set (match_operand:DI 0 "register_operand" "=r")
4844           (zero_extend:DI 
4845             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4846                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4847                      (match_operand:SI 2 "general_operand" "rim"))))
4848    (clobber (reg:CC FLAGS_REG))]
4849   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4850   "adc{l}\t{%2, %k0|%k0, %2}"
4851   [(set_attr "type" "alu")
4852    (set_attr "pent_pair" "pu")
4853    (set_attr "mode" "SI")])
4855 (define_insn "*addsi3_cc"
4856   [(set (reg:CC FLAGS_REG)
4857         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4858                     (match_operand:SI 2 "general_operand" "ri,rm")]
4859                    UNSPEC_ADD_CARRY))
4860    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4861         (plus:SI (match_dup 1) (match_dup 2)))]
4862   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4863   "add{l}\t{%2, %0|%0, %2}"
4864   [(set_attr "type" "alu")
4865    (set_attr "mode" "SI")])
4867 (define_insn "addqi3_cc"
4868   [(set (reg:CC FLAGS_REG)
4869         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4870                     (match_operand:QI 2 "general_operand" "qi,qm")]
4871                    UNSPEC_ADD_CARRY))
4872    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4873         (plus:QI (match_dup 1) (match_dup 2)))]
4874   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4875   "add{b}\t{%2, %0|%0, %2}"
4876   [(set_attr "type" "alu")
4877    (set_attr "mode" "QI")])
4879 (define_expand "addsi3"
4880   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4881                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4882                             (match_operand:SI 2 "general_operand" "")))
4883               (clobber (reg:CC FLAGS_REG))])]
4884   ""
4885   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4887 (define_insn "*lea_1"
4888   [(set (match_operand:SI 0 "register_operand" "=r")
4889         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4890   "!TARGET_64BIT"
4891   "lea{l}\t{%a1, %0|%0, %a1}"
4892   [(set_attr "type" "lea")
4893    (set_attr "mode" "SI")])
4895 (define_insn "*lea_1_rex64"
4896   [(set (match_operand:SI 0 "register_operand" "=r")
4897         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4898   "TARGET_64BIT"
4899   "lea{l}\t{%a1, %0|%0, %a1}"
4900   [(set_attr "type" "lea")
4901    (set_attr "mode" "SI")])
4903 (define_insn "*lea_1_zext"
4904   [(set (match_operand:DI 0 "register_operand" "=r")
4905         (zero_extend:DI
4906          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4907   "TARGET_64BIT"
4908   "lea{l}\t{%a1, %k0|%k0, %a1}"
4909   [(set_attr "type" "lea")
4910    (set_attr "mode" "SI")])
4912 (define_insn "*lea_2_rex64"
4913   [(set (match_operand:DI 0 "register_operand" "=r")
4914         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4915   "TARGET_64BIT"
4916   "lea{q}\t{%a1, %0|%0, %a1}"
4917   [(set_attr "type" "lea")
4918    (set_attr "mode" "DI")])
4920 ;; The lea patterns for non-Pmodes needs to be matched by several
4921 ;; insns converted to real lea by splitters.
4923 (define_insn_and_split "*lea_general_1"
4924   [(set (match_operand 0 "register_operand" "=r")
4925         (plus (plus (match_operand 1 "index_register_operand" "l")
4926                     (match_operand 2 "register_operand" "r"))
4927               (match_operand 3 "immediate_operand" "i")))]
4928   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4929     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4930    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4931    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4932    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4933    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4934        || GET_MODE (operands[3]) == VOIDmode)"
4935   "#"
4936   "&& reload_completed"
4937   [(const_int 0)]
4939   rtx pat;
4940   operands[0] = gen_lowpart (SImode, operands[0]);
4941   operands[1] = gen_lowpart (Pmode, operands[1]);
4942   operands[2] = gen_lowpart (Pmode, operands[2]);
4943   operands[3] = gen_lowpart (Pmode, operands[3]);
4944   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4945                       operands[3]);
4946   if (Pmode != SImode)
4947     pat = gen_rtx_SUBREG (SImode, pat, 0);
4948   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4949   DONE;
4951   [(set_attr "type" "lea")
4952    (set_attr "mode" "SI")])
4954 (define_insn_and_split "*lea_general_1_zext"
4955   [(set (match_operand:DI 0 "register_operand" "=r")
4956         (zero_extend:DI
4957           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4958                             (match_operand:SI 2 "register_operand" "r"))
4959                    (match_operand:SI 3 "immediate_operand" "i"))))]
4960   "TARGET_64BIT"
4961   "#"
4962   "&& reload_completed"
4963   [(set (match_dup 0)
4964         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4965                                                      (match_dup 2))
4966                                             (match_dup 3)) 0)))]
4968   operands[1] = gen_lowpart (Pmode, operands[1]);
4969   operands[2] = gen_lowpart (Pmode, operands[2]);
4970   operands[3] = gen_lowpart (Pmode, operands[3]);
4972   [(set_attr "type" "lea")
4973    (set_attr "mode" "SI")])
4975 (define_insn_and_split "*lea_general_2"
4976   [(set (match_operand 0 "register_operand" "=r")
4977         (plus (mult (match_operand 1 "index_register_operand" "l")
4978                     (match_operand 2 "const248_operand" "i"))
4979               (match_operand 3 "nonmemory_operand" "ri")))]
4980   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4981     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4982    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4983    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4984    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4985        || GET_MODE (operands[3]) == VOIDmode)"
4986   "#"
4987   "&& reload_completed"
4988   [(const_int 0)]
4990   rtx pat;
4991   operands[0] = gen_lowpart (SImode, operands[0]);
4992   operands[1] = gen_lowpart (Pmode, operands[1]);
4993   operands[3] = gen_lowpart (Pmode, operands[3]);
4994   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4995                       operands[3]);
4996   if (Pmode != SImode)
4997     pat = gen_rtx_SUBREG (SImode, pat, 0);
4998   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4999   DONE;
5001   [(set_attr "type" "lea")
5002    (set_attr "mode" "SI")])
5004 (define_insn_and_split "*lea_general_2_zext"
5005   [(set (match_operand:DI 0 "register_operand" "=r")
5006         (zero_extend:DI
5007           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5008                             (match_operand:SI 2 "const248_operand" "n"))
5009                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5010   "TARGET_64BIT"
5011   "#"
5012   "&& reload_completed"
5013   [(set (match_dup 0)
5014         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5015                                                      (match_dup 2))
5016                                             (match_dup 3)) 0)))]
5018   operands[1] = gen_lowpart (Pmode, operands[1]);
5019   operands[3] = gen_lowpart (Pmode, operands[3]);
5021   [(set_attr "type" "lea")
5022    (set_attr "mode" "SI")])
5024 (define_insn_and_split "*lea_general_3"
5025   [(set (match_operand 0 "register_operand" "=r")
5026         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5027                           (match_operand 2 "const248_operand" "i"))
5028                     (match_operand 3 "register_operand" "r"))
5029               (match_operand 4 "immediate_operand" "i")))]
5030   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5031     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5032    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5033    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5034    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5035   "#"
5036   "&& reload_completed"
5037   [(const_int 0)]
5039   rtx pat;
5040   operands[0] = gen_lowpart (SImode, operands[0]);
5041   operands[1] = gen_lowpart (Pmode, operands[1]);
5042   operands[3] = gen_lowpart (Pmode, operands[3]);
5043   operands[4] = gen_lowpart (Pmode, operands[4]);
5044   pat = gen_rtx_PLUS (Pmode,
5045                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5046                                                          operands[2]),
5047                                     operands[3]),
5048                       operands[4]);
5049   if (Pmode != SImode)
5050     pat = gen_rtx_SUBREG (SImode, pat, 0);
5051   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5052   DONE;
5054   [(set_attr "type" "lea")
5055    (set_attr "mode" "SI")])
5057 (define_insn_and_split "*lea_general_3_zext"
5058   [(set (match_operand:DI 0 "register_operand" "=r")
5059         (zero_extend:DI
5060           (plus:SI (plus:SI (mult:SI
5061                               (match_operand:SI 1 "index_register_operand" "l")
5062                               (match_operand:SI 2 "const248_operand" "n"))
5063                             (match_operand:SI 3 "register_operand" "r"))
5064                    (match_operand:SI 4 "immediate_operand" "i"))))]
5065   "TARGET_64BIT"
5066   "#"
5067   "&& reload_completed"
5068   [(set (match_dup 0)
5069         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5070                                                               (match_dup 2))
5071                                                      (match_dup 3))
5072                                             (match_dup 4)) 0)))]
5074   operands[1] = gen_lowpart (Pmode, operands[1]);
5075   operands[3] = gen_lowpart (Pmode, operands[3]);
5076   operands[4] = gen_lowpart (Pmode, operands[4]);
5078   [(set_attr "type" "lea")
5079    (set_attr "mode" "SI")])
5081 (define_insn "*adddi_1_rex64"
5082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5083         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5084                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5085    (clobber (reg:CC FLAGS_REG))]
5086   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5088   switch (get_attr_type (insn))
5089     {
5090     case TYPE_LEA:
5091       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5092       return "lea{q}\t{%a2, %0|%0, %a2}";
5094     case TYPE_INCDEC:
5095       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5096       if (operands[2] == const1_rtx)
5097         return "inc{q}\t%0";
5098       else
5099         {
5100           gcc_assert (operands[2] == constm1_rtx);
5101           return "dec{q}\t%0";
5102         }
5104     default:
5105       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5107       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5108          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5109       if (GET_CODE (operands[2]) == CONST_INT
5110           /* Avoid overflows.  */
5111           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5112           && (INTVAL (operands[2]) == 128
5113               || (INTVAL (operands[2]) < 0
5114                   && INTVAL (operands[2]) != -128)))
5115         {
5116           operands[2] = GEN_INT (-INTVAL (operands[2]));
5117           return "sub{q}\t{%2, %0|%0, %2}";
5118         }
5119       return "add{q}\t{%2, %0|%0, %2}";
5120     }
5122   [(set (attr "type")
5123      (cond [(eq_attr "alternative" "2")
5124               (const_string "lea")
5125             ; Current assemblers are broken and do not allow @GOTOFF in
5126             ; ought but a memory context.
5127             (match_operand:DI 2 "pic_symbolic_operand" "")
5128               (const_string "lea")
5129             (match_operand:DI 2 "incdec_operand" "")
5130               (const_string "incdec")
5131            ]
5132            (const_string "alu")))
5133    (set_attr "mode" "DI")])
5135 ;; Convert lea to the lea pattern to avoid flags dependency.
5136 (define_split
5137   [(set (match_operand:DI 0 "register_operand" "")
5138         (plus:DI (match_operand:DI 1 "register_operand" "")
5139                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5140    (clobber (reg:CC FLAGS_REG))]
5141   "TARGET_64BIT && reload_completed
5142    && true_regnum (operands[0]) != true_regnum (operands[1])"
5143   [(set (match_dup 0)
5144         (plus:DI (match_dup 1)
5145                  (match_dup 2)))]
5146   "")
5148 (define_insn "*adddi_2_rex64"
5149   [(set (reg FLAGS_REG)
5150         (compare
5151           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5152                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5153           (const_int 0)))                       
5154    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5155         (plus:DI (match_dup 1) (match_dup 2)))]
5156   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5157    && ix86_binary_operator_ok (PLUS, DImode, operands)
5158    /* Current assemblers are broken and do not allow @GOTOFF in
5159       ought but a memory context.  */
5160    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5162   switch (get_attr_type (insn))
5163     {
5164     case TYPE_INCDEC:
5165       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5166       if (operands[2] == const1_rtx)
5167         return "inc{q}\t%0";
5168       else
5169         {
5170           gcc_assert (operands[2] == constm1_rtx);
5171           return "dec{q}\t%0";
5172         }
5174     default:
5175       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5176       /* ???? We ought to handle there the 32bit case too
5177          - do we need new constraint?  */
5178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5179          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5180       if (GET_CODE (operands[2]) == CONST_INT
5181           /* Avoid overflows.  */
5182           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5183           && (INTVAL (operands[2]) == 128
5184               || (INTVAL (operands[2]) < 0
5185                   && INTVAL (operands[2]) != -128)))
5186         {
5187           operands[2] = GEN_INT (-INTVAL (operands[2]));
5188           return "sub{q}\t{%2, %0|%0, %2}";
5189         }
5190       return "add{q}\t{%2, %0|%0, %2}";
5191     }
5193   [(set (attr "type")
5194      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5195         (const_string "incdec")
5196         (const_string "alu")))
5197    (set_attr "mode" "DI")])
5199 (define_insn "*adddi_3_rex64"
5200   [(set (reg FLAGS_REG)
5201         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5202                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5203    (clobber (match_scratch:DI 0 "=r"))]
5204   "TARGET_64BIT
5205    && ix86_match_ccmode (insn, CCZmode)
5206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5207    /* Current assemblers are broken and do not allow @GOTOFF in
5208       ought but a memory context.  */
5209    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5211   switch (get_attr_type (insn))
5212     {
5213     case TYPE_INCDEC:
5214       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5215       if (operands[2] == const1_rtx)
5216         return "inc{q}\t%0";
5217       else
5218         {
5219           gcc_assert (operands[2] == constm1_rtx);
5220           return "dec{q}\t%0";
5221         }
5223     default:
5224       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5225       /* ???? We ought to handle there the 32bit case too
5226          - do we need new constraint?  */
5227       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5228          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5229       if (GET_CODE (operands[2]) == CONST_INT
5230           /* Avoid overflows.  */
5231           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5232           && (INTVAL (operands[2]) == 128
5233               || (INTVAL (operands[2]) < 0
5234                   && INTVAL (operands[2]) != -128)))
5235         {
5236           operands[2] = GEN_INT (-INTVAL (operands[2]));
5237           return "sub{q}\t{%2, %0|%0, %2}";
5238         }
5239       return "add{q}\t{%2, %0|%0, %2}";
5240     }
5242   [(set (attr "type")
5243      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5244         (const_string "incdec")
5245         (const_string "alu")))
5246    (set_attr "mode" "DI")])
5248 ; For comparisons against 1, -1 and 128, we may generate better code
5249 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5250 ; is matched then.  We can't accept general immediate, because for
5251 ; case of overflows,  the result is messed up.
5252 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5253 ; when negated.
5254 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5255 ; only for comparisons not depending on it.
5256 (define_insn "*adddi_4_rex64"
5257   [(set (reg FLAGS_REG)
5258         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5259                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5260    (clobber (match_scratch:DI 0 "=rm"))]
5261   "TARGET_64BIT
5262    &&  ix86_match_ccmode (insn, CCGCmode)"
5264   switch (get_attr_type (insn))
5265     {
5266     case TYPE_INCDEC:
5267       if (operands[2] == constm1_rtx)
5268         return "inc{q}\t%0";
5269       else
5270         {
5271           gcc_assert (operands[2] == const1_rtx);
5272           return "dec{q}\t%0";
5273         }
5275     default:
5276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5278          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5279       if ((INTVAL (operands[2]) == -128
5280            || (INTVAL (operands[2]) > 0
5281                && INTVAL (operands[2]) != 128))
5282           /* Avoid overflows.  */
5283           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5284         return "sub{q}\t{%2, %0|%0, %2}";
5285       operands[2] = GEN_INT (-INTVAL (operands[2]));
5286       return "add{q}\t{%2, %0|%0, %2}";
5287     }
5289   [(set (attr "type")
5290      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291         (const_string "incdec")
5292         (const_string "alu")))
5293    (set_attr "mode" "DI")])
5295 (define_insn "*adddi_5_rex64"
5296   [(set (reg FLAGS_REG)
5297         (compare
5298           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5299                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5300           (const_int 0)))                       
5301    (clobber (match_scratch:DI 0 "=r"))]
5302   "TARGET_64BIT
5303    && ix86_match_ccmode (insn, CCGOCmode)
5304    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5305    /* Current assemblers are broken and do not allow @GOTOFF in
5306       ought but a memory context.  */
5307    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5309   switch (get_attr_type (insn))
5310     {
5311     case TYPE_INCDEC:
5312       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313       if (operands[2] == const1_rtx)
5314         return "inc{q}\t%0";
5315       else
5316         {
5317           gcc_assert (operands[2] == constm1_rtx);
5318           return "dec{q}\t%0";
5319         }
5321     default:
5322       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5324          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5325       if (GET_CODE (operands[2]) == CONST_INT
5326           /* Avoid overflows.  */
5327           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5328           && (INTVAL (operands[2]) == 128
5329               || (INTVAL (operands[2]) < 0
5330                   && INTVAL (operands[2]) != -128)))
5331         {
5332           operands[2] = GEN_INT (-INTVAL (operands[2]));
5333           return "sub{q}\t{%2, %0|%0, %2}";
5334         }
5335       return "add{q}\t{%2, %0|%0, %2}";
5336     }
5338   [(set (attr "type")
5339      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5340         (const_string "incdec")
5341         (const_string "alu")))
5342    (set_attr "mode" "DI")])
5345 (define_insn "*addsi_1"
5346   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5347         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5348                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5349    (clobber (reg:CC FLAGS_REG))]
5350   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5352   switch (get_attr_type (insn))
5353     {
5354     case TYPE_LEA:
5355       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5356       return "lea{l}\t{%a2, %0|%0, %a2}";
5358     case TYPE_INCDEC:
5359       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360       if (operands[2] == const1_rtx)
5361         return "inc{l}\t%0";
5362       else
5363         {
5364           gcc_assert (operands[2] == constm1_rtx);
5365           return "dec{l}\t%0";
5366         }
5368     default:
5369       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5371       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5372          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5373       if (GET_CODE (operands[2]) == CONST_INT
5374           && (INTVAL (operands[2]) == 128
5375               || (INTVAL (operands[2]) < 0
5376                   && INTVAL (operands[2]) != -128)))
5377         {
5378           operands[2] = GEN_INT (-INTVAL (operands[2]));
5379           return "sub{l}\t{%2, %0|%0, %2}";
5380         }
5381       return "add{l}\t{%2, %0|%0, %2}";
5382     }
5384   [(set (attr "type")
5385      (cond [(eq_attr "alternative" "2")
5386               (const_string "lea")
5387             ; Current assemblers are broken and do not allow @GOTOFF in
5388             ; ought but a memory context.
5389             (match_operand:SI 2 "pic_symbolic_operand" "")
5390               (const_string "lea")
5391             (match_operand:SI 2 "incdec_operand" "")
5392               (const_string "incdec")
5393            ]
5394            (const_string "alu")))
5395    (set_attr "mode" "SI")])
5397 ;; Convert lea to the lea pattern to avoid flags dependency.
5398 (define_split
5399   [(set (match_operand 0 "register_operand" "")
5400         (plus (match_operand 1 "register_operand" "")
5401               (match_operand 2 "nonmemory_operand" "")))
5402    (clobber (reg:CC FLAGS_REG))]
5403   "reload_completed
5404    && true_regnum (operands[0]) != true_regnum (operands[1])"
5405   [(const_int 0)]
5407   rtx pat;
5408   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5409      may confuse gen_lowpart.  */
5410   if (GET_MODE (operands[0]) != Pmode)
5411     {
5412       operands[1] = gen_lowpart (Pmode, operands[1]);
5413       operands[2] = gen_lowpart (Pmode, operands[2]);
5414     }
5415   operands[0] = gen_lowpart (SImode, operands[0]);
5416   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5417   if (Pmode != SImode)
5418     pat = gen_rtx_SUBREG (SImode, pat, 0);
5419   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5420   DONE;
5423 ;; It may seem that nonimmediate operand is proper one for operand 1.
5424 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5425 ;; we take care in ix86_binary_operator_ok to not allow two memory
5426 ;; operands so proper swapping will be done in reload.  This allow
5427 ;; patterns constructed from addsi_1 to match.
5428 (define_insn "addsi_1_zext"
5429   [(set (match_operand:DI 0 "register_operand" "=r,r")
5430         (zero_extend:DI
5431           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5432                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5433    (clobber (reg:CC FLAGS_REG))]
5434   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5436   switch (get_attr_type (insn))
5437     {
5438     case TYPE_LEA:
5439       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5442     case TYPE_INCDEC:
5443       if (operands[2] == const1_rtx)
5444         return "inc{l}\t%k0";
5445       else
5446         {
5447           gcc_assert (operands[2] == constm1_rtx);
5448           return "dec{l}\t%k0";
5449         }
5451     default:
5452       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5454       if (GET_CODE (operands[2]) == CONST_INT
5455           && (INTVAL (operands[2]) == 128
5456               || (INTVAL (operands[2]) < 0
5457                   && INTVAL (operands[2]) != -128)))
5458         {
5459           operands[2] = GEN_INT (-INTVAL (operands[2]));
5460           return "sub{l}\t{%2, %k0|%k0, %2}";
5461         }
5462       return "add{l}\t{%2, %k0|%k0, %2}";
5463     }
5465   [(set (attr "type")
5466      (cond [(eq_attr "alternative" "1")
5467               (const_string "lea")
5468             ; Current assemblers are broken and do not allow @GOTOFF in
5469             ; ought but a memory context.
5470             (match_operand:SI 2 "pic_symbolic_operand" "")
5471               (const_string "lea")
5472             (match_operand:SI 2 "incdec_operand" "")
5473               (const_string "incdec")
5474            ]
5475            (const_string "alu")))
5476    (set_attr "mode" "SI")])
5478 ;; Convert lea to the lea pattern to avoid flags dependency.
5479 (define_split
5480   [(set (match_operand:DI 0 "register_operand" "")
5481         (zero_extend:DI
5482           (plus:SI (match_operand:SI 1 "register_operand" "")
5483                    (match_operand:SI 2 "nonmemory_operand" ""))))
5484    (clobber (reg:CC FLAGS_REG))]
5485   "TARGET_64BIT && reload_completed
5486    && true_regnum (operands[0]) != true_regnum (operands[1])"
5487   [(set (match_dup 0)
5488         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5490   operands[1] = gen_lowpart (Pmode, operands[1]);
5491   operands[2] = gen_lowpart (Pmode, operands[2]);
5494 (define_insn "*addsi_2"
5495   [(set (reg FLAGS_REG)
5496         (compare
5497           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5498                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5499           (const_int 0)))                       
5500    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5501         (plus:SI (match_dup 1) (match_dup 2)))]
5502   "ix86_match_ccmode (insn, CCGOCmode)
5503    && ix86_binary_operator_ok (PLUS, SImode, operands)
5504    /* Current assemblers are broken and do not allow @GOTOFF in
5505       ought but a memory context.  */
5506    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5508   switch (get_attr_type (insn))
5509     {
5510     case TYPE_INCDEC:
5511       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5512       if (operands[2] == const1_rtx)
5513         return "inc{l}\t%0";
5514       else
5515         {
5516           gcc_assert (operands[2] == constm1_rtx);
5517           return "dec{l}\t%0";
5518         }
5520     default:
5521       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5522       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5524       if (GET_CODE (operands[2]) == CONST_INT
5525           && (INTVAL (operands[2]) == 128
5526               || (INTVAL (operands[2]) < 0
5527                   && INTVAL (operands[2]) != -128)))
5528         {
5529           operands[2] = GEN_INT (-INTVAL (operands[2]));
5530           return "sub{l}\t{%2, %0|%0, %2}";
5531         }
5532       return "add{l}\t{%2, %0|%0, %2}";
5533     }
5535   [(set (attr "type")
5536      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537         (const_string "incdec")
5538         (const_string "alu")))
5539    (set_attr "mode" "SI")])
5541 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5542 (define_insn "*addsi_2_zext"
5543   [(set (reg FLAGS_REG)
5544         (compare
5545           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5546                    (match_operand:SI 2 "general_operand" "rmni"))
5547           (const_int 0)))                       
5548    (set (match_operand:DI 0 "register_operand" "=r")
5549         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5550   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5551    && ix86_binary_operator_ok (PLUS, SImode, operands)
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       if (operands[2] == const1_rtx)
5560         return "inc{l}\t%k0";
5561       else
5562         {
5563           gcc_assert (operands[2] == constm1_rtx);
5564           return "dec{l}\t%k0";
5565         }
5567     default:
5568       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5569          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5570       if (GET_CODE (operands[2]) == CONST_INT
5571           && (INTVAL (operands[2]) == 128
5572               || (INTVAL (operands[2]) < 0
5573                   && INTVAL (operands[2]) != -128)))
5574         {
5575           operands[2] = GEN_INT (-INTVAL (operands[2]));
5576           return "sub{l}\t{%2, %k0|%k0, %2}";
5577         }
5578       return "add{l}\t{%2, %k0|%k0, %2}";
5579     }
5581   [(set (attr "type")
5582      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5583         (const_string "incdec")
5584         (const_string "alu")))
5585    (set_attr "mode" "SI")])
5587 (define_insn "*addsi_3"
5588   [(set (reg FLAGS_REG)
5589         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5590                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5591    (clobber (match_scratch:SI 0 "=r"))]
5592   "ix86_match_ccmode (insn, CCZmode)
5593    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5594    /* Current assemblers are broken and do not allow @GOTOFF in
5595       ought but a memory context.  */
5596    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5598   switch (get_attr_type (insn))
5599     {
5600     case TYPE_INCDEC:
5601       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%0";
5604       else
5605         {
5606           gcc_assert (operands[2] == constm1_rtx);
5607           return "dec{l}\t%0";
5608         }
5610     default:
5611       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5612       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5614       if (GET_CODE (operands[2]) == CONST_INT
5615           && (INTVAL (operands[2]) == 128
5616               || (INTVAL (operands[2]) < 0
5617                   && INTVAL (operands[2]) != -128)))
5618         {
5619           operands[2] = GEN_INT (-INTVAL (operands[2]));
5620           return "sub{l}\t{%2, %0|%0, %2}";
5621         }
5622       return "add{l}\t{%2, %0|%0, %2}";
5623     }
5625   [(set (attr "type")
5626      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5627         (const_string "incdec")
5628         (const_string "alu")))
5629    (set_attr "mode" "SI")])
5631 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5632 (define_insn "*addsi_3_zext"
5633   [(set (reg FLAGS_REG)
5634         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5635                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5636    (set (match_operand:DI 0 "register_operand" "=r")
5637         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5639    && ix86_binary_operator_ok (PLUS, SImode, operands)
5640    /* Current assemblers are broken and do not allow @GOTOFF in
5641       ought but a memory context.  */
5642    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5644   switch (get_attr_type (insn))
5645     {
5646     case TYPE_INCDEC:
5647       if (operands[2] == const1_rtx)
5648         return "inc{l}\t%k0";
5649       else
5650         {
5651           gcc_assert (operands[2] == constm1_rtx);
5652           return "dec{l}\t%k0";
5653         }
5655     default:
5656       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5657          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5658       if (GET_CODE (operands[2]) == CONST_INT
5659           && (INTVAL (operands[2]) == 128
5660               || (INTVAL (operands[2]) < 0
5661                   && INTVAL (operands[2]) != -128)))
5662         {
5663           operands[2] = GEN_INT (-INTVAL (operands[2]));
5664           return "sub{l}\t{%2, %k0|%k0, %2}";
5665         }
5666       return "add{l}\t{%2, %k0|%k0, %2}";
5667     }
5669   [(set (attr "type")
5670      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5671         (const_string "incdec")
5672         (const_string "alu")))
5673    (set_attr "mode" "SI")])
5675 ; For comparisons against 1, -1 and 128, we may generate better code
5676 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5677 ; is matched then.  We can't accept general immediate, because for
5678 ; case of overflows,  the result is messed up.
5679 ; This pattern also don't hold of 0x80000000, since the value overflows
5680 ; when negated.
5681 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5682 ; only for comparisons not depending on it.
5683 (define_insn "*addsi_4"
5684   [(set (reg FLAGS_REG)
5685         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5686                  (match_operand:SI 2 "const_int_operand" "n")))
5687    (clobber (match_scratch:SI 0 "=rm"))]
5688   "ix86_match_ccmode (insn, CCGCmode)
5689    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (operands[2] == constm1_rtx)
5695         return "inc{l}\t%0";
5696       else
5697         {
5698           gcc_assert (operands[2] == const1_rtx);
5699           return "dec{l}\t%0";
5700         }
5702     default:
5703       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5704       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5705          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5706       if ((INTVAL (operands[2]) == -128
5707            || (INTVAL (operands[2]) > 0
5708                && INTVAL (operands[2]) != 128)))
5709         return "sub{l}\t{%2, %0|%0, %2}";
5710       operands[2] = GEN_INT (-INTVAL (operands[2]));
5711       return "add{l}\t{%2, %0|%0, %2}";
5712     }
5714   [(set (attr "type")
5715      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5716         (const_string "incdec")
5717         (const_string "alu")))
5718    (set_attr "mode" "SI")])
5720 (define_insn "*addsi_5"
5721   [(set (reg FLAGS_REG)
5722         (compare
5723           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5724                    (match_operand:SI 2 "general_operand" "rmni"))
5725           (const_int 0)))                       
5726    (clobber (match_scratch:SI 0 "=r"))]
5727   "ix86_match_ccmode (insn, CCGOCmode)
5728    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5729    /* Current assemblers are broken and do not allow @GOTOFF in
5730       ought but a memory context.  */
5731    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5733   switch (get_attr_type (insn))
5734     {
5735     case TYPE_INCDEC:
5736       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5737       if (operands[2] == const1_rtx)
5738         return "inc{l}\t%0";
5739       else
5740         {
5741           gcc_assert (operands[2] == constm1_rtx);
5742           return "dec{l}\t%0";
5743         }
5745     default:
5746       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5747       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5748          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5749       if (GET_CODE (operands[2]) == CONST_INT
5750           && (INTVAL (operands[2]) == 128
5751               || (INTVAL (operands[2]) < 0
5752                   && INTVAL (operands[2]) != -128)))
5753         {
5754           operands[2] = GEN_INT (-INTVAL (operands[2]));
5755           return "sub{l}\t{%2, %0|%0, %2}";
5756         }
5757       return "add{l}\t{%2, %0|%0, %2}";
5758     }
5760   [(set (attr "type")
5761      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762         (const_string "incdec")
5763         (const_string "alu")))
5764    (set_attr "mode" "SI")])
5766 (define_expand "addhi3"
5767   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5768                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5769                             (match_operand:HI 2 "general_operand" "")))
5770               (clobber (reg:CC FLAGS_REG))])]
5771   "TARGET_HIMODE_MATH"
5772   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5774 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5775 ;; type optimizations enabled by define-splits.  This is not important
5776 ;; for PII, and in fact harmful because of partial register stalls.
5778 (define_insn "*addhi_1_lea"
5779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5780         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5781                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5782    (clobber (reg:CC FLAGS_REG))]
5783   "!TARGET_PARTIAL_REG_STALL
5784    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_LEA:
5789       return "#";
5790     case TYPE_INCDEC:
5791       if (operands[2] == const1_rtx)
5792         return "inc{w}\t%0";
5793       else
5794         {
5795           gcc_assert (operands[2] == constm1_rtx);
5796           return "dec{w}\t%0";
5797         }
5799     default:
5800       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5802       if (GET_CODE (operands[2]) == CONST_INT
5803           && (INTVAL (operands[2]) == 128
5804               || (INTVAL (operands[2]) < 0
5805                   && INTVAL (operands[2]) != -128)))
5806         {
5807           operands[2] = GEN_INT (-INTVAL (operands[2]));
5808           return "sub{w}\t{%2, %0|%0, %2}";
5809         }
5810       return "add{w}\t{%2, %0|%0, %2}";
5811     }
5813   [(set (attr "type")
5814      (if_then_else (eq_attr "alternative" "2")
5815         (const_string "lea")
5816         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5817            (const_string "incdec")
5818            (const_string "alu"))))
5819    (set_attr "mode" "HI,HI,SI")])
5821 (define_insn "*addhi_1"
5822   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5823         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5824                  (match_operand:HI 2 "general_operand" "ri,rm")))
5825    (clobber (reg:CC FLAGS_REG))]
5826   "TARGET_PARTIAL_REG_STALL
5827    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5829   switch (get_attr_type (insn))
5830     {
5831     case TYPE_INCDEC:
5832       if (operands[2] == const1_rtx)
5833         return "inc{w}\t%0";
5834       else
5835         {
5836           gcc_assert (operands[2] == constm1_rtx);
5837           return "dec{w}\t%0";
5838         }
5840     default:
5841       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5843       if (GET_CODE (operands[2]) == CONST_INT
5844           && (INTVAL (operands[2]) == 128
5845               || (INTVAL (operands[2]) < 0
5846                   && INTVAL (operands[2]) != -128)))
5847         {
5848           operands[2] = GEN_INT (-INTVAL (operands[2]));
5849           return "sub{w}\t{%2, %0|%0, %2}";
5850         }
5851       return "add{w}\t{%2, %0|%0, %2}";
5852     }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856         (const_string "incdec")
5857         (const_string "alu")))
5858    (set_attr "mode" "HI")])
5860 (define_insn "*addhi_2"
5861   [(set (reg FLAGS_REG)
5862         (compare
5863           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5864                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5865           (const_int 0)))                       
5866    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5867         (plus:HI (match_dup 1) (match_dup 2)))]
5868   "ix86_match_ccmode (insn, CCGOCmode)
5869    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_INCDEC:
5874       if (operands[2] == const1_rtx)
5875         return "inc{w}\t%0";
5876       else
5877         {
5878           gcc_assert (operands[2] == constm1_rtx);
5879           return "dec{w}\t%0";
5880         }
5882     default:
5883       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5884          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5885       if (GET_CODE (operands[2]) == CONST_INT
5886           && (INTVAL (operands[2]) == 128
5887               || (INTVAL (operands[2]) < 0
5888                   && INTVAL (operands[2]) != -128)))
5889         {
5890           operands[2] = GEN_INT (-INTVAL (operands[2]));
5891           return "sub{w}\t{%2, %0|%0, %2}";
5892         }
5893       return "add{w}\t{%2, %0|%0, %2}";
5894     }
5896   [(set (attr "type")
5897      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5898         (const_string "incdec")
5899         (const_string "alu")))
5900    (set_attr "mode" "HI")])
5902 (define_insn "*addhi_3"
5903   [(set (reg FLAGS_REG)
5904         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5905                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5906    (clobber (match_scratch:HI 0 "=r"))]
5907   "ix86_match_ccmode (insn, CCZmode)
5908    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5910   switch (get_attr_type (insn))
5911     {
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return "inc{w}\t%0";
5915       else
5916         {
5917           gcc_assert (operands[2] == constm1_rtx);
5918           return "dec{w}\t%0";
5919         }
5921     default:
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (GET_CODE (operands[2]) == CONST_INT
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{w}\t{%2, %0|%0, %2}";
5931         }
5932       return "add{w}\t{%2, %0|%0, %2}";
5933     }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set_attr "mode" "HI")])
5941 ; See comments above addsi_4 for details.
5942 (define_insn "*addhi_4"
5943   [(set (reg FLAGS_REG)
5944         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5945                  (match_operand:HI 2 "const_int_operand" "n")))
5946    (clobber (match_scratch:HI 0 "=rm"))]
5947   "ix86_match_ccmode (insn, CCGCmode)
5948    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5950   switch (get_attr_type (insn))
5951     {
5952     case TYPE_INCDEC:
5953       if (operands[2] == constm1_rtx)
5954         return "inc{w}\t%0";
5955       else
5956         {
5957           gcc_assert (operands[2] == const1_rtx);
5958           return "dec{w}\t%0";
5959         }
5961     default:
5962       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5963       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5964          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5965       if ((INTVAL (operands[2]) == -128
5966            || (INTVAL (operands[2]) > 0
5967                && INTVAL (operands[2]) != 128)))
5968         return "sub{w}\t{%2, %0|%0, %2}";
5969       operands[2] = GEN_INT (-INTVAL (operands[2]));
5970       return "add{w}\t{%2, %0|%0, %2}";
5971     }
5973   [(set (attr "type")
5974      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975         (const_string "incdec")
5976         (const_string "alu")))
5977    (set_attr "mode" "SI")])
5980 (define_insn "*addhi_5"
5981   [(set (reg FLAGS_REG)
5982         (compare
5983           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5984                    (match_operand:HI 2 "general_operand" "rmni"))
5985           (const_int 0)))                       
5986    (clobber (match_scratch:HI 0 "=r"))]
5987   "ix86_match_ccmode (insn, CCGOCmode)
5988    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5990   switch (get_attr_type (insn))
5991     {
5992     case TYPE_INCDEC:
5993       if (operands[2] == const1_rtx)
5994         return "inc{w}\t%0";
5995       else
5996         {
5997           gcc_assert (operands[2] == constm1_rtx);
5998           return "dec{w}\t%0";
5999         }
6001     default:
6002       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6003          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6004       if (GET_CODE (operands[2]) == CONST_INT
6005           && (INTVAL (operands[2]) == 128
6006               || (INTVAL (operands[2]) < 0
6007                   && INTVAL (operands[2]) != -128)))
6008         {
6009           operands[2] = GEN_INT (-INTVAL (operands[2]));
6010           return "sub{w}\t{%2, %0|%0, %2}";
6011         }
6012       return "add{w}\t{%2, %0|%0, %2}";
6013     }
6015   [(set (attr "type")
6016      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6017         (const_string "incdec")
6018         (const_string "alu")))
6019    (set_attr "mode" "HI")])
6021 (define_expand "addqi3"
6022   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6023                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6024                             (match_operand:QI 2 "general_operand" "")))
6025               (clobber (reg:CC FLAGS_REG))])]
6026   "TARGET_QIMODE_MATH"
6027   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6029 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6030 (define_insn "*addqi_1_lea"
6031   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6032         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6033                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6034    (clobber (reg:CC FLAGS_REG))]
6035   "!TARGET_PARTIAL_REG_STALL
6036    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6038   int widen = (which_alternative == 2);
6039   switch (get_attr_type (insn))
6040     {
6041     case TYPE_LEA:
6042       return "#";
6043     case TYPE_INCDEC:
6044       if (operands[2] == const1_rtx)
6045         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6046       else
6047         {
6048           gcc_assert (operands[2] == constm1_rtx);
6049           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6050         }
6052     default:
6053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055       if (GET_CODE (operands[2]) == CONST_INT
6056           && (INTVAL (operands[2]) == 128
6057               || (INTVAL (operands[2]) < 0
6058                   && INTVAL (operands[2]) != -128)))
6059         {
6060           operands[2] = GEN_INT (-INTVAL (operands[2]));
6061           if (widen)
6062             return "sub{l}\t{%2, %k0|%k0, %2}";
6063           else
6064             return "sub{b}\t{%2, %0|%0, %2}";
6065         }
6066       if (widen)
6067         return "add{l}\t{%k2, %k0|%k0, %k2}";
6068       else
6069         return "add{b}\t{%2, %0|%0, %2}";
6070     }
6072   [(set (attr "type")
6073      (if_then_else (eq_attr "alternative" "3")
6074         (const_string "lea")
6075         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6076            (const_string "incdec")
6077            (const_string "alu"))))
6078    (set_attr "mode" "QI,QI,SI,SI")])
6080 (define_insn "*addqi_1"
6081   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6082         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6083                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "TARGET_PARTIAL_REG_STALL
6086    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6088   int widen = (which_alternative == 2);
6089   switch (get_attr_type (insn))
6090     {
6091     case TYPE_INCDEC:
6092       if (operands[2] == const1_rtx)
6093         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6094       else
6095         {
6096           gcc_assert (operands[2] == constm1_rtx);
6097           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6098         }
6100     default:
6101       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6102          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6103       if (GET_CODE (operands[2]) == CONST_INT
6104           && (INTVAL (operands[2]) == 128
6105               || (INTVAL (operands[2]) < 0
6106                   && INTVAL (operands[2]) != -128)))
6107         {
6108           operands[2] = GEN_INT (-INTVAL (operands[2]));
6109           if (widen)
6110             return "sub{l}\t{%2, %k0|%k0, %2}";
6111           else
6112             return "sub{b}\t{%2, %0|%0, %2}";
6113         }
6114       if (widen)
6115         return "add{l}\t{%k2, %k0|%k0, %k2}";
6116       else
6117         return "add{b}\t{%2, %0|%0, %2}";
6118     }
6120   [(set (attr "type")
6121      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6122         (const_string "incdec")
6123         (const_string "alu")))
6124    (set_attr "mode" "QI,QI,SI")])
6126 (define_insn "*addqi_1_slp"
6127   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6128         (plus:QI (match_dup 0)
6129                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6130    (clobber (reg:CC FLAGS_REG))]
6131   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6132    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6134   switch (get_attr_type (insn))
6135     {
6136     case TYPE_INCDEC:
6137       if (operands[1] == const1_rtx)
6138         return "inc{b}\t%0";
6139       else
6140         {
6141           gcc_assert (operands[1] == constm1_rtx);
6142           return "dec{b}\t%0";
6143         }
6145     default:
6146       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6147       if (GET_CODE (operands[1]) == CONST_INT
6148           && INTVAL (operands[1]) < 0)
6149         {
6150           operands[1] = GEN_INT (-INTVAL (operands[1]));
6151           return "sub{b}\t{%1, %0|%0, %1}";
6152         }
6153       return "add{b}\t{%1, %0|%0, %1}";
6154     }
6156   [(set (attr "type")
6157      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6158         (const_string "incdec")
6159         (const_string "alu1")))
6160    (set (attr "memory")
6161      (if_then_else (match_operand 1 "memory_operand" "")
6162         (const_string "load")
6163         (const_string "none")))
6164    (set_attr "mode" "QI")])
6166 (define_insn "*addqi_2"
6167   [(set (reg FLAGS_REG)
6168         (compare
6169           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6170                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6171           (const_int 0)))
6172    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6173         (plus:QI (match_dup 1) (match_dup 2)))]
6174   "ix86_match_ccmode (insn, CCGOCmode)
6175    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{b}\t%0";
6182       else
6183         {
6184           gcc_assert (operands[2] == constm1_rtx
6185                       || (GET_CODE (operands[2]) == CONST_INT
6186                           && INTVAL (operands[2]) == 255));
6187           return "dec{b}\t%0";
6188         }
6190     default:
6191       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6192       if (GET_CODE (operands[2]) == CONST_INT
6193           && INTVAL (operands[2]) < 0)
6194         {
6195           operands[2] = GEN_INT (-INTVAL (operands[2]));
6196           return "sub{b}\t{%2, %0|%0, %2}";
6197         }
6198       return "add{b}\t{%2, %0|%0, %2}";
6199     }
6201   [(set (attr "type")
6202      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6203         (const_string "incdec")
6204         (const_string "alu")))
6205    (set_attr "mode" "QI")])
6207 (define_insn "*addqi_3"
6208   [(set (reg FLAGS_REG)
6209         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6210                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6211    (clobber (match_scratch:QI 0 "=q"))]
6212   "ix86_match_ccmode (insn, CCZmode)
6213    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6215   switch (get_attr_type (insn))
6216     {
6217     case TYPE_INCDEC:
6218       if (operands[2] == const1_rtx)
6219         return "inc{b}\t%0";
6220       else
6221         {
6222           gcc_assert (operands[2] == constm1_rtx
6223                       || (GET_CODE (operands[2]) == CONST_INT
6224                           && INTVAL (operands[2]) == 255));
6225           return "dec{b}\t%0";
6226         }
6228     default:
6229       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6230       if (GET_CODE (operands[2]) == CONST_INT
6231           && INTVAL (operands[2]) < 0)
6232         {
6233           operands[2] = GEN_INT (-INTVAL (operands[2]));
6234           return "sub{b}\t{%2, %0|%0, %2}";
6235         }
6236       return "add{b}\t{%2, %0|%0, %2}";
6237     }
6239   [(set (attr "type")
6240      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241         (const_string "incdec")
6242         (const_string "alu")))
6243    (set_attr "mode" "QI")])
6245 ; See comments above addsi_4 for details.
6246 (define_insn "*addqi_4"
6247   [(set (reg FLAGS_REG)
6248         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6249                  (match_operand:QI 2 "const_int_operand" "n")))
6250    (clobber (match_scratch:QI 0 "=qm"))]
6251   "ix86_match_ccmode (insn, CCGCmode)
6252    && (INTVAL (operands[2]) & 0xff) != 0x80"
6254   switch (get_attr_type (insn))
6255     {
6256     case TYPE_INCDEC:
6257       if (operands[2] == constm1_rtx
6258           || (GET_CODE (operands[2]) == CONST_INT
6259               && INTVAL (operands[2]) == 255))
6260         return "inc{b}\t%0";
6261       else
6262         {
6263           gcc_assert (operands[2] == const1_rtx);
6264           return "dec{b}\t%0";
6265         }
6267     default:
6268       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6269       if (INTVAL (operands[2]) < 0)
6270         {
6271           operands[2] = GEN_INT (-INTVAL (operands[2]));
6272           return "add{b}\t{%2, %0|%0, %2}";
6273         }
6274       return "sub{b}\t{%2, %0|%0, %2}";
6275     }
6277   [(set (attr "type")
6278      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6279         (const_string "incdec")
6280         (const_string "alu")))
6281    (set_attr "mode" "QI")])
6284 (define_insn "*addqi_5"
6285   [(set (reg FLAGS_REG)
6286         (compare
6287           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6288                    (match_operand:QI 2 "general_operand" "qmni"))
6289           (const_int 0)))
6290    (clobber (match_scratch:QI 0 "=q"))]
6291   "ix86_match_ccmode (insn, CCGOCmode)
6292    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6294   switch (get_attr_type (insn))
6295     {
6296     case TYPE_INCDEC:
6297       if (operands[2] == const1_rtx)
6298         return "inc{b}\t%0";
6299       else
6300         {
6301           gcc_assert (operands[2] == constm1_rtx
6302                       || (GET_CODE (operands[2]) == CONST_INT
6303                           && INTVAL (operands[2]) == 255));
6304           return "dec{b}\t%0";
6305         }
6307     default:
6308       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6309       if (GET_CODE (operands[2]) == CONST_INT
6310           && INTVAL (operands[2]) < 0)
6311         {
6312           operands[2] = GEN_INT (-INTVAL (operands[2]));
6313           return "sub{b}\t{%2, %0|%0, %2}";
6314         }
6315       return "add{b}\t{%2, %0|%0, %2}";
6316     }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set_attr "mode" "QI")])
6325 (define_insn "addqi_ext_1"
6326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6327                          (const_int 8)
6328                          (const_int 8))
6329         (plus:SI
6330           (zero_extract:SI
6331             (match_operand 1 "ext_register_operand" "0")
6332             (const_int 8)
6333             (const_int 8))
6334           (match_operand:QI 2 "general_operand" "Qmn")))
6335    (clobber (reg:CC FLAGS_REG))]
6336   "!TARGET_64BIT"
6338   switch (get_attr_type (insn))
6339     {
6340     case TYPE_INCDEC:
6341       if (operands[2] == const1_rtx)
6342         return "inc{b}\t%h0";
6343       else
6344         {
6345           gcc_assert (operands[2] == constm1_rtx
6346                       || (GET_CODE (operands[2]) == CONST_INT
6347                           && INTVAL (operands[2]) == 255));
6348           return "dec{b}\t%h0";
6349         }
6351     default:
6352       return "add{b}\t{%2, %h0|%h0, %2}";
6353     }
6355   [(set (attr "type")
6356      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357         (const_string "incdec")
6358         (const_string "alu")))
6359    (set_attr "mode" "QI")])
6361 (define_insn "*addqi_ext_1_rex64"
6362   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363                          (const_int 8)
6364                          (const_int 8))
6365         (plus:SI
6366           (zero_extract:SI
6367             (match_operand 1 "ext_register_operand" "0")
6368             (const_int 8)
6369             (const_int 8))
6370           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6371    (clobber (reg:CC FLAGS_REG))]
6372   "TARGET_64BIT"
6374   switch (get_attr_type (insn))
6375     {
6376     case TYPE_INCDEC:
6377       if (operands[2] == const1_rtx)
6378         return "inc{b}\t%h0";
6379       else
6380         {
6381           gcc_assert (operands[2] == constm1_rtx
6382                       || (GET_CODE (operands[2]) == CONST_INT
6383                           && INTVAL (operands[2]) == 255));
6384           return "dec{b}\t%h0";
6385         }
6387     default:
6388       return "add{b}\t{%2, %h0|%h0, %2}";
6389     }
6391   [(set (attr "type")
6392      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6393         (const_string "incdec")
6394         (const_string "alu")))
6395    (set_attr "mode" "QI")])
6397 (define_insn "*addqi_ext_2"
6398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399                          (const_int 8)
6400                          (const_int 8))
6401         (plus:SI
6402           (zero_extract:SI
6403             (match_operand 1 "ext_register_operand" "%0")
6404             (const_int 8)
6405             (const_int 8))
6406           (zero_extract:SI
6407             (match_operand 2 "ext_register_operand" "Q")
6408             (const_int 8)
6409             (const_int 8))))
6410    (clobber (reg:CC FLAGS_REG))]
6411   ""
6412   "add{b}\t{%h2, %h0|%h0, %h2}"
6413   [(set_attr "type" "alu")
6414    (set_attr "mode" "QI")])
6416 ;; The patterns that match these are at the end of this file.
6418 (define_expand "addxf3"
6419   [(set (match_operand:XF 0 "register_operand" "")
6420         (plus:XF (match_operand:XF 1 "register_operand" "")
6421                  (match_operand:XF 2 "register_operand" "")))]
6422   "TARGET_80387"
6423   "")
6425 (define_expand "adddf3"
6426   [(set (match_operand:DF 0 "register_operand" "")
6427         (plus:DF (match_operand:DF 1 "register_operand" "")
6428                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6429   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6430   "")
6432 (define_expand "addsf3"
6433   [(set (match_operand:SF 0 "register_operand" "")
6434         (plus:SF (match_operand:SF 1 "register_operand" "")
6435                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6436   "TARGET_80387 || TARGET_SSE_MATH"
6437   "")
6439 ;; Subtract instructions
6441 ;; %%% splits for subditi3
6443 (define_expand "subti3"
6444   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6445                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6446                              (match_operand:TI 2 "x86_64_general_operand" "")))
6447               (clobber (reg:CC FLAGS_REG))])]
6448   "TARGET_64BIT"
6449   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6451 (define_insn "*subti3_1"
6452   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6453         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6454                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6455    (clobber (reg:CC FLAGS_REG))]
6456   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6457   "#")
6459 (define_split
6460   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6461         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6462                   (match_operand:TI 2 "general_operand" "")))
6463    (clobber (reg:CC FLAGS_REG))]
6464   "TARGET_64BIT && reload_completed"
6465   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6466               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6467    (parallel [(set (match_dup 3)
6468                    (minus:DI (match_dup 4)
6469                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6470                                       (match_dup 5))))
6471               (clobber (reg:CC FLAGS_REG))])]
6472   "split_ti (operands+0, 1, operands+0, operands+3);
6473    split_ti (operands+1, 1, operands+1, operands+4);
6474    split_ti (operands+2, 1, operands+2, operands+5);")
6476 ;; %%% splits for subsidi3
6478 (define_expand "subdi3"
6479   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6480                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6481                              (match_operand:DI 2 "x86_64_general_operand" "")))
6482               (clobber (reg:CC FLAGS_REG))])]
6483   ""
6484   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6486 (define_insn "*subdi3_1"
6487   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6488         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6489                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6490    (clobber (reg:CC FLAGS_REG))]
6491   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6492   "#")
6494 (define_split
6495   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6496         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6497                   (match_operand:DI 2 "general_operand" "")))
6498    (clobber (reg:CC FLAGS_REG))]
6499   "!TARGET_64BIT && reload_completed"
6500   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6501               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6502    (parallel [(set (match_dup 3)
6503                    (minus:SI (match_dup 4)
6504                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6505                                       (match_dup 5))))
6506               (clobber (reg:CC FLAGS_REG))])]
6507   "split_di (operands+0, 1, operands+0, operands+3);
6508    split_di (operands+1, 1, operands+1, operands+4);
6509    split_di (operands+2, 1, operands+2, operands+5);")
6511 (define_insn "subdi3_carry_rex64"
6512   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6513           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6514             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6515                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6516    (clobber (reg:CC FLAGS_REG))]
6517   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6518   "sbb{q}\t{%2, %0|%0, %2}"
6519   [(set_attr "type" "alu")
6520    (set_attr "pent_pair" "pu")
6521    (set_attr "mode" "DI")])
6523 (define_insn "*subdi_1_rex64"
6524   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6525         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6526                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6529   "sub{q}\t{%2, %0|%0, %2}"
6530   [(set_attr "type" "alu")
6531    (set_attr "mode" "DI")])
6533 (define_insn "*subdi_2_rex64"
6534   [(set (reg FLAGS_REG)
6535         (compare
6536           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6537                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6538           (const_int 0)))
6539    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6540         (minus:DI (match_dup 1) (match_dup 2)))]
6541   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6542    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6543   "sub{q}\t{%2, %0|%0, %2}"
6544   [(set_attr "type" "alu")
6545    (set_attr "mode" "DI")])
6547 (define_insn "*subdi_3_rex63"
6548   [(set (reg FLAGS_REG)
6549         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6550                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6551    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6552         (minus:DI (match_dup 1) (match_dup 2)))]
6553   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555   "sub{q}\t{%2, %0|%0, %2}"
6556   [(set_attr "type" "alu")
6557    (set_attr "mode" "DI")])
6559 (define_insn "subqi3_carry"
6560   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6561           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6562             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6563                (match_operand:QI 2 "general_operand" "qi,qm"))))
6564    (clobber (reg:CC FLAGS_REG))]
6565   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6566   "sbb{b}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "pent_pair" "pu")
6569    (set_attr "mode" "QI")])
6571 (define_insn "subhi3_carry"
6572   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6573           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6574             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6575                (match_operand:HI 2 "general_operand" "ri,rm"))))
6576    (clobber (reg:CC FLAGS_REG))]
6577   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6578   "sbb{w}\t{%2, %0|%0, %2}"
6579   [(set_attr "type" "alu")
6580    (set_attr "pent_pair" "pu")
6581    (set_attr "mode" "HI")])
6583 (define_insn "subsi3_carry"
6584   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6585           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6586             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6587                (match_operand:SI 2 "general_operand" "ri,rm"))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6590   "sbb{l}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "pent_pair" "pu")
6593    (set_attr "mode" "SI")])
6595 (define_insn "subsi3_carry_zext"
6596   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6597           (zero_extend:DI
6598             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6599               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6600                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6601    (clobber (reg:CC FLAGS_REG))]
6602   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6603   "sbb{l}\t{%2, %k0|%k0, %2}"
6604   [(set_attr "type" "alu")
6605    (set_attr "pent_pair" "pu")
6606    (set_attr "mode" "SI")])
6608 (define_expand "subsi3"
6609   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6610                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6611                              (match_operand:SI 2 "general_operand" "")))
6612               (clobber (reg:CC FLAGS_REG))])]
6613   ""
6614   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6616 (define_insn "*subsi_1"
6617   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6618         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6619                   (match_operand:SI 2 "general_operand" "ri,rm")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622   "sub{l}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "mode" "SI")])
6626 (define_insn "*subsi_1_zext"
6627   [(set (match_operand:DI 0 "register_operand" "=r")
6628         (zero_extend:DI
6629           (minus:SI (match_operand:SI 1 "register_operand" "0")
6630                     (match_operand:SI 2 "general_operand" "rim"))))
6631    (clobber (reg:CC FLAGS_REG))]
6632   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6633   "sub{l}\t{%2, %k0|%k0, %2}"
6634   [(set_attr "type" "alu")
6635    (set_attr "mode" "SI")])
6637 (define_insn "*subsi_2"
6638   [(set (reg FLAGS_REG)
6639         (compare
6640           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6641                     (match_operand:SI 2 "general_operand" "ri,rm"))
6642           (const_int 0)))
6643    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6644         (minus:SI (match_dup 1) (match_dup 2)))]
6645   "ix86_match_ccmode (insn, CCGOCmode)
6646    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647   "sub{l}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "mode" "SI")])
6651 (define_insn "*subsi_2_zext"
6652   [(set (reg FLAGS_REG)
6653         (compare
6654           (minus:SI (match_operand:SI 1 "register_operand" "0")
6655                     (match_operand:SI 2 "general_operand" "rim"))
6656           (const_int 0)))
6657    (set (match_operand:DI 0 "register_operand" "=r")
6658         (zero_extend:DI
6659           (minus:SI (match_dup 1)
6660                     (match_dup 2))))]
6661   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6662    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663   "sub{l}\t{%2, %k0|%k0, %2}"
6664   [(set_attr "type" "alu")
6665    (set_attr "mode" "SI")])
6667 (define_insn "*subsi_3"
6668   [(set (reg FLAGS_REG)
6669         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670                  (match_operand:SI 2 "general_operand" "ri,rm")))
6671    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672         (minus:SI (match_dup 1) (match_dup 2)))]
6673   "ix86_match_ccmode (insn, CCmode)
6674    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675   "sub{l}\t{%2, %0|%0, %2}"
6676   [(set_attr "type" "alu")
6677    (set_attr "mode" "SI")])
6679 (define_insn "*subsi_3_zext"
6680   [(set (reg FLAGS_REG)
6681         (compare (match_operand:SI 1 "register_operand" "0")
6682                  (match_operand:SI 2 "general_operand" "rim")))
6683    (set (match_operand:DI 0 "register_operand" "=r")
6684         (zero_extend:DI
6685           (minus:SI (match_dup 1)
6686                     (match_dup 2))))]
6687   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6688    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689   "sub{q}\t{%2, %0|%0, %2}"
6690   [(set_attr "type" "alu")
6691    (set_attr "mode" "DI")])
6693 (define_expand "subhi3"
6694   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6695                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6696                              (match_operand:HI 2 "general_operand" "")))
6697               (clobber (reg:CC FLAGS_REG))])]
6698   "TARGET_HIMODE_MATH"
6699   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6701 (define_insn "*subhi_1"
6702   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6703         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6704                   (match_operand:HI 2 "general_operand" "ri,rm")))
6705    (clobber (reg:CC FLAGS_REG))]
6706   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6707   "sub{w}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "HI")])
6711 (define_insn "*subhi_2"
6712   [(set (reg FLAGS_REG)
6713         (compare
6714           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6715                     (match_operand:HI 2 "general_operand" "ri,rm"))
6716           (const_int 0)))
6717    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6718         (minus:HI (match_dup 1) (match_dup 2)))]
6719   "ix86_match_ccmode (insn, CCGOCmode)
6720    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6721   "sub{w}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "HI")])
6725 (define_insn "*subhi_3"
6726   [(set (reg FLAGS_REG)
6727         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6728                  (match_operand:HI 2 "general_operand" "ri,rm")))
6729    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6730         (minus:HI (match_dup 1) (match_dup 2)))]
6731   "ix86_match_ccmode (insn, CCmode)
6732    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6733   "sub{w}\t{%2, %0|%0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "mode" "HI")])
6737 (define_expand "subqi3"
6738   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6739                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6740                              (match_operand:QI 2 "general_operand" "")))
6741               (clobber (reg:CC FLAGS_REG))])]
6742   "TARGET_QIMODE_MATH"
6743   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6745 (define_insn "*subqi_1"
6746   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6747         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6748                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6749    (clobber (reg:CC FLAGS_REG))]
6750   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6751   "sub{b}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "mode" "QI")])
6755 (define_insn "*subqi_1_slp"
6756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6757         (minus:QI (match_dup 0)
6758                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6761    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6762   "sub{b}\t{%1, %0|%0, %1}"
6763   [(set_attr "type" "alu1")
6764    (set_attr "mode" "QI")])
6766 (define_insn "*subqi_2"
6767   [(set (reg FLAGS_REG)
6768         (compare
6769           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6770                     (match_operand:QI 2 "general_operand" "qi,qm"))
6771           (const_int 0)))
6772    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6773         (minus:HI (match_dup 1) (match_dup 2)))]
6774   "ix86_match_ccmode (insn, CCGOCmode)
6775    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6776   "sub{b}\t{%2, %0|%0, %2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "QI")])
6780 (define_insn "*subqi_3"
6781   [(set (reg FLAGS_REG)
6782         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6783                  (match_operand:QI 2 "general_operand" "qi,qm")))
6784    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6785         (minus:HI (match_dup 1) (match_dup 2)))]
6786   "ix86_match_ccmode (insn, CCmode)
6787    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6788   "sub{b}\t{%2, %0|%0, %2}"
6789   [(set_attr "type" "alu")
6790    (set_attr "mode" "QI")])
6792 ;; The patterns that match these are at the end of this file.
6794 (define_expand "subxf3"
6795   [(set (match_operand:XF 0 "register_operand" "")
6796         (minus:XF (match_operand:XF 1 "register_operand" "")
6797                   (match_operand:XF 2 "register_operand" "")))]
6798   "TARGET_80387"
6799   "")
6801 (define_expand "subdf3"
6802   [(set (match_operand:DF 0 "register_operand" "")
6803         (minus:DF (match_operand:DF 1 "register_operand" "")
6804                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6805   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6806   "")
6808 (define_expand "subsf3"
6809   [(set (match_operand:SF 0 "register_operand" "")
6810         (minus:SF (match_operand:SF 1 "register_operand" "")
6811                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6812   "TARGET_80387 || TARGET_SSE_MATH"
6813   "")
6815 ;; Multiply instructions
6817 (define_expand "muldi3"
6818   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6819                    (mult:DI (match_operand:DI 1 "register_operand" "")
6820                             (match_operand:DI 2 "x86_64_general_operand" "")))
6821               (clobber (reg:CC FLAGS_REG))])]
6822   "TARGET_64BIT"
6823   "")
6825 (define_insn "*muldi3_1_rex64"
6826   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6827         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6828                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6829    (clobber (reg:CC FLAGS_REG))]
6830   "TARGET_64BIT
6831    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6832   "@
6833    imul{q}\t{%2, %1, %0|%0, %1, %2}
6834    imul{q}\t{%2, %1, %0|%0, %1, %2}
6835    imul{q}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "imul")
6837    (set_attr "prefix_0f" "0,0,1")
6838    (set (attr "athlon_decode")
6839         (cond [(eq_attr "cpu" "athlon")
6840                   (const_string "vector")
6841                (eq_attr "alternative" "1")
6842                   (const_string "vector")
6843                (and (eq_attr "alternative" "2")
6844                     (match_operand 1 "memory_operand" ""))
6845                   (const_string "vector")]
6846               (const_string "direct")))
6847    (set_attr "mode" "DI")])
6849 (define_expand "mulsi3"
6850   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6851                    (mult:SI (match_operand:SI 1 "register_operand" "")
6852                             (match_operand:SI 2 "general_operand" "")))
6853               (clobber (reg:CC FLAGS_REG))])]
6854   ""
6855   "")
6857 (define_insn "*mulsi3_1"
6858   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6859         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6860                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6863   "@
6864    imul{l}\t{%2, %1, %0|%0, %1, %2}
6865    imul{l}\t{%2, %1, %0|%0, %1, %2}
6866    imul{l}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "imul")
6868    (set_attr "prefix_0f" "0,0,1")
6869    (set (attr "athlon_decode")
6870         (cond [(eq_attr "cpu" "athlon")
6871                   (const_string "vector")
6872                (eq_attr "alternative" "1")
6873                   (const_string "vector")
6874                (and (eq_attr "alternative" "2")
6875                     (match_operand 1 "memory_operand" ""))
6876                   (const_string "vector")]
6877               (const_string "direct")))
6878    (set_attr "mode" "SI")])
6880 (define_insn "*mulsi3_1_zext"
6881   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6882         (zero_extend:DI
6883           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6884                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6885    (clobber (reg:CC FLAGS_REG))]
6886   "TARGET_64BIT
6887    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6888   "@
6889    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6891    imul{l}\t{%2, %k0|%k0, %2}"
6892   [(set_attr "type" "imul")
6893    (set_attr "prefix_0f" "0,0,1")
6894    (set (attr "athlon_decode")
6895         (cond [(eq_attr "cpu" "athlon")
6896                   (const_string "vector")
6897                (eq_attr "alternative" "1")
6898                   (const_string "vector")
6899                (and (eq_attr "alternative" "2")
6900                     (match_operand 1 "memory_operand" ""))
6901                   (const_string "vector")]
6902               (const_string "direct")))
6903    (set_attr "mode" "SI")])
6905 (define_expand "mulhi3"
6906   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6907                    (mult:HI (match_operand:HI 1 "register_operand" "")
6908                             (match_operand:HI 2 "general_operand" "")))
6909               (clobber (reg:CC FLAGS_REG))])]
6910   "TARGET_HIMODE_MATH"
6911   "")
6913 (define_insn "*mulhi3_1"
6914   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6915         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6916                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6919   "@
6920    imul{w}\t{%2, %1, %0|%0, %1, %2}
6921    imul{w}\t{%2, %1, %0|%0, %1, %2}
6922    imul{w}\t{%2, %0|%0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1,2")
6929                   (const_string "vector")]
6930               (const_string "direct")))
6931    (set_attr "mode" "HI")])
6933 (define_expand "mulqi3"
6934   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6935                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6936                             (match_operand:QI 2 "register_operand" "")))
6937               (clobber (reg:CC FLAGS_REG))])]
6938   "TARGET_QIMODE_MATH"
6939   "")
6941 (define_insn "*mulqi3_1"
6942   [(set (match_operand:QI 0 "register_operand" "=a")
6943         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6944                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6945    (clobber (reg:CC FLAGS_REG))]
6946   "TARGET_QIMODE_MATH
6947    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6948   "mul{b}\t%2"
6949   [(set_attr "type" "imul")
6950    (set_attr "length_immediate" "0")
6951    (set (attr "athlon_decode")
6952      (if_then_else (eq_attr "cpu" "athlon")
6953         (const_string "vector")
6954         (const_string "direct")))
6955    (set_attr "mode" "QI")])
6957 (define_expand "umulqihi3"
6958   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6959                    (mult:HI (zero_extend:HI
6960                               (match_operand:QI 1 "nonimmediate_operand" ""))
6961                             (zero_extend:HI
6962                               (match_operand:QI 2 "register_operand" ""))))
6963               (clobber (reg:CC FLAGS_REG))])]
6964   "TARGET_QIMODE_MATH"
6965   "")
6967 (define_insn "*umulqihi3_1"
6968   [(set (match_operand:HI 0 "register_operand" "=a")
6969         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6970                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "TARGET_QIMODE_MATH
6973    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6974   "mul{b}\t%2"
6975   [(set_attr "type" "imul")
6976    (set_attr "length_immediate" "0")
6977    (set (attr "athlon_decode")
6978      (if_then_else (eq_attr "cpu" "athlon")
6979         (const_string "vector")
6980         (const_string "direct")))
6981    (set_attr "mode" "QI")])
6983 (define_expand "mulqihi3"
6984   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6985                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6986                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6987               (clobber (reg:CC FLAGS_REG))])]
6988   "TARGET_QIMODE_MATH"
6989   "")
6991 (define_insn "*mulqihi3_insn"
6992   [(set (match_operand:HI 0 "register_operand" "=a")
6993         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6994                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_QIMODE_MATH
6997    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6998   "imul{b}\t%2"
6999   [(set_attr "type" "imul")
7000    (set_attr "length_immediate" "0")
7001    (set (attr "athlon_decode")
7002      (if_then_else (eq_attr "cpu" "athlon")
7003         (const_string "vector")
7004         (const_string "direct")))
7005    (set_attr "mode" "QI")])
7007 (define_expand "umulditi3"
7008   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7009                    (mult:TI (zero_extend:TI
7010                               (match_operand:DI 1 "nonimmediate_operand" ""))
7011                             (zero_extend:TI
7012                               (match_operand:DI 2 "register_operand" ""))))
7013               (clobber (reg:CC FLAGS_REG))])]
7014   "TARGET_64BIT"
7015   "")
7017 (define_insn "*umulditi3_insn"
7018   [(set (match_operand:TI 0 "register_operand" "=A")
7019         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7020                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7021    (clobber (reg:CC FLAGS_REG))]
7022   "TARGET_64BIT
7023    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7024   "mul{q}\t%2"
7025   [(set_attr "type" "imul")
7026    (set_attr "length_immediate" "0")
7027    (set (attr "athlon_decode")
7028      (if_then_else (eq_attr "cpu" "athlon")
7029         (const_string "vector")
7030         (const_string "double")))
7031    (set_attr "mode" "DI")])
7033 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7034 (define_expand "umulsidi3"
7035   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7036                    (mult:DI (zero_extend:DI
7037                               (match_operand:SI 1 "nonimmediate_operand" ""))
7038                             (zero_extend:DI
7039                               (match_operand:SI 2 "register_operand" ""))))
7040               (clobber (reg:CC FLAGS_REG))])]
7041   "!TARGET_64BIT"
7042   "")
7044 (define_insn "*umulsidi3_insn"
7045   [(set (match_operand:DI 0 "register_operand" "=A")
7046         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7047                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7048    (clobber (reg:CC FLAGS_REG))]
7049   "!TARGET_64BIT
7050    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7051   "mul{l}\t%2"
7052   [(set_attr "type" "imul")
7053    (set_attr "length_immediate" "0")
7054    (set (attr "athlon_decode")
7055      (if_then_else (eq_attr "cpu" "athlon")
7056         (const_string "vector")
7057         (const_string "double")))
7058    (set_attr "mode" "SI")])
7060 (define_expand "mulditi3"
7061   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7062                    (mult:TI (sign_extend:TI
7063                               (match_operand:DI 1 "nonimmediate_operand" ""))
7064                             (sign_extend:TI
7065                               (match_operand:DI 2 "register_operand" ""))))
7066               (clobber (reg:CC FLAGS_REG))])]
7067   "TARGET_64BIT"
7068   "")
7070 (define_insn "*mulditi3_insn"
7071   [(set (match_operand:TI 0 "register_operand" "=A")
7072         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7073                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7074    (clobber (reg:CC FLAGS_REG))]
7075   "TARGET_64BIT
7076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7077   "imul{q}\t%2"
7078   [(set_attr "type" "imul")
7079    (set_attr "length_immediate" "0")
7080    (set (attr "athlon_decode")
7081      (if_then_else (eq_attr "cpu" "athlon")
7082         (const_string "vector")
7083         (const_string "double")))
7084    (set_attr "mode" "DI")])
7086 (define_expand "mulsidi3"
7087   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7088                    (mult:DI (sign_extend:DI
7089                               (match_operand:SI 1 "nonimmediate_operand" ""))
7090                             (sign_extend:DI
7091                               (match_operand:SI 2 "register_operand" ""))))
7092               (clobber (reg:CC FLAGS_REG))])]
7093   "!TARGET_64BIT"
7094   "")
7096 (define_insn "*mulsidi3_insn"
7097   [(set (match_operand:DI 0 "register_operand" "=A")
7098         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7099                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7100    (clobber (reg:CC FLAGS_REG))]
7101   "!TARGET_64BIT
7102    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7103   "imul{l}\t%2"
7104   [(set_attr "type" "imul")
7105    (set_attr "length_immediate" "0")
7106    (set (attr "athlon_decode")
7107      (if_then_else (eq_attr "cpu" "athlon")
7108         (const_string "vector")
7109         (const_string "double")))
7110    (set_attr "mode" "SI")])
7112 (define_expand "umuldi3_highpart"
7113   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7114                    (truncate:DI
7115                      (lshiftrt:TI
7116                        (mult:TI (zero_extend:TI
7117                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7118                                 (zero_extend:TI
7119                                   (match_operand:DI 2 "register_operand" "")))
7120                        (const_int 64))))
7121               (clobber (match_scratch:DI 3 ""))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "TARGET_64BIT"
7124   "")
7126 (define_insn "*umuldi3_highpart_rex64"
7127   [(set (match_operand:DI 0 "register_operand" "=d")
7128         (truncate:DI
7129           (lshiftrt:TI
7130             (mult:TI (zero_extend:TI
7131                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7132                      (zero_extend:TI
7133                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7134             (const_int 64))))
7135    (clobber (match_scratch:DI 3 "=1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT
7138    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139   "mul{q}\t%2"
7140   [(set_attr "type" "imul")
7141    (set_attr "length_immediate" "0")
7142    (set (attr "athlon_decode")
7143      (if_then_else (eq_attr "cpu" "athlon")
7144         (const_string "vector")
7145         (const_string "double")))
7146    (set_attr "mode" "DI")])
7148 (define_expand "umulsi3_highpart"
7149   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7150                    (truncate:SI
7151                      (lshiftrt:DI
7152                        (mult:DI (zero_extend:DI
7153                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7154                                 (zero_extend:DI
7155                                   (match_operand:SI 2 "register_operand" "")))
7156                        (const_int 32))))
7157               (clobber (match_scratch:SI 3 ""))
7158               (clobber (reg:CC FLAGS_REG))])]
7159   ""
7160   "")
7162 (define_insn "*umulsi3_highpart_insn"
7163   [(set (match_operand:SI 0 "register_operand" "=d")
7164         (truncate:SI
7165           (lshiftrt:DI
7166             (mult:DI (zero_extend:DI
7167                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7168                      (zero_extend:DI
7169                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7170             (const_int 32))))
7171    (clobber (match_scratch:SI 3 "=1"))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7174   "mul{l}\t%2"
7175   [(set_attr "type" "imul")
7176    (set_attr "length_immediate" "0")
7177    (set (attr "athlon_decode")
7178      (if_then_else (eq_attr "cpu" "athlon")
7179         (const_string "vector")
7180         (const_string "double")))
7181    (set_attr "mode" "SI")])
7183 (define_insn "*umulsi3_highpart_zext"
7184   [(set (match_operand:DI 0 "register_operand" "=d")
7185         (zero_extend:DI (truncate:SI
7186           (lshiftrt:DI
7187             (mult:DI (zero_extend:DI
7188                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7189                      (zero_extend:DI
7190                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7191             (const_int 32)))))
7192    (clobber (match_scratch:SI 3 "=1"))
7193    (clobber (reg:CC FLAGS_REG))]
7194   "TARGET_64BIT
7195    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7196   "mul{l}\t%2"
7197   [(set_attr "type" "imul")
7198    (set_attr "length_immediate" "0")
7199    (set (attr "athlon_decode")
7200      (if_then_else (eq_attr "cpu" "athlon")
7201         (const_string "vector")
7202         (const_string "double")))
7203    (set_attr "mode" "SI")])
7205 (define_expand "smuldi3_highpart"
7206   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7207                    (truncate:DI
7208                      (lshiftrt:TI
7209                        (mult:TI (sign_extend:TI
7210                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7211                                 (sign_extend:TI
7212                                   (match_operand:DI 2 "register_operand" "")))
7213                        (const_int 64))))
7214               (clobber (match_scratch:DI 3 ""))
7215               (clobber (reg:CC FLAGS_REG))])]
7216   "TARGET_64BIT"
7217   "")
7219 (define_insn "*smuldi3_highpart_rex64"
7220   [(set (match_operand:DI 0 "register_operand" "=d")
7221         (truncate:DI
7222           (lshiftrt:TI
7223             (mult:TI (sign_extend:TI
7224                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7225                      (sign_extend:TI
7226                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7227             (const_int 64))))
7228    (clobber (match_scratch:DI 3 "=1"))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_64BIT
7231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7232   "imul{q}\t%2"
7233   [(set_attr "type" "imul")
7234    (set (attr "athlon_decode")
7235      (if_then_else (eq_attr "cpu" "athlon")
7236         (const_string "vector")
7237         (const_string "double")))
7238    (set_attr "mode" "DI")])
7240 (define_expand "smulsi3_highpart"
7241   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7242                    (truncate:SI
7243                      (lshiftrt:DI
7244                        (mult:DI (sign_extend:DI
7245                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7246                                 (sign_extend:DI
7247                                   (match_operand:SI 2 "register_operand" "")))
7248                        (const_int 32))))
7249               (clobber (match_scratch:SI 3 ""))
7250               (clobber (reg:CC FLAGS_REG))])]
7251   ""
7252   "")
7254 (define_insn "*smulsi3_highpart_insn"
7255   [(set (match_operand:SI 0 "register_operand" "=d")
7256         (truncate:SI
7257           (lshiftrt:DI
7258             (mult:DI (sign_extend:DI
7259                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7260                      (sign_extend:DI
7261                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7262             (const_int 32))))
7263    (clobber (match_scratch:SI 3 "=1"))
7264    (clobber (reg:CC FLAGS_REG))]
7265   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7266   "imul{l}\t%2"
7267   [(set_attr "type" "imul")
7268    (set (attr "athlon_decode")
7269      (if_then_else (eq_attr "cpu" "athlon")
7270         (const_string "vector")
7271         (const_string "double")))
7272    (set_attr "mode" "SI")])
7274 (define_insn "*smulsi3_highpart_zext"
7275   [(set (match_operand:DI 0 "register_operand" "=d")
7276         (zero_extend:DI (truncate:SI
7277           (lshiftrt:DI
7278             (mult:DI (sign_extend:DI
7279                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7280                      (sign_extend:DI
7281                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7282             (const_int 32)))))
7283    (clobber (match_scratch:SI 3 "=1"))
7284    (clobber (reg:CC FLAGS_REG))]
7285   "TARGET_64BIT
7286    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287   "imul{l}\t%2"
7288   [(set_attr "type" "imul")
7289    (set (attr "athlon_decode")
7290      (if_then_else (eq_attr "cpu" "athlon")
7291         (const_string "vector")
7292         (const_string "double")))
7293    (set_attr "mode" "SI")])
7295 ;; The patterns that match these are at the end of this file.
7297 (define_expand "mulxf3"
7298   [(set (match_operand:XF 0 "register_operand" "")
7299         (mult:XF (match_operand:XF 1 "register_operand" "")
7300                  (match_operand:XF 2 "register_operand" "")))]
7301   "TARGET_80387"
7302   "")
7304 (define_expand "muldf3"
7305   [(set (match_operand:DF 0 "register_operand" "")
7306         (mult:DF (match_operand:DF 1 "register_operand" "")
7307                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7308   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7309   "")
7311 (define_expand "mulsf3"
7312   [(set (match_operand:SF 0 "register_operand" "")
7313         (mult:SF (match_operand:SF 1 "register_operand" "")
7314                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7315   "TARGET_80387 || TARGET_SSE_MATH"
7316   "")
7318 ;; Divide instructions
7320 (define_insn "divqi3"
7321   [(set (match_operand:QI 0 "register_operand" "=a")
7322         (div:QI (match_operand:HI 1 "register_operand" "0")
7323                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_QIMODE_MATH"
7326   "idiv{b}\t%2"
7327   [(set_attr "type" "idiv")
7328    (set_attr "mode" "QI")])
7330 (define_insn "udivqi3"
7331   [(set (match_operand:QI 0 "register_operand" "=a")
7332         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7333                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7334    (clobber (reg:CC FLAGS_REG))]
7335   "TARGET_QIMODE_MATH"
7336   "div{b}\t%2"
7337   [(set_attr "type" "idiv")
7338    (set_attr "mode" "QI")])
7340 ;; The patterns that match these are at the end of this file.
7342 (define_expand "divxf3"
7343   [(set (match_operand:XF 0 "register_operand" "")
7344         (div:XF (match_operand:XF 1 "register_operand" "")
7345                 (match_operand:XF 2 "register_operand" "")))]
7346   "TARGET_80387"
7347   "")
7349 (define_expand "divdf3"
7350   [(set (match_operand:DF 0 "register_operand" "")
7351         (div:DF (match_operand:DF 1 "register_operand" "")
7352                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7353    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7354    "")
7356 (define_expand "divsf3"
7357   [(set (match_operand:SF 0 "register_operand" "")
7358         (div:SF (match_operand:SF 1 "register_operand" "")
7359                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7360   "TARGET_80387 || TARGET_SSE_MATH"
7361   "")
7363 ;; Remainder instructions.
7365 (define_expand "divmoddi4"
7366   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7367                    (div:DI (match_operand:DI 1 "register_operand" "")
7368                            (match_operand:DI 2 "nonimmediate_operand" "")))
7369               (set (match_operand:DI 3 "register_operand" "")
7370                    (mod:DI (match_dup 1) (match_dup 2)))
7371               (clobber (reg:CC FLAGS_REG))])]
7372   "TARGET_64BIT"
7373   "")
7375 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7376 ;; Penalize eax case slightly because it results in worse scheduling
7377 ;; of code.
7378 (define_insn "*divmoddi4_nocltd_rex64"
7379   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7380         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7381                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7382    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7383         (mod:DI (match_dup 2) (match_dup 3)))
7384    (clobber (reg:CC FLAGS_REG))]
7385   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7386   "#"
7387   [(set_attr "type" "multi")])
7389 (define_insn "*divmoddi4_cltd_rex64"
7390   [(set (match_operand:DI 0 "register_operand" "=a")
7391         (div:DI (match_operand:DI 2 "register_operand" "a")
7392                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7393    (set (match_operand:DI 1 "register_operand" "=&d")
7394         (mod:DI (match_dup 2) (match_dup 3)))
7395    (clobber (reg:CC FLAGS_REG))]
7396   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7397   "#"
7398   [(set_attr "type" "multi")])
7400 (define_insn "*divmoddi_noext_rex64"
7401   [(set (match_operand:DI 0 "register_operand" "=a")
7402         (div:DI (match_operand:DI 1 "register_operand" "0")
7403                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7404    (set (match_operand:DI 3 "register_operand" "=d")
7405         (mod:DI (match_dup 1) (match_dup 2)))
7406    (use (match_operand:DI 4 "register_operand" "3"))
7407    (clobber (reg:CC FLAGS_REG))]
7408   "TARGET_64BIT"
7409   "idiv{q}\t%2"
7410   [(set_attr "type" "idiv")
7411    (set_attr "mode" "DI")])
7413 (define_split
7414   [(set (match_operand:DI 0 "register_operand" "")
7415         (div:DI (match_operand:DI 1 "register_operand" "")
7416                 (match_operand:DI 2 "nonimmediate_operand" "")))
7417    (set (match_operand:DI 3 "register_operand" "")
7418         (mod:DI (match_dup 1) (match_dup 2)))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_64BIT && reload_completed"
7421   [(parallel [(set (match_dup 3)
7422                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7423               (clobber (reg:CC FLAGS_REG))])
7424    (parallel [(set (match_dup 0)
7425                    (div:DI (reg:DI 0) (match_dup 2)))
7426               (set (match_dup 3)
7427                    (mod:DI (reg:DI 0) (match_dup 2)))
7428               (use (match_dup 3))
7429               (clobber (reg:CC FLAGS_REG))])]
7431   /* Avoid use of cltd in favor of a mov+shift.  */
7432   if (!TARGET_USE_CLTD && !optimize_size)
7433     {
7434       if (true_regnum (operands[1]))
7435         emit_move_insn (operands[0], operands[1]);
7436       else
7437         emit_move_insn (operands[3], operands[1]);
7438       operands[4] = operands[3];
7439     }
7440   else
7441     {
7442       gcc_assert (!true_regnum (operands[1]));
7443       operands[4] = operands[1];
7444     }
7448 (define_expand "divmodsi4"
7449   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7450                    (div:SI (match_operand:SI 1 "register_operand" "")
7451                            (match_operand:SI 2 "nonimmediate_operand" "")))
7452               (set (match_operand:SI 3 "register_operand" "")
7453                    (mod:SI (match_dup 1) (match_dup 2)))
7454               (clobber (reg:CC FLAGS_REG))])]
7455   ""
7456   "")
7458 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7459 ;; Penalize eax case slightly because it results in worse scheduling
7460 ;; of code.
7461 (define_insn "*divmodsi4_nocltd"
7462   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7463         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7464                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7465    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7466         (mod:SI (match_dup 2) (match_dup 3)))
7467    (clobber (reg:CC FLAGS_REG))]
7468   "!optimize_size && !TARGET_USE_CLTD"
7469   "#"
7470   [(set_attr "type" "multi")])
7472 (define_insn "*divmodsi4_cltd"
7473   [(set (match_operand:SI 0 "register_operand" "=a")
7474         (div:SI (match_operand:SI 2 "register_operand" "a")
7475                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7476    (set (match_operand:SI 1 "register_operand" "=&d")
7477         (mod:SI (match_dup 2) (match_dup 3)))
7478    (clobber (reg:CC FLAGS_REG))]
7479   "optimize_size || TARGET_USE_CLTD"
7480   "#"
7481   [(set_attr "type" "multi")])
7483 (define_insn "*divmodsi_noext"
7484   [(set (match_operand:SI 0 "register_operand" "=a")
7485         (div:SI (match_operand:SI 1 "register_operand" "0")
7486                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7487    (set (match_operand:SI 3 "register_operand" "=d")
7488         (mod:SI (match_dup 1) (match_dup 2)))
7489    (use (match_operand:SI 4 "register_operand" "3"))
7490    (clobber (reg:CC FLAGS_REG))]
7491   ""
7492   "idiv{l}\t%2"
7493   [(set_attr "type" "idiv")
7494    (set_attr "mode" "SI")])
7496 (define_split
7497   [(set (match_operand:SI 0 "register_operand" "")
7498         (div:SI (match_operand:SI 1 "register_operand" "")
7499                 (match_operand:SI 2 "nonimmediate_operand" "")))
7500    (set (match_operand:SI 3 "register_operand" "")
7501         (mod:SI (match_dup 1) (match_dup 2)))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "reload_completed"
7504   [(parallel [(set (match_dup 3)
7505                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7506               (clobber (reg:CC FLAGS_REG))])
7507    (parallel [(set (match_dup 0)
7508                    (div:SI (reg:SI 0) (match_dup 2)))
7509               (set (match_dup 3)
7510                    (mod:SI (reg:SI 0) (match_dup 2)))
7511               (use (match_dup 3))
7512               (clobber (reg:CC FLAGS_REG))])]
7514   /* Avoid use of cltd in favor of a mov+shift.  */
7515   if (!TARGET_USE_CLTD && !optimize_size)
7516     {
7517       if (true_regnum (operands[1]))
7518         emit_move_insn (operands[0], operands[1]);
7519       else
7520         emit_move_insn (operands[3], operands[1]);
7521       operands[4] = operands[3];
7522     }
7523   else
7524     {
7525       gcc_assert (!true_regnum (operands[1]));
7526       operands[4] = operands[1];
7527     }
7529 ;; %%% Split me.
7530 (define_insn "divmodhi4"
7531   [(set (match_operand:HI 0 "register_operand" "=a")
7532         (div:HI (match_operand:HI 1 "register_operand" "0")
7533                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:HI 3 "register_operand" "=&d")
7535         (mod:HI (match_dup 1) (match_dup 2)))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "TARGET_HIMODE_MATH"
7538   "cwtd\;idiv{w}\t%2"
7539   [(set_attr "type" "multi")
7540    (set_attr "length_immediate" "0")
7541    (set_attr "mode" "SI")])
7543 (define_insn "udivmoddi4"
7544   [(set (match_operand:DI 0 "register_operand" "=a")
7545         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7546                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7547    (set (match_operand:DI 3 "register_operand" "=&d")
7548         (umod:DI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "TARGET_64BIT"
7551   "xor{q}\t%3, %3\;div{q}\t%2"
7552   [(set_attr "type" "multi")
7553    (set_attr "length_immediate" "0")
7554    (set_attr "mode" "DI")])
7556 (define_insn "*udivmoddi4_noext"
7557   [(set (match_operand:DI 0 "register_operand" "=a")
7558         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7559                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7560    (set (match_operand:DI 3 "register_operand" "=d")
7561         (umod:DI (match_dup 1) (match_dup 2)))
7562    (use (match_dup 3))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "TARGET_64BIT"
7565   "div{q}\t%2"
7566   [(set_attr "type" "idiv")
7567    (set_attr "mode" "DI")])
7569 (define_split
7570   [(set (match_operand:DI 0 "register_operand" "")
7571         (udiv:DI (match_operand:DI 1 "register_operand" "")
7572                  (match_operand:DI 2 "nonimmediate_operand" "")))
7573    (set (match_operand:DI 3 "register_operand" "")
7574         (umod:DI (match_dup 1) (match_dup 2)))
7575    (clobber (reg:CC FLAGS_REG))]
7576   "TARGET_64BIT && reload_completed"
7577   [(set (match_dup 3) (const_int 0))
7578    (parallel [(set (match_dup 0)
7579                    (udiv:DI (match_dup 1) (match_dup 2)))
7580               (set (match_dup 3)
7581                    (umod:DI (match_dup 1) (match_dup 2)))
7582               (use (match_dup 3))
7583               (clobber (reg:CC FLAGS_REG))])]
7584   "")
7586 (define_insn "udivmodsi4"
7587   [(set (match_operand:SI 0 "register_operand" "=a")
7588         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7589                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7590    (set (match_operand:SI 3 "register_operand" "=&d")
7591         (umod:SI (match_dup 1) (match_dup 2)))
7592    (clobber (reg:CC FLAGS_REG))]
7593   ""
7594   "xor{l}\t%3, %3\;div{l}\t%2"
7595   [(set_attr "type" "multi")
7596    (set_attr "length_immediate" "0")
7597    (set_attr "mode" "SI")])
7599 (define_insn "*udivmodsi4_noext"
7600   [(set (match_operand:SI 0 "register_operand" "=a")
7601         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7602                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7603    (set (match_operand:SI 3 "register_operand" "=d")
7604         (umod:SI (match_dup 1) (match_dup 2)))
7605    (use (match_dup 3))
7606    (clobber (reg:CC FLAGS_REG))]
7607   ""
7608   "div{l}\t%2"
7609   [(set_attr "type" "idiv")
7610    (set_attr "mode" "SI")])
7612 (define_split
7613   [(set (match_operand:SI 0 "register_operand" "")
7614         (udiv:SI (match_operand:SI 1 "register_operand" "")
7615                  (match_operand:SI 2 "nonimmediate_operand" "")))
7616    (set (match_operand:SI 3 "register_operand" "")
7617         (umod:SI (match_dup 1) (match_dup 2)))
7618    (clobber (reg:CC FLAGS_REG))]
7619   "reload_completed"
7620   [(set (match_dup 3) (const_int 0))
7621    (parallel [(set (match_dup 0)
7622                    (udiv:SI (match_dup 1) (match_dup 2)))
7623               (set (match_dup 3)
7624                    (umod:SI (match_dup 1) (match_dup 2)))
7625               (use (match_dup 3))
7626               (clobber (reg:CC FLAGS_REG))])]
7627   "")
7629 (define_expand "udivmodhi4"
7630   [(set (match_dup 4) (const_int 0))
7631    (parallel [(set (match_operand:HI 0 "register_operand" "")
7632                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7633                             (match_operand:HI 2 "nonimmediate_operand" "")))
7634               (set (match_operand:HI 3 "register_operand" "")
7635                    (umod:HI (match_dup 1) (match_dup 2)))
7636               (use (match_dup 4))
7637               (clobber (reg:CC FLAGS_REG))])]
7638   "TARGET_HIMODE_MATH"
7639   "operands[4] = gen_reg_rtx (HImode);")
7641 (define_insn "*udivmodhi_noext"
7642   [(set (match_operand:HI 0 "register_operand" "=a")
7643         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7644                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7645    (set (match_operand:HI 3 "register_operand" "=d")
7646         (umod:HI (match_dup 1) (match_dup 2)))
7647    (use (match_operand:HI 4 "register_operand" "3"))
7648    (clobber (reg:CC FLAGS_REG))]
7649   ""
7650   "div{w}\t%2"
7651   [(set_attr "type" "idiv")
7652    (set_attr "mode" "HI")])
7654 ;; We cannot use div/idiv for double division, because it causes
7655 ;; "division by zero" on the overflow and that's not what we expect
7656 ;; from truncate.  Because true (non truncating) double division is
7657 ;; never generated, we can't create this insn anyway.
7659 ;(define_insn ""
7660 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7661 ;       (truncate:SI
7662 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7663 ;                  (zero_extend:DI
7664 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7665 ;   (set (match_operand:SI 3 "register_operand" "=d")
7666 ;       (truncate:SI
7667 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7668 ;   (clobber (reg:CC FLAGS_REG))]
7669 ;  ""
7670 ;  "div{l}\t{%2, %0|%0, %2}"
7671 ;  [(set_attr "type" "idiv")])
7673 ;;- Logical AND instructions
7675 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7676 ;; Note that this excludes ah.
7678 (define_insn "*testdi_1_rex64"
7679   [(set (reg FLAGS_REG)
7680         (compare
7681           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7682                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7683           (const_int 0)))]
7684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7686   "@
7687    test{l}\t{%k1, %k0|%k0, %k1}
7688    test{l}\t{%k1, %k0|%k0, %k1}
7689    test{q}\t{%1, %0|%0, %1}
7690    test{q}\t{%1, %0|%0, %1}
7691    test{q}\t{%1, %0|%0, %1}"
7692   [(set_attr "type" "test")
7693    (set_attr "modrm" "0,1,0,1,1")
7694    (set_attr "mode" "SI,SI,DI,DI,DI")
7695    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7697 (define_insn "testsi_1"
7698   [(set (reg FLAGS_REG)
7699         (compare
7700           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7701                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7702           (const_int 0)))]
7703   "ix86_match_ccmode (insn, CCNOmode)
7704    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7705   "test{l}\t{%1, %0|%0, %1}"
7706   [(set_attr "type" "test")
7707    (set_attr "modrm" "0,1,1")
7708    (set_attr "mode" "SI")
7709    (set_attr "pent_pair" "uv,np,uv")])
7711 (define_expand "testsi_ccno_1"
7712   [(set (reg:CCNO FLAGS_REG)
7713         (compare:CCNO
7714           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7715                   (match_operand:SI 1 "nonmemory_operand" ""))
7716           (const_int 0)))]
7717   ""
7718   "")
7720 (define_insn "*testhi_1"
7721   [(set (reg FLAGS_REG)
7722         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7723                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7724                  (const_int 0)))]
7725   "ix86_match_ccmode (insn, CCNOmode)
7726    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7727   "test{w}\t{%1, %0|%0, %1}"
7728   [(set_attr "type" "test")
7729    (set_attr "modrm" "0,1,1")
7730    (set_attr "mode" "HI")
7731    (set_attr "pent_pair" "uv,np,uv")])
7733 (define_expand "testqi_ccz_1"
7734   [(set (reg:CCZ FLAGS_REG)
7735         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7736                              (match_operand:QI 1 "nonmemory_operand" ""))
7737                  (const_int 0)))]
7738   ""
7739   "")
7741 (define_insn "*testqi_1_maybe_si"
7742   [(set (reg FLAGS_REG)
7743         (compare
7744           (and:QI
7745             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7746             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7747           (const_int 0)))]
7748    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7749     && ix86_match_ccmode (insn,
7750                          GET_CODE (operands[1]) == CONST_INT
7751                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7753   if (which_alternative == 3)
7754     {
7755       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7756         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7757       return "test{l}\t{%1, %k0|%k0, %1}";
7758     }
7759   return "test{b}\t{%1, %0|%0, %1}";
7761   [(set_attr "type" "test")
7762    (set_attr "modrm" "0,1,1,1")
7763    (set_attr "mode" "QI,QI,QI,SI")
7764    (set_attr "pent_pair" "uv,np,uv,np")])
7766 (define_insn "*testqi_1"
7767   [(set (reg FLAGS_REG)
7768         (compare
7769           (and:QI
7770             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7771             (match_operand:QI 1 "general_operand" "n,n,qn"))
7772           (const_int 0)))]
7773   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7774    && ix86_match_ccmode (insn, CCNOmode)"
7775   "test{b}\t{%1, %0|%0, %1}"
7776   [(set_attr "type" "test")
7777    (set_attr "modrm" "0,1,1")
7778    (set_attr "mode" "QI")
7779    (set_attr "pent_pair" "uv,np,uv")])
7781 (define_expand "testqi_ext_ccno_0"
7782   [(set (reg:CCNO FLAGS_REG)
7783         (compare:CCNO
7784           (and:SI
7785             (zero_extract:SI
7786               (match_operand 0 "ext_register_operand" "")
7787               (const_int 8)
7788               (const_int 8))
7789             (match_operand 1 "const_int_operand" ""))
7790           (const_int 0)))]
7791   ""
7792   "")
7794 (define_insn "*testqi_ext_0"
7795   [(set (reg FLAGS_REG)
7796         (compare
7797           (and:SI
7798             (zero_extract:SI
7799               (match_operand 0 "ext_register_operand" "Q")
7800               (const_int 8)
7801               (const_int 8))
7802             (match_operand 1 "const_int_operand" "n"))
7803           (const_int 0)))]
7804   "ix86_match_ccmode (insn, CCNOmode)"
7805   "test{b}\t{%1, %h0|%h0, %1}"
7806   [(set_attr "type" "test")
7807    (set_attr "mode" "QI")
7808    (set_attr "length_immediate" "1")
7809    (set_attr "pent_pair" "np")])
7811 (define_insn "*testqi_ext_1"
7812   [(set (reg FLAGS_REG)
7813         (compare
7814           (and:SI
7815             (zero_extract:SI
7816               (match_operand 0 "ext_register_operand" "Q")
7817               (const_int 8)
7818               (const_int 8))
7819             (zero_extend:SI
7820               (match_operand:QI 1 "general_operand" "Qm")))
7821           (const_int 0)))]
7822   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7824   "test{b}\t{%1, %h0|%h0, %1}"
7825   [(set_attr "type" "test")
7826    (set_attr "mode" "QI")])
7828 (define_insn "*testqi_ext_1_rex64"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:SI
7832             (zero_extract:SI
7833               (match_operand 0 "ext_register_operand" "Q")
7834               (const_int 8)
7835               (const_int 8))
7836             (zero_extend:SI
7837               (match_operand:QI 1 "register_operand" "Q")))
7838           (const_int 0)))]
7839   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7840   "test{b}\t{%1, %h0|%h0, %1}"
7841   [(set_attr "type" "test")
7842    (set_attr "mode" "QI")])
7844 (define_insn "*testqi_ext_2"
7845   [(set (reg FLAGS_REG)
7846         (compare
7847           (and:SI
7848             (zero_extract:SI
7849               (match_operand 0 "ext_register_operand" "Q")
7850               (const_int 8)
7851               (const_int 8))
7852             (zero_extract:SI
7853               (match_operand 1 "ext_register_operand" "Q")
7854               (const_int 8)
7855               (const_int 8)))
7856           (const_int 0)))]
7857   "ix86_match_ccmode (insn, CCNOmode)"
7858   "test{b}\t{%h1, %h0|%h0, %h1}"
7859   [(set_attr "type" "test")
7860    (set_attr "mode" "QI")])
7862 ;; Combine likes to form bit extractions for some tests.  Humor it.
7863 (define_insn "*testqi_ext_3"
7864   [(set (reg FLAGS_REG)
7865         (compare (zero_extract:SI
7866                    (match_operand 0 "nonimmediate_operand" "rm")
7867                    (match_operand:SI 1 "const_int_operand" "")
7868                    (match_operand:SI 2 "const_int_operand" ""))
7869                  (const_int 0)))]
7870   "ix86_match_ccmode (insn, CCNOmode)
7871    && INTVAL (operands[1]) > 0
7872    && INTVAL (operands[2]) >= 0
7873    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7874    && (GET_MODE (operands[0]) == SImode
7875        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7876        || GET_MODE (operands[0]) == HImode
7877        || GET_MODE (operands[0]) == QImode)"
7878   "#")
7880 (define_insn "*testqi_ext_3_rex64"
7881   [(set (reg FLAGS_REG)
7882         (compare (zero_extract:DI
7883                    (match_operand 0 "nonimmediate_operand" "rm")
7884                    (match_operand:DI 1 "const_int_operand" "")
7885                    (match_operand:DI 2 "const_int_operand" ""))
7886                  (const_int 0)))]
7887   "TARGET_64BIT
7888    && ix86_match_ccmode (insn, CCNOmode)
7889    && INTVAL (operands[1]) > 0
7890    && INTVAL (operands[2]) >= 0
7891    /* Ensure that resulting mask is zero or sign extended operand.  */
7892    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7893        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7894            && INTVAL (operands[1]) > 32))
7895    && (GET_MODE (operands[0]) == SImode
7896        || GET_MODE (operands[0]) == DImode
7897        || GET_MODE (operands[0]) == HImode
7898        || GET_MODE (operands[0]) == QImode)"
7899   "#")
7901 (define_split
7902   [(set (match_operand 0 "flags_reg_operand" "")
7903         (match_operator 1 "compare_operator"
7904           [(zero_extract
7905              (match_operand 2 "nonimmediate_operand" "")
7906              (match_operand 3 "const_int_operand" "")
7907              (match_operand 4 "const_int_operand" ""))
7908            (const_int 0)]))]
7909   "ix86_match_ccmode (insn, CCNOmode)"
7910   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7912   rtx val = operands[2];
7913   HOST_WIDE_INT len = INTVAL (operands[3]);
7914   HOST_WIDE_INT pos = INTVAL (operands[4]);
7915   HOST_WIDE_INT mask;
7916   enum machine_mode mode, submode;
7918   mode = GET_MODE (val);
7919   if (GET_CODE (val) == MEM)
7920     {
7921       /* ??? Combine likes to put non-volatile mem extractions in QImode
7922          no matter the size of the test.  So find a mode that works.  */
7923       if (! MEM_VOLATILE_P (val))
7924         {
7925           mode = smallest_mode_for_size (pos + len, MODE_INT);
7926           val = adjust_address (val, mode, 0);
7927         }
7928     }
7929   else if (GET_CODE (val) == SUBREG
7930            && (submode = GET_MODE (SUBREG_REG (val)),
7931                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7932            && pos + len <= GET_MODE_BITSIZE (submode))
7933     {
7934       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7935       mode = submode;
7936       val = SUBREG_REG (val);
7937     }
7938   else if (mode == HImode && pos + len <= 8)
7939     {
7940       /* Small HImode tests can be converted to QImode.  */
7941       mode = QImode;
7942       val = gen_lowpart (QImode, val);
7943     }
7945   if (len == HOST_BITS_PER_WIDE_INT)
7946     mask = -1;
7947   else
7948     mask = ((HOST_WIDE_INT)1 << len) - 1;
7949   mask <<= pos;
7951   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7954 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7955 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7956 ;; this is relatively important trick.
7957 ;; Do the conversion only post-reload to avoid limiting of the register class
7958 ;; to QI regs.
7959 (define_split
7960   [(set (match_operand 0 "flags_reg_operand" "")
7961         (match_operator 1 "compare_operator"
7962           [(and (match_operand 2 "register_operand" "")
7963                 (match_operand 3 "const_int_operand" ""))
7964            (const_int 0)]))]
7965    "reload_completed
7966     && QI_REG_P (operands[2])
7967     && GET_MODE (operands[2]) != QImode
7968     && ((ix86_match_ccmode (insn, CCZmode)
7969          && !(INTVAL (operands[3]) & ~(255 << 8)))
7970         || (ix86_match_ccmode (insn, CCNOmode)
7971             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7972   [(set (match_dup 0)
7973         (match_op_dup 1
7974           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7975                    (match_dup 3))
7976            (const_int 0)]))]
7977   "operands[2] = gen_lowpart (SImode, operands[2]);
7978    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7980 (define_split
7981   [(set (match_operand 0 "flags_reg_operand" "")
7982         (match_operator 1 "compare_operator"
7983           [(and (match_operand 2 "nonimmediate_operand" "")
7984                 (match_operand 3 "const_int_operand" ""))
7985            (const_int 0)]))]
7986    "reload_completed
7987     && GET_MODE (operands[2]) != QImode
7988     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7989     && ((ix86_match_ccmode (insn, CCZmode)
7990          && !(INTVAL (operands[3]) & ~255))
7991         || (ix86_match_ccmode (insn, CCNOmode)
7992             && !(INTVAL (operands[3]) & ~127)))"
7993   [(set (match_dup 0)
7994         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7995                          (const_int 0)]))]
7996   "operands[2] = gen_lowpart (QImode, operands[2]);
7997    operands[3] = gen_lowpart (QImode, operands[3]);")
8000 ;; %%% This used to optimize known byte-wide and operations to memory,
8001 ;; and sometimes to QImode registers.  If this is considered useful,
8002 ;; it should be done with splitters.
8004 (define_expand "anddi3"
8005   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8006         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8007                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "TARGET_64BIT"
8010   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8012 (define_insn "*anddi_1_rex64"
8013   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8014         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8015                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8016    (clobber (reg:CC FLAGS_REG))]
8017   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8019   switch (get_attr_type (insn))
8020     {
8021     case TYPE_IMOVX:
8022       {
8023         enum machine_mode mode;
8025         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8026         if (INTVAL (operands[2]) == 0xff)
8027           mode = QImode;
8028         else
8029           {
8030             gcc_assert (INTVAL (operands[2]) == 0xffff);
8031             mode = HImode;
8032           }
8033         
8034         operands[1] = gen_lowpart (mode, operands[1]);
8035         if (mode == QImode)
8036           return "movz{bq|x}\t{%1,%0|%0, %1}";
8037         else
8038           return "movz{wq|x}\t{%1,%0|%0, %1}";
8039       }
8041     default:
8042       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8043       if (get_attr_mode (insn) == MODE_SI)
8044         return "and{l}\t{%k2, %k0|%k0, %k2}";
8045       else
8046         return "and{q}\t{%2, %0|%0, %2}";
8047     }
8049   [(set_attr "type" "alu,alu,alu,imovx")
8050    (set_attr "length_immediate" "*,*,*,0")
8051    (set_attr "mode" "SI,DI,DI,DI")])
8053 (define_insn "*anddi_2"
8054   [(set (reg FLAGS_REG)
8055         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8056                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8057                  (const_int 0)))
8058    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8059         (and:DI (match_dup 1) (match_dup 2)))]
8060   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8061    && ix86_binary_operator_ok (AND, DImode, operands)"
8062   "@
8063    and{l}\t{%k2, %k0|%k0, %k2}
8064    and{q}\t{%2, %0|%0, %2}
8065    and{q}\t{%2, %0|%0, %2}"
8066   [(set_attr "type" "alu")
8067    (set_attr "mode" "SI,DI,DI")])
8069 (define_expand "andsi3"
8070   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8071         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8072                 (match_operand:SI 2 "general_operand" "")))
8073    (clobber (reg:CC FLAGS_REG))]
8074   ""
8075   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8077 (define_insn "*andsi_1"
8078   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8079         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8080                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8081    (clobber (reg:CC FLAGS_REG))]
8082   "ix86_binary_operator_ok (AND, SImode, operands)"
8084   switch (get_attr_type (insn))
8085     {
8086     case TYPE_IMOVX:
8087       {
8088         enum machine_mode mode;
8090         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8091         if (INTVAL (operands[2]) == 0xff)
8092           mode = QImode;
8093         else
8094           {
8095             gcc_assert (INTVAL (operands[2]) == 0xffff);
8096             mode = HImode;
8097           }
8098         
8099         operands[1] = gen_lowpart (mode, operands[1]);
8100         if (mode == QImode)
8101           return "movz{bl|x}\t{%1,%0|%0, %1}";
8102         else
8103           return "movz{wl|x}\t{%1,%0|%0, %1}";
8104       }
8106     default:
8107       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8108       return "and{l}\t{%2, %0|%0, %2}";
8109     }
8111   [(set_attr "type" "alu,alu,imovx")
8112    (set_attr "length_immediate" "*,*,0")
8113    (set_attr "mode" "SI")])
8115 (define_split
8116   [(set (match_operand 0 "register_operand" "")
8117         (and (match_dup 0)
8118              (const_int -65536)))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8121   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8122   "operands[1] = gen_lowpart (HImode, operands[0]);")
8124 (define_split
8125   [(set (match_operand 0 "ext_register_operand" "")
8126         (and (match_dup 0)
8127              (const_int -256)))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8130   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8131   "operands[1] = gen_lowpart (QImode, operands[0]);")
8133 (define_split
8134   [(set (match_operand 0 "ext_register_operand" "")
8135         (and (match_dup 0)
8136              (const_int -65281)))
8137    (clobber (reg:CC FLAGS_REG))]
8138   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8139   [(parallel [(set (zero_extract:SI (match_dup 0)
8140                                     (const_int 8)
8141                                     (const_int 8))
8142                    (xor:SI 
8143                      (zero_extract:SI (match_dup 0)
8144                                       (const_int 8)
8145                                       (const_int 8))
8146                      (zero_extract:SI (match_dup 0)
8147                                       (const_int 8)
8148                                       (const_int 8))))
8149               (clobber (reg:CC FLAGS_REG))])]
8150   "operands[0] = gen_lowpart (SImode, operands[0]);")
8152 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8153 (define_insn "*andsi_1_zext"
8154   [(set (match_operand:DI 0 "register_operand" "=r")
8155         (zero_extend:DI
8156           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8157                   (match_operand:SI 2 "general_operand" "rim"))))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8160   "and{l}\t{%2, %k0|%k0, %2}"
8161   [(set_attr "type" "alu")
8162    (set_attr "mode" "SI")])
8164 (define_insn "*andsi_2"
8165   [(set (reg FLAGS_REG)
8166         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8167                          (match_operand:SI 2 "general_operand" "rim,ri"))
8168                  (const_int 0)))
8169    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8170         (and:SI (match_dup 1) (match_dup 2)))]
8171   "ix86_match_ccmode (insn, CCNOmode)
8172    && ix86_binary_operator_ok (AND, SImode, operands)"
8173   "and{l}\t{%2, %0|%0, %2}"
8174   [(set_attr "type" "alu")
8175    (set_attr "mode" "SI")])
8177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178 (define_insn "*andsi_2_zext"
8179   [(set (reg FLAGS_REG)
8180         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8181                          (match_operand:SI 2 "general_operand" "rim"))
8182                  (const_int 0)))
8183    (set (match_operand:DI 0 "register_operand" "=r")
8184         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8185   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8186    && ix86_binary_operator_ok (AND, SImode, operands)"
8187   "and{l}\t{%2, %k0|%k0, %2}"
8188   [(set_attr "type" "alu")
8189    (set_attr "mode" "SI")])
8191 (define_expand "andhi3"
8192   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8193         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8194                 (match_operand:HI 2 "general_operand" "")))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "TARGET_HIMODE_MATH"
8197   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8199 (define_insn "*andhi_1"
8200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8201         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8202                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8203    (clobber (reg:CC FLAGS_REG))]
8204   "ix86_binary_operator_ok (AND, HImode, operands)"
8206   switch (get_attr_type (insn))
8207     {
8208     case TYPE_IMOVX:
8209       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8210       gcc_assert (INTVAL (operands[2]) == 0xff);
8211       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8213     default:
8214       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8216       return "and{w}\t{%2, %0|%0, %2}";
8217     }
8219   [(set_attr "type" "alu,alu,imovx")
8220    (set_attr "length_immediate" "*,*,0")
8221    (set_attr "mode" "HI,HI,SI")])
8223 (define_insn "*andhi_2"
8224   [(set (reg FLAGS_REG)
8225         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8226                          (match_operand:HI 2 "general_operand" "rim,ri"))
8227                  (const_int 0)))
8228    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8229         (and:HI (match_dup 1) (match_dup 2)))]
8230   "ix86_match_ccmode (insn, CCNOmode)
8231    && ix86_binary_operator_ok (AND, HImode, operands)"
8232   "and{w}\t{%2, %0|%0, %2}"
8233   [(set_attr "type" "alu")
8234    (set_attr "mode" "HI")])
8236 (define_expand "andqi3"
8237   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8238         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8239                 (match_operand:QI 2 "general_operand" "")))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "TARGET_QIMODE_MATH"
8242   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8244 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8245 (define_insn "*andqi_1"
8246   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8247         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8248                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8249    (clobber (reg:CC FLAGS_REG))]
8250   "ix86_binary_operator_ok (AND, QImode, operands)"
8251   "@
8252    and{b}\t{%2, %0|%0, %2}
8253    and{b}\t{%2, %0|%0, %2}
8254    and{l}\t{%k2, %k0|%k0, %k2}"
8255   [(set_attr "type" "alu")
8256    (set_attr "mode" "QI,QI,SI")])
8258 (define_insn "*andqi_1_slp"
8259   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8260         (and:QI (match_dup 0)
8261                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8264    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8265   "and{b}\t{%1, %0|%0, %1}"
8266   [(set_attr "type" "alu1")
8267    (set_attr "mode" "QI")])
8269 (define_insn "*andqi_2_maybe_si"
8270   [(set (reg FLAGS_REG)
8271         (compare (and:QI
8272                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8273                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8274                  (const_int 0)))
8275    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8276         (and:QI (match_dup 1) (match_dup 2)))]
8277   "ix86_binary_operator_ok (AND, QImode, operands)
8278    && ix86_match_ccmode (insn,
8279                          GET_CODE (operands[2]) == CONST_INT
8280                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8282   if (which_alternative == 2)
8283     {
8284       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8285         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8286       return "and{l}\t{%2, %k0|%k0, %2}";
8287     }
8288   return "and{b}\t{%2, %0|%0, %2}";
8290   [(set_attr "type" "alu")
8291    (set_attr "mode" "QI,QI,SI")])
8293 (define_insn "*andqi_2"
8294   [(set (reg FLAGS_REG)
8295         (compare (and:QI
8296                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8297                    (match_operand:QI 2 "general_operand" "qim,qi"))
8298                  (const_int 0)))
8299    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8300         (and:QI (match_dup 1) (match_dup 2)))]
8301   "ix86_match_ccmode (insn, CCNOmode)
8302    && ix86_binary_operator_ok (AND, QImode, operands)"
8303   "and{b}\t{%2, %0|%0, %2}"
8304   [(set_attr "type" "alu")
8305    (set_attr "mode" "QI")])
8307 (define_insn "*andqi_2_slp"
8308   [(set (reg FLAGS_REG)
8309         (compare (and:QI
8310                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8311                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8312                  (const_int 0)))
8313    (set (strict_low_part (match_dup 0))
8314         (and:QI (match_dup 0) (match_dup 1)))]
8315   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8316    && ix86_match_ccmode (insn, CCNOmode)
8317    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8318   "and{b}\t{%1, %0|%0, %1}"
8319   [(set_attr "type" "alu1")
8320    (set_attr "mode" "QI")])
8322 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8323 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8324 ;; for a QImode operand, which of course failed.
8326 (define_insn "andqi_ext_0"
8327   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328                          (const_int 8)
8329                          (const_int 8))
8330         (and:SI 
8331           (zero_extract:SI
8332             (match_operand 1 "ext_register_operand" "0")
8333             (const_int 8)
8334             (const_int 8))
8335           (match_operand 2 "const_int_operand" "n")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   ""
8338   "and{b}\t{%2, %h0|%h0, %2}"
8339   [(set_attr "type" "alu")
8340    (set_attr "length_immediate" "1")
8341    (set_attr "mode" "QI")])
8343 ;; Generated by peephole translating test to and.  This shows up
8344 ;; often in fp comparisons.
8346 (define_insn "*andqi_ext_0_cc"
8347   [(set (reg FLAGS_REG)
8348         (compare
8349           (and:SI
8350             (zero_extract:SI
8351               (match_operand 1 "ext_register_operand" "0")
8352               (const_int 8)
8353               (const_int 8))
8354             (match_operand 2 "const_int_operand" "n"))
8355           (const_int 0)))
8356    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8357                          (const_int 8)
8358                          (const_int 8))
8359         (and:SI 
8360           (zero_extract:SI
8361             (match_dup 1)
8362             (const_int 8)
8363             (const_int 8))
8364           (match_dup 2)))]
8365   "ix86_match_ccmode (insn, CCNOmode)"
8366   "and{b}\t{%2, %h0|%h0, %2}"
8367   [(set_attr "type" "alu")
8368    (set_attr "length_immediate" "1")
8369    (set_attr "mode" "QI")])
8371 (define_insn "*andqi_ext_1"
8372   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8373                          (const_int 8)
8374                          (const_int 8))
8375         (and:SI 
8376           (zero_extract:SI
8377             (match_operand 1 "ext_register_operand" "0")
8378             (const_int 8)
8379             (const_int 8))
8380           (zero_extend:SI
8381             (match_operand:QI 2 "general_operand" "Qm"))))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "!TARGET_64BIT"
8384   "and{b}\t{%2, %h0|%h0, %2}"
8385   [(set_attr "type" "alu")
8386    (set_attr "length_immediate" "0")
8387    (set_attr "mode" "QI")])
8389 (define_insn "*andqi_ext_1_rex64"
8390   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8391                          (const_int 8)
8392                          (const_int 8))
8393         (and:SI 
8394           (zero_extract:SI
8395             (match_operand 1 "ext_register_operand" "0")
8396             (const_int 8)
8397             (const_int 8))
8398           (zero_extend:SI
8399             (match_operand 2 "ext_register_operand" "Q"))))
8400    (clobber (reg:CC FLAGS_REG))]
8401   "TARGET_64BIT"
8402   "and{b}\t{%2, %h0|%h0, %2}"
8403   [(set_attr "type" "alu")
8404    (set_attr "length_immediate" "0")
8405    (set_attr "mode" "QI")])
8407 (define_insn "*andqi_ext_2"
8408   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409                          (const_int 8)
8410                          (const_int 8))
8411         (and:SI
8412           (zero_extract:SI
8413             (match_operand 1 "ext_register_operand" "%0")
8414             (const_int 8)
8415             (const_int 8))
8416           (zero_extract:SI
8417             (match_operand 2 "ext_register_operand" "Q")
8418             (const_int 8)
8419             (const_int 8))))
8420    (clobber (reg:CC FLAGS_REG))]
8421   ""
8422   "and{b}\t{%h2, %h0|%h0, %h2}"
8423   [(set_attr "type" "alu")
8424    (set_attr "length_immediate" "0")
8425    (set_attr "mode" "QI")])
8427 ;; Convert wide AND instructions with immediate operand to shorter QImode
8428 ;; equivalents when possible.
8429 ;; Don't do the splitting with memory operands, since it introduces risk
8430 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8431 ;; for size, but that can (should?) be handled by generic code instead.
8432 (define_split
8433   [(set (match_operand 0 "register_operand" "")
8434         (and (match_operand 1 "register_operand" "")
8435              (match_operand 2 "const_int_operand" "")))
8436    (clobber (reg:CC FLAGS_REG))]
8437    "reload_completed
8438     && QI_REG_P (operands[0])
8439     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8440     && !(~INTVAL (operands[2]) & ~(255 << 8))
8441     && GET_MODE (operands[0]) != QImode"
8442   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8443                    (and:SI (zero_extract:SI (match_dup 1)
8444                                             (const_int 8) (const_int 8))
8445                            (match_dup 2)))
8446               (clobber (reg:CC FLAGS_REG))])]
8447   "operands[0] = gen_lowpart (SImode, operands[0]);
8448    operands[1] = gen_lowpart (SImode, operands[1]);
8449    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8451 ;; Since AND can be encoded with sign extended immediate, this is only
8452 ;; profitable when 7th bit is not set.
8453 (define_split
8454   [(set (match_operand 0 "register_operand" "")
8455         (and (match_operand 1 "general_operand" "")
8456              (match_operand 2 "const_int_operand" "")))
8457    (clobber (reg:CC FLAGS_REG))]
8458    "reload_completed
8459     && ANY_QI_REG_P (operands[0])
8460     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8461     && !(~INTVAL (operands[2]) & ~255)
8462     && !(INTVAL (operands[2]) & 128)
8463     && GET_MODE (operands[0]) != QImode"
8464   [(parallel [(set (strict_low_part (match_dup 0))
8465                    (and:QI (match_dup 1)
8466                            (match_dup 2)))
8467               (clobber (reg:CC FLAGS_REG))])]
8468   "operands[0] = gen_lowpart (QImode, operands[0]);
8469    operands[1] = gen_lowpart (QImode, operands[1]);
8470    operands[2] = gen_lowpart (QImode, operands[2]);")
8472 ;; Logical inclusive OR instructions
8474 ;; %%% This used to optimize known byte-wide and operations to memory.
8475 ;; If this is considered useful, it should be done with splitters.
8477 (define_expand "iordi3"
8478   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8479         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8480                 (match_operand:DI 2 "x86_64_general_operand" "")))
8481    (clobber (reg:CC FLAGS_REG))]
8482   "TARGET_64BIT"
8483   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8485 (define_insn "*iordi_1_rex64"
8486   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8487         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8488                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8489    (clobber (reg:CC FLAGS_REG))]
8490   "TARGET_64BIT
8491    && ix86_binary_operator_ok (IOR, DImode, operands)"
8492   "or{q}\t{%2, %0|%0, %2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "mode" "DI")])
8496 (define_insn "*iordi_2_rex64"
8497   [(set (reg FLAGS_REG)
8498         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8499                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8500                  (const_int 0)))
8501    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8502         (ior:DI (match_dup 1) (match_dup 2)))]
8503   "TARGET_64BIT
8504    && ix86_match_ccmode (insn, CCNOmode)
8505    && ix86_binary_operator_ok (IOR, DImode, operands)"
8506   "or{q}\t{%2, %0|%0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "mode" "DI")])
8510 (define_insn "*iordi_3_rex64"
8511   [(set (reg FLAGS_REG)
8512         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8513                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8514                  (const_int 0)))
8515    (clobber (match_scratch:DI 0 "=r"))]
8516   "TARGET_64BIT
8517    && ix86_match_ccmode (insn, CCNOmode)
8518    && ix86_binary_operator_ok (IOR, DImode, operands)"
8519   "or{q}\t{%2, %0|%0, %2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "mode" "DI")])
8524 (define_expand "iorsi3"
8525   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8526         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8527                 (match_operand:SI 2 "general_operand" "")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   ""
8530   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8532 (define_insn "*iorsi_1"
8533   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8534         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8535                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "ix86_binary_operator_ok (IOR, SImode, operands)"
8538   "or{l}\t{%2, %0|%0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "SI")])
8542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8543 (define_insn "*iorsi_1_zext"
8544   [(set (match_operand:DI 0 "register_operand" "=rm")
8545         (zero_extend:DI
8546           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8547                   (match_operand:SI 2 "general_operand" "rim"))))
8548    (clobber (reg:CC FLAGS_REG))]
8549   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8550   "or{l}\t{%2, %k0|%k0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "SI")])
8554 (define_insn "*iorsi_1_zext_imm"
8555   [(set (match_operand:DI 0 "register_operand" "=rm")
8556         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8557                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8558    (clobber (reg:CC FLAGS_REG))]
8559   "TARGET_64BIT"
8560   "or{l}\t{%2, %k0|%k0, %2}"
8561   [(set_attr "type" "alu")
8562    (set_attr "mode" "SI")])
8564 (define_insn "*iorsi_2"
8565   [(set (reg FLAGS_REG)
8566         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567                          (match_operand:SI 2 "general_operand" "rim,ri"))
8568                  (const_int 0)))
8569    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8570         (ior:SI (match_dup 1) (match_dup 2)))]
8571   "ix86_match_ccmode (insn, CCNOmode)
8572    && ix86_binary_operator_ok (IOR, SImode, operands)"
8573   "or{l}\t{%2, %0|%0, %2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "SI")])
8577 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8578 ;; ??? Special case for immediate operand is missing - it is tricky.
8579 (define_insn "*iorsi_2_zext"
8580   [(set (reg FLAGS_REG)
8581         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8582                          (match_operand:SI 2 "general_operand" "rim"))
8583                  (const_int 0)))
8584    (set (match_operand:DI 0 "register_operand" "=r")
8585         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8586   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8587    && ix86_binary_operator_ok (IOR, SImode, operands)"
8588   "or{l}\t{%2, %k0|%k0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "SI")])
8592 (define_insn "*iorsi_2_zext_imm"
8593   [(set (reg FLAGS_REG)
8594         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8595                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8596                  (const_int 0)))
8597    (set (match_operand:DI 0 "register_operand" "=r")
8598         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8599   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8600    && ix86_binary_operator_ok (IOR, SImode, operands)"
8601   "or{l}\t{%2, %k0|%k0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "SI")])
8605 (define_insn "*iorsi_3"
8606   [(set (reg FLAGS_REG)
8607         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8608                          (match_operand:SI 2 "general_operand" "rim"))
8609                  (const_int 0)))
8610    (clobber (match_scratch:SI 0 "=r"))]
8611   "ix86_match_ccmode (insn, CCNOmode)
8612    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8613   "or{l}\t{%2, %0|%0, %2}"
8614   [(set_attr "type" "alu")
8615    (set_attr "mode" "SI")])
8617 (define_expand "iorhi3"
8618   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8619         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8620                 (match_operand:HI 2 "general_operand" "")))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "TARGET_HIMODE_MATH"
8623   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8625 (define_insn "*iorhi_1"
8626   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8627         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8628                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8629    (clobber (reg:CC FLAGS_REG))]
8630   "ix86_binary_operator_ok (IOR, HImode, operands)"
8631   "or{w}\t{%2, %0|%0, %2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "HI")])
8635 (define_insn "*iorhi_2"
8636   [(set (reg FLAGS_REG)
8637         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8638                          (match_operand:HI 2 "general_operand" "rim,ri"))
8639                  (const_int 0)))
8640    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8641         (ior:HI (match_dup 1) (match_dup 2)))]
8642   "ix86_match_ccmode (insn, CCNOmode)
8643    && ix86_binary_operator_ok (IOR, HImode, operands)"
8644   "or{w}\t{%2, %0|%0, %2}"
8645   [(set_attr "type" "alu")
8646    (set_attr "mode" "HI")])
8648 (define_insn "*iorhi_3"
8649   [(set (reg FLAGS_REG)
8650         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8651                          (match_operand:HI 2 "general_operand" "rim"))
8652                  (const_int 0)))
8653    (clobber (match_scratch:HI 0 "=r"))]
8654   "ix86_match_ccmode (insn, CCNOmode)
8655    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8656   "or{w}\t{%2, %0|%0, %2}"
8657   [(set_attr "type" "alu")
8658    (set_attr "mode" "HI")])
8660 (define_expand "iorqi3"
8661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8662         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8663                 (match_operand:QI 2 "general_operand" "")))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "TARGET_QIMODE_MATH"
8666   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8668 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8669 (define_insn "*iorqi_1"
8670   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8671         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8672                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8673    (clobber (reg:CC FLAGS_REG))]
8674   "ix86_binary_operator_ok (IOR, QImode, operands)"
8675   "@
8676    or{b}\t{%2, %0|%0, %2}
8677    or{b}\t{%2, %0|%0, %2}
8678    or{l}\t{%k2, %k0|%k0, %k2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "QI,QI,SI")])
8682 (define_insn "*iorqi_1_slp"
8683   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8684         (ior:QI (match_dup 0)
8685                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8688    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8689   "or{b}\t{%1, %0|%0, %1}"
8690   [(set_attr "type" "alu1")
8691    (set_attr "mode" "QI")])
8693 (define_insn "*iorqi_2"
8694   [(set (reg FLAGS_REG)
8695         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8696                          (match_operand:QI 2 "general_operand" "qim,qi"))
8697                  (const_int 0)))
8698    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8699         (ior:QI (match_dup 1) (match_dup 2)))]
8700   "ix86_match_ccmode (insn, CCNOmode)
8701    && ix86_binary_operator_ok (IOR, QImode, operands)"
8702   "or{b}\t{%2, %0|%0, %2}"
8703   [(set_attr "type" "alu")
8704    (set_attr "mode" "QI")])
8706 (define_insn "*iorqi_2_slp"
8707   [(set (reg FLAGS_REG)
8708         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8709                          (match_operand:QI 1 "general_operand" "qim,qi"))
8710                  (const_int 0)))
8711    (set (strict_low_part (match_dup 0))
8712         (ior:QI (match_dup 0) (match_dup 1)))]
8713   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8714    && ix86_match_ccmode (insn, CCNOmode)
8715    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8716   "or{b}\t{%1, %0|%0, %1}"
8717   [(set_attr "type" "alu1")
8718    (set_attr "mode" "QI")])
8720 (define_insn "*iorqi_3"
8721   [(set (reg FLAGS_REG)
8722         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8723                          (match_operand:QI 2 "general_operand" "qim"))
8724                  (const_int 0)))
8725    (clobber (match_scratch:QI 0 "=q"))]
8726   "ix86_match_ccmode (insn, CCNOmode)
8727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8728   "or{b}\t{%2, %0|%0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "mode" "QI")])
8732 (define_insn "iorqi_ext_0"
8733   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8734                          (const_int 8)
8735                          (const_int 8))
8736         (ior:SI 
8737           (zero_extract:SI
8738             (match_operand 1 "ext_register_operand" "0")
8739             (const_int 8)
8740             (const_int 8))
8741           (match_operand 2 "const_int_operand" "n")))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8744   "or{b}\t{%2, %h0|%h0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "length_immediate" "1")
8747    (set_attr "mode" "QI")])
8749 (define_insn "*iorqi_ext_1"
8750   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751                          (const_int 8)
8752                          (const_int 8))
8753         (ior:SI 
8754           (zero_extract:SI
8755             (match_operand 1 "ext_register_operand" "0")
8756             (const_int 8)
8757             (const_int 8))
8758           (zero_extend:SI
8759             (match_operand:QI 2 "general_operand" "Qm"))))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "!TARGET_64BIT
8762    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8763   "or{b}\t{%2, %h0|%h0, %2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "length_immediate" "0")
8766    (set_attr "mode" "QI")])
8768 (define_insn "*iorqi_ext_1_rex64"
8769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8770                          (const_int 8)
8771                          (const_int 8))
8772         (ior:SI 
8773           (zero_extract:SI
8774             (match_operand 1 "ext_register_operand" "0")
8775             (const_int 8)
8776             (const_int 8))
8777           (zero_extend:SI
8778             (match_operand 2 "ext_register_operand" "Q"))))
8779    (clobber (reg:CC FLAGS_REG))]
8780   "TARGET_64BIT
8781    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782   "or{b}\t{%2, %h0|%h0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "length_immediate" "0")
8785    (set_attr "mode" "QI")])
8787 (define_insn "*iorqi_ext_2"
8788   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789                          (const_int 8)
8790                          (const_int 8))
8791         (ior:SI 
8792           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8793                            (const_int 8)
8794                            (const_int 8))
8795           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8796                            (const_int 8)
8797                            (const_int 8))))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8800   "ior{b}\t{%h2, %h0|%h0, %h2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "length_immediate" "0")
8803    (set_attr "mode" "QI")])
8805 (define_split
8806   [(set (match_operand 0 "register_operand" "")
8807         (ior (match_operand 1 "register_operand" "")
8808              (match_operand 2 "const_int_operand" "")))
8809    (clobber (reg:CC FLAGS_REG))]
8810    "reload_completed
8811     && QI_REG_P (operands[0])
8812     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8813     && !(INTVAL (operands[2]) & ~(255 << 8))
8814     && GET_MODE (operands[0]) != QImode"
8815   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8816                    (ior:SI (zero_extract:SI (match_dup 1)
8817                                             (const_int 8) (const_int 8))
8818                            (match_dup 2)))
8819               (clobber (reg:CC FLAGS_REG))])]
8820   "operands[0] = gen_lowpart (SImode, operands[0]);
8821    operands[1] = gen_lowpart (SImode, operands[1]);
8822    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8824 ;; Since OR can be encoded with sign extended immediate, this is only
8825 ;; profitable when 7th bit is set.
8826 (define_split
8827   [(set (match_operand 0 "register_operand" "")
8828         (ior (match_operand 1 "general_operand" "")
8829              (match_operand 2 "const_int_operand" "")))
8830    (clobber (reg:CC FLAGS_REG))]
8831    "reload_completed
8832     && ANY_QI_REG_P (operands[0])
8833     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8834     && !(INTVAL (operands[2]) & ~255)
8835     && (INTVAL (operands[2]) & 128)
8836     && GET_MODE (operands[0]) != QImode"
8837   [(parallel [(set (strict_low_part (match_dup 0))
8838                    (ior:QI (match_dup 1)
8839                            (match_dup 2)))
8840               (clobber (reg:CC FLAGS_REG))])]
8841   "operands[0] = gen_lowpart (QImode, operands[0]);
8842    operands[1] = gen_lowpart (QImode, operands[1]);
8843    operands[2] = gen_lowpart (QImode, operands[2]);")
8845 ;; Logical XOR instructions
8847 ;; %%% This used to optimize known byte-wide and operations to memory.
8848 ;; If this is considered useful, it should be done with splitters.
8850 (define_expand "xordi3"
8851   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8852         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8853                 (match_operand:DI 2 "x86_64_general_operand" "")))
8854    (clobber (reg:CC FLAGS_REG))]
8855   "TARGET_64BIT"
8856   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8858 (define_insn "*xordi_1_rex64"
8859   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8860         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8861                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8862    (clobber (reg:CC FLAGS_REG))]
8863   "TARGET_64BIT
8864    && ix86_binary_operator_ok (XOR, DImode, operands)"
8865   "@
8866    xor{q}\t{%2, %0|%0, %2}
8867    xor{q}\t{%2, %0|%0, %2}"
8868   [(set_attr "type" "alu")
8869    (set_attr "mode" "DI,DI")])
8871 (define_insn "*xordi_2_rex64"
8872   [(set (reg FLAGS_REG)
8873         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8874                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8875                  (const_int 0)))
8876    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8877         (xor:DI (match_dup 1) (match_dup 2)))]
8878   "TARGET_64BIT
8879    && ix86_match_ccmode (insn, CCNOmode)
8880    && ix86_binary_operator_ok (XOR, DImode, operands)"
8881   "@
8882    xor{q}\t{%2, %0|%0, %2}
8883    xor{q}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "DI,DI")])
8887 (define_insn "*xordi_3_rex64"
8888   [(set (reg FLAGS_REG)
8889         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891                  (const_int 0)))
8892    (clobber (match_scratch:DI 0 "=r"))]
8893   "TARGET_64BIT
8894    && ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (XOR, DImode, operands)"
8896   "xor{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8900 (define_expand "xorsi3"
8901   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8902         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8903                 (match_operand:SI 2 "general_operand" "")))
8904    (clobber (reg:CC FLAGS_REG))]
8905   ""
8906   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8908 (define_insn "*xorsi_1"
8909   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8910         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8911                 (match_operand:SI 2 "general_operand" "ri,rm")))
8912    (clobber (reg:CC FLAGS_REG))]
8913   "ix86_binary_operator_ok (XOR, SImode, operands)"
8914   "xor{l}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "SI")])
8918 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8919 ;; Add speccase for immediates
8920 (define_insn "*xorsi_1_zext"
8921   [(set (match_operand:DI 0 "register_operand" "=r")
8922         (zero_extend:DI
8923           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924                   (match_operand:SI 2 "general_operand" "rim"))))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8927   "xor{l}\t{%2, %k0|%k0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "SI")])
8931 (define_insn "*xorsi_1_zext_imm"
8932   [(set (match_operand:DI 0 "register_operand" "=r")
8933         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8937   "xor{l}\t{%2, %k0|%k0, %2}"
8938   [(set_attr "type" "alu")
8939    (set_attr "mode" "SI")])
8941 (define_insn "*xorsi_2"
8942   [(set (reg FLAGS_REG)
8943         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944                          (match_operand:SI 2 "general_operand" "rim,ri"))
8945                  (const_int 0)))
8946    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947         (xor:SI (match_dup 1) (match_dup 2)))]
8948   "ix86_match_ccmode (insn, CCNOmode)
8949    && ix86_binary_operator_ok (XOR, SImode, operands)"
8950   "xor{l}\t{%2, %0|%0, %2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "SI")])
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*xorsi_2_zext"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959                          (match_operand:SI 2 "general_operand" "rim"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "register_operand" "=r")
8962         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8963   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (XOR, SImode, operands)"
8965   "xor{l}\t{%2, %k0|%k0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "SI")])
8969 (define_insn "*xorsi_2_zext_imm"
8970   [(set (reg FLAGS_REG)
8971         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "register_operand" "=r")
8975         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977    && ix86_binary_operator_ok (XOR, SImode, operands)"
8978   "xor{l}\t{%2, %k0|%k0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "SI")])
8982 (define_insn "*xorsi_3"
8983   [(set (reg FLAGS_REG)
8984         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985                          (match_operand:SI 2 "general_operand" "rim"))
8986                  (const_int 0)))
8987    (clobber (match_scratch:SI 0 "=r"))]
8988   "ix86_match_ccmode (insn, CCNOmode)
8989    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8990   "xor{l}\t{%2, %0|%0, %2}"
8991   [(set_attr "type" "alu")
8992    (set_attr "mode" "SI")])
8994 (define_expand "xorhi3"
8995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997                 (match_operand:HI 2 "general_operand" "")))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "TARGET_HIMODE_MATH"
9000   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9002 (define_insn "*xorhi_1"
9003   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "ix86_binary_operator_ok (XOR, HImode, operands)"
9008   "xor{w}\t{%2, %0|%0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "HI")])
9012 (define_insn "*xorhi_2"
9013   [(set (reg FLAGS_REG)
9014         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015                          (match_operand:HI 2 "general_operand" "rim,ri"))
9016                  (const_int 0)))
9017    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018         (xor:HI (match_dup 1) (match_dup 2)))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && ix86_binary_operator_ok (XOR, HImode, operands)"
9021   "xor{w}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "HI")])
9025 (define_insn "*xorhi_3"
9026   [(set (reg FLAGS_REG)
9027         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028                          (match_operand:HI 2 "general_operand" "rim"))
9029                  (const_int 0)))
9030    (clobber (match_scratch:HI 0 "=r"))]
9031   "ix86_match_ccmode (insn, CCNOmode)
9032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9033   "xor{w}\t{%2, %0|%0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "HI")])
9037 (define_expand "xorqi3"
9038   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040                 (match_operand:QI 2 "general_operand" "")))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "TARGET_QIMODE_MATH"
9043   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9045 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9046 (define_insn "*xorqi_1"
9047   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050    (clobber (reg:CC FLAGS_REG))]
9051   "ix86_binary_operator_ok (XOR, QImode, operands)"
9052   "@
9053    xor{b}\t{%2, %0|%0, %2}
9054    xor{b}\t{%2, %0|%0, %2}
9055    xor{l}\t{%k2, %k0|%k0, %k2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "QI,QI,SI")])
9059 (define_insn "*xorqi_1_slp"
9060   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9061         (xor:QI (match_dup 0)
9062                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9066   "xor{b}\t{%1, %0|%0, %1}"
9067   [(set_attr "type" "alu1")
9068    (set_attr "mode" "QI")])
9070 (define_insn "xorqi_ext_0"
9071   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9072                          (const_int 8)
9073                          (const_int 8))
9074         (xor:SI 
9075           (zero_extract:SI
9076             (match_operand 1 "ext_register_operand" "0")
9077             (const_int 8)
9078             (const_int 8))
9079           (match_operand 2 "const_int_operand" "n")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9082   "xor{b}\t{%2, %h0|%h0, %2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "length_immediate" "1")
9085    (set_attr "mode" "QI")])
9087 (define_insn "*xorqi_ext_1"
9088   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089                          (const_int 8)
9090                          (const_int 8))
9091         (xor:SI 
9092           (zero_extract:SI
9093             (match_operand 1 "ext_register_operand" "0")
9094             (const_int 8)
9095             (const_int 8))
9096           (zero_extend:SI
9097             (match_operand:QI 2 "general_operand" "Qm"))))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "!TARGET_64BIT
9100    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9101   "xor{b}\t{%2, %h0|%h0, %2}"
9102   [(set_attr "type" "alu")
9103    (set_attr "length_immediate" "0")
9104    (set_attr "mode" "QI")])
9106 (define_insn "*xorqi_ext_1_rex64"
9107   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9108                          (const_int 8)
9109                          (const_int 8))
9110         (xor:SI 
9111           (zero_extract:SI
9112             (match_operand 1 "ext_register_operand" "0")
9113             (const_int 8)
9114             (const_int 8))
9115           (zero_extend:SI
9116             (match_operand 2 "ext_register_operand" "Q"))))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "TARGET_64BIT
9119    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120   "xor{b}\t{%2, %h0|%h0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "length_immediate" "0")
9123    (set_attr "mode" "QI")])
9125 (define_insn "*xorqi_ext_2"
9126   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127                          (const_int 8)
9128                          (const_int 8))
9129         (xor:SI 
9130           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9131                            (const_int 8)
9132                            (const_int 8))
9133           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9134                            (const_int 8)
9135                            (const_int 8))))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138   "xor{b}\t{%h2, %h0|%h0, %h2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "length_immediate" "0")
9141    (set_attr "mode" "QI")])
9143 (define_insn "*xorqi_cc_1"
9144   [(set (reg FLAGS_REG)
9145         (compare
9146           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9147                   (match_operand:QI 2 "general_operand" "qim,qi"))
9148           (const_int 0)))
9149    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9150         (xor:QI (match_dup 1) (match_dup 2)))]
9151   "ix86_match_ccmode (insn, CCNOmode)
9152    && ix86_binary_operator_ok (XOR, QImode, operands)"
9153   "xor{b}\t{%2, %0|%0, %2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "mode" "QI")])
9157 (define_insn "*xorqi_2_slp"
9158   [(set (reg FLAGS_REG)
9159         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9160                          (match_operand:QI 1 "general_operand" "qim,qi"))
9161                  (const_int 0)))
9162    (set (strict_low_part (match_dup 0))
9163         (xor:QI (match_dup 0) (match_dup 1)))]
9164   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9165    && ix86_match_ccmode (insn, CCNOmode)
9166    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9167   "xor{b}\t{%1, %0|%0, %1}"
9168   [(set_attr "type" "alu1")
9169    (set_attr "mode" "QI")])
9171 (define_insn "*xorqi_cc_2"
9172   [(set (reg FLAGS_REG)
9173         (compare
9174           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9175                   (match_operand:QI 2 "general_operand" "qim"))
9176           (const_int 0)))
9177    (clobber (match_scratch:QI 0 "=q"))]
9178   "ix86_match_ccmode (insn, CCNOmode)
9179    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9180   "xor{b}\t{%2, %0|%0, %2}"
9181   [(set_attr "type" "alu")
9182    (set_attr "mode" "QI")])
9184 (define_insn "*xorqi_cc_ext_1"
9185   [(set (reg FLAGS_REG)
9186         (compare
9187           (xor:SI
9188             (zero_extract:SI
9189               (match_operand 1 "ext_register_operand" "0")
9190               (const_int 8)
9191               (const_int 8))
9192             (match_operand:QI 2 "general_operand" "qmn"))
9193           (const_int 0)))
9194    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9195                          (const_int 8)
9196                          (const_int 8))
9197         (xor:SI 
9198           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9199           (match_dup 2)))]
9200   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9201   "xor{b}\t{%2, %h0|%h0, %2}"
9202   [(set_attr "type" "alu")
9203    (set_attr "mode" "QI")])
9205 (define_insn "*xorqi_cc_ext_1_rex64"
9206   [(set (reg FLAGS_REG)
9207         (compare
9208           (xor:SI
9209             (zero_extract:SI
9210               (match_operand 1 "ext_register_operand" "0")
9211               (const_int 8)
9212               (const_int 8))
9213             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9214           (const_int 0)))
9215    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216                          (const_int 8)
9217                          (const_int 8))
9218         (xor:SI 
9219           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9220           (match_dup 2)))]
9221   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9222   "xor{b}\t{%2, %h0|%h0, %2}"
9223   [(set_attr "type" "alu")
9224    (set_attr "mode" "QI")])
9226 (define_expand "xorqi_cc_ext_1"
9227   [(parallel [
9228      (set (reg:CCNO FLAGS_REG)
9229           (compare:CCNO
9230             (xor:SI
9231               (zero_extract:SI
9232                 (match_operand 1 "ext_register_operand" "")
9233                 (const_int 8)
9234                 (const_int 8))
9235               (match_operand:QI 2 "general_operand" ""))
9236             (const_int 0)))
9237      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9238                            (const_int 8)
9239                            (const_int 8))
9240           (xor:SI 
9241             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9242             (match_dup 2)))])]
9243   ""
9244   "")
9246 (define_split
9247   [(set (match_operand 0 "register_operand" "")
9248         (xor (match_operand 1 "register_operand" "")
9249              (match_operand 2 "const_int_operand" "")))
9250    (clobber (reg:CC FLAGS_REG))]
9251    "reload_completed
9252     && QI_REG_P (operands[0])
9253     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9254     && !(INTVAL (operands[2]) & ~(255 << 8))
9255     && GET_MODE (operands[0]) != QImode"
9256   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9257                    (xor:SI (zero_extract:SI (match_dup 1)
9258                                             (const_int 8) (const_int 8))
9259                            (match_dup 2)))
9260               (clobber (reg:CC FLAGS_REG))])]
9261   "operands[0] = gen_lowpart (SImode, operands[0]);
9262    operands[1] = gen_lowpart (SImode, operands[1]);
9263    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9265 ;; Since XOR can be encoded with sign extended immediate, this is only
9266 ;; profitable when 7th bit is set.
9267 (define_split
9268   [(set (match_operand 0 "register_operand" "")
9269         (xor (match_operand 1 "general_operand" "")
9270              (match_operand 2 "const_int_operand" "")))
9271    (clobber (reg:CC FLAGS_REG))]
9272    "reload_completed
9273     && ANY_QI_REG_P (operands[0])
9274     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9275     && !(INTVAL (operands[2]) & ~255)
9276     && (INTVAL (operands[2]) & 128)
9277     && GET_MODE (operands[0]) != QImode"
9278   [(parallel [(set (strict_low_part (match_dup 0))
9279                    (xor:QI (match_dup 1)
9280                            (match_dup 2)))
9281               (clobber (reg:CC FLAGS_REG))])]
9282   "operands[0] = gen_lowpart (QImode, operands[0]);
9283    operands[1] = gen_lowpart (QImode, operands[1]);
9284    operands[2] = gen_lowpart (QImode, operands[2]);")
9286 ;; Negation instructions
9288 (define_expand "negti2"
9289   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9290                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9291               (clobber (reg:CC FLAGS_REG))])]
9292   "TARGET_64BIT"
9293   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9295 (define_insn "*negti2_1"
9296   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9297         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9298    (clobber (reg:CC FLAGS_REG))]
9299   "TARGET_64BIT
9300    && ix86_unary_operator_ok (NEG, TImode, operands)"
9301   "#")
9303 (define_split
9304   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9305         (neg:TI (match_operand:TI 1 "general_operand" "")))
9306    (clobber (reg:CC FLAGS_REG))]
9307   "TARGET_64BIT && reload_completed"
9308   [(parallel
9309     [(set (reg:CCZ FLAGS_REG)
9310           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9311      (set (match_dup 0) (neg:DI (match_dup 2)))])
9312    (parallel
9313     [(set (match_dup 1)
9314           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9315                             (match_dup 3))
9316                    (const_int 0)))
9317      (clobber (reg:CC FLAGS_REG))])
9318    (parallel
9319     [(set (match_dup 1)
9320           (neg:DI (match_dup 1)))
9321      (clobber (reg:CC FLAGS_REG))])]
9322   "split_ti (operands+1, 1, operands+2, operands+3);
9323    split_ti (operands+0, 1, operands+0, operands+1);")
9325 (define_expand "negdi2"
9326   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9327                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9328               (clobber (reg:CC FLAGS_REG))])]
9329   ""
9330   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9332 (define_insn "*negdi2_1"
9333   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9334         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "!TARGET_64BIT
9337    && ix86_unary_operator_ok (NEG, DImode, operands)"
9338   "#")
9340 (define_split
9341   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9342         (neg:DI (match_operand:DI 1 "general_operand" "")))
9343    (clobber (reg:CC FLAGS_REG))]
9344   "!TARGET_64BIT && reload_completed"
9345   [(parallel
9346     [(set (reg:CCZ FLAGS_REG)
9347           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9348      (set (match_dup 0) (neg:SI (match_dup 2)))])
9349    (parallel
9350     [(set (match_dup 1)
9351           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9352                             (match_dup 3))
9353                    (const_int 0)))
9354      (clobber (reg:CC FLAGS_REG))])
9355    (parallel
9356     [(set (match_dup 1)
9357           (neg:SI (match_dup 1)))
9358      (clobber (reg:CC FLAGS_REG))])]
9359   "split_di (operands+1, 1, operands+2, operands+3);
9360    split_di (operands+0, 1, operands+0, operands+1);")
9362 (define_insn "*negdi2_1_rex64"
9363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9364         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9365    (clobber (reg:CC FLAGS_REG))]
9366   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9367   "neg{q}\t%0"
9368   [(set_attr "type" "negnot")
9369    (set_attr "mode" "DI")])
9371 ;; The problem with neg is that it does not perform (compare x 0),
9372 ;; it really performs (compare 0 x), which leaves us with the zero
9373 ;; flag being the only useful item.
9375 (define_insn "*negdi2_cmpz_rex64"
9376   [(set (reg:CCZ FLAGS_REG)
9377         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9378                      (const_int 0)))
9379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9380         (neg:DI (match_dup 1)))]
9381   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9382   "neg{q}\t%0"
9383   [(set_attr "type" "negnot")
9384    (set_attr "mode" "DI")])
9387 (define_expand "negsi2"
9388   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9389                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9390               (clobber (reg:CC FLAGS_REG))])]
9391   ""
9392   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9394 (define_insn "*negsi2_1"
9395   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9396         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "ix86_unary_operator_ok (NEG, SImode, operands)"
9399   "neg{l}\t%0"
9400   [(set_attr "type" "negnot")
9401    (set_attr "mode" "SI")])
9403 ;; Combine is quite creative about this pattern.
9404 (define_insn "*negsi2_1_zext"
9405   [(set (match_operand:DI 0 "register_operand" "=r")
9406         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9407                                         (const_int 32)))
9408                      (const_int 32)))
9409    (clobber (reg:CC FLAGS_REG))]
9410   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9411   "neg{l}\t%k0"
9412   [(set_attr "type" "negnot")
9413    (set_attr "mode" "SI")])
9415 ;; The problem with neg is that it does not perform (compare x 0),
9416 ;; it really performs (compare 0 x), which leaves us with the zero
9417 ;; flag being the only useful item.
9419 (define_insn "*negsi2_cmpz"
9420   [(set (reg:CCZ FLAGS_REG)
9421         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9422                      (const_int 0)))
9423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9424         (neg:SI (match_dup 1)))]
9425   "ix86_unary_operator_ok (NEG, SImode, operands)"
9426   "neg{l}\t%0"
9427   [(set_attr "type" "negnot")
9428    (set_attr "mode" "SI")])
9430 (define_insn "*negsi2_cmpz_zext"
9431   [(set (reg:CCZ FLAGS_REG)
9432         (compare:CCZ (lshiftrt:DI
9433                        (neg:DI (ashift:DI
9434                                  (match_operand:DI 1 "register_operand" "0")
9435                                  (const_int 32)))
9436                        (const_int 32))
9437                      (const_int 0)))
9438    (set (match_operand:DI 0 "register_operand" "=r")
9439         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9440                                         (const_int 32)))
9441                      (const_int 32)))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443   "neg{l}\t%k0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "SI")])
9447 (define_expand "neghi2"
9448   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9449                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9450               (clobber (reg:CC FLAGS_REG))])]
9451   "TARGET_HIMODE_MATH"
9452   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9454 (define_insn "*neghi2_1"
9455   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9456         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "ix86_unary_operator_ok (NEG, HImode, operands)"
9459   "neg{w}\t%0"
9460   [(set_attr "type" "negnot")
9461    (set_attr "mode" "HI")])
9463 (define_insn "*neghi2_cmpz"
9464   [(set (reg:CCZ FLAGS_REG)
9465         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9466                      (const_int 0)))
9467    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9468         (neg:HI (match_dup 1)))]
9469   "ix86_unary_operator_ok (NEG, HImode, operands)"
9470   "neg{w}\t%0"
9471   [(set_attr "type" "negnot")
9472    (set_attr "mode" "HI")])
9474 (define_expand "negqi2"
9475   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9476                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9477               (clobber (reg:CC FLAGS_REG))])]
9478   "TARGET_QIMODE_MATH"
9479   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9481 (define_insn "*negqi2_1"
9482   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9483         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "ix86_unary_operator_ok (NEG, QImode, operands)"
9486   "neg{b}\t%0"
9487   [(set_attr "type" "negnot")
9488    (set_attr "mode" "QI")])
9490 (define_insn "*negqi2_cmpz"
9491   [(set (reg:CCZ FLAGS_REG)
9492         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9493                      (const_int 0)))
9494    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9495         (neg:QI (match_dup 1)))]
9496   "ix86_unary_operator_ok (NEG, QImode, operands)"
9497   "neg{b}\t%0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "QI")])
9501 ;; Changing of sign for FP values is doable using integer unit too.
9503 (define_expand "negsf2"
9504   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9505         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9506   "TARGET_80387 || TARGET_SSE_MATH"
9507   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9509 (define_expand "abssf2"
9510   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9511         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9512   "TARGET_80387 || TARGET_SSE_MATH"
9513   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9515 (define_insn "*absnegsf2_mixed"
9516   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9517         (match_operator:SF 3 "absneg_operator"
9518           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9519    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9520    (clobber (reg:CC FLAGS_REG))]
9521   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9522    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9523   "#")
9525 (define_insn "*absnegsf2_sse"
9526   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9527         (match_operator:SF 3 "absneg_operator"
9528           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9529    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9530    (clobber (reg:CC FLAGS_REG))]
9531   "TARGET_SSE_MATH
9532    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9533   "#")
9535 (define_insn "*absnegsf2_i387"
9536   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9537         (match_operator:SF 3 "absneg_operator"
9538           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9539    (use (match_operand 2 "" ""))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "TARGET_80387 && !TARGET_SSE_MATH
9542    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9543   "#")
9545 (define_expand "copysignsf3"
9546   [(match_operand:SF 0 "register_operand" "")
9547    (match_operand:SF 1 "nonmemory_operand" "")
9548    (match_operand:SF 2 "register_operand" "")]
9549   "TARGET_SSE_MATH"
9551   ix86_expand_copysign (operands);
9552   DONE;
9555 (define_insn_and_split "copysignsf3_const"
9556   [(set (match_operand:SF 0 "register_operand"          "=x")
9557         (unspec:SF
9558           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9559            (match_operand:SF 2 "register_operand"       "0")
9560            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9561           UNSPEC_COPYSIGN))]
9562   "TARGET_SSE_MATH"
9563   "#"
9564   "&& reload_completed"
9565   [(const_int 0)]
9567   ix86_split_copysign_const (operands);
9568   DONE;
9571 (define_insn "copysignsf3_var"
9572   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9573         (unspec:SF
9574           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9575            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9576            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9577            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9578           UNSPEC_COPYSIGN))
9579    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9580   "TARGET_SSE_MATH"
9581   "#")
9583 (define_split
9584   [(set (match_operand:SF 0 "register_operand" "")
9585         (unspec:SF
9586           [(match_operand:SF 2 "register_operand" "")
9587            (match_operand:SF 3 "register_operand" "")
9588            (match_operand:V4SF 4 "" "")
9589            (match_operand:V4SF 5 "" "")]
9590           UNSPEC_COPYSIGN))
9591    (clobber (match_scratch:V4SF 1 ""))]
9592   "TARGET_SSE_MATH && reload_completed"
9593   [(const_int 0)]
9595   ix86_split_copysign_var (operands);
9596   DONE;
9599 (define_expand "negdf2"
9600   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9601         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9602   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9603   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9605 (define_expand "absdf2"
9606   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9607         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9608   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9609   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9611 (define_insn "*absnegdf2_mixed"
9612   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9613         (match_operator:DF 3 "absneg_operator"
9614           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9615    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9618    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9619   "#")
9621 (define_insn "*absnegdf2_sse"
9622   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9623         (match_operator:DF 3 "absneg_operator"
9624           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9625    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "TARGET_SSE2 && TARGET_SSE_MATH
9628    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9629   "#")
9631 (define_insn "*absnegdf2_i387"
9632   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9633         (match_operator:DF 3 "absneg_operator"
9634           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9635    (use (match_operand 2 "" ""))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9638    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9639   "#")
9641 (define_expand "copysigndf3"
9642   [(match_operand:DF 0 "register_operand" "")
9643    (match_operand:DF 1 "nonmemory_operand" "")
9644    (match_operand:DF 2 "register_operand" "")]
9645   "TARGET_SSE2 && TARGET_SSE_MATH"
9647   ix86_expand_copysign (operands);
9648   DONE;
9651 (define_insn_and_split "copysigndf3_const"
9652   [(set (match_operand:DF 0 "register_operand"          "=x")
9653         (unspec:DF
9654           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9655            (match_operand:DF 2 "register_operand"       "0")
9656            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9657           UNSPEC_COPYSIGN))]
9658   "TARGET_SSE2 && TARGET_SSE_MATH"
9659   "#"
9660   "&& reload_completed"
9661   [(const_int 0)]
9663   ix86_split_copysign_const (operands);
9664   DONE;
9667 (define_insn "copysigndf3_var"
9668   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9669         (unspec:DF
9670           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9671            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9672            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9673            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9674           UNSPEC_COPYSIGN))
9675    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9676   "TARGET_SSE2 && TARGET_SSE_MATH"
9677   "#")
9679 (define_split
9680   [(set (match_operand:DF 0 "register_operand" "")
9681         (unspec:DF
9682           [(match_operand:DF 2 "register_operand" "")
9683            (match_operand:DF 3 "register_operand" "")
9684            (match_operand:V2DF 4 "" "")
9685            (match_operand:V2DF 5 "" "")]
9686           UNSPEC_COPYSIGN))
9687    (clobber (match_scratch:V2DF 1 ""))]
9688   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9689   [(const_int 0)]
9691   ix86_split_copysign_var (operands);
9692   DONE;
9695 (define_expand "negxf2"
9696   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9697         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9698   "TARGET_80387"
9699   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9701 (define_expand "absxf2"
9702   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9703         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9704   "TARGET_80387"
9705   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9707 (define_insn "*absnegxf2_i387"
9708   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9709         (match_operator:XF 3 "absneg_operator"
9710           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9711    (use (match_operand 2 "" ""))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "TARGET_80387
9714    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9715   "#")
9717 ;; Splitters for fp abs and neg.
9719 (define_split
9720   [(set (match_operand 0 "fp_register_operand" "")
9721         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "reload_completed"
9725   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9727 (define_split
9728   [(set (match_operand 0 "register_operand" "")
9729         (match_operator 3 "absneg_operator"
9730           [(match_operand 1 "register_operand" "")]))
9731    (use (match_operand 2 "nonimmediate_operand" ""))
9732    (clobber (reg:CC FLAGS_REG))]
9733   "reload_completed && SSE_REG_P (operands[0])"
9734   [(set (match_dup 0) (match_dup 3))]
9736   enum machine_mode mode = GET_MODE (operands[0]);
9737   enum machine_mode vmode = GET_MODE (operands[2]);
9738   rtx tmp;
9739   
9740   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9741   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9742   if (operands_match_p (operands[0], operands[2]))
9743     {
9744       tmp = operands[1];
9745       operands[1] = operands[2];
9746       operands[2] = tmp;
9747     }
9748   if (GET_CODE (operands[3]) == ABS)
9749     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9750   else
9751     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9752   operands[3] = tmp;
9755 (define_split
9756   [(set (match_operand:SF 0 "register_operand" "")
9757         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9758    (use (match_operand:V4SF 2 "" ""))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "reload_completed"
9761   [(parallel [(set (match_dup 0) (match_dup 1))
9762               (clobber (reg:CC FLAGS_REG))])]
9764   rtx tmp;
9765   operands[0] = gen_lowpart (SImode, operands[0]);
9766   if (GET_CODE (operands[1]) == ABS)
9767     {
9768       tmp = gen_int_mode (0x7fffffff, SImode);
9769       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9770     }
9771   else
9772     {
9773       tmp = gen_int_mode (0x80000000, SImode);
9774       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9775     }
9776   operands[1] = tmp;
9779 (define_split
9780   [(set (match_operand:DF 0 "register_operand" "")
9781         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9782    (use (match_operand 2 "" ""))
9783    (clobber (reg:CC FLAGS_REG))]
9784   "reload_completed"
9785   [(parallel [(set (match_dup 0) (match_dup 1))
9786               (clobber (reg:CC FLAGS_REG))])]
9788   rtx tmp;
9789   if (TARGET_64BIT)
9790     {
9791       tmp = gen_lowpart (DImode, operands[0]);
9792       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9793       operands[0] = tmp;
9795       if (GET_CODE (operands[1]) == ABS)
9796         tmp = const0_rtx;
9797       else
9798         tmp = gen_rtx_NOT (DImode, tmp);
9799     }
9800   else
9801     {
9802       operands[0] = gen_highpart (SImode, operands[0]);
9803       if (GET_CODE (operands[1]) == ABS)
9804         {
9805           tmp = gen_int_mode (0x7fffffff, SImode);
9806           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9807         }
9808       else
9809         {
9810           tmp = gen_int_mode (0x80000000, SImode);
9811           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9812         }
9813     }
9814   operands[1] = tmp;
9817 (define_split
9818   [(set (match_operand:XF 0 "register_operand" "")
9819         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9820    (use (match_operand 2 "" ""))
9821    (clobber (reg:CC FLAGS_REG))]
9822   "reload_completed"
9823   [(parallel [(set (match_dup 0) (match_dup 1))
9824               (clobber (reg:CC FLAGS_REG))])]
9826   rtx tmp;
9827   operands[0] = gen_rtx_REG (SImode,
9828                              true_regnum (operands[0])
9829                              + (TARGET_64BIT ? 1 : 2));
9830   if (GET_CODE (operands[1]) == ABS)
9831     {
9832       tmp = GEN_INT (0x7fff);
9833       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9834     }
9835   else
9836     {
9837       tmp = GEN_INT (0x8000);
9838       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9839     }
9840   operands[1] = tmp;
9843 (define_split
9844   [(set (match_operand 0 "memory_operand" "")
9845         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9846    (use (match_operand 2 "" ""))
9847    (clobber (reg:CC FLAGS_REG))]
9848   "reload_completed"
9849   [(parallel [(set (match_dup 0) (match_dup 1))
9850               (clobber (reg:CC FLAGS_REG))])]
9852   enum machine_mode mode = GET_MODE (operands[0]);
9853   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9854   rtx tmp;
9856   operands[0] = adjust_address (operands[0], QImode, size - 1);
9857   if (GET_CODE (operands[1]) == ABS)
9858     {
9859       tmp = gen_int_mode (0x7f, QImode);
9860       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9861     }
9862   else
9863     {
9864       tmp = gen_int_mode (0x80, QImode);
9865       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9866     }
9867   operands[1] = tmp;
9870 ;; Conditionalize these after reload. If they match before reload, we 
9871 ;; lose the clobber and ability to use integer instructions.
9873 (define_insn "*negsf2_1"
9874   [(set (match_operand:SF 0 "register_operand" "=f")
9875         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9876   "TARGET_80387 && reload_completed"
9877   "fchs"
9878   [(set_attr "type" "fsgn")
9879    (set_attr "mode" "SF")])
9881 (define_insn "*negdf2_1"
9882   [(set (match_operand:DF 0 "register_operand" "=f")
9883         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9884   "TARGET_80387 && reload_completed"
9885   "fchs"
9886   [(set_attr "type" "fsgn")
9887    (set_attr "mode" "DF")])
9889 (define_insn "*negxf2_1"
9890   [(set (match_operand:XF 0 "register_operand" "=f")
9891         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9892   "TARGET_80387 && reload_completed"
9893   "fchs"
9894   [(set_attr "type" "fsgn")
9895    (set_attr "mode" "XF")])
9897 (define_insn "*abssf2_1"
9898   [(set (match_operand:SF 0 "register_operand" "=f")
9899         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9900   "TARGET_80387 && reload_completed"
9901   "fabs"
9902   [(set_attr "type" "fsgn")
9903    (set_attr "mode" "SF")])
9905 (define_insn "*absdf2_1"
9906   [(set (match_operand:DF 0 "register_operand" "=f")
9907         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9908   "TARGET_80387 && reload_completed"
9909   "fabs"
9910   [(set_attr "type" "fsgn")
9911    (set_attr "mode" "DF")])
9913 (define_insn "*absxf2_1"
9914   [(set (match_operand:XF 0 "register_operand" "=f")
9915         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9916   "TARGET_80387 && reload_completed"
9917   "fabs"
9918   [(set_attr "type" "fsgn")
9919    (set_attr "mode" "DF")])
9921 (define_insn "*negextendsfdf2"
9922   [(set (match_operand:DF 0 "register_operand" "=f")
9923         (neg:DF (float_extend:DF
9924                   (match_operand:SF 1 "register_operand" "0"))))]
9925   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9926   "fchs"
9927   [(set_attr "type" "fsgn")
9928    (set_attr "mode" "DF")])
9930 (define_insn "*negextenddfxf2"
9931   [(set (match_operand:XF 0 "register_operand" "=f")
9932         (neg:XF (float_extend:XF
9933                   (match_operand:DF 1 "register_operand" "0"))))]
9934   "TARGET_80387"
9935   "fchs"
9936   [(set_attr "type" "fsgn")
9937    (set_attr "mode" "XF")])
9939 (define_insn "*negextendsfxf2"
9940   [(set (match_operand:XF 0 "register_operand" "=f")
9941         (neg:XF (float_extend:XF
9942                   (match_operand:SF 1 "register_operand" "0"))))]
9943   "TARGET_80387"
9944   "fchs"
9945   [(set_attr "type" "fsgn")
9946    (set_attr "mode" "XF")])
9948 (define_insn "*absextendsfdf2"
9949   [(set (match_operand:DF 0 "register_operand" "=f")
9950         (abs:DF (float_extend:DF
9951                   (match_operand:SF 1 "register_operand" "0"))))]
9952   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9953   "fabs"
9954   [(set_attr "type" "fsgn")
9955    (set_attr "mode" "DF")])
9957 (define_insn "*absextenddfxf2"
9958   [(set (match_operand:XF 0 "register_operand" "=f")
9959         (abs:XF (float_extend:XF
9960           (match_operand:DF 1 "register_operand" "0"))))]
9961   "TARGET_80387"
9962   "fabs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "XF")])
9966 (define_insn "*absextendsfxf2"
9967   [(set (match_operand:XF 0 "register_operand" "=f")
9968         (abs:XF (float_extend:XF
9969           (match_operand:SF 1 "register_operand" "0"))))]
9970   "TARGET_80387"
9971   "fabs"
9972   [(set_attr "type" "fsgn")
9973    (set_attr "mode" "XF")])
9975 ;; One complement instructions
9977 (define_expand "one_cmpldi2"
9978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9979         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9980   "TARGET_64BIT"
9981   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9983 (define_insn "*one_cmpldi2_1_rex64"
9984   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9985         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9986   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9987   "not{q}\t%0"
9988   [(set_attr "type" "negnot")
9989    (set_attr "mode" "DI")])
9991 (define_insn "*one_cmpldi2_2_rex64"
9992   [(set (reg FLAGS_REG)
9993         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9994                  (const_int 0)))
9995    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9996         (not:DI (match_dup 1)))]
9997   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9998    && ix86_unary_operator_ok (NOT, DImode, operands)"
9999   "#"
10000   [(set_attr "type" "alu1")
10001    (set_attr "mode" "DI")])
10003 (define_split
10004   [(set (match_operand 0 "flags_reg_operand" "")
10005         (match_operator 2 "compare_operator"
10006           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10007            (const_int 0)]))
10008    (set (match_operand:DI 1 "nonimmediate_operand" "")
10009         (not:DI (match_dup 3)))]
10010   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10011   [(parallel [(set (match_dup 0)
10012                    (match_op_dup 2
10013                      [(xor:DI (match_dup 3) (const_int -1))
10014                       (const_int 0)]))
10015               (set (match_dup 1)
10016                    (xor:DI (match_dup 3) (const_int -1)))])]
10017   "")
10019 (define_expand "one_cmplsi2"
10020   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10021         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10022   ""
10023   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10025 (define_insn "*one_cmplsi2_1"
10026   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10027         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10028   "ix86_unary_operator_ok (NOT, SImode, operands)"
10029   "not{l}\t%0"
10030   [(set_attr "type" "negnot")
10031    (set_attr "mode" "SI")])
10033 ;; ??? Currently never generated - xor is used instead.
10034 (define_insn "*one_cmplsi2_1_zext"
10035   [(set (match_operand:DI 0 "register_operand" "=r")
10036         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10037   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10038   "not{l}\t%k0"
10039   [(set_attr "type" "negnot")
10040    (set_attr "mode" "SI")])
10042 (define_insn "*one_cmplsi2_2"
10043   [(set (reg FLAGS_REG)
10044         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10045                  (const_int 0)))
10046    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10047         (not:SI (match_dup 1)))]
10048   "ix86_match_ccmode (insn, CCNOmode)
10049    && ix86_unary_operator_ok (NOT, SImode, operands)"
10050   "#"
10051   [(set_attr "type" "alu1")
10052    (set_attr "mode" "SI")])
10054 (define_split
10055   [(set (match_operand 0 "flags_reg_operand" "")
10056         (match_operator 2 "compare_operator"
10057           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10058            (const_int 0)]))
10059    (set (match_operand:SI 1 "nonimmediate_operand" "")
10060         (not:SI (match_dup 3)))]
10061   "ix86_match_ccmode (insn, CCNOmode)"
10062   [(parallel [(set (match_dup 0)
10063                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10064                                     (const_int 0)]))
10065               (set (match_dup 1)
10066                    (xor:SI (match_dup 3) (const_int -1)))])]
10067   "")
10069 ;; ??? Currently never generated - xor is used instead.
10070 (define_insn "*one_cmplsi2_2_zext"
10071   [(set (reg FLAGS_REG)
10072         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10073                  (const_int 0)))
10074    (set (match_operand:DI 0 "register_operand" "=r")
10075         (zero_extend:DI (not:SI (match_dup 1))))]
10076   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10077    && ix86_unary_operator_ok (NOT, SImode, operands)"
10078   "#"
10079   [(set_attr "type" "alu1")
10080    (set_attr "mode" "SI")])
10082 (define_split
10083   [(set (match_operand 0 "flags_reg_operand" "")
10084         (match_operator 2 "compare_operator"
10085           [(not:SI (match_operand:SI 3 "register_operand" ""))
10086            (const_int 0)]))
10087    (set (match_operand:DI 1 "register_operand" "")
10088         (zero_extend:DI (not:SI (match_dup 3))))]
10089   "ix86_match_ccmode (insn, CCNOmode)"
10090   [(parallel [(set (match_dup 0)
10091                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10092                                     (const_int 0)]))
10093               (set (match_dup 1)
10094                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10095   "")
10097 (define_expand "one_cmplhi2"
10098   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10099         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10100   "TARGET_HIMODE_MATH"
10101   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10103 (define_insn "*one_cmplhi2_1"
10104   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10105         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10106   "ix86_unary_operator_ok (NOT, HImode, operands)"
10107   "not{w}\t%0"
10108   [(set_attr "type" "negnot")
10109    (set_attr "mode" "HI")])
10111 (define_insn "*one_cmplhi2_2"
10112   [(set (reg FLAGS_REG)
10113         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10114                  (const_int 0)))
10115    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10116         (not:HI (match_dup 1)))]
10117   "ix86_match_ccmode (insn, CCNOmode)
10118    && ix86_unary_operator_ok (NEG, HImode, operands)"
10119   "#"
10120   [(set_attr "type" "alu1")
10121    (set_attr "mode" "HI")])
10123 (define_split
10124   [(set (match_operand 0 "flags_reg_operand" "")
10125         (match_operator 2 "compare_operator"
10126           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10127            (const_int 0)]))
10128    (set (match_operand:HI 1 "nonimmediate_operand" "")
10129         (not:HI (match_dup 3)))]
10130   "ix86_match_ccmode (insn, CCNOmode)"
10131   [(parallel [(set (match_dup 0)
10132                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10133                                     (const_int 0)]))
10134               (set (match_dup 1)
10135                    (xor:HI (match_dup 3) (const_int -1)))])]
10136   "")
10138 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10139 (define_expand "one_cmplqi2"
10140   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10141         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10142   "TARGET_QIMODE_MATH"
10143   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10145 (define_insn "*one_cmplqi2_1"
10146   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10147         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10148   "ix86_unary_operator_ok (NOT, QImode, operands)"
10149   "@
10150    not{b}\t%0
10151    not{l}\t%k0"
10152   [(set_attr "type" "negnot")
10153    (set_attr "mode" "QI,SI")])
10155 (define_insn "*one_cmplqi2_2"
10156   [(set (reg FLAGS_REG)
10157         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10158                  (const_int 0)))
10159    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10160         (not:QI (match_dup 1)))]
10161   "ix86_match_ccmode (insn, CCNOmode)
10162    && ix86_unary_operator_ok (NOT, QImode, operands)"
10163   "#"
10164   [(set_attr "type" "alu1")
10165    (set_attr "mode" "QI")])
10167 (define_split
10168   [(set (match_operand 0 "flags_reg_operand" "")
10169         (match_operator 2 "compare_operator"
10170           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10171            (const_int 0)]))
10172    (set (match_operand:QI 1 "nonimmediate_operand" "")
10173         (not:QI (match_dup 3)))]
10174   "ix86_match_ccmode (insn, CCNOmode)"
10175   [(parallel [(set (match_dup 0)
10176                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10177                                     (const_int 0)]))
10178               (set (match_dup 1)
10179                    (xor:QI (match_dup 3) (const_int -1)))])]
10180   "")
10182 ;; Arithmetic shift instructions
10184 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10185 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10186 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10187 ;; from the assembler input.
10189 ;; This instruction shifts the target reg/mem as usual, but instead of
10190 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10191 ;; is a left shift double, bits are taken from the high order bits of
10192 ;; reg, else if the insn is a shift right double, bits are taken from the
10193 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10194 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10196 ;; Since sh[lr]d does not change the `reg' operand, that is done
10197 ;; separately, making all shifts emit pairs of shift double and normal
10198 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10199 ;; support a 63 bit shift, each shift where the count is in a reg expands
10200 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10202 ;; If the shift count is a constant, we need never emit more than one
10203 ;; shift pair, instead using moves and sign extension for counts greater
10204 ;; than 31.
10206 (define_expand "ashlti3"
10207   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10208                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10209                               (match_operand:QI 2 "nonmemory_operand" "")))
10210               (clobber (reg:CC FLAGS_REG))])]
10211   "TARGET_64BIT"
10213   if (! immediate_operand (operands[2], QImode))
10214     {
10215       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10216       DONE;
10217     }
10218   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10219   DONE;
10222 (define_insn "ashlti3_1"
10223   [(set (match_operand:TI 0 "register_operand" "=r")
10224         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10225                    (match_operand:QI 2 "register_operand" "c")))
10226    (clobber (match_scratch:DI 3 "=&r"))
10227    (clobber (reg:CC FLAGS_REG))]
10228   "TARGET_64BIT"
10229   "#"
10230   [(set_attr "type" "multi")])
10232 (define_insn "*ashlti3_2"
10233   [(set (match_operand:TI 0 "register_operand" "=r")
10234         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10235                    (match_operand:QI 2 "immediate_operand" "O")))
10236    (clobber (reg:CC FLAGS_REG))]
10237   "TARGET_64BIT"
10238   "#"
10239   [(set_attr "type" "multi")])
10241 (define_split
10242   [(set (match_operand:TI 0 "register_operand" "")
10243         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10244                    (match_operand:QI 2 "register_operand" "")))
10245    (clobber (match_scratch:DI 3 ""))
10246    (clobber (reg:CC FLAGS_REG))]
10247   "TARGET_64BIT && reload_completed"
10248   [(const_int 0)]
10249   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10251 (define_split
10252   [(set (match_operand:TI 0 "register_operand" "")
10253         (ashift:TI (match_operand:TI 1 "register_operand" "")
10254                    (match_operand:QI 2 "immediate_operand" "")))
10255    (clobber (reg:CC FLAGS_REG))]
10256   "TARGET_64BIT && reload_completed"
10257   [(const_int 0)]
10258   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10260 (define_insn "x86_64_shld"
10261   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10262         (ior:DI (ashift:DI (match_dup 0)
10263                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10264                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10265                   (minus:QI (const_int 64) (match_dup 2)))))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "TARGET_64BIT"
10268   "@
10269    shld{q}\t{%2, %1, %0|%0, %1, %2}
10270    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10271   [(set_attr "type" "ishift")
10272    (set_attr "prefix_0f" "1")
10273    (set_attr "mode" "DI")
10274    (set_attr "athlon_decode" "vector")])
10276 (define_expand "x86_64_shift_adj"
10277   [(set (reg:CCZ FLAGS_REG)
10278         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10279                              (const_int 64))
10280                      (const_int 0)))
10281    (set (match_operand:DI 0 "register_operand" "")
10282         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10283                          (match_operand:DI 1 "register_operand" "")
10284                          (match_dup 0)))
10285    (set (match_dup 1)
10286         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10287                          (match_operand:DI 3 "register_operand" "r")
10288                          (match_dup 1)))]
10289   "TARGET_64BIT"
10290   "")
10292 (define_expand "ashldi3"
10293   [(set (match_operand:DI 0 "shiftdi_operand" "")
10294         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10295                    (match_operand:QI 2 "nonmemory_operand" "")))]
10296   ""
10297   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10299 (define_insn "*ashldi3_1_rex64"
10300   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10301         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10302                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10303    (clobber (reg:CC FLAGS_REG))]
10304   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10306   switch (get_attr_type (insn))
10307     {
10308     case TYPE_ALU:
10309       gcc_assert (operands[2] == const1_rtx);
10310       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10311       return "add{q}\t{%0, %0|%0, %0}";
10313     case TYPE_LEA:
10314       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10315       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10316       operands[1] = gen_rtx_MULT (DImode, operands[1],
10317                                   GEN_INT (1 << INTVAL (operands[2])));
10318       return "lea{q}\t{%a1, %0|%0, %a1}";
10320     default:
10321       if (REG_P (operands[2]))
10322         return "sal{q}\t{%b2, %0|%0, %b2}";
10323       else if (operands[2] == const1_rtx
10324                && (TARGET_SHIFT1 || optimize_size))
10325         return "sal{q}\t%0";
10326       else
10327         return "sal{q}\t{%2, %0|%0, %2}";
10328     }
10330   [(set (attr "type")
10331      (cond [(eq_attr "alternative" "1")
10332               (const_string "lea")
10333             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10334                           (const_int 0))
10335                       (match_operand 0 "register_operand" ""))
10336                  (match_operand 2 "const1_operand" ""))
10337               (const_string "alu")
10338            ]
10339            (const_string "ishift")))
10340    (set_attr "mode" "DI")])
10342 ;; Convert lea to the lea pattern to avoid flags dependency.
10343 (define_split
10344   [(set (match_operand:DI 0 "register_operand" "")
10345         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10346                    (match_operand:QI 2 "immediate_operand" "")))
10347    (clobber (reg:CC FLAGS_REG))]
10348   "TARGET_64BIT && reload_completed
10349    && true_regnum (operands[0]) != true_regnum (operands[1])"
10350   [(set (match_dup 0)
10351         (mult:DI (match_dup 1)
10352                  (match_dup 2)))]
10353   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10355 ;; This pattern can't accept a variable shift count, since shifts by
10356 ;; zero don't affect the flags.  We assume that shifts by constant
10357 ;; zero are optimized away.
10358 (define_insn "*ashldi3_cmp_rex64"
10359   [(set (reg FLAGS_REG)
10360         (compare
10361           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10362                      (match_operand:QI 2 "immediate_operand" "e"))
10363           (const_int 0)))
10364    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10365         (ashift:DI (match_dup 1) (match_dup 2)))]
10366   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10367    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10369   switch (get_attr_type (insn))
10370     {
10371     case TYPE_ALU:
10372       gcc_assert (operands[2] == const1_rtx);
10373       return "add{q}\t{%0, %0|%0, %0}";
10375     default:
10376       if (REG_P (operands[2]))
10377         return "sal{q}\t{%b2, %0|%0, %b2}";
10378       else if (operands[2] == const1_rtx
10379                && (TARGET_SHIFT1 || optimize_size))
10380         return "sal{q}\t%0";
10381       else
10382         return "sal{q}\t{%2, %0|%0, %2}";
10383     }
10385   [(set (attr "type")
10386      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10387                           (const_int 0))
10388                       (match_operand 0 "register_operand" ""))
10389                  (match_operand 2 "const1_operand" ""))
10390               (const_string "alu")
10391            ]
10392            (const_string "ishift")))
10393    (set_attr "mode" "DI")])
10395 (define_insn "*ashldi3_cconly_rex64"
10396   [(set (reg FLAGS_REG)
10397         (compare
10398           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10399                      (match_operand:QI 2 "immediate_operand" "e"))
10400           (const_int 0)))
10401    (clobber (match_scratch:DI 0 "=r"))]
10402   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10403    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10405   switch (get_attr_type (insn))
10406     {
10407     case TYPE_ALU:
10408       gcc_assert (operands[2] == const1_rtx);
10409       return "add{q}\t{%0, %0|%0, %0}";
10411     default:
10412       if (REG_P (operands[2]))
10413         return "sal{q}\t{%b2, %0|%0, %b2}";
10414       else if (operands[2] == const1_rtx
10415                && (TARGET_SHIFT1 || optimize_size))
10416         return "sal{q}\t%0";
10417       else
10418         return "sal{q}\t{%2, %0|%0, %2}";
10419     }
10421   [(set (attr "type")
10422      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10423                           (const_int 0))
10424                       (match_operand 0 "register_operand" ""))
10425                  (match_operand 2 "const1_operand" ""))
10426               (const_string "alu")
10427            ]
10428            (const_string "ishift")))
10429    (set_attr "mode" "DI")])
10431 (define_insn "*ashldi3_1"
10432   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10433         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10434                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "!TARGET_64BIT"
10437   "#"
10438   [(set_attr "type" "multi")])
10440 ;; By default we don't ask for a scratch register, because when DImode
10441 ;; values are manipulated, registers are already at a premium.  But if
10442 ;; we have one handy, we won't turn it away.
10443 (define_peephole2
10444   [(match_scratch:SI 3 "r")
10445    (parallel [(set (match_operand:DI 0 "register_operand" "")
10446                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10447                               (match_operand:QI 2 "nonmemory_operand" "")))
10448               (clobber (reg:CC FLAGS_REG))])
10449    (match_dup 3)]
10450   "!TARGET_64BIT && TARGET_CMOVE"
10451   [(const_int 0)]
10452   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10454 (define_split
10455   [(set (match_operand:DI 0 "register_operand" "")
10456         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10457                    (match_operand:QI 2 "nonmemory_operand" "")))
10458    (clobber (reg:CC FLAGS_REG))]
10459   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10460                      ? flow2_completed : reload_completed)"
10461   [(const_int 0)]
10462   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10464 (define_insn "x86_shld_1"
10465   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10466         (ior:SI (ashift:SI (match_dup 0)
10467                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10468                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10469                   (minus:QI (const_int 32) (match_dup 2)))))
10470    (clobber (reg:CC FLAGS_REG))]
10471   ""
10472   "@
10473    shld{l}\t{%2, %1, %0|%0, %1, %2}
10474    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10475   [(set_attr "type" "ishift")
10476    (set_attr "prefix_0f" "1")
10477    (set_attr "mode" "SI")
10478    (set_attr "pent_pair" "np")
10479    (set_attr "athlon_decode" "vector")])
10481 (define_expand "x86_shift_adj_1"
10482   [(set (reg:CCZ FLAGS_REG)
10483         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10484                              (const_int 32))
10485                      (const_int 0)))
10486    (set (match_operand:SI 0 "register_operand" "")
10487         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488                          (match_operand:SI 1 "register_operand" "")
10489                          (match_dup 0)))
10490    (set (match_dup 1)
10491         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10492                          (match_operand:SI 3 "register_operand" "r")
10493                          (match_dup 1)))]
10494   "TARGET_CMOVE"
10495   "")
10497 (define_expand "x86_shift_adj_2"
10498   [(use (match_operand:SI 0 "register_operand" ""))
10499    (use (match_operand:SI 1 "register_operand" ""))
10500    (use (match_operand:QI 2 "register_operand" ""))]
10501   ""
10503   rtx label = gen_label_rtx ();
10504   rtx tmp;
10506   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10508   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10509   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10510   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10511                               gen_rtx_LABEL_REF (VOIDmode, label),
10512                               pc_rtx);
10513   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10514   JUMP_LABEL (tmp) = label;
10516   emit_move_insn (operands[0], operands[1]);
10517   ix86_expand_clear (operands[1]);
10519   emit_label (label);
10520   LABEL_NUSES (label) = 1;
10522   DONE;
10525 (define_expand "ashlsi3"
10526   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10527         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10528                    (match_operand:QI 2 "nonmemory_operand" "")))
10529    (clobber (reg:CC FLAGS_REG))]
10530   ""
10531   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10533 (define_insn "*ashlsi3_1"
10534   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10535         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10536                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10537    (clobber (reg:CC FLAGS_REG))]
10538   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10540   switch (get_attr_type (insn))
10541     {
10542     case TYPE_ALU:
10543       gcc_assert (operands[2] == const1_rtx);
10544       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10545       return "add{l}\t{%0, %0|%0, %0}";
10547     case TYPE_LEA:
10548       return "#";
10550     default:
10551       if (REG_P (operands[2]))
10552         return "sal{l}\t{%b2, %0|%0, %b2}";
10553       else if (operands[2] == const1_rtx
10554                && (TARGET_SHIFT1 || optimize_size))
10555         return "sal{l}\t%0";
10556       else
10557         return "sal{l}\t{%2, %0|%0, %2}";
10558     }
10560   [(set (attr "type")
10561      (cond [(eq_attr "alternative" "1")
10562               (const_string "lea")
10563             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10564                           (const_int 0))
10565                       (match_operand 0 "register_operand" ""))
10566                  (match_operand 2 "const1_operand" ""))
10567               (const_string "alu")
10568            ]
10569            (const_string "ishift")))
10570    (set_attr "mode" "SI")])
10572 ;; Convert lea to the lea pattern to avoid flags dependency.
10573 (define_split
10574   [(set (match_operand 0 "register_operand" "")
10575         (ashift (match_operand 1 "index_register_operand" "")
10576                 (match_operand:QI 2 "const_int_operand" "")))
10577    (clobber (reg:CC FLAGS_REG))]
10578   "reload_completed
10579    && true_regnum (operands[0]) != true_regnum (operands[1])
10580    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10581   [(const_int 0)]
10583   rtx pat;
10584   enum machine_mode mode = GET_MODE (operands[0]);
10586   if (GET_MODE_SIZE (mode) < 4)
10587     operands[0] = gen_lowpart (SImode, operands[0]);
10588   if (mode != Pmode)
10589     operands[1] = gen_lowpart (Pmode, operands[1]);
10590   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10592   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10593   if (Pmode != SImode)
10594     pat = gen_rtx_SUBREG (SImode, pat, 0);
10595   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10596   DONE;
10599 ;; Rare case of shifting RSP is handled by generating move and shift
10600 (define_split
10601   [(set (match_operand 0 "register_operand" "")
10602         (ashift (match_operand 1 "register_operand" "")
10603                 (match_operand:QI 2 "const_int_operand" "")))
10604    (clobber (reg:CC FLAGS_REG))]
10605   "reload_completed
10606    && true_regnum (operands[0]) != true_regnum (operands[1])"
10607   [(const_int 0)]
10609   rtx pat, clob;
10610   emit_move_insn (operands[1], operands[0]);
10611   pat = gen_rtx_SET (VOIDmode, operands[0],
10612                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10613                                      operands[0], operands[2]));
10614   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10615   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10616   DONE;
10619 (define_insn "*ashlsi3_1_zext"
10620   [(set (match_operand:DI 0 "register_operand" "=r,r")
10621         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10622                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10626   switch (get_attr_type (insn))
10627     {
10628     case TYPE_ALU:
10629       gcc_assert (operands[2] == const1_rtx);
10630       return "add{l}\t{%k0, %k0|%k0, %k0}";
10632     case TYPE_LEA:
10633       return "#";
10635     default:
10636       if (REG_P (operands[2]))
10637         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10638       else if (operands[2] == const1_rtx
10639                && (TARGET_SHIFT1 || optimize_size))
10640         return "sal{l}\t%k0";
10641       else
10642         return "sal{l}\t{%2, %k0|%k0, %2}";
10643     }
10645   [(set (attr "type")
10646      (cond [(eq_attr "alternative" "1")
10647               (const_string "lea")
10648             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10649                      (const_int 0))
10650                  (match_operand 2 "const1_operand" ""))
10651               (const_string "alu")
10652            ]
10653            (const_string "ishift")))
10654    (set_attr "mode" "SI")])
10656 ;; Convert lea to the lea pattern to avoid flags dependency.
10657 (define_split
10658   [(set (match_operand:DI 0 "register_operand" "")
10659         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10660                                 (match_operand:QI 2 "const_int_operand" ""))))
10661    (clobber (reg:CC FLAGS_REG))]
10662   "TARGET_64BIT && reload_completed
10663    && true_regnum (operands[0]) != true_regnum (operands[1])"
10664   [(set (match_dup 0) (zero_extend:DI
10665                         (subreg:SI (mult:SI (match_dup 1)
10666                                             (match_dup 2)) 0)))]
10668   operands[1] = gen_lowpart (Pmode, operands[1]);
10669   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10672 ;; This pattern can't accept a variable shift count, since shifts by
10673 ;; zero don't affect the flags.  We assume that shifts by constant
10674 ;; zero are optimized away.
10675 (define_insn "*ashlsi3_cmp"
10676   [(set (reg FLAGS_REG)
10677         (compare
10678           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10679                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10680           (const_int 0)))
10681    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10682         (ashift:SI (match_dup 1) (match_dup 2)))]
10683   "ix86_match_ccmode (insn, CCGOCmode)
10684    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10686   switch (get_attr_type (insn))
10687     {
10688     case TYPE_ALU:
10689       gcc_assert (operands[2] == const1_rtx);
10690       return "add{l}\t{%0, %0|%0, %0}";
10692     default:
10693       if (REG_P (operands[2]))
10694         return "sal{l}\t{%b2, %0|%0, %b2}";
10695       else if (operands[2] == const1_rtx
10696                && (TARGET_SHIFT1 || optimize_size))
10697         return "sal{l}\t%0";
10698       else
10699         return "sal{l}\t{%2, %0|%0, %2}";
10700     }
10702   [(set (attr "type")
10703      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10704                           (const_int 0))
10705                       (match_operand 0 "register_operand" ""))
10706                  (match_operand 2 "const1_operand" ""))
10707               (const_string "alu")
10708            ]
10709            (const_string "ishift")))
10710    (set_attr "mode" "SI")])
10712 (define_insn "*ashlsi3_cconly"
10713   [(set (reg FLAGS_REG)
10714         (compare
10715           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10716                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10717           (const_int 0)))
10718    (clobber (match_scratch:SI 0 "=r"))]
10719   "ix86_match_ccmode (insn, CCGOCmode)
10720    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10722   switch (get_attr_type (insn))
10723     {
10724     case TYPE_ALU:
10725       gcc_assert (operands[2] == const1_rtx);
10726       return "add{l}\t{%0, %0|%0, %0}";
10728     default:
10729       if (REG_P (operands[2]))
10730         return "sal{l}\t{%b2, %0|%0, %b2}";
10731       else if (operands[2] == const1_rtx
10732                && (TARGET_SHIFT1 || optimize_size))
10733         return "sal{l}\t%0";
10734       else
10735         return "sal{l}\t{%2, %0|%0, %2}";
10736     }
10738   [(set (attr "type")
10739      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10740                           (const_int 0))
10741                       (match_operand 0 "register_operand" ""))
10742                  (match_operand 2 "const1_operand" ""))
10743               (const_string "alu")
10744            ]
10745            (const_string "ishift")))
10746    (set_attr "mode" "SI")])
10748 (define_insn "*ashlsi3_cmp_zext"
10749   [(set (reg FLAGS_REG)
10750         (compare
10751           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10752                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10753           (const_int 0)))
10754    (set (match_operand:DI 0 "register_operand" "=r")
10755         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10756   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10757    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10759   switch (get_attr_type (insn))
10760     {
10761     case TYPE_ALU:
10762       gcc_assert (operands[2] == const1_rtx);
10763       return "add{l}\t{%k0, %k0|%k0, %k0}";
10765     default:
10766       if (REG_P (operands[2]))
10767         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10768       else if (operands[2] == const1_rtx
10769                && (TARGET_SHIFT1 || optimize_size))
10770         return "sal{l}\t%k0";
10771       else
10772         return "sal{l}\t{%2, %k0|%k0, %2}";
10773     }
10775   [(set (attr "type")
10776      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10777                      (const_int 0))
10778                  (match_operand 2 "const1_operand" ""))
10779               (const_string "alu")
10780            ]
10781            (const_string "ishift")))
10782    (set_attr "mode" "SI")])
10784 (define_expand "ashlhi3"
10785   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10786         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10787                    (match_operand:QI 2 "nonmemory_operand" "")))
10788    (clobber (reg:CC FLAGS_REG))]
10789   "TARGET_HIMODE_MATH"
10790   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10792 (define_insn "*ashlhi3_1_lea"
10793   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10794         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10795                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10796    (clobber (reg:CC FLAGS_REG))]
10797   "!TARGET_PARTIAL_REG_STALL
10798    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10800   switch (get_attr_type (insn))
10801     {
10802     case TYPE_LEA:
10803       return "#";
10804     case TYPE_ALU:
10805       gcc_assert (operands[2] == const1_rtx);
10806       return "add{w}\t{%0, %0|%0, %0}";
10808     default:
10809       if (REG_P (operands[2]))
10810         return "sal{w}\t{%b2, %0|%0, %b2}";
10811       else if (operands[2] == const1_rtx
10812                && (TARGET_SHIFT1 || optimize_size))
10813         return "sal{w}\t%0";
10814       else
10815         return "sal{w}\t{%2, %0|%0, %2}";
10816     }
10818   [(set (attr "type")
10819      (cond [(eq_attr "alternative" "1")
10820               (const_string "lea")
10821             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822                           (const_int 0))
10823                       (match_operand 0 "register_operand" ""))
10824                  (match_operand 2 "const1_operand" ""))
10825               (const_string "alu")
10826            ]
10827            (const_string "ishift")))
10828    (set_attr "mode" "HI,SI")])
10830 (define_insn "*ashlhi3_1"
10831   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10832         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10833                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "TARGET_PARTIAL_REG_STALL
10836    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10838   switch (get_attr_type (insn))
10839     {
10840     case TYPE_ALU:
10841       gcc_assert (operands[2] == const1_rtx);
10842       return "add{w}\t{%0, %0|%0, %0}";
10844     default:
10845       if (REG_P (operands[2]))
10846         return "sal{w}\t{%b2, %0|%0, %b2}";
10847       else if (operands[2] == const1_rtx
10848                && (TARGET_SHIFT1 || optimize_size))
10849         return "sal{w}\t%0";
10850       else
10851         return "sal{w}\t{%2, %0|%0, %2}";
10852     }
10854   [(set (attr "type")
10855      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10856                           (const_int 0))
10857                       (match_operand 0 "register_operand" ""))
10858                  (match_operand 2 "const1_operand" ""))
10859               (const_string "alu")
10860            ]
10861            (const_string "ishift")))
10862    (set_attr "mode" "HI")])
10864 ;; This pattern can't accept a variable shift count, since shifts by
10865 ;; zero don't affect the flags.  We assume that shifts by constant
10866 ;; zero are optimized away.
10867 (define_insn "*ashlhi3_cmp"
10868   [(set (reg FLAGS_REG)
10869         (compare
10870           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10871                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10872           (const_int 0)))
10873    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10874         (ashift:HI (match_dup 1) (match_dup 2)))]
10875   "ix86_match_ccmode (insn, CCGOCmode)
10876    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10878   switch (get_attr_type (insn))
10879     {
10880     case TYPE_ALU:
10881       gcc_assert (operands[2] == const1_rtx);
10882       return "add{w}\t{%0, %0|%0, %0}";
10884     default:
10885       if (REG_P (operands[2]))
10886         return "sal{w}\t{%b2, %0|%0, %b2}";
10887       else if (operands[2] == const1_rtx
10888                && (TARGET_SHIFT1 || optimize_size))
10889         return "sal{w}\t%0";
10890       else
10891         return "sal{w}\t{%2, %0|%0, %2}";
10892     }
10894   [(set (attr "type")
10895      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10896                           (const_int 0))
10897                       (match_operand 0 "register_operand" ""))
10898                  (match_operand 2 "const1_operand" ""))
10899               (const_string "alu")
10900            ]
10901            (const_string "ishift")))
10902    (set_attr "mode" "HI")])
10904 (define_insn "*ashlhi3_cconly"
10905   [(set (reg FLAGS_REG)
10906         (compare
10907           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10908                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10909           (const_int 0)))
10910    (clobber (match_scratch:HI 0 "=r"))]
10911   "ix86_match_ccmode (insn, CCGOCmode)
10912    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10914   switch (get_attr_type (insn))
10915     {
10916     case TYPE_ALU:
10917       gcc_assert (operands[2] == const1_rtx);
10918       return "add{w}\t{%0, %0|%0, %0}";
10920     default:
10921       if (REG_P (operands[2]))
10922         return "sal{w}\t{%b2, %0|%0, %b2}";
10923       else if (operands[2] == const1_rtx
10924                && (TARGET_SHIFT1 || optimize_size))
10925         return "sal{w}\t%0";
10926       else
10927         return "sal{w}\t{%2, %0|%0, %2}";
10928     }
10930   [(set (attr "type")
10931      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10932                           (const_int 0))
10933                       (match_operand 0 "register_operand" ""))
10934                  (match_operand 2 "const1_operand" ""))
10935               (const_string "alu")
10936            ]
10937            (const_string "ishift")))
10938    (set_attr "mode" "HI")])
10940 (define_expand "ashlqi3"
10941   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10942         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10943                    (match_operand:QI 2 "nonmemory_operand" "")))
10944    (clobber (reg:CC FLAGS_REG))]
10945   "TARGET_QIMODE_MATH"
10946   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10948 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10950 (define_insn "*ashlqi3_1_lea"
10951   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10952         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10953                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10954    (clobber (reg:CC FLAGS_REG))]
10955   "!TARGET_PARTIAL_REG_STALL
10956    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10958   switch (get_attr_type (insn))
10959     {
10960     case TYPE_LEA:
10961       return "#";
10962     case TYPE_ALU:
10963       gcc_assert (operands[2] == const1_rtx);
10964       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10965         return "add{l}\t{%k0, %k0|%k0, %k0}";
10966       else
10967         return "add{b}\t{%0, %0|%0, %0}";
10969     default:
10970       if (REG_P (operands[2]))
10971         {
10972           if (get_attr_mode (insn) == MODE_SI)
10973             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10974           else
10975             return "sal{b}\t{%b2, %0|%0, %b2}";
10976         }
10977       else if (operands[2] == const1_rtx
10978                && (TARGET_SHIFT1 || optimize_size))
10979         {
10980           if (get_attr_mode (insn) == MODE_SI)
10981             return "sal{l}\t%0";
10982           else
10983             return "sal{b}\t%0";
10984         }
10985       else
10986         {
10987           if (get_attr_mode (insn) == MODE_SI)
10988             return "sal{l}\t{%2, %k0|%k0, %2}";
10989           else
10990             return "sal{b}\t{%2, %0|%0, %2}";
10991         }
10992     }
10994   [(set (attr "type")
10995      (cond [(eq_attr "alternative" "2")
10996               (const_string "lea")
10997             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10998                           (const_int 0))
10999                       (match_operand 0 "register_operand" ""))
11000                  (match_operand 2 "const1_operand" ""))
11001               (const_string "alu")
11002            ]
11003            (const_string "ishift")))
11004    (set_attr "mode" "QI,SI,SI")])
11006 (define_insn "*ashlqi3_1"
11007   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11008         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11009                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11010    (clobber (reg:CC FLAGS_REG))]
11011   "TARGET_PARTIAL_REG_STALL
11012    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11014   switch (get_attr_type (insn))
11015     {
11016     case TYPE_ALU:
11017       gcc_assert (operands[2] == const1_rtx);
11018       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11019         return "add{l}\t{%k0, %k0|%k0, %k0}";
11020       else
11021         return "add{b}\t{%0, %0|%0, %0}";
11023     default:
11024       if (REG_P (operands[2]))
11025         {
11026           if (get_attr_mode (insn) == MODE_SI)
11027             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11028           else
11029             return "sal{b}\t{%b2, %0|%0, %b2}";
11030         }
11031       else if (operands[2] == const1_rtx
11032                && (TARGET_SHIFT1 || optimize_size))
11033         {
11034           if (get_attr_mode (insn) == MODE_SI)
11035             return "sal{l}\t%0";
11036           else
11037             return "sal{b}\t%0";
11038         }
11039       else
11040         {
11041           if (get_attr_mode (insn) == MODE_SI)
11042             return "sal{l}\t{%2, %k0|%k0, %2}";
11043           else
11044             return "sal{b}\t{%2, %0|%0, %2}";
11045         }
11046     }
11048   [(set (attr "type")
11049      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11050                           (const_int 0))
11051                       (match_operand 0 "register_operand" ""))
11052                  (match_operand 2 "const1_operand" ""))
11053               (const_string "alu")
11054            ]
11055            (const_string "ishift")))
11056    (set_attr "mode" "QI,SI")])
11058 ;; This pattern can't accept a variable shift count, since shifts by
11059 ;; zero don't affect the flags.  We assume that shifts by constant
11060 ;; zero are optimized away.
11061 (define_insn "*ashlqi3_cmp"
11062   [(set (reg FLAGS_REG)
11063         (compare
11064           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11065                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11066           (const_int 0)))
11067    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11068         (ashift:QI (match_dup 1) (match_dup 2)))]
11069   "ix86_match_ccmode (insn, CCGOCmode)
11070    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11072   switch (get_attr_type (insn))
11073     {
11074     case TYPE_ALU:
11075       gcc_assert (operands[2] == const1_rtx);
11076       return "add{b}\t{%0, %0|%0, %0}";
11078     default:
11079       if (REG_P (operands[2]))
11080         return "sal{b}\t{%b2, %0|%0, %b2}";
11081       else if (operands[2] == const1_rtx
11082                && (TARGET_SHIFT1 || optimize_size))
11083         return "sal{b}\t%0";
11084       else
11085         return "sal{b}\t{%2, %0|%0, %2}";
11086     }
11088   [(set (attr "type")
11089      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090                           (const_int 0))
11091                       (match_operand 0 "register_operand" ""))
11092                  (match_operand 2 "const1_operand" ""))
11093               (const_string "alu")
11094            ]
11095            (const_string "ishift")))
11096    (set_attr "mode" "QI")])
11098 (define_insn "*ashlqi3_cconly"
11099   [(set (reg FLAGS_REG)
11100         (compare
11101           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11102                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11103           (const_int 0)))
11104    (clobber (match_scratch:QI 0 "=q"))]
11105   "ix86_match_ccmode (insn, CCGOCmode)
11106    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11108   switch (get_attr_type (insn))
11109     {
11110     case TYPE_ALU:
11111       gcc_assert (operands[2] == const1_rtx);
11112       return "add{b}\t{%0, %0|%0, %0}";
11114     default:
11115       if (REG_P (operands[2]))
11116         return "sal{b}\t{%b2, %0|%0, %b2}";
11117       else if (operands[2] == const1_rtx
11118                && (TARGET_SHIFT1 || optimize_size))
11119         return "sal{b}\t%0";
11120       else
11121         return "sal{b}\t{%2, %0|%0, %2}";
11122     }
11124   [(set (attr "type")
11125      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11126                           (const_int 0))
11127                       (match_operand 0 "register_operand" ""))
11128                  (match_operand 2 "const1_operand" ""))
11129               (const_string "alu")
11130            ]
11131            (const_string "ishift")))
11132    (set_attr "mode" "QI")])
11134 ;; See comment above `ashldi3' about how this works.
11136 (define_expand "ashrti3"
11137   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11138                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11139                                 (match_operand:QI 2 "nonmemory_operand" "")))
11140               (clobber (reg:CC FLAGS_REG))])]
11141   "TARGET_64BIT"
11143   if (! immediate_operand (operands[2], QImode))
11144     {
11145       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11146       DONE;
11147     }
11148   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11149   DONE;
11152 (define_insn "ashrti3_1"
11153   [(set (match_operand:TI 0 "register_operand" "=r")
11154         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11155                      (match_operand:QI 2 "register_operand" "c")))
11156    (clobber (match_scratch:DI 3 "=&r"))
11157    (clobber (reg:CC FLAGS_REG))]
11158   "TARGET_64BIT"
11159   "#"
11160   [(set_attr "type" "multi")])
11162 (define_insn "*ashrti3_2"
11163   [(set (match_operand:TI 0 "register_operand" "=r")
11164         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11165                      (match_operand:QI 2 "immediate_operand" "O")))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "TARGET_64BIT"
11168   "#"
11169   [(set_attr "type" "multi")])
11171 (define_split
11172   [(set (match_operand:TI 0 "register_operand" "")
11173         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11174                      (match_operand:QI 2 "register_operand" "")))
11175    (clobber (match_scratch:DI 3 ""))
11176    (clobber (reg:CC FLAGS_REG))]
11177   "TARGET_64BIT && reload_completed"
11178   [(const_int 0)]
11179   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11181 (define_split
11182   [(set (match_operand:TI 0 "register_operand" "")
11183         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11184                      (match_operand:QI 2 "immediate_operand" "")))
11185    (clobber (reg:CC FLAGS_REG))]
11186   "TARGET_64BIT && reload_completed"
11187   [(const_int 0)]
11188   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11190 (define_insn "x86_64_shrd"
11191   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11192         (ior:DI (ashiftrt:DI (match_dup 0)
11193                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11194                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11195                   (minus:QI (const_int 64) (match_dup 2)))))
11196    (clobber (reg:CC FLAGS_REG))]
11197   "TARGET_64BIT"
11198   "@
11199    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11200    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11201   [(set_attr "type" "ishift")
11202    (set_attr "prefix_0f" "1")
11203    (set_attr "mode" "DI")
11204    (set_attr "athlon_decode" "vector")])
11206 (define_expand "ashrdi3"
11207   [(set (match_operand:DI 0 "shiftdi_operand" "")
11208         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11209                      (match_operand:QI 2 "nonmemory_operand" "")))]
11210   ""
11211   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11213 (define_insn "*ashrdi3_63_rex64"
11214   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11215         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11216                      (match_operand:DI 2 "const_int_operand" "i,i")))
11217    (clobber (reg:CC FLAGS_REG))]
11218   "TARGET_64BIT && INTVAL (operands[2]) == 63
11219    && (TARGET_USE_CLTD || optimize_size)
11220    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11221   "@
11222    {cqto|cqo}
11223    sar{q}\t{%2, %0|%0, %2}"
11224   [(set_attr "type" "imovx,ishift")
11225    (set_attr "prefix_0f" "0,*")
11226    (set_attr "length_immediate" "0,*")
11227    (set_attr "modrm" "0,1")
11228    (set_attr "mode" "DI")])
11230 (define_insn "*ashrdi3_1_one_bit_rex64"
11231   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11232         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11233                      (match_operand:QI 2 "const1_operand" "")))
11234    (clobber (reg:CC FLAGS_REG))]
11235   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11236    && (TARGET_SHIFT1 || optimize_size)"
11237   "sar{q}\t%0"
11238   [(set_attr "type" "ishift")
11239    (set (attr "length") 
11240      (if_then_else (match_operand:DI 0 "register_operand" "") 
11241         (const_string "2")
11242         (const_string "*")))])
11244 (define_insn "*ashrdi3_1_rex64"
11245   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11246         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11247                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11248    (clobber (reg:CC FLAGS_REG))]
11249   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11250   "@
11251    sar{q}\t{%2, %0|%0, %2}
11252    sar{q}\t{%b2, %0|%0, %b2}"
11253   [(set_attr "type" "ishift")
11254    (set_attr "mode" "DI")])
11256 ;; This pattern can't accept a variable shift count, since shifts by
11257 ;; zero don't affect the flags.  We assume that shifts by constant
11258 ;; zero are optimized away.
11259 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11260   [(set (reg FLAGS_REG)
11261         (compare
11262           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11263                        (match_operand:QI 2 "const1_operand" ""))
11264           (const_int 0)))
11265    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11266         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11267   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11268    && (TARGET_SHIFT1 || optimize_size)
11269    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11270   "sar{q}\t%0"
11271   [(set_attr "type" "ishift")
11272    (set (attr "length") 
11273      (if_then_else (match_operand:DI 0 "register_operand" "") 
11274         (const_string "2")
11275         (const_string "*")))])
11277 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11278   [(set (reg FLAGS_REG)
11279         (compare
11280           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11281                        (match_operand:QI 2 "const1_operand" ""))
11282           (const_int 0)))
11283    (clobber (match_scratch:DI 0 "=r"))]
11284   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11285    && (TARGET_SHIFT1 || optimize_size)
11286    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11287   "sar{q}\t%0"
11288   [(set_attr "type" "ishift")
11289    (set_attr "length" "2")])
11291 ;; This pattern can't accept a variable shift count, since shifts by
11292 ;; zero don't affect the flags.  We assume that shifts by constant
11293 ;; zero are optimized away.
11294 (define_insn "*ashrdi3_cmp_rex64"
11295   [(set (reg FLAGS_REG)
11296         (compare
11297           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11298                        (match_operand:QI 2 "const_int_operand" "n"))
11299           (const_int 0)))
11300    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11301         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11302   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11303    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11304   "sar{q}\t{%2, %0|%0, %2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "DI")])
11308 (define_insn "*ashrdi3_cconly_rex64"
11309   [(set (reg FLAGS_REG)
11310         (compare
11311           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11312                        (match_operand:QI 2 "const_int_operand" "n"))
11313           (const_int 0)))
11314    (clobber (match_scratch:DI 0 "=r"))]
11315   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11316    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11317   "sar{q}\t{%2, %0|%0, %2}"
11318   [(set_attr "type" "ishift")
11319    (set_attr "mode" "DI")])
11321 (define_insn "*ashrdi3_1"
11322   [(set (match_operand:DI 0 "register_operand" "=r")
11323         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11324                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11325    (clobber (reg:CC FLAGS_REG))]
11326   "!TARGET_64BIT"
11327   "#"
11328   [(set_attr "type" "multi")])
11330 ;; By default we don't ask for a scratch register, because when DImode
11331 ;; values are manipulated, registers are already at a premium.  But if
11332 ;; we have one handy, we won't turn it away.
11333 (define_peephole2
11334   [(match_scratch:SI 3 "r")
11335    (parallel [(set (match_operand:DI 0 "register_operand" "")
11336                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11337                                 (match_operand:QI 2 "nonmemory_operand" "")))
11338               (clobber (reg:CC FLAGS_REG))])
11339    (match_dup 3)]
11340   "!TARGET_64BIT && TARGET_CMOVE"
11341   [(const_int 0)]
11342   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11344 (define_split
11345   [(set (match_operand:DI 0 "register_operand" "")
11346         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11347                      (match_operand:QI 2 "nonmemory_operand" "")))
11348    (clobber (reg:CC FLAGS_REG))]
11349   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11350                      ? flow2_completed : reload_completed)"
11351   [(const_int 0)]
11352   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11354 (define_insn "x86_shrd_1"
11355   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11356         (ior:SI (ashiftrt:SI (match_dup 0)
11357                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11358                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11359                   (minus:QI (const_int 32) (match_dup 2)))))
11360    (clobber (reg:CC FLAGS_REG))]
11361   ""
11362   "@
11363    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11364    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11365   [(set_attr "type" "ishift")
11366    (set_attr "prefix_0f" "1")
11367    (set_attr "pent_pair" "np")
11368    (set_attr "mode" "SI")])
11370 (define_expand "x86_shift_adj_3"
11371   [(use (match_operand:SI 0 "register_operand" ""))
11372    (use (match_operand:SI 1 "register_operand" ""))
11373    (use (match_operand:QI 2 "register_operand" ""))]
11374   ""
11376   rtx label = gen_label_rtx ();
11377   rtx tmp;
11379   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11381   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11382   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11383   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11384                               gen_rtx_LABEL_REF (VOIDmode, label),
11385                               pc_rtx);
11386   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11387   JUMP_LABEL (tmp) = label;
11389   emit_move_insn (operands[0], operands[1]);
11390   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11392   emit_label (label);
11393   LABEL_NUSES (label) = 1;
11395   DONE;
11398 (define_insn "ashrsi3_31"
11399   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11400         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11401                      (match_operand:SI 2 "const_int_operand" "i,i")))
11402    (clobber (reg:CC FLAGS_REG))]
11403   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11404    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11405   "@
11406    {cltd|cdq}
11407    sar{l}\t{%2, %0|%0, %2}"
11408   [(set_attr "type" "imovx,ishift")
11409    (set_attr "prefix_0f" "0,*")
11410    (set_attr "length_immediate" "0,*")
11411    (set_attr "modrm" "0,1")
11412    (set_attr "mode" "SI")])
11414 (define_insn "*ashrsi3_31_zext"
11415   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11416         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11417                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11420    && INTVAL (operands[2]) == 31
11421    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11422   "@
11423    {cltd|cdq}
11424    sar{l}\t{%2, %k0|%k0, %2}"
11425   [(set_attr "type" "imovx,ishift")
11426    (set_attr "prefix_0f" "0,*")
11427    (set_attr "length_immediate" "0,*")
11428    (set_attr "modrm" "0,1")
11429    (set_attr "mode" "SI")])
11431 (define_expand "ashrsi3"
11432   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11433         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11434                      (match_operand:QI 2 "nonmemory_operand" "")))
11435    (clobber (reg:CC FLAGS_REG))]
11436   ""
11437   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11439 (define_insn "*ashrsi3_1_one_bit"
11440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11441         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11442                      (match_operand:QI 2 "const1_operand" "")))
11443    (clobber (reg:CC FLAGS_REG))]
11444   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11445    && (TARGET_SHIFT1 || optimize_size)"
11446   "sar{l}\t%0"
11447   [(set_attr "type" "ishift")
11448    (set (attr "length") 
11449      (if_then_else (match_operand:SI 0 "register_operand" "") 
11450         (const_string "2")
11451         (const_string "*")))])
11453 (define_insn "*ashrsi3_1_one_bit_zext"
11454   [(set (match_operand:DI 0 "register_operand" "=r")
11455         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11456                                      (match_operand:QI 2 "const1_operand" ""))))
11457    (clobber (reg:CC FLAGS_REG))]
11458   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11459    && (TARGET_SHIFT1 || optimize_size)"
11460   "sar{l}\t%k0"
11461   [(set_attr "type" "ishift")
11462    (set_attr "length" "2")])
11464 (define_insn "*ashrsi3_1"
11465   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11466         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11467                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11468    (clobber (reg:CC FLAGS_REG))]
11469   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11470   "@
11471    sar{l}\t{%2, %0|%0, %2}
11472    sar{l}\t{%b2, %0|%0, %b2}"
11473   [(set_attr "type" "ishift")
11474    (set_attr "mode" "SI")])
11476 (define_insn "*ashrsi3_1_zext"
11477   [(set (match_operand:DI 0 "register_operand" "=r,r")
11478         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11479                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11480    (clobber (reg:CC FLAGS_REG))]
11481   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11482   "@
11483    sar{l}\t{%2, %k0|%k0, %2}
11484    sar{l}\t{%b2, %k0|%k0, %b2}"
11485   [(set_attr "type" "ishift")
11486    (set_attr "mode" "SI")])
11488 ;; This pattern can't accept a variable shift count, since shifts by
11489 ;; zero don't affect the flags.  We assume that shifts by constant
11490 ;; zero are optimized away.
11491 (define_insn "*ashrsi3_one_bit_cmp"
11492   [(set (reg FLAGS_REG)
11493         (compare
11494           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11495                        (match_operand:QI 2 "const1_operand" ""))
11496           (const_int 0)))
11497    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11498         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11499   "ix86_match_ccmode (insn, CCGOCmode)
11500    && (TARGET_SHIFT1 || optimize_size)
11501    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11502   "sar{l}\t%0"
11503   [(set_attr "type" "ishift")
11504    (set (attr "length") 
11505      (if_then_else (match_operand:SI 0 "register_operand" "") 
11506         (const_string "2")
11507         (const_string "*")))])
11509 (define_insn "*ashrsi3_one_bit_cconly"
11510   [(set (reg FLAGS_REG)
11511         (compare
11512           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11513                        (match_operand:QI 2 "const1_operand" ""))
11514           (const_int 0)))
11515    (clobber (match_scratch:SI 0 "=r"))]
11516   "ix86_match_ccmode (insn, CCGOCmode)
11517    && (TARGET_SHIFT1 || optimize_size)
11518    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519   "sar{l}\t%0"
11520   [(set_attr "type" "ishift")
11521    (set_attr "length" "2")])
11523 (define_insn "*ashrsi3_one_bit_cmp_zext"
11524   [(set (reg FLAGS_REG)
11525         (compare
11526           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11527                        (match_operand:QI 2 "const1_operand" ""))
11528           (const_int 0)))
11529    (set (match_operand:DI 0 "register_operand" "=r")
11530         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11531   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11532    && (TARGET_SHIFT1 || optimize_size)
11533    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11534   "sar{l}\t%k0"
11535   [(set_attr "type" "ishift")
11536    (set_attr "length" "2")])
11538 ;; This pattern can't accept a variable shift count, since shifts by
11539 ;; zero don't affect the flags.  We assume that shifts by constant
11540 ;; zero are optimized away.
11541 (define_insn "*ashrsi3_cmp"
11542   [(set (reg FLAGS_REG)
11543         (compare
11544           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11545                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11546           (const_int 0)))
11547    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11548         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11549   "ix86_match_ccmode (insn, CCGOCmode)
11550    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551   "sar{l}\t{%2, %0|%0, %2}"
11552   [(set_attr "type" "ishift")
11553    (set_attr "mode" "SI")])
11555 (define_insn "*ashrsi3_cconly"
11556   [(set (reg FLAGS_REG)
11557         (compare
11558           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11559                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11560           (const_int 0)))
11561    (clobber (match_scratch:SI 0 "=r"))]
11562   "ix86_match_ccmode (insn, CCGOCmode)
11563    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11564   "sar{l}\t{%2, %0|%0, %2}"
11565   [(set_attr "type" "ishift")
11566    (set_attr "mode" "SI")])
11568 (define_insn "*ashrsi3_cmp_zext"
11569   [(set (reg FLAGS_REG)
11570         (compare
11571           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11572                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11573           (const_int 0)))
11574    (set (match_operand:DI 0 "register_operand" "=r")
11575         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11576   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11577    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578   "sar{l}\t{%2, %k0|%k0, %2}"
11579   [(set_attr "type" "ishift")
11580    (set_attr "mode" "SI")])
11582 (define_expand "ashrhi3"
11583   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11584         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11585                      (match_operand:QI 2 "nonmemory_operand" "")))
11586    (clobber (reg:CC FLAGS_REG))]
11587   "TARGET_HIMODE_MATH"
11588   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11590 (define_insn "*ashrhi3_1_one_bit"
11591   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11592         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11593                      (match_operand:QI 2 "const1_operand" "")))
11594    (clobber (reg:CC FLAGS_REG))]
11595   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11596    && (TARGET_SHIFT1 || optimize_size)"
11597   "sar{w}\t%0"
11598   [(set_attr "type" "ishift")
11599    (set (attr "length") 
11600      (if_then_else (match_operand 0 "register_operand" "") 
11601         (const_string "2")
11602         (const_string "*")))])
11604 (define_insn "*ashrhi3_1"
11605   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11606         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11607                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11610   "@
11611    sar{w}\t{%2, %0|%0, %2}
11612    sar{w}\t{%b2, %0|%0, %b2}"
11613   [(set_attr "type" "ishift")
11614    (set_attr "mode" "HI")])
11616 ;; This pattern can't accept a variable shift count, since shifts by
11617 ;; zero don't affect the flags.  We assume that shifts by constant
11618 ;; zero are optimized away.
11619 (define_insn "*ashrhi3_one_bit_cmp"
11620   [(set (reg FLAGS_REG)
11621         (compare
11622           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11623                        (match_operand:QI 2 "const1_operand" ""))
11624           (const_int 0)))
11625    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11626         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11627   "ix86_match_ccmode (insn, CCGOCmode)
11628    && (TARGET_SHIFT1 || optimize_size)
11629    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11630   "sar{w}\t%0"
11631   [(set_attr "type" "ishift")
11632    (set (attr "length") 
11633      (if_then_else (match_operand 0 "register_operand" "") 
11634         (const_string "2")
11635         (const_string "*")))])
11637 (define_insn "*ashrhi3_one_bit_cconly"
11638   [(set (reg FLAGS_REG)
11639         (compare
11640           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11641                        (match_operand:QI 2 "const1_operand" ""))
11642           (const_int 0)))
11643    (clobber (match_scratch:HI 0 "=r"))]
11644   "ix86_match_ccmode (insn, CCGOCmode)
11645    && (TARGET_SHIFT1 || optimize_size)
11646    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11647   "sar{w}\t%0"
11648   [(set_attr "type" "ishift")
11649    (set_attr "length" "2")])
11651 ;; This pattern can't accept a variable shift count, since shifts by
11652 ;; zero don't affect the flags.  We assume that shifts by constant
11653 ;; zero are optimized away.
11654 (define_insn "*ashrhi3_cmp"
11655   [(set (reg FLAGS_REG)
11656         (compare
11657           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11658                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11659           (const_int 0)))
11660    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11661         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11662   "ix86_match_ccmode (insn, CCGOCmode)
11663    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11664   "sar{w}\t{%2, %0|%0, %2}"
11665   [(set_attr "type" "ishift")
11666    (set_attr "mode" "HI")])
11668 (define_insn "*ashrhi3_cconly"
11669   [(set (reg FLAGS_REG)
11670         (compare
11671           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11672                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673           (const_int 0)))
11674    (clobber (match_scratch:HI 0 "=r"))]
11675   "ix86_match_ccmode (insn, CCGOCmode)
11676    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11677   "sar{w}\t{%2, %0|%0, %2}"
11678   [(set_attr "type" "ishift")
11679    (set_attr "mode" "HI")])
11681 (define_expand "ashrqi3"
11682   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11683         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11684                      (match_operand:QI 2 "nonmemory_operand" "")))
11685    (clobber (reg:CC FLAGS_REG))]
11686   "TARGET_QIMODE_MATH"
11687   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11689 (define_insn "*ashrqi3_1_one_bit"
11690   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11691         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11692                      (match_operand:QI 2 "const1_operand" "")))
11693    (clobber (reg:CC FLAGS_REG))]
11694   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11695    && (TARGET_SHIFT1 || optimize_size)"
11696   "sar{b}\t%0"
11697   [(set_attr "type" "ishift")
11698    (set (attr "length") 
11699      (if_then_else (match_operand 0 "register_operand" "") 
11700         (const_string "2")
11701         (const_string "*")))])
11703 (define_insn "*ashrqi3_1_one_bit_slp"
11704   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11705         (ashiftrt:QI (match_dup 0)
11706                      (match_operand:QI 1 "const1_operand" "")))
11707    (clobber (reg:CC FLAGS_REG))]
11708   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11709    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11710    && (TARGET_SHIFT1 || optimize_size)"
11711   "sar{b}\t%0"
11712   [(set_attr "type" "ishift1")
11713    (set (attr "length") 
11714      (if_then_else (match_operand 0 "register_operand" "") 
11715         (const_string "2")
11716         (const_string "*")))])
11718 (define_insn "*ashrqi3_1"
11719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11720         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11721                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11724   "@
11725    sar{b}\t{%2, %0|%0, %2}
11726    sar{b}\t{%b2, %0|%0, %b2}"
11727   [(set_attr "type" "ishift")
11728    (set_attr "mode" "QI")])
11730 (define_insn "*ashrqi3_1_slp"
11731   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11732         (ashiftrt:QI (match_dup 0)
11733                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11736    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11737   "@
11738    sar{b}\t{%1, %0|%0, %1}
11739    sar{b}\t{%b1, %0|%0, %b1}"
11740   [(set_attr "type" "ishift1")
11741    (set_attr "mode" "QI")])
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags.  We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrqi3_one_bit_cmp"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const1_operand" "I"))
11751           (const_int 0)))
11752    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11754   "ix86_match_ccmode (insn, CCGOCmode)
11755    && (TARGET_SHIFT1 || optimize_size)
11756    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11757   "sar{b}\t%0"
11758   [(set_attr "type" "ishift")
11759    (set (attr "length") 
11760      (if_then_else (match_operand 0 "register_operand" "") 
11761         (const_string "2")
11762         (const_string "*")))])
11764 (define_insn "*ashrqi3_one_bit_cconly"
11765   [(set (reg FLAGS_REG)
11766         (compare
11767           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11768                        (match_operand:QI 2 "const1_operand" "I"))
11769           (const_int 0)))
11770    (clobber (match_scratch:QI 0 "=q"))]
11771   "ix86_match_ccmode (insn, CCGOCmode)
11772    && (TARGET_SHIFT1 || optimize_size)
11773    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11774   "sar{b}\t%0"
11775   [(set_attr "type" "ishift")
11776    (set_attr "length" "2")])
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags.  We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*ashrqi3_cmp"
11782   [(set (reg FLAGS_REG)
11783         (compare
11784           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11785                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11786           (const_int 0)))
11787    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11789   "ix86_match_ccmode (insn, CCGOCmode)
11790    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11791   "sar{b}\t{%2, %0|%0, %2}"
11792   [(set_attr "type" "ishift")
11793    (set_attr "mode" "QI")])
11795 (define_insn "*ashrqi3_cconly"
11796   [(set (reg FLAGS_REG)
11797         (compare
11798           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11799                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800           (const_int 0)))
11801    (clobber (match_scratch:QI 0 "=q"))]
11802   "ix86_match_ccmode (insn, CCGOCmode)
11803    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11804   "sar{b}\t{%2, %0|%0, %2}"
11805   [(set_attr "type" "ishift")
11806    (set_attr "mode" "QI")])
11809 ;; Logical shift instructions
11811 ;; See comment above `ashldi3' about how this works.
11813 (define_expand "lshrti3"
11814   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11815                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11816                                 (match_operand:QI 2 "nonmemory_operand" "")))
11817               (clobber (reg:CC FLAGS_REG))])]
11818   "TARGET_64BIT"
11820   if (! immediate_operand (operands[2], QImode))
11821     {
11822       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11823       DONE;
11824     }
11825   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11826   DONE;
11829 (define_insn "lshrti3_1"
11830   [(set (match_operand:TI 0 "register_operand" "=r")
11831         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11832                      (match_operand:QI 2 "register_operand" "c")))
11833    (clobber (match_scratch:DI 3 "=&r"))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "TARGET_64BIT"
11836   "#"
11837   [(set_attr "type" "multi")])
11839 (define_insn "*lshrti3_2"
11840   [(set (match_operand:TI 0 "register_operand" "=r")
11841         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11842                      (match_operand:QI 2 "immediate_operand" "O")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "TARGET_64BIT"
11845   "#"
11846   [(set_attr "type" "multi")])
11848 (define_split 
11849   [(set (match_operand:TI 0 "register_operand" "")
11850         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11851                      (match_operand:QI 2 "register_operand" "")))
11852    (clobber (match_scratch:DI 3 ""))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "TARGET_64BIT && reload_completed"
11855   [(const_int 0)]
11856   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11858 (define_split 
11859   [(set (match_operand:TI 0 "register_operand" "")
11860         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11861                      (match_operand:QI 2 "immediate_operand" "")))
11862    (clobber (reg:CC FLAGS_REG))]
11863   "TARGET_64BIT && reload_completed"
11864   [(const_int 0)]
11865   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11867 (define_expand "lshrdi3"
11868   [(set (match_operand:DI 0 "shiftdi_operand" "")
11869         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11870                      (match_operand:QI 2 "nonmemory_operand" "")))]
11871   ""
11872   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11874 (define_insn "*lshrdi3_1_one_bit_rex64"
11875   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11876         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11877                      (match_operand:QI 2 "const1_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11880    && (TARGET_SHIFT1 || optimize_size)"
11881   "shr{q}\t%0"
11882   [(set_attr "type" "ishift")
11883    (set (attr "length") 
11884      (if_then_else (match_operand:DI 0 "register_operand" "") 
11885         (const_string "2")
11886         (const_string "*")))])
11888 (define_insn "*lshrdi3_1_rex64"
11889   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11890         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11891                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894   "@
11895    shr{q}\t{%2, %0|%0, %2}
11896    shr{q}\t{%b2, %0|%0, %b2}"
11897   [(set_attr "type" "ishift")
11898    (set_attr "mode" "DI")])
11900 ;; This pattern can't accept a variable shift count, since shifts by
11901 ;; zero don't affect the flags.  We assume that shifts by constant
11902 ;; zero are optimized away.
11903 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11904   [(set (reg FLAGS_REG)
11905         (compare
11906           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11907                        (match_operand:QI 2 "const1_operand" ""))
11908           (const_int 0)))
11909    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11910         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11911   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11912    && (TARGET_SHIFT1 || optimize_size)
11913    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11914   "shr{q}\t%0"
11915   [(set_attr "type" "ishift")
11916    (set (attr "length") 
11917      (if_then_else (match_operand:DI 0 "register_operand" "") 
11918         (const_string "2")
11919         (const_string "*")))])
11921 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11922   [(set (reg FLAGS_REG)
11923         (compare
11924           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11925                        (match_operand:QI 2 "const1_operand" ""))
11926           (const_int 0)))
11927    (clobber (match_scratch:DI 0 "=r"))]
11928   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11929    && (TARGET_SHIFT1 || optimize_size)
11930    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11931   "shr{q}\t%0"
11932   [(set_attr "type" "ishift")
11933    (set_attr "length" "2")])
11935 ;; This pattern can't accept a variable shift count, since shifts by
11936 ;; zero don't affect the flags.  We assume that shifts by constant
11937 ;; zero are optimized away.
11938 (define_insn "*lshrdi3_cmp_rex64"
11939   [(set (reg FLAGS_REG)
11940         (compare
11941           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11942                        (match_operand:QI 2 "const_int_operand" "e"))
11943           (const_int 0)))
11944    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11945         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11946   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11947    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11948   "shr{q}\t{%2, %0|%0, %2}"
11949   [(set_attr "type" "ishift")
11950    (set_attr "mode" "DI")])
11952 (define_insn "*lshrdi3_cconly_rex64"
11953   [(set (reg FLAGS_REG)
11954         (compare
11955           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11956                        (match_operand:QI 2 "const_int_operand" "e"))
11957           (const_int 0)))
11958    (clobber (match_scratch:DI 0 "=r"))]
11959   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11960    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11961   "shr{q}\t{%2, %0|%0, %2}"
11962   [(set_attr "type" "ishift")
11963    (set_attr "mode" "DI")])
11965 (define_insn "*lshrdi3_1"
11966   [(set (match_operand:DI 0 "register_operand" "=r")
11967         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11968                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "!TARGET_64BIT"
11971   "#"
11972   [(set_attr "type" "multi")])
11974 ;; By default we don't ask for a scratch register, because when DImode
11975 ;; values are manipulated, registers are already at a premium.  But if
11976 ;; we have one handy, we won't turn it away.
11977 (define_peephole2
11978   [(match_scratch:SI 3 "r")
11979    (parallel [(set (match_operand:DI 0 "register_operand" "")
11980                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11981                                 (match_operand:QI 2 "nonmemory_operand" "")))
11982               (clobber (reg:CC FLAGS_REG))])
11983    (match_dup 3)]
11984   "!TARGET_64BIT && TARGET_CMOVE"
11985   [(const_int 0)]
11986   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11988 (define_split 
11989   [(set (match_operand:DI 0 "register_operand" "")
11990         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11991                      (match_operand:QI 2 "nonmemory_operand" "")))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11994                      ? flow2_completed : reload_completed)"
11995   [(const_int 0)]
11996   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11998 (define_expand "lshrsi3"
11999   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12000         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12001                      (match_operand:QI 2 "nonmemory_operand" "")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   ""
12004   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12006 (define_insn "*lshrsi3_1_one_bit"
12007   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12008         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12009                      (match_operand:QI 2 "const1_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12012    && (TARGET_SHIFT1 || optimize_size)"
12013   "shr{l}\t%0"
12014   [(set_attr "type" "ishift")
12015    (set (attr "length") 
12016      (if_then_else (match_operand:SI 0 "register_operand" "") 
12017         (const_string "2")
12018         (const_string "*")))])
12020 (define_insn "*lshrsi3_1_one_bit_zext"
12021   [(set (match_operand:DI 0 "register_operand" "=r")
12022         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12023                      (match_operand:QI 2 "const1_operand" "")))
12024    (clobber (reg:CC FLAGS_REG))]
12025   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12026    && (TARGET_SHIFT1 || optimize_size)"
12027   "shr{l}\t%k0"
12028   [(set_attr "type" "ishift")
12029    (set_attr "length" "2")])
12031 (define_insn "*lshrsi3_1"
12032   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12033         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12034                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12035    (clobber (reg:CC FLAGS_REG))]
12036   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12037   "@
12038    shr{l}\t{%2, %0|%0, %2}
12039    shr{l}\t{%b2, %0|%0, %b2}"
12040   [(set_attr "type" "ishift")
12041    (set_attr "mode" "SI")])
12043 (define_insn "*lshrsi3_1_zext"
12044   [(set (match_operand:DI 0 "register_operand" "=r,r")
12045         (zero_extend:DI
12046           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12047                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12050   "@
12051    shr{l}\t{%2, %k0|%k0, %2}
12052    shr{l}\t{%b2, %k0|%k0, %b2}"
12053   [(set_attr "type" "ishift")
12054    (set_attr "mode" "SI")])
12056 ;; This pattern can't accept a variable shift count, since shifts by
12057 ;; zero don't affect the flags.  We assume that shifts by constant
12058 ;; zero are optimized away.
12059 (define_insn "*lshrsi3_one_bit_cmp"
12060   [(set (reg FLAGS_REG)
12061         (compare
12062           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12063                        (match_operand:QI 2 "const1_operand" ""))
12064           (const_int 0)))
12065    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12066         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12067   "ix86_match_ccmode (insn, CCGOCmode)
12068    && (TARGET_SHIFT1 || optimize_size)
12069    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12070   "shr{l}\t%0"
12071   [(set_attr "type" "ishift")
12072    (set (attr "length") 
12073      (if_then_else (match_operand:SI 0 "register_operand" "") 
12074         (const_string "2")
12075         (const_string "*")))])
12077 (define_insn "*lshrsi3_one_bit_cconly"
12078   [(set (reg FLAGS_REG)
12079         (compare
12080           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12081                        (match_operand:QI 2 "const1_operand" ""))
12082           (const_int 0)))
12083    (clobber (match_scratch:SI 0 "=r"))]
12084   "ix86_match_ccmode (insn, CCGOCmode)
12085    && (TARGET_SHIFT1 || optimize_size)
12086    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12087   "shr{l}\t%0"
12088   [(set_attr "type" "ishift")
12089    (set_attr "length" "2")])
12091 (define_insn "*lshrsi3_cmp_one_bit_zext"
12092   [(set (reg FLAGS_REG)
12093         (compare
12094           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12095                        (match_operand:QI 2 "const1_operand" ""))
12096           (const_int 0)))
12097    (set (match_operand:DI 0 "register_operand" "=r")
12098         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12099   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12100    && (TARGET_SHIFT1 || optimize_size)
12101    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102   "shr{l}\t%k0"
12103   [(set_attr "type" "ishift")
12104    (set_attr "length" "2")])
12106 ;; This pattern can't accept a variable shift count, since shifts by
12107 ;; zero don't affect the flags.  We assume that shifts by constant
12108 ;; zero are optimized away.
12109 (define_insn "*lshrsi3_cmp"
12110   [(set (reg FLAGS_REG)
12111         (compare
12112           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12113                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12114           (const_int 0)))
12115    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12116         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12117   "ix86_match_ccmode (insn, CCGOCmode)
12118    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12119   "shr{l}\t{%2, %0|%0, %2}"
12120   [(set_attr "type" "ishift")
12121    (set_attr "mode" "SI")])
12123 (define_insn "*lshrsi3_cconly"
12124   [(set (reg FLAGS_REG)
12125       (compare
12126         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12127                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12128         (const_int 0)))
12129    (clobber (match_scratch:SI 0 "=r"))]
12130   "ix86_match_ccmode (insn, CCGOCmode)
12131    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12132   "shr{l}\t{%2, %0|%0, %2}"
12133   [(set_attr "type" "ishift")
12134    (set_attr "mode" "SI")])
12136 (define_insn "*lshrsi3_cmp_zext"
12137   [(set (reg FLAGS_REG)
12138         (compare
12139           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12140                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12141           (const_int 0)))
12142    (set (match_operand:DI 0 "register_operand" "=r")
12143         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12144   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12145    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12146   "shr{l}\t{%2, %k0|%k0, %2}"
12147   [(set_attr "type" "ishift")
12148    (set_attr "mode" "SI")])
12150 (define_expand "lshrhi3"
12151   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12152         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_HIMODE_MATH"
12156   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12158 (define_insn "*lshrhi3_1_one_bit"
12159   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12160         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12161                      (match_operand:QI 2 "const1_operand" "")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12164    && (TARGET_SHIFT1 || optimize_size)"
12165   "shr{w}\t%0"
12166   [(set_attr "type" "ishift")
12167    (set (attr "length") 
12168      (if_then_else (match_operand 0 "register_operand" "") 
12169         (const_string "2")
12170         (const_string "*")))])
12172 (define_insn "*lshrhi3_1"
12173   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12174         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12175                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12176    (clobber (reg:CC FLAGS_REG))]
12177   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12178   "@
12179    shr{w}\t{%2, %0|%0, %2}
12180    shr{w}\t{%b2, %0|%0, %b2}"
12181   [(set_attr "type" "ishift")
12182    (set_attr "mode" "HI")])
12184 ;; This pattern can't accept a variable shift count, since shifts by
12185 ;; zero don't affect the flags.  We assume that shifts by constant
12186 ;; zero are optimized away.
12187 (define_insn "*lshrhi3_one_bit_cmp"
12188   [(set (reg FLAGS_REG)
12189         (compare
12190           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12191                        (match_operand:QI 2 "const1_operand" ""))
12192           (const_int 0)))
12193    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12194         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12195   "ix86_match_ccmode (insn, CCGOCmode)
12196    && (TARGET_SHIFT1 || optimize_size)
12197    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12198   "shr{w}\t%0"
12199   [(set_attr "type" "ishift")
12200    (set (attr "length") 
12201      (if_then_else (match_operand:SI 0 "register_operand" "") 
12202         (const_string "2")
12203         (const_string "*")))])
12205 (define_insn "*lshrhi3_one_bit_cconly"
12206   [(set (reg FLAGS_REG)
12207         (compare
12208           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12209                        (match_operand:QI 2 "const1_operand" ""))
12210           (const_int 0)))
12211    (clobber (match_scratch:HI 0 "=r"))]
12212   "ix86_match_ccmode (insn, CCGOCmode)
12213    && (TARGET_SHIFT1 || optimize_size)
12214    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12215   "shr{w}\t%0"
12216   [(set_attr "type" "ishift")
12217    (set_attr "length" "2")])
12219 ;; This pattern can't accept a variable shift count, since shifts by
12220 ;; zero don't affect the flags.  We assume that shifts by constant
12221 ;; zero are optimized away.
12222 (define_insn "*lshrhi3_cmp"
12223   [(set (reg FLAGS_REG)
12224         (compare
12225           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12226                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12227           (const_int 0)))
12228    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12229         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12230   "ix86_match_ccmode (insn, CCGOCmode)
12231    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12232   "shr{w}\t{%2, %0|%0, %2}"
12233   [(set_attr "type" "ishift")
12234    (set_attr "mode" "HI")])
12236 (define_insn "*lshrhi3_cconly"
12237   [(set (reg FLAGS_REG)
12238         (compare
12239           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12240                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241           (const_int 0)))
12242    (clobber (match_scratch:HI 0 "=r"))]
12243   "ix86_match_ccmode (insn, CCGOCmode)
12244    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12245   "shr{w}\t{%2, %0|%0, %2}"
12246   [(set_attr "type" "ishift")
12247    (set_attr "mode" "HI")])
12249 (define_expand "lshrqi3"
12250   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12251         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12252                      (match_operand:QI 2 "nonmemory_operand" "")))
12253    (clobber (reg:CC FLAGS_REG))]
12254   "TARGET_QIMODE_MATH"
12255   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12257 (define_insn "*lshrqi3_1_one_bit"
12258   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12259         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12260                      (match_operand:QI 2 "const1_operand" "")))
12261    (clobber (reg:CC FLAGS_REG))]
12262   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12263    && (TARGET_SHIFT1 || optimize_size)"
12264   "shr{b}\t%0"
12265   [(set_attr "type" "ishift")
12266    (set (attr "length") 
12267      (if_then_else (match_operand 0 "register_operand" "") 
12268         (const_string "2")
12269         (const_string "*")))])
12271 (define_insn "*lshrqi3_1_one_bit_slp"
12272   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12273         (lshiftrt:QI (match_dup 0)
12274                      (match_operand:QI 1 "const1_operand" "")))
12275    (clobber (reg:CC FLAGS_REG))]
12276   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12277    && (TARGET_SHIFT1 || optimize_size)"
12278   "shr{b}\t%0"
12279   [(set_attr "type" "ishift1")
12280    (set (attr "length") 
12281      (if_then_else (match_operand 0 "register_operand" "") 
12282         (const_string "2")
12283         (const_string "*")))])
12285 (define_insn "*lshrqi3_1"
12286   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12287         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12288                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12289    (clobber (reg:CC FLAGS_REG))]
12290   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12291   "@
12292    shr{b}\t{%2, %0|%0, %2}
12293    shr{b}\t{%b2, %0|%0, %b2}"
12294   [(set_attr "type" "ishift")
12295    (set_attr "mode" "QI")])
12297 (define_insn "*lshrqi3_1_slp"
12298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12299         (lshiftrt:QI (match_dup 0)
12300                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12301    (clobber (reg:CC FLAGS_REG))]
12302   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12303    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12304   "@
12305    shr{b}\t{%1, %0|%0, %1}
12306    shr{b}\t{%b1, %0|%0, %b1}"
12307   [(set_attr "type" "ishift1")
12308    (set_attr "mode" "QI")])
12310 ;; This pattern can't accept a variable shift count, since shifts by
12311 ;; zero don't affect the flags.  We assume that shifts by constant
12312 ;; zero are optimized away.
12313 (define_insn "*lshrqi2_one_bit_cmp"
12314   [(set (reg FLAGS_REG)
12315         (compare
12316           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12317                        (match_operand:QI 2 "const1_operand" ""))
12318           (const_int 0)))
12319    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12320         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12321   "ix86_match_ccmode (insn, CCGOCmode)
12322    && (TARGET_SHIFT1 || optimize_size)
12323    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12324   "shr{b}\t%0"
12325   [(set_attr "type" "ishift")
12326    (set (attr "length") 
12327      (if_then_else (match_operand:SI 0 "register_operand" "") 
12328         (const_string "2")
12329         (const_string "*")))])
12331 (define_insn "*lshrqi2_one_bit_cconly"
12332   [(set (reg FLAGS_REG)
12333         (compare
12334           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12335                        (match_operand:QI 2 "const1_operand" ""))
12336           (const_int 0)))
12337    (clobber (match_scratch:QI 0 "=q"))]
12338   "ix86_match_ccmode (insn, CCGOCmode)
12339    && (TARGET_SHIFT1 || optimize_size)
12340    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12341   "shr{b}\t%0"
12342   [(set_attr "type" "ishift")
12343    (set_attr "length" "2")])
12345 ;; This pattern can't accept a variable shift count, since shifts by
12346 ;; zero don't affect the flags.  We assume that shifts by constant
12347 ;; zero are optimized away.
12348 (define_insn "*lshrqi2_cmp"
12349   [(set (reg FLAGS_REG)
12350         (compare
12351           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12352                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12353           (const_int 0)))
12354    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12355         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12356   "ix86_match_ccmode (insn, CCGOCmode)
12357    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12358   "shr{b}\t{%2, %0|%0, %2}"
12359   [(set_attr "type" "ishift")
12360    (set_attr "mode" "QI")])
12362 (define_insn "*lshrqi2_cconly"
12363   [(set (reg FLAGS_REG)
12364         (compare
12365           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12366                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12367           (const_int 0)))
12368    (clobber (match_scratch:QI 0 "=q"))]
12369   "ix86_match_ccmode (insn, CCGOCmode)
12370    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12371   "shr{b}\t{%2, %0|%0, %2}"
12372   [(set_attr "type" "ishift")
12373    (set_attr "mode" "QI")])
12375 ;; Rotate instructions
12377 (define_expand "rotldi3"
12378   [(set (match_operand:DI 0 "shiftdi_operand" "")
12379         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12380                    (match_operand:QI 2 "nonmemory_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382  ""
12384   if (TARGET_64BIT)
12385     {
12386       ix86_expand_binary_operator (ROTATE, DImode, operands);
12387       DONE;
12388     }
12389   if (!const_1_to_31_operand (operands[2], VOIDmode))
12390     FAIL;
12391   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12392   DONE;
12395 ;; Implement rotation using two double-precision shift instructions
12396 ;; and a scratch register.   
12397 (define_insn_and_split "ix86_rotldi3"
12398  [(set (match_operand:DI 0 "register_operand" "=r")
12399        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12400                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12401   (clobber (reg:CC FLAGS_REG))
12402   (clobber (match_scratch:SI 3 "=&r"))]
12403  "!TARGET_64BIT"
12404  "" 
12405  "&& reload_completed"
12406  [(set (match_dup 3) (match_dup 4))
12407   (parallel
12408    [(set (match_dup 4)
12409          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12410                  (lshiftrt:SI (match_dup 5)
12411                               (minus:QI (const_int 32) (match_dup 2)))))
12412     (clobber (reg:CC FLAGS_REG))])
12413   (parallel
12414    [(set (match_dup 5)
12415          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12416                  (lshiftrt:SI (match_dup 3)
12417                               (minus:QI (const_int 32) (match_dup 2)))))
12418     (clobber (reg:CC FLAGS_REG))])]
12419  "split_di (operands, 1, operands + 4, operands + 5);")
12421 (define_insn "*rotlsi3_1_one_bit_rex64"
12422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12423         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12424                    (match_operand:QI 2 "const1_operand" "")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12427    && (TARGET_SHIFT1 || optimize_size)"
12428   "rol{q}\t%0"
12429   [(set_attr "type" "rotate")
12430    (set (attr "length") 
12431      (if_then_else (match_operand:DI 0 "register_operand" "") 
12432         (const_string "2")
12433         (const_string "*")))])
12435 (define_insn "*rotldi3_1_rex64"
12436   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12437         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12438                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12441   "@
12442    rol{q}\t{%2, %0|%0, %2}
12443    rol{q}\t{%b2, %0|%0, %b2}"
12444   [(set_attr "type" "rotate")
12445    (set_attr "mode" "DI")])
12447 (define_expand "rotlsi3"
12448   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12449         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12450                    (match_operand:QI 2 "nonmemory_operand" "")))
12451    (clobber (reg:CC FLAGS_REG))]
12452   ""
12453   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12455 (define_insn "*rotlsi3_1_one_bit"
12456   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12457         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458                    (match_operand:QI 2 "const1_operand" "")))
12459    (clobber (reg:CC FLAGS_REG))]
12460   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12461    && (TARGET_SHIFT1 || optimize_size)"
12462   "rol{l}\t%0"
12463   [(set_attr "type" "rotate")
12464    (set (attr "length") 
12465      (if_then_else (match_operand:SI 0 "register_operand" "") 
12466         (const_string "2")
12467         (const_string "*")))])
12469 (define_insn "*rotlsi3_1_one_bit_zext"
12470   [(set (match_operand:DI 0 "register_operand" "=r")
12471         (zero_extend:DI
12472           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12473                      (match_operand:QI 2 "const1_operand" ""))))
12474    (clobber (reg:CC FLAGS_REG))]
12475   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12476    && (TARGET_SHIFT1 || optimize_size)"
12477   "rol{l}\t%k0"
12478   [(set_attr "type" "rotate")
12479    (set_attr "length" "2")])
12481 (define_insn "*rotlsi3_1"
12482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12483         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12484                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12485    (clobber (reg:CC FLAGS_REG))]
12486   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12487   "@
12488    rol{l}\t{%2, %0|%0, %2}
12489    rol{l}\t{%b2, %0|%0, %b2}"
12490   [(set_attr "type" "rotate")
12491    (set_attr "mode" "SI")])
12493 (define_insn "*rotlsi3_1_zext"
12494   [(set (match_operand:DI 0 "register_operand" "=r,r")
12495         (zero_extend:DI
12496           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12497                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12500   "@
12501    rol{l}\t{%2, %k0|%k0, %2}
12502    rol{l}\t{%b2, %k0|%k0, %b2}"
12503   [(set_attr "type" "rotate")
12504    (set_attr "mode" "SI")])
12506 (define_expand "rotlhi3"
12507   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12508         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12509                    (match_operand:QI 2 "nonmemory_operand" "")))
12510    (clobber (reg:CC FLAGS_REG))]
12511   "TARGET_HIMODE_MATH"
12512   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12514 (define_insn "*rotlhi3_1_one_bit"
12515   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12516         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12517                    (match_operand:QI 2 "const1_operand" "")))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12520    && (TARGET_SHIFT1 || optimize_size)"
12521   "rol{w}\t%0"
12522   [(set_attr "type" "rotate")
12523    (set (attr "length") 
12524      (if_then_else (match_operand 0 "register_operand" "") 
12525         (const_string "2")
12526         (const_string "*")))])
12528 (define_insn "*rotlhi3_1"
12529   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12530         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12531                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12532    (clobber (reg:CC FLAGS_REG))]
12533   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12534   "@
12535    rol{w}\t{%2, %0|%0, %2}
12536    rol{w}\t{%b2, %0|%0, %b2}"
12537   [(set_attr "type" "rotate")
12538    (set_attr "mode" "HI")])
12540 (define_expand "rotlqi3"
12541   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12542         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12543                    (match_operand:QI 2 "nonmemory_operand" "")))
12544    (clobber (reg:CC FLAGS_REG))]
12545   "TARGET_QIMODE_MATH"
12546   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12548 (define_insn "*rotlqi3_1_one_bit_slp"
12549   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12550         (rotate:QI (match_dup 0)
12551                    (match_operand:QI 1 "const1_operand" "")))
12552    (clobber (reg:CC FLAGS_REG))]
12553   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12554    && (TARGET_SHIFT1 || optimize_size)"
12555   "rol{b}\t%0"
12556   [(set_attr "type" "rotate1")
12557    (set (attr "length") 
12558      (if_then_else (match_operand 0 "register_operand" "") 
12559         (const_string "2")
12560         (const_string "*")))])
12562 (define_insn "*rotlqi3_1_one_bit"
12563   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12564         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12565                    (match_operand:QI 2 "const1_operand" "")))
12566    (clobber (reg:CC FLAGS_REG))]
12567   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12568    && (TARGET_SHIFT1 || optimize_size)"
12569   "rol{b}\t%0"
12570   [(set_attr "type" "rotate")
12571    (set (attr "length") 
12572      (if_then_else (match_operand 0 "register_operand" "") 
12573         (const_string "2")
12574         (const_string "*")))])
12576 (define_insn "*rotlqi3_1_slp"
12577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12578         (rotate:QI (match_dup 0)
12579                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12580    (clobber (reg:CC FLAGS_REG))]
12581   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12582    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12583   "@
12584    rol{b}\t{%1, %0|%0, %1}
12585    rol{b}\t{%b1, %0|%0, %b1}"
12586   [(set_attr "type" "rotate1")
12587    (set_attr "mode" "QI")])
12589 (define_insn "*rotlqi3_1"
12590   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12591         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12592                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12595   "@
12596    rol{b}\t{%2, %0|%0, %2}
12597    rol{b}\t{%b2, %0|%0, %b2}"
12598   [(set_attr "type" "rotate")
12599    (set_attr "mode" "QI")])
12601 (define_expand "rotrdi3"
12602   [(set (match_operand:DI 0 "shiftdi_operand" "")
12603         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12604                    (match_operand:QI 2 "nonmemory_operand" "")))
12605    (clobber (reg:CC FLAGS_REG))]
12606  ""
12608   if (TARGET_64BIT)
12609     {
12610       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12611       DONE;
12612     }
12613   if (!const_1_to_31_operand (operands[2], VOIDmode))
12614     FAIL;
12615   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12616   DONE;
12618   
12619 ;; Implement rotation using two double-precision shift instructions
12620 ;; and a scratch register.   
12621 (define_insn_and_split "ix86_rotrdi3"
12622  [(set (match_operand:DI 0 "register_operand" "=r")
12623        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12624                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12625   (clobber (reg:CC FLAGS_REG))
12626   (clobber (match_scratch:SI 3 "=&r"))]
12627  "!TARGET_64BIT"
12628  ""
12629  "&& reload_completed"
12630  [(set (match_dup 3) (match_dup 4))
12631   (parallel
12632    [(set (match_dup 4)
12633          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12634                  (ashift:SI (match_dup 5)
12635                             (minus:QI (const_int 32) (match_dup 2)))))
12636     (clobber (reg:CC FLAGS_REG))])
12637   (parallel
12638    [(set (match_dup 5)
12639          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12640                  (ashift:SI (match_dup 3)
12641                             (minus:QI (const_int 32) (match_dup 2)))))
12642     (clobber (reg:CC FLAGS_REG))])]
12643  "split_di (operands, 1, operands + 4, operands + 5);")
12645 (define_insn "*rotrdi3_1_one_bit_rex64"
12646   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12647         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12648                      (match_operand:QI 2 "const1_operand" "")))
12649    (clobber (reg:CC FLAGS_REG))]
12650   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12651    && (TARGET_SHIFT1 || optimize_size)"
12652   "ror{q}\t%0"
12653   [(set_attr "type" "rotate")
12654    (set (attr "length") 
12655      (if_then_else (match_operand:DI 0 "register_operand" "") 
12656         (const_string "2")
12657         (const_string "*")))])
12659 (define_insn "*rotrdi3_1_rex64"
12660   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12661         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12662                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12663    (clobber (reg:CC FLAGS_REG))]
12664   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12665   "@
12666    ror{q}\t{%2, %0|%0, %2}
12667    ror{q}\t{%b2, %0|%0, %b2}"
12668   [(set_attr "type" "rotate")
12669    (set_attr "mode" "DI")])
12671 (define_expand "rotrsi3"
12672   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12673         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12674                      (match_operand:QI 2 "nonmemory_operand" "")))
12675    (clobber (reg:CC FLAGS_REG))]
12676   ""
12677   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12679 (define_insn "*rotrsi3_1_one_bit"
12680   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12681         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12682                      (match_operand:QI 2 "const1_operand" "")))
12683    (clobber (reg:CC FLAGS_REG))]
12684   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12685    && (TARGET_SHIFT1 || optimize_size)"
12686   "ror{l}\t%0"
12687   [(set_attr "type" "rotate")
12688    (set (attr "length") 
12689      (if_then_else (match_operand:SI 0 "register_operand" "") 
12690         (const_string "2")
12691         (const_string "*")))])
12693 (define_insn "*rotrsi3_1_one_bit_zext"
12694   [(set (match_operand:DI 0 "register_operand" "=r")
12695         (zero_extend:DI
12696           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12697                        (match_operand:QI 2 "const1_operand" ""))))
12698    (clobber (reg:CC FLAGS_REG))]
12699   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12700    && (TARGET_SHIFT1 || optimize_size)"
12701   "ror{l}\t%k0"
12702   [(set_attr "type" "rotate")
12703    (set (attr "length") 
12704      (if_then_else (match_operand:SI 0 "register_operand" "") 
12705         (const_string "2")
12706         (const_string "*")))])
12708 (define_insn "*rotrsi3_1"
12709   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12710         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12711                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12712    (clobber (reg:CC FLAGS_REG))]
12713   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12714   "@
12715    ror{l}\t{%2, %0|%0, %2}
12716    ror{l}\t{%b2, %0|%0, %b2}"
12717   [(set_attr "type" "rotate")
12718    (set_attr "mode" "SI")])
12720 (define_insn "*rotrsi3_1_zext"
12721   [(set (match_operand:DI 0 "register_operand" "=r,r")
12722         (zero_extend:DI
12723           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12724                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12725    (clobber (reg:CC FLAGS_REG))]
12726   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12727   "@
12728    ror{l}\t{%2, %k0|%k0, %2}
12729    ror{l}\t{%b2, %k0|%k0, %b2}"
12730   [(set_attr "type" "rotate")
12731    (set_attr "mode" "SI")])
12733 (define_expand "rotrhi3"
12734   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12735         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12736                      (match_operand:QI 2 "nonmemory_operand" "")))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "TARGET_HIMODE_MATH"
12739   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12741 (define_insn "*rotrhi3_one_bit"
12742   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12743         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12744                      (match_operand:QI 2 "const1_operand" "")))
12745    (clobber (reg:CC FLAGS_REG))]
12746   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12747    && (TARGET_SHIFT1 || optimize_size)"
12748   "ror{w}\t%0"
12749   [(set_attr "type" "rotate")
12750    (set (attr "length") 
12751      (if_then_else (match_operand 0 "register_operand" "") 
12752         (const_string "2")
12753         (const_string "*")))])
12755 (define_insn "*rotrhi3"
12756   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12757         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12758                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12761   "@
12762    ror{w}\t{%2, %0|%0, %2}
12763    ror{w}\t{%b2, %0|%0, %b2}"
12764   [(set_attr "type" "rotate")
12765    (set_attr "mode" "HI")])
12767 (define_expand "rotrqi3"
12768   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12769         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12770                      (match_operand:QI 2 "nonmemory_operand" "")))
12771    (clobber (reg:CC FLAGS_REG))]
12772   "TARGET_QIMODE_MATH"
12773   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12775 (define_insn "*rotrqi3_1_one_bit"
12776   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12778                      (match_operand:QI 2 "const1_operand" "")))
12779    (clobber (reg:CC FLAGS_REG))]
12780   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12781    && (TARGET_SHIFT1 || optimize_size)"
12782   "ror{b}\t%0"
12783   [(set_attr "type" "rotate")
12784    (set (attr "length") 
12785      (if_then_else (match_operand 0 "register_operand" "") 
12786         (const_string "2")
12787         (const_string "*")))])
12789 (define_insn "*rotrqi3_1_one_bit_slp"
12790   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12791         (rotatert:QI (match_dup 0)
12792                      (match_operand:QI 1 "const1_operand" "")))
12793    (clobber (reg:CC FLAGS_REG))]
12794   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12795    && (TARGET_SHIFT1 || optimize_size)"
12796   "ror{b}\t%0"
12797   [(set_attr "type" "rotate1")
12798    (set (attr "length") 
12799      (if_then_else (match_operand 0 "register_operand" "") 
12800         (const_string "2")
12801         (const_string "*")))])
12803 (define_insn "*rotrqi3_1"
12804   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12805         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12806                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12807    (clobber (reg:CC FLAGS_REG))]
12808   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12809   "@
12810    ror{b}\t{%2, %0|%0, %2}
12811    ror{b}\t{%b2, %0|%0, %b2}"
12812   [(set_attr "type" "rotate")
12813    (set_attr "mode" "QI")])
12815 (define_insn "*rotrqi3_1_slp"
12816   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12817         (rotatert:QI (match_dup 0)
12818                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12819    (clobber (reg:CC FLAGS_REG))]
12820   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12821    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12822   "@
12823    ror{b}\t{%1, %0|%0, %1}
12824    ror{b}\t{%b1, %0|%0, %b1}"
12825   [(set_attr "type" "rotate1")
12826    (set_attr "mode" "QI")])
12828 ;; Bit set / bit test instructions
12830 (define_expand "extv"
12831   [(set (match_operand:SI 0 "register_operand" "")
12832         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12833                          (match_operand:SI 2 "const8_operand" "")
12834                          (match_operand:SI 3 "const8_operand" "")))]
12835   ""
12837   /* Handle extractions from %ah et al.  */
12838   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12839     FAIL;
12841   /* From mips.md: extract_bit_field doesn't verify that our source
12842      matches the predicate, so check it again here.  */
12843   if (! ext_register_operand (operands[1], VOIDmode))
12844     FAIL;
12847 (define_expand "extzv"
12848   [(set (match_operand:SI 0 "register_operand" "")
12849         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12850                          (match_operand:SI 2 "const8_operand" "")
12851                          (match_operand:SI 3 "const8_operand" "")))]
12852   ""
12854   /* Handle extractions from %ah et al.  */
12855   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12856     FAIL;
12858   /* From mips.md: extract_bit_field doesn't verify that our source
12859      matches the predicate, so check it again here.  */
12860   if (! ext_register_operand (operands[1], VOIDmode))
12861     FAIL;
12864 (define_expand "insv"
12865   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12866                       (match_operand 1 "const8_operand" "")
12867                       (match_operand 2 "const8_operand" ""))
12868         (match_operand 3 "register_operand" ""))]
12869   ""
12871   /* Handle insertions to %ah et al.  */
12872   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12873     FAIL;
12875   /* From mips.md: insert_bit_field doesn't verify that our source
12876      matches the predicate, so check it again here.  */
12877   if (! ext_register_operand (operands[0], VOIDmode))
12878     FAIL;
12880   if (TARGET_64BIT)
12881     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12882   else
12883     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12885   DONE;
12888 ;; %%% bts, btr, btc, bt.
12889 ;; In general these instructions are *slow* when applied to memory,
12890 ;; since they enforce atomic operation.  When applied to registers,
12891 ;; it depends on the cpu implementation.  They're never faster than
12892 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12893 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12894 ;; within the instruction itself, so operating on bits in the high
12895 ;; 32-bits of a register becomes easier.
12897 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12898 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12899 ;; negdf respectively, so they can never be disabled entirely.
12901 (define_insn "*btsq"
12902   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12903                          (const_int 1)
12904                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12905         (const_int 1))
12906    (clobber (reg:CC FLAGS_REG))]
12907   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12908   "bts{q} %1,%0"
12909   [(set_attr "type" "alu1")])
12911 (define_insn "*btrq"
12912   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12913                          (const_int 1)
12914                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12915         (const_int 0))
12916    (clobber (reg:CC FLAGS_REG))]
12917   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12918   "btr{q} %1,%0"
12919   [(set_attr "type" "alu1")])
12921 (define_insn "*btcq"
12922   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12923                          (const_int 1)
12924                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12925         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12928   "btc{q} %1,%0"
12929   [(set_attr "type" "alu1")])
12931 ;; Allow Nocona to avoid these instructions if a register is available.
12933 (define_peephole2
12934   [(match_scratch:DI 2 "r")
12935    (parallel [(set (zero_extract:DI
12936                      (match_operand:DI 0 "register_operand" "")
12937                      (const_int 1)
12938                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12939                    (const_int 1))
12940               (clobber (reg:CC FLAGS_REG))])]
12941   "TARGET_64BIT && !TARGET_USE_BT"
12942   [(const_int 0)]
12944   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12945   rtx op1;
12947   if (HOST_BITS_PER_WIDE_INT >= 64)
12948     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12949   else if (i < HOST_BITS_PER_WIDE_INT)
12950     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12951   else
12952     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12954   op1 = immed_double_const (lo, hi, DImode);
12955   if (i >= 31)
12956     {
12957       emit_move_insn (operands[2], op1);
12958       op1 = operands[2];
12959     }
12961   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12962   DONE;
12965 (define_peephole2
12966   [(match_scratch:DI 2 "r")
12967    (parallel [(set (zero_extract:DI
12968                      (match_operand:DI 0 "register_operand" "")
12969                      (const_int 1)
12970                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12971                    (const_int 0))
12972               (clobber (reg:CC FLAGS_REG))])]
12973   "TARGET_64BIT && !TARGET_USE_BT"
12974   [(const_int 0)]
12976   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12977   rtx op1;
12979   if (HOST_BITS_PER_WIDE_INT >= 64)
12980     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12981   else if (i < HOST_BITS_PER_WIDE_INT)
12982     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12983   else
12984     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12986   op1 = immed_double_const (~lo, ~hi, DImode);
12987   if (i >= 32)
12988     {
12989       emit_move_insn (operands[2], op1);
12990       op1 = operands[2];
12991     }
12993   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12994   DONE;
12997 (define_peephole2
12998   [(match_scratch:DI 2 "r")
12999    (parallel [(set (zero_extract:DI
13000                      (match_operand:DI 0 "register_operand" "")
13001                      (const_int 1)
13002                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13003               (not:DI (zero_extract:DI
13004                         (match_dup 0) (const_int 1) (match_dup 1))))
13005               (clobber (reg:CC FLAGS_REG))])]
13006   "TARGET_64BIT && !TARGET_USE_BT"
13007   [(const_int 0)]
13009   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13010   rtx op1;
13012   if (HOST_BITS_PER_WIDE_INT >= 64)
13013     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13014   else if (i < HOST_BITS_PER_WIDE_INT)
13015     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13016   else
13017     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13019   op1 = immed_double_const (lo, hi, DImode);
13020   if (i >= 31)
13021     {
13022       emit_move_insn (operands[2], op1);
13023       op1 = operands[2];
13024     }
13026   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13027   DONE;
13030 ;; Store-flag instructions.
13032 ;; For all sCOND expanders, also expand the compare or test insn that
13033 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13035 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13036 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13037 ;; way, which can later delete the movzx if only QImode is needed.
13039 (define_expand "seq"
13040   [(set (match_operand:QI 0 "register_operand" "")
13041         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13042   ""
13043   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13045 (define_expand "sne"
13046   [(set (match_operand:QI 0 "register_operand" "")
13047         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13048   ""
13049   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13051 (define_expand "sgt"
13052   [(set (match_operand:QI 0 "register_operand" "")
13053         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13054   ""
13055   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13057 (define_expand "sgtu"
13058   [(set (match_operand:QI 0 "register_operand" "")
13059         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13060   ""
13061   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13063 (define_expand "slt"
13064   [(set (match_operand:QI 0 "register_operand" "")
13065         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13066   ""
13067   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13069 (define_expand "sltu"
13070   [(set (match_operand:QI 0 "register_operand" "")
13071         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13072   ""
13073   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13075 (define_expand "sge"
13076   [(set (match_operand:QI 0 "register_operand" "")
13077         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13078   ""
13079   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13081 (define_expand "sgeu"
13082   [(set (match_operand:QI 0 "register_operand" "")
13083         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13084   ""
13085   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13087 (define_expand "sle"
13088   [(set (match_operand:QI 0 "register_operand" "")
13089         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13090   ""
13091   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13093 (define_expand "sleu"
13094   [(set (match_operand:QI 0 "register_operand" "")
13095         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13096   ""
13097   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13099 (define_expand "sunordered"
13100   [(set (match_operand:QI 0 "register_operand" "")
13101         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13102   "TARGET_80387 || TARGET_SSE"
13103   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13105 (define_expand "sordered"
13106   [(set (match_operand:QI 0 "register_operand" "")
13107         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13108   "TARGET_80387"
13109   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13111 (define_expand "suneq"
13112   [(set (match_operand:QI 0 "register_operand" "")
13113         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13114   "TARGET_80387 || TARGET_SSE"
13115   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13117 (define_expand "sunge"
13118   [(set (match_operand:QI 0 "register_operand" "")
13119         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13120   "TARGET_80387 || TARGET_SSE"
13121   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13123 (define_expand "sungt"
13124   [(set (match_operand:QI 0 "register_operand" "")
13125         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13126   "TARGET_80387 || TARGET_SSE"
13127   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13129 (define_expand "sunle"
13130   [(set (match_operand:QI 0 "register_operand" "")
13131         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13132   "TARGET_80387 || TARGET_SSE"
13133   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13135 (define_expand "sunlt"
13136   [(set (match_operand:QI 0 "register_operand" "")
13137         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13138   "TARGET_80387 || TARGET_SSE"
13139   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13141 (define_expand "sltgt"
13142   [(set (match_operand:QI 0 "register_operand" "")
13143         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13144   "TARGET_80387 || TARGET_SSE"
13145   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13147 (define_insn "*setcc_1"
13148   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13149         (match_operator:QI 1 "ix86_comparison_operator"
13150           [(reg FLAGS_REG) (const_int 0)]))]
13151   ""
13152   "set%C1\t%0"
13153   [(set_attr "type" "setcc")
13154    (set_attr "mode" "QI")])
13156 (define_insn "*setcc_2"
13157   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13158         (match_operator:QI 1 "ix86_comparison_operator"
13159           [(reg FLAGS_REG) (const_int 0)]))]
13160   ""
13161   "set%C1\t%0"
13162   [(set_attr "type" "setcc")
13163    (set_attr "mode" "QI")])
13165 ;; In general it is not safe to assume too much about CCmode registers,
13166 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13167 ;; conditions this is safe on x86, so help combine not create
13169 ;;      seta    %al
13170 ;;      testb   %al, %al
13171 ;;      sete    %al
13173 (define_split 
13174   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13175         (ne:QI (match_operator 1 "ix86_comparison_operator"
13176                  [(reg FLAGS_REG) (const_int 0)])
13177             (const_int 0)))]
13178   ""
13179   [(set (match_dup 0) (match_dup 1))]
13181   PUT_MODE (operands[1], QImode);
13184 (define_split 
13185   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13186         (ne:QI (match_operator 1 "ix86_comparison_operator"
13187                  [(reg FLAGS_REG) (const_int 0)])
13188             (const_int 0)))]
13189   ""
13190   [(set (match_dup 0) (match_dup 1))]
13192   PUT_MODE (operands[1], QImode);
13195 (define_split 
13196   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13197         (eq:QI (match_operator 1 "ix86_comparison_operator"
13198                  [(reg FLAGS_REG) (const_int 0)])
13199             (const_int 0)))]
13200   ""
13201   [(set (match_dup 0) (match_dup 1))]
13203   rtx new_op1 = copy_rtx (operands[1]);
13204   operands[1] = new_op1;
13205   PUT_MODE (new_op1, QImode);
13206   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13207                                              GET_MODE (XEXP (new_op1, 0))));
13209   /* Make sure that (a) the CCmode we have for the flags is strong
13210      enough for the reversed compare or (b) we have a valid FP compare.  */
13211   if (! ix86_comparison_operator (new_op1, VOIDmode))
13212     FAIL;
13215 (define_split 
13216   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13217         (eq:QI (match_operator 1 "ix86_comparison_operator"
13218                  [(reg FLAGS_REG) (const_int 0)])
13219             (const_int 0)))]
13220   ""
13221   [(set (match_dup 0) (match_dup 1))]
13223   rtx new_op1 = copy_rtx (operands[1]);
13224   operands[1] = new_op1;
13225   PUT_MODE (new_op1, QImode);
13226   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13227                                              GET_MODE (XEXP (new_op1, 0))));
13229   /* Make sure that (a) the CCmode we have for the flags is strong
13230      enough for the reversed compare or (b) we have a valid FP compare.  */
13231   if (! ix86_comparison_operator (new_op1, VOIDmode))
13232     FAIL;
13235 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13236 ;; subsequent logical operations are used to imitate conditional moves.
13237 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13238 ;; it directly.
13240 (define_insn "*sse_setccsf"
13241   [(set (match_operand:SF 0 "register_operand" "=x")
13242         (match_operator:SF 1 "sse_comparison_operator"
13243           [(match_operand:SF 2 "register_operand" "0")
13244            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13245   "TARGET_SSE"
13246   "cmp%D1ss\t{%3, %0|%0, %3}"
13247   [(set_attr "type" "ssecmp")
13248    (set_attr "mode" "SF")])
13250 (define_insn "*sse_setccdf"
13251   [(set (match_operand:DF 0 "register_operand" "=Y")
13252         (match_operator:DF 1 "sse_comparison_operator"
13253           [(match_operand:DF 2 "register_operand" "0")
13254            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13255   "TARGET_SSE2"
13256   "cmp%D1sd\t{%3, %0|%0, %3}"
13257   [(set_attr "type" "ssecmp")
13258    (set_attr "mode" "DF")])
13260 ;; Basic conditional jump instructions.
13261 ;; We ignore the overflow flag for signed branch instructions.
13263 ;; For all bCOND expanders, also expand the compare or test insn that
13264 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13266 (define_expand "beq"
13267   [(set (pc)
13268         (if_then_else (match_dup 1)
13269                       (label_ref (match_operand 0 "" ""))
13270                       (pc)))]
13271   ""
13272   "ix86_expand_branch (EQ, operands[0]); DONE;")
13274 (define_expand "bne"
13275   [(set (pc)
13276         (if_then_else (match_dup 1)
13277                       (label_ref (match_operand 0 "" ""))
13278                       (pc)))]
13279   ""
13280   "ix86_expand_branch (NE, operands[0]); DONE;")
13282 (define_expand "bgt"
13283   [(set (pc)
13284         (if_then_else (match_dup 1)
13285                       (label_ref (match_operand 0 "" ""))
13286                       (pc)))]
13287   ""
13288   "ix86_expand_branch (GT, operands[0]); DONE;")
13290 (define_expand "bgtu"
13291   [(set (pc)
13292         (if_then_else (match_dup 1)
13293                       (label_ref (match_operand 0 "" ""))
13294                       (pc)))]
13295   ""
13296   "ix86_expand_branch (GTU, operands[0]); DONE;")
13298 (define_expand "blt"
13299   [(set (pc)
13300         (if_then_else (match_dup 1)
13301                       (label_ref (match_operand 0 "" ""))
13302                       (pc)))]
13303   ""
13304   "ix86_expand_branch (LT, operands[0]); DONE;")
13306 (define_expand "bltu"
13307   [(set (pc)
13308         (if_then_else (match_dup 1)
13309                       (label_ref (match_operand 0 "" ""))
13310                       (pc)))]
13311   ""
13312   "ix86_expand_branch (LTU, operands[0]); DONE;")
13314 (define_expand "bge"
13315   [(set (pc)
13316         (if_then_else (match_dup 1)
13317                       (label_ref (match_operand 0 "" ""))
13318                       (pc)))]
13319   ""
13320   "ix86_expand_branch (GE, operands[0]); DONE;")
13322 (define_expand "bgeu"
13323   [(set (pc)
13324         (if_then_else (match_dup 1)
13325                       (label_ref (match_operand 0 "" ""))
13326                       (pc)))]
13327   ""
13328   "ix86_expand_branch (GEU, operands[0]); DONE;")
13330 (define_expand "ble"
13331   [(set (pc)
13332         (if_then_else (match_dup 1)
13333                       (label_ref (match_operand 0 "" ""))
13334                       (pc)))]
13335   ""
13336   "ix86_expand_branch (LE, operands[0]); DONE;")
13338 (define_expand "bleu"
13339   [(set (pc)
13340         (if_then_else (match_dup 1)
13341                       (label_ref (match_operand 0 "" ""))
13342                       (pc)))]
13343   ""
13344   "ix86_expand_branch (LEU, operands[0]); DONE;")
13346 (define_expand "bunordered"
13347   [(set (pc)
13348         (if_then_else (match_dup 1)
13349                       (label_ref (match_operand 0 "" ""))
13350                       (pc)))]
13351   "TARGET_80387 || TARGET_SSE_MATH"
13352   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13354 (define_expand "bordered"
13355   [(set (pc)
13356         (if_then_else (match_dup 1)
13357                       (label_ref (match_operand 0 "" ""))
13358                       (pc)))]
13359   "TARGET_80387 || TARGET_SSE_MATH"
13360   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13362 (define_expand "buneq"
13363   [(set (pc)
13364         (if_then_else (match_dup 1)
13365                       (label_ref (match_operand 0 "" ""))
13366                       (pc)))]
13367   "TARGET_80387 || TARGET_SSE_MATH"
13368   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13370 (define_expand "bunge"
13371   [(set (pc)
13372         (if_then_else (match_dup 1)
13373                       (label_ref (match_operand 0 "" ""))
13374                       (pc)))]
13375   "TARGET_80387 || TARGET_SSE_MATH"
13376   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13378 (define_expand "bungt"
13379   [(set (pc)
13380         (if_then_else (match_dup 1)
13381                       (label_ref (match_operand 0 "" ""))
13382                       (pc)))]
13383   "TARGET_80387 || TARGET_SSE_MATH"
13384   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13386 (define_expand "bunle"
13387   [(set (pc)
13388         (if_then_else (match_dup 1)
13389                       (label_ref (match_operand 0 "" ""))
13390                       (pc)))]
13391   "TARGET_80387 || TARGET_SSE_MATH"
13392   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13394 (define_expand "bunlt"
13395   [(set (pc)
13396         (if_then_else (match_dup 1)
13397                       (label_ref (match_operand 0 "" ""))
13398                       (pc)))]
13399   "TARGET_80387 || TARGET_SSE_MATH"
13400   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13402 (define_expand "bltgt"
13403   [(set (pc)
13404         (if_then_else (match_dup 1)
13405                       (label_ref (match_operand 0 "" ""))
13406                       (pc)))]
13407   "TARGET_80387 || TARGET_SSE_MATH"
13408   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13410 (define_insn "*jcc_1"
13411   [(set (pc)
13412         (if_then_else (match_operator 1 "ix86_comparison_operator"
13413                                       [(reg FLAGS_REG) (const_int 0)])
13414                       (label_ref (match_operand 0 "" ""))
13415                       (pc)))]
13416   ""
13417   "%+j%C1\t%l0"
13418   [(set_attr "type" "ibr")
13419    (set_attr "modrm" "0")
13420    (set (attr "length")
13421            (if_then_else (and (ge (minus (match_dup 0) (pc))
13422                                   (const_int -126))
13423                               (lt (minus (match_dup 0) (pc))
13424                                   (const_int 128)))
13425              (const_int 2)
13426              (const_int 6)))])
13428 (define_insn "*jcc_2"
13429   [(set (pc)
13430         (if_then_else (match_operator 1 "ix86_comparison_operator"
13431                                       [(reg FLAGS_REG) (const_int 0)])
13432                       (pc)
13433                       (label_ref (match_operand 0 "" ""))))]
13434   ""
13435   "%+j%c1\t%l0"
13436   [(set_attr "type" "ibr")
13437    (set_attr "modrm" "0")
13438    (set (attr "length")
13439            (if_then_else (and (ge (minus (match_dup 0) (pc))
13440                                   (const_int -126))
13441                               (lt (minus (match_dup 0) (pc))
13442                                   (const_int 128)))
13443              (const_int 2)
13444              (const_int 6)))])
13446 ;; In general it is not safe to assume too much about CCmode registers,
13447 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13448 ;; conditions this is safe on x86, so help combine not create
13450 ;;      seta    %al
13451 ;;      testb   %al, %al
13452 ;;      je      Lfoo
13454 (define_split 
13455   [(set (pc)
13456         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13457                                       [(reg FLAGS_REG) (const_int 0)])
13458                           (const_int 0))
13459                       (label_ref (match_operand 1 "" ""))
13460                       (pc)))]
13461   ""
13462   [(set (pc)
13463         (if_then_else (match_dup 0)
13464                       (label_ref (match_dup 1))
13465                       (pc)))]
13467   PUT_MODE (operands[0], VOIDmode);
13469   
13470 (define_split 
13471   [(set (pc)
13472         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13473                                       [(reg FLAGS_REG) (const_int 0)])
13474                           (const_int 0))
13475                       (label_ref (match_operand 1 "" ""))
13476                       (pc)))]
13477   ""
13478   [(set (pc)
13479         (if_then_else (match_dup 0)
13480                       (label_ref (match_dup 1))
13481                       (pc)))]
13483   rtx new_op0 = copy_rtx (operands[0]);
13484   operands[0] = new_op0;
13485   PUT_MODE (new_op0, VOIDmode);
13486   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13487                                              GET_MODE (XEXP (new_op0, 0))));
13489   /* Make sure that (a) the CCmode we have for the flags is strong
13490      enough for the reversed compare or (b) we have a valid FP compare.  */
13491   if (! ix86_comparison_operator (new_op0, VOIDmode))
13492     FAIL;
13495 ;; Define combination compare-and-branch fp compare instructions to use
13496 ;; during early optimization.  Splitting the operation apart early makes
13497 ;; for bad code when we want to reverse the operation.
13499 (define_insn "*fp_jcc_1_mixed"
13500   [(set (pc)
13501         (if_then_else (match_operator 0 "comparison_operator"
13502                         [(match_operand 1 "register_operand" "f#x,x#f")
13503                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13504           (label_ref (match_operand 3 "" ""))
13505           (pc)))
13506    (clobber (reg:CCFP FPSR_REG))
13507    (clobber (reg:CCFP FLAGS_REG))]
13508   "TARGET_MIX_SSE_I387
13509    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13510    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13511    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13512   "#")
13514 (define_insn "*fp_jcc_1_sse"
13515   [(set (pc)
13516         (if_then_else (match_operator 0 "comparison_operator"
13517                         [(match_operand 1 "register_operand" "x")
13518                          (match_operand 2 "nonimmediate_operand" "xm")])
13519           (label_ref (match_operand 3 "" ""))
13520           (pc)))
13521    (clobber (reg:CCFP FPSR_REG))
13522    (clobber (reg:CCFP FLAGS_REG))]
13523   "TARGET_SSE_MATH
13524    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13525    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13526    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13527   "#")
13529 (define_insn "*fp_jcc_1_387"
13530   [(set (pc)
13531         (if_then_else (match_operator 0 "comparison_operator"
13532                         [(match_operand 1 "register_operand" "f")
13533                          (match_operand 2 "register_operand" "f")])
13534           (label_ref (match_operand 3 "" ""))
13535           (pc)))
13536    (clobber (reg:CCFP FPSR_REG))
13537    (clobber (reg:CCFP FLAGS_REG))]
13538   "TARGET_CMOVE && TARGET_80387
13539    && FLOAT_MODE_P (GET_MODE (operands[1]))
13540    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13541    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13542   "#")
13544 (define_insn "*fp_jcc_2_mixed"
13545   [(set (pc)
13546         (if_then_else (match_operator 0 "comparison_operator"
13547                         [(match_operand 1 "register_operand" "f#x,x#f")
13548                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13549           (pc)
13550           (label_ref (match_operand 3 "" ""))))
13551    (clobber (reg:CCFP FPSR_REG))
13552    (clobber (reg:CCFP FLAGS_REG))]
13553   "TARGET_MIX_SSE_I387
13554    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13555    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13556    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13557   "#")
13559 (define_insn "*fp_jcc_2_sse"
13560   [(set (pc)
13561         (if_then_else (match_operator 0 "comparison_operator"
13562                         [(match_operand 1 "register_operand" "x")
13563                          (match_operand 2 "nonimmediate_operand" "xm")])
13564           (pc)
13565           (label_ref (match_operand 3 "" ""))))
13566    (clobber (reg:CCFP FPSR_REG))
13567    (clobber (reg:CCFP FLAGS_REG))]
13568   "TARGET_SSE_MATH
13569    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13570    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13571    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13572   "#")
13574 (define_insn "*fp_jcc_2_387"
13575   [(set (pc)
13576         (if_then_else (match_operator 0 "comparison_operator"
13577                         [(match_operand 1 "register_operand" "f")
13578                          (match_operand 2 "register_operand" "f")])
13579           (pc)
13580           (label_ref (match_operand 3 "" ""))))
13581    (clobber (reg:CCFP FPSR_REG))
13582    (clobber (reg:CCFP FLAGS_REG))]
13583   "TARGET_CMOVE && TARGET_80387
13584    && FLOAT_MODE_P (GET_MODE (operands[1]))
13585    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13586    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13587   "#")
13589 (define_insn "*fp_jcc_3_387"
13590   [(set (pc)
13591         (if_then_else (match_operator 0 "comparison_operator"
13592                         [(match_operand 1 "register_operand" "f")
13593                          (match_operand 2 "nonimmediate_operand" "fm")])
13594           (label_ref (match_operand 3 "" ""))
13595           (pc)))
13596    (clobber (reg:CCFP FPSR_REG))
13597    (clobber (reg:CCFP FLAGS_REG))
13598    (clobber (match_scratch:HI 4 "=a"))]
13599   "TARGET_80387
13600    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13601    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13602    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13603    && SELECT_CC_MODE (GET_CODE (operands[0]),
13604                       operands[1], operands[2]) == CCFPmode
13605    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13606   "#")
13608 (define_insn "*fp_jcc_4_387"
13609   [(set (pc)
13610         (if_then_else (match_operator 0 "comparison_operator"
13611                         [(match_operand 1 "register_operand" "f")
13612                          (match_operand 2 "nonimmediate_operand" "fm")])
13613           (pc)
13614           (label_ref (match_operand 3 "" ""))))
13615    (clobber (reg:CCFP FPSR_REG))
13616    (clobber (reg:CCFP FLAGS_REG))
13617    (clobber (match_scratch:HI 4 "=a"))]
13618   "TARGET_80387
13619    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13620    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13621    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13622    && SELECT_CC_MODE (GET_CODE (operands[0]),
13623                       operands[1], operands[2]) == CCFPmode
13624    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13625   "#")
13627 (define_insn "*fp_jcc_5_387"
13628   [(set (pc)
13629         (if_then_else (match_operator 0 "comparison_operator"
13630                         [(match_operand 1 "register_operand" "f")
13631                          (match_operand 2 "register_operand" "f")])
13632           (label_ref (match_operand 3 "" ""))
13633           (pc)))
13634    (clobber (reg:CCFP FPSR_REG))
13635    (clobber (reg:CCFP FLAGS_REG))
13636    (clobber (match_scratch:HI 4 "=a"))]
13637   "TARGET_80387
13638    && FLOAT_MODE_P (GET_MODE (operands[1]))
13639    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13640    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13641   "#")
13643 (define_insn "*fp_jcc_6_387"
13644   [(set (pc)
13645         (if_then_else (match_operator 0 "comparison_operator"
13646                         [(match_operand 1 "register_operand" "f")
13647                          (match_operand 2 "register_operand" "f")])
13648           (pc)
13649           (label_ref (match_operand 3 "" ""))))
13650    (clobber (reg:CCFP FPSR_REG))
13651    (clobber (reg:CCFP FLAGS_REG))
13652    (clobber (match_scratch:HI 4 "=a"))]
13653   "TARGET_80387
13654    && FLOAT_MODE_P (GET_MODE (operands[1]))
13655    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13656    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13657   "#")
13659 (define_insn "*fp_jcc_7_387"
13660   [(set (pc)
13661         (if_then_else (match_operator 0 "comparison_operator"
13662                         [(match_operand 1 "register_operand" "f")
13663                          (match_operand 2 "const0_operand" "X")])
13664           (label_ref (match_operand 3 "" ""))
13665           (pc)))
13666    (clobber (reg:CCFP FPSR_REG))
13667    (clobber (reg:CCFP FLAGS_REG))
13668    (clobber (match_scratch:HI 4 "=a"))]
13669   "TARGET_80387
13670    && FLOAT_MODE_P (GET_MODE (operands[1]))
13671    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13672    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13673    && SELECT_CC_MODE (GET_CODE (operands[0]),
13674                       operands[1], operands[2]) == CCFPmode
13675    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13676   "#")
13678 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13679 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13680 ;; with a precedence over other operators and is always put in the first
13681 ;; place. Swap condition and operands to match ficom instruction.
13683 (define_insn "*fp_jcc_8<mode>_387"
13684   [(set (pc)
13685         (if_then_else (match_operator 0 "comparison_operator"
13686                         [(match_operator 1 "float_operator"
13687                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13688                            (match_operand 3 "register_operand" "f,f")])
13689           (label_ref (match_operand 4 "" ""))
13690           (pc)))
13691    (clobber (reg:CCFP FPSR_REG))
13692    (clobber (reg:CCFP FLAGS_REG))
13693    (clobber (match_scratch:HI 5 "=a,a"))]
13694   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13695    && FLOAT_MODE_P (GET_MODE (operands[3]))
13696    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13697    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13698    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13699    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13700   "#")
13702 (define_split
13703   [(set (pc)
13704         (if_then_else (match_operator 0 "comparison_operator"
13705                         [(match_operand 1 "register_operand" "")
13706                          (match_operand 2 "nonimmediate_operand" "")])
13707           (match_operand 3 "" "")
13708           (match_operand 4 "" "")))
13709    (clobber (reg:CCFP FPSR_REG))
13710    (clobber (reg:CCFP FLAGS_REG))]
13711   "reload_completed"
13712   [(const_int 0)]
13714   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13715                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13716   DONE;
13719 (define_split
13720   [(set (pc)
13721         (if_then_else (match_operator 0 "comparison_operator"
13722                         [(match_operand 1 "register_operand" "")
13723                          (match_operand 2 "general_operand" "")])
13724           (match_operand 3 "" "")
13725           (match_operand 4 "" "")))
13726    (clobber (reg:CCFP FPSR_REG))
13727    (clobber (reg:CCFP FLAGS_REG))
13728    (clobber (match_scratch:HI 5 "=a"))]
13729   "reload_completed"
13730   [(const_int 0)]
13732   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13733                         operands[3], operands[4], operands[5], NULL_RTX);
13734   DONE;
13737 (define_split
13738   [(set (pc)
13739         (if_then_else (match_operator 0 "comparison_operator"
13740                         [(match_operator 1 "float_operator"
13741                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13742                            (match_operand 3 "register_operand" "")])
13743           (match_operand 4 "" "")
13744           (match_operand 5 "" "")))
13745    (clobber (reg:CCFP FPSR_REG))
13746    (clobber (reg:CCFP FLAGS_REG))
13747    (clobber (match_scratch:HI 6 "=a"))]
13748   "reload_completed"
13749   [(const_int 0)]
13751   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13752   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13753                         operands[3], operands[7],
13754                         operands[4], operands[5], operands[6], NULL_RTX);
13755   DONE;
13758 ;; %%% Kill this when reload knows how to do it.
13759 (define_split
13760   [(set (pc)
13761         (if_then_else (match_operator 0 "comparison_operator"
13762                         [(match_operator 1 "float_operator"
13763                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13764                            (match_operand 3 "register_operand" "")])
13765           (match_operand 4 "" "")
13766           (match_operand 5 "" "")))
13767    (clobber (reg:CCFP FPSR_REG))
13768    (clobber (reg:CCFP FLAGS_REG))
13769    (clobber (match_scratch:HI 6 "=a"))]
13770   "reload_completed"
13771   [(const_int 0)]
13773   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13774   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13775   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13776                         operands[3], operands[7],
13777                         operands[4], operands[5], operands[6], operands[2]);
13778   DONE;
13781 ;; Unconditional and other jump instructions
13783 (define_insn "jump"
13784   [(set (pc)
13785         (label_ref (match_operand 0 "" "")))]
13786   ""
13787   "jmp\t%l0"
13788   [(set_attr "type" "ibr")
13789    (set (attr "length")
13790            (if_then_else (and (ge (minus (match_dup 0) (pc))
13791                                   (const_int -126))
13792                               (lt (minus (match_dup 0) (pc))
13793                                   (const_int 128)))
13794              (const_int 2)
13795              (const_int 5)))
13796    (set_attr "modrm" "0")])
13798 (define_expand "indirect_jump"
13799   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13800   ""
13801   "")
13803 (define_insn "*indirect_jump"
13804   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13805   "!TARGET_64BIT"
13806   "jmp\t%A0"
13807   [(set_attr "type" "ibr")
13808    (set_attr "length_immediate" "0")])
13810 (define_insn "*indirect_jump_rtx64"
13811   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13812   "TARGET_64BIT"
13813   "jmp\t%A0"
13814   [(set_attr "type" "ibr")
13815    (set_attr "length_immediate" "0")])
13817 (define_expand "tablejump"
13818   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13819               (use (label_ref (match_operand 1 "" "")))])]
13820   ""
13822   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13823      relative.  Convert the relative address to an absolute address.  */
13824   if (flag_pic)
13825     {
13826       rtx op0, op1;
13827       enum rtx_code code;
13829       if (TARGET_64BIT)
13830         {
13831           code = PLUS;
13832           op0 = operands[0];
13833           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13834         }
13835       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13836         {
13837           code = PLUS;
13838           op0 = operands[0];
13839           op1 = pic_offset_table_rtx;
13840         }
13841       else
13842         {
13843           code = MINUS;
13844           op0 = pic_offset_table_rtx;
13845           op1 = operands[0];
13846         }
13848       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13849                                          OPTAB_DIRECT);
13850     }
13853 (define_insn "*tablejump_1"
13854   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13855    (use (label_ref (match_operand 1 "" "")))]
13856   "!TARGET_64BIT"
13857   "jmp\t%A0"
13858   [(set_attr "type" "ibr")
13859    (set_attr "length_immediate" "0")])
13861 (define_insn "*tablejump_1_rtx64"
13862   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13863    (use (label_ref (match_operand 1 "" "")))]
13864   "TARGET_64BIT"
13865   "jmp\t%A0"
13866   [(set_attr "type" "ibr")
13867    (set_attr "length_immediate" "0")])
13869 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13871 (define_peephole2
13872   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13873    (set (match_operand:QI 1 "register_operand" "")
13874         (match_operator:QI 2 "ix86_comparison_operator"
13875           [(reg FLAGS_REG) (const_int 0)]))
13876    (set (match_operand 3 "q_regs_operand" "")
13877         (zero_extend (match_dup 1)))]
13878   "(peep2_reg_dead_p (3, operands[1])
13879     || operands_match_p (operands[1], operands[3]))
13880    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13881   [(set (match_dup 4) (match_dup 0))
13882    (set (strict_low_part (match_dup 5))
13883         (match_dup 2))]
13885   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13886   operands[5] = gen_lowpart (QImode, operands[3]);
13887   ix86_expand_clear (operands[3]);
13890 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13892 (define_peephole2
13893   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13894    (set (match_operand:QI 1 "register_operand" "")
13895         (match_operator:QI 2 "ix86_comparison_operator"
13896           [(reg FLAGS_REG) (const_int 0)]))
13897    (parallel [(set (match_operand 3 "q_regs_operand" "")
13898                    (zero_extend (match_dup 1)))
13899               (clobber (reg:CC FLAGS_REG))])]
13900   "(peep2_reg_dead_p (3, operands[1])
13901     || operands_match_p (operands[1], operands[3]))
13902    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13903   [(set (match_dup 4) (match_dup 0))
13904    (set (strict_low_part (match_dup 5))
13905         (match_dup 2))]
13907   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13908   operands[5] = gen_lowpart (QImode, operands[3]);
13909   ix86_expand_clear (operands[3]);
13912 ;; Call instructions.
13914 ;; The predicates normally associated with named expanders are not properly
13915 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13916 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13918 ;; Call subroutine returning no value.
13920 (define_expand "call_pop"
13921   [(parallel [(call (match_operand:QI 0 "" "")
13922                     (match_operand:SI 1 "" ""))
13923               (set (reg:SI SP_REG)
13924                    (plus:SI (reg:SI SP_REG)
13925                             (match_operand:SI 3 "" "")))])]
13926   "!TARGET_64BIT"
13928   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13929   DONE;
13932 (define_insn "*call_pop_0"
13933   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13934          (match_operand:SI 1 "" ""))
13935    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13936                             (match_operand:SI 2 "immediate_operand" "")))]
13937   "!TARGET_64BIT"
13939   if (SIBLING_CALL_P (insn))
13940     return "jmp\t%P0";
13941   else
13942     return "call\t%P0";
13944   [(set_attr "type" "call")])
13945   
13946 (define_insn "*call_pop_1"
13947   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13948          (match_operand:SI 1 "" ""))
13949    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13950                             (match_operand:SI 2 "immediate_operand" "i")))]
13951   "!TARGET_64BIT"
13953   if (constant_call_address_operand (operands[0], Pmode))
13954     {
13955       if (SIBLING_CALL_P (insn))
13956         return "jmp\t%P0";
13957       else
13958         return "call\t%P0";
13959     }
13960   if (SIBLING_CALL_P (insn))
13961     return "jmp\t%A0";
13962   else
13963     return "call\t%A0";
13965   [(set_attr "type" "call")])
13967 (define_expand "call"
13968   [(call (match_operand:QI 0 "" "")
13969          (match_operand 1 "" ""))
13970    (use (match_operand 2 "" ""))]
13971   ""
13973   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13974   DONE;
13977 (define_expand "sibcall"
13978   [(call (match_operand:QI 0 "" "")
13979          (match_operand 1 "" ""))
13980    (use (match_operand 2 "" ""))]
13981   ""
13983   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13984   DONE;
13987 (define_insn "*call_0"
13988   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13989          (match_operand 1 "" ""))]
13990   ""
13992   if (SIBLING_CALL_P (insn))
13993     return "jmp\t%P0";
13994   else
13995     return "call\t%P0";
13997   [(set_attr "type" "call")])
13999 (define_insn "*call_1"
14000   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14001          (match_operand 1 "" ""))]
14002   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14004   if (constant_call_address_operand (operands[0], Pmode))
14005     return "call\t%P0";
14006   return "call\t%A0";
14008   [(set_attr "type" "call")])
14010 (define_insn "*sibcall_1"
14011   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14012          (match_operand 1 "" ""))]
14013   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14015   if (constant_call_address_operand (operands[0], Pmode))
14016     return "jmp\t%P0";
14017   return "jmp\t%A0";
14019   [(set_attr "type" "call")])
14021 (define_insn "*call_1_rex64"
14022   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14023          (match_operand 1 "" ""))]
14024   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14026   if (constant_call_address_operand (operands[0], Pmode))
14027     return "call\t%P0";
14028   return "call\t%A0";
14030   [(set_attr "type" "call")])
14032 (define_insn "*sibcall_1_rex64"
14033   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14034          (match_operand 1 "" ""))]
14035   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14036   "jmp\t%P0"
14037   [(set_attr "type" "call")])
14039 (define_insn "*sibcall_1_rex64_v"
14040   [(call (mem:QI (reg:DI 40))
14041          (match_operand 0 "" ""))]
14042   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14043   "jmp\t*%%r11"
14044   [(set_attr "type" "call")])
14047 ;; Call subroutine, returning value in operand 0
14049 (define_expand "call_value_pop"
14050   [(parallel [(set (match_operand 0 "" "")
14051                    (call (match_operand:QI 1 "" "")
14052                          (match_operand:SI 2 "" "")))
14053               (set (reg:SI SP_REG)
14054                    (plus:SI (reg:SI SP_REG)
14055                             (match_operand:SI 4 "" "")))])]
14056   "!TARGET_64BIT"
14058   ix86_expand_call (operands[0], operands[1], operands[2],
14059                     operands[3], operands[4], 0);
14060   DONE;
14063 (define_expand "call_value"
14064   [(set (match_operand 0 "" "")
14065         (call (match_operand:QI 1 "" "")
14066               (match_operand:SI 2 "" "")))
14067    (use (match_operand:SI 3 "" ""))]
14068   ;; Operand 2 not used on the i386.
14069   ""
14071   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14072   DONE;
14075 (define_expand "sibcall_value"
14076   [(set (match_operand 0 "" "")
14077         (call (match_operand:QI 1 "" "")
14078               (match_operand:SI 2 "" "")))
14079    (use (match_operand:SI 3 "" ""))]
14080   ;; Operand 2 not used on the i386.
14081   ""
14083   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14084   DONE;
14087 ;; Call subroutine returning any type.
14089 (define_expand "untyped_call"
14090   [(parallel [(call (match_operand 0 "" "")
14091                     (const_int 0))
14092               (match_operand 1 "" "")
14093               (match_operand 2 "" "")])]
14094   ""
14096   int i;
14098   /* In order to give reg-stack an easier job in validating two
14099      coprocessor registers as containing a possible return value,
14100      simply pretend the untyped call returns a complex long double
14101      value.  */
14103   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14104                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14105                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14106                     NULL, 0);
14108   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14109     {
14110       rtx set = XVECEXP (operands[2], 0, i);
14111       emit_move_insn (SET_DEST (set), SET_SRC (set));
14112     }
14114   /* The optimizer does not know that the call sets the function value
14115      registers we stored in the result block.  We avoid problems by
14116      claiming that all hard registers are used and clobbered at this
14117      point.  */
14118   emit_insn (gen_blockage (const0_rtx));
14120   DONE;
14123 ;; Prologue and epilogue instructions
14125 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14126 ;; all of memory.  This blocks insns from being moved across this point.
14128 (define_insn "blockage"
14129   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14130   ""
14131   ""
14132   [(set_attr "length" "0")])
14134 ;; Insn emitted into the body of a function to return from a function.
14135 ;; This is only done if the function's epilogue is known to be simple.
14136 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14138 (define_expand "return"
14139   [(return)]
14140   "ix86_can_use_return_insn_p ()"
14142   if (current_function_pops_args)
14143     {
14144       rtx popc = GEN_INT (current_function_pops_args);
14145       emit_jump_insn (gen_return_pop_internal (popc));
14146       DONE;
14147     }
14150 (define_insn "return_internal"
14151   [(return)]
14152   "reload_completed"
14153   "ret"
14154   [(set_attr "length" "1")
14155    (set_attr "length_immediate" "0")
14156    (set_attr "modrm" "0")])
14158 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14159 ;; instruction Athlon and K8 have.
14161 (define_insn "return_internal_long"
14162   [(return)
14163    (unspec [(const_int 0)] UNSPEC_REP)]
14164   "reload_completed"
14165   "rep {;} ret"
14166   [(set_attr "length" "1")
14167    (set_attr "length_immediate" "0")
14168    (set_attr "prefix_rep" "1")
14169    (set_attr "modrm" "0")])
14171 (define_insn "return_pop_internal"
14172   [(return)
14173    (use (match_operand:SI 0 "const_int_operand" ""))]
14174   "reload_completed"
14175   "ret\t%0"
14176   [(set_attr "length" "3")
14177    (set_attr "length_immediate" "2")
14178    (set_attr "modrm" "0")])
14180 (define_insn "return_indirect_internal"
14181   [(return)
14182    (use (match_operand:SI 0 "register_operand" "r"))]
14183   "reload_completed"
14184   "jmp\t%A0"
14185   [(set_attr "type" "ibr")
14186    (set_attr "length_immediate" "0")])
14188 (define_insn "nop"
14189   [(const_int 0)]
14190   ""
14191   "nop"
14192   [(set_attr "length" "1")
14193    (set_attr "length_immediate" "0")
14194    (set_attr "modrm" "0")])
14196 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14197 ;; branch prediction penalty for the third jump in a 16-byte
14198 ;; block on K8.
14200 (define_insn "align"
14201   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14202   ""
14204 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14205   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14206 #else
14207   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14208      The align insn is used to avoid 3 jump instructions in the row to improve
14209      branch prediction and the benefits hardly outweight the cost of extra 8
14210      nops on the average inserted by full alignment pseudo operation.  */
14211 #endif
14212   return "";
14214   [(set_attr "length" "16")])
14216 (define_expand "prologue"
14217   [(const_int 1)]
14218   ""
14219   "ix86_expand_prologue (); DONE;")
14221 (define_insn "set_got"
14222   [(set (match_operand:SI 0 "register_operand" "=r")
14223         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14224    (clobber (reg:CC FLAGS_REG))]
14225   "!TARGET_64BIT"
14226   { return output_set_got (operands[0]); }
14227   [(set_attr "type" "multi")
14228    (set_attr "length" "12")])
14230 (define_insn "set_got_rex64"
14231   [(set (match_operand:DI 0 "register_operand" "=r")
14232         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14233   "TARGET_64BIT"
14234   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14235   [(set_attr "type" "lea")
14236    (set_attr "length" "6")])
14238 (define_expand "epilogue"
14239   [(const_int 1)]
14240   ""
14241   "ix86_expand_epilogue (1); DONE;")
14243 (define_expand "sibcall_epilogue"
14244   [(const_int 1)]
14245   ""
14246   "ix86_expand_epilogue (0); DONE;")
14248 (define_expand "eh_return"
14249   [(use (match_operand 0 "register_operand" ""))]
14250   ""
14252   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14254   /* Tricky bit: we write the address of the handler to which we will
14255      be returning into someone else's stack frame, one word below the
14256      stack address we wish to restore.  */
14257   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14258   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14259   tmp = gen_rtx_MEM (Pmode, tmp);
14260   emit_move_insn (tmp, ra);
14262   if (Pmode == SImode)
14263     emit_jump_insn (gen_eh_return_si (sa));
14264   else
14265     emit_jump_insn (gen_eh_return_di (sa));
14266   emit_barrier ();
14267   DONE;
14270 (define_insn_and_split "eh_return_si"
14271   [(set (pc) 
14272         (unspec [(match_operand:SI 0 "register_operand" "c")]
14273                  UNSPEC_EH_RETURN))]
14274   "!TARGET_64BIT"
14275   "#"
14276   "reload_completed"
14277   [(const_int 1)]
14278   "ix86_expand_epilogue (2); DONE;")
14280 (define_insn_and_split "eh_return_di"
14281   [(set (pc) 
14282         (unspec [(match_operand:DI 0 "register_operand" "c")]
14283                  UNSPEC_EH_RETURN))]
14284   "TARGET_64BIT"
14285   "#"
14286   "reload_completed"
14287   [(const_int 1)]
14288   "ix86_expand_epilogue (2); DONE;")
14290 (define_insn "leave"
14291   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14292    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14293    (clobber (mem:BLK (scratch)))]
14294   "!TARGET_64BIT"
14295   "leave"
14296   [(set_attr "type" "leave")])
14298 (define_insn "leave_rex64"
14299   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14300    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14301    (clobber (mem:BLK (scratch)))]
14302   "TARGET_64BIT"
14303   "leave"
14304   [(set_attr "type" "leave")])
14306 (define_expand "ffssi2"
14307   [(parallel
14308      [(set (match_operand:SI 0 "register_operand" "") 
14309            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14310       (clobber (match_scratch:SI 2 ""))
14311       (clobber (reg:CC FLAGS_REG))])]
14312   ""
14313   "")
14315 (define_insn_and_split "*ffs_cmove"
14316   [(set (match_operand:SI 0 "register_operand" "=r") 
14317         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14318    (clobber (match_scratch:SI 2 "=&r"))
14319    (clobber (reg:CC FLAGS_REG))]
14320   "TARGET_CMOVE"
14321   "#"
14322   "&& reload_completed"
14323   [(set (match_dup 2) (const_int -1))
14324    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14325               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14326    (set (match_dup 0) (if_then_else:SI
14327                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14328                         (match_dup 2)
14329                         (match_dup 0)))
14330    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14331               (clobber (reg:CC FLAGS_REG))])]
14332   "")
14334 (define_insn_and_split "*ffs_no_cmove"
14335   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14336         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14337    (clobber (match_scratch:SI 2 "=&q"))
14338    (clobber (reg:CC FLAGS_REG))]
14339   ""
14340   "#"
14341   "reload_completed"
14342   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14343               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14344    (set (strict_low_part (match_dup 3))
14345         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14346    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14347               (clobber (reg:CC FLAGS_REG))])
14348    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14349               (clobber (reg:CC FLAGS_REG))])
14350    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14351               (clobber (reg:CC FLAGS_REG))])]
14353   operands[3] = gen_lowpart (QImode, operands[2]);
14354   ix86_expand_clear (operands[2]);
14357 (define_insn "*ffssi_1"
14358   [(set (reg:CCZ FLAGS_REG)
14359         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14360                      (const_int 0)))
14361    (set (match_operand:SI 0 "register_operand" "=r")
14362         (ctz:SI (match_dup 1)))]
14363   ""
14364   "bsf{l}\t{%1, %0|%0, %1}"
14365   [(set_attr "prefix_0f" "1")])
14367 (define_expand "ffsdi2"
14368   [(parallel
14369      [(set (match_operand:DI 0 "register_operand" "") 
14370            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14371       (clobber (match_scratch:DI 2 ""))
14372       (clobber (reg:CC FLAGS_REG))])]
14373   "TARGET_64BIT && TARGET_CMOVE"
14374   "")
14376 (define_insn_and_split "*ffs_rex64"
14377   [(set (match_operand:DI 0 "register_operand" "=r") 
14378         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14379    (clobber (match_scratch:DI 2 "=&r"))
14380    (clobber (reg:CC FLAGS_REG))]
14381   "TARGET_64BIT && TARGET_CMOVE"
14382   "#"
14383   "&& reload_completed"
14384   [(set (match_dup 2) (const_int -1))
14385    (parallel [(set (reg:CCZ FLAGS_REG)
14386                    (compare:CCZ (match_dup 1) (const_int 0)))
14387               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14388    (set (match_dup 0) (if_then_else:DI
14389                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14390                         (match_dup 2)
14391                         (match_dup 0)))
14392    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14393               (clobber (reg:CC FLAGS_REG))])]
14394   "")
14396 (define_insn "*ffsdi_1"
14397   [(set (reg:CCZ FLAGS_REG)
14398         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14399                      (const_int 0)))
14400    (set (match_operand:DI 0 "register_operand" "=r")
14401         (ctz:DI (match_dup 1)))]
14402   "TARGET_64BIT"
14403   "bsf{q}\t{%1, %0|%0, %1}"
14404   [(set_attr "prefix_0f" "1")])
14406 (define_insn "ctzsi2"
14407   [(set (match_operand:SI 0 "register_operand" "=r")
14408         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14409    (clobber (reg:CC FLAGS_REG))]
14410   ""
14411   "bsf{l}\t{%1, %0|%0, %1}"
14412   [(set_attr "prefix_0f" "1")])
14414 (define_insn "ctzdi2"
14415   [(set (match_operand:DI 0 "register_operand" "=r")
14416         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14417    (clobber (reg:CC FLAGS_REG))]
14418   "TARGET_64BIT"
14419   "bsf{q}\t{%1, %0|%0, %1}"
14420   [(set_attr "prefix_0f" "1")])
14422 (define_expand "clzsi2"
14423   [(parallel
14424      [(set (match_operand:SI 0 "register_operand" "")
14425            (minus:SI (const_int 31)
14426                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14427       (clobber (reg:CC FLAGS_REG))])
14428    (parallel
14429      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14430       (clobber (reg:CC FLAGS_REG))])]
14431   ""
14432   "")
14434 (define_insn "*bsr"
14435   [(set (match_operand:SI 0 "register_operand" "=r")
14436         (minus:SI (const_int 31)
14437                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14438    (clobber (reg:CC FLAGS_REG))]
14439   ""
14440   "bsr{l}\t{%1, %0|%0, %1}"
14441   [(set_attr "prefix_0f" "1")])
14443 (define_expand "clzdi2"
14444   [(parallel
14445      [(set (match_operand:DI 0 "register_operand" "")
14446            (minus:DI (const_int 63)
14447                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14448       (clobber (reg:CC FLAGS_REG))])
14449    (parallel
14450      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14451       (clobber (reg:CC FLAGS_REG))])]
14452   "TARGET_64BIT"
14453   "")
14455 (define_insn "*bsr_rex64"
14456   [(set (match_operand:DI 0 "register_operand" "=r")
14457         (minus:DI (const_int 63)
14458                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14459    (clobber (reg:CC FLAGS_REG))]
14460   "TARGET_64BIT"
14461   "bsr{q}\t{%1, %0|%0, %1}"
14462   [(set_attr "prefix_0f" "1")])
14464 ;; Thread-local storage patterns for ELF.
14466 ;; Note that these code sequences must appear exactly as shown
14467 ;; in order to allow linker relaxation.
14469 (define_insn "*tls_global_dynamic_32_gnu"
14470   [(set (match_operand:SI 0 "register_operand" "=a")
14471         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14472                     (match_operand:SI 2 "tls_symbolic_operand" "")
14473                     (match_operand:SI 3 "call_insn_operand" "")]
14474                     UNSPEC_TLS_GD))
14475    (clobber (match_scratch:SI 4 "=d"))
14476    (clobber (match_scratch:SI 5 "=c"))
14477    (clobber (reg:CC FLAGS_REG))]
14478   "!TARGET_64BIT && TARGET_GNU_TLS"
14479   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14480   [(set_attr "type" "multi")
14481    (set_attr "length" "12")])
14483 (define_insn "*tls_global_dynamic_32_sun"
14484   [(set (match_operand:SI 0 "register_operand" "=a")
14485         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14486                     (match_operand:SI 2 "tls_symbolic_operand" "")
14487                     (match_operand:SI 3 "call_insn_operand" "")]
14488                     UNSPEC_TLS_GD))
14489    (clobber (match_scratch:SI 4 "=d"))
14490    (clobber (match_scratch:SI 5 "=c"))
14491    (clobber (reg:CC FLAGS_REG))]
14492   "!TARGET_64BIT && TARGET_SUN_TLS"
14493   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14494         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14495   [(set_attr "type" "multi")
14496    (set_attr "length" "14")])
14498 (define_expand "tls_global_dynamic_32"
14499   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14500                    (unspec:SI
14501                     [(match_dup 2)
14502                      (match_operand:SI 1 "tls_symbolic_operand" "")
14503                      (match_dup 3)]
14504                     UNSPEC_TLS_GD))
14505               (clobber (match_scratch:SI 4 ""))
14506               (clobber (match_scratch:SI 5 ""))
14507               (clobber (reg:CC FLAGS_REG))])]
14508   ""
14510   if (flag_pic)
14511     operands[2] = pic_offset_table_rtx;
14512   else
14513     {
14514       operands[2] = gen_reg_rtx (Pmode);
14515       emit_insn (gen_set_got (operands[2]));
14516     }
14517   operands[3] = ix86_tls_get_addr ();
14520 (define_insn "*tls_global_dynamic_64"
14521   [(set (match_operand:DI 0 "register_operand" "=a")
14522         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14523                  (match_operand:DI 3 "" "")))
14524    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14525               UNSPEC_TLS_GD)]
14526   "TARGET_64BIT"
14527   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14528   [(set_attr "type" "multi")
14529    (set_attr "length" "16")])
14531 (define_expand "tls_global_dynamic_64"
14532   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14533                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14534               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14535                          UNSPEC_TLS_GD)])]
14536   ""
14538   operands[2] = ix86_tls_get_addr ();
14541 (define_insn "*tls_local_dynamic_base_32_gnu"
14542   [(set (match_operand:SI 0 "register_operand" "=a")
14543         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14544                     (match_operand:SI 2 "call_insn_operand" "")]
14545                    UNSPEC_TLS_LD_BASE))
14546    (clobber (match_scratch:SI 3 "=d"))
14547    (clobber (match_scratch:SI 4 "=c"))
14548    (clobber (reg:CC FLAGS_REG))]
14549   "!TARGET_64BIT && TARGET_GNU_TLS"
14550   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14551   [(set_attr "type" "multi")
14552    (set_attr "length" "11")])
14554 (define_insn "*tls_local_dynamic_base_32_sun"
14555   [(set (match_operand:SI 0 "register_operand" "=a")
14556         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14557                     (match_operand:SI 2 "call_insn_operand" "")]
14558                    UNSPEC_TLS_LD_BASE))
14559    (clobber (match_scratch:SI 3 "=d"))
14560    (clobber (match_scratch:SI 4 "=c"))
14561    (clobber (reg:CC FLAGS_REG))]
14562   "!TARGET_64BIT && TARGET_SUN_TLS"
14563   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14564         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14565   [(set_attr "type" "multi")
14566    (set_attr "length" "13")])
14568 (define_expand "tls_local_dynamic_base_32"
14569   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14570                    (unspec:SI [(match_dup 1) (match_dup 2)]
14571                               UNSPEC_TLS_LD_BASE))
14572               (clobber (match_scratch:SI 3 ""))
14573               (clobber (match_scratch:SI 4 ""))
14574               (clobber (reg:CC FLAGS_REG))])]
14575   ""
14577   if (flag_pic)
14578     operands[1] = pic_offset_table_rtx;
14579   else
14580     {
14581       operands[1] = gen_reg_rtx (Pmode);
14582       emit_insn (gen_set_got (operands[1]));
14583     }
14584   operands[2] = ix86_tls_get_addr ();
14587 (define_insn "*tls_local_dynamic_base_64"
14588   [(set (match_operand:DI 0 "register_operand" "=a")
14589         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14590                  (match_operand:DI 2 "" "")))
14591    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14592   "TARGET_64BIT"
14593   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14594   [(set_attr "type" "multi")
14595    (set_attr "length" "12")])
14597 (define_expand "tls_local_dynamic_base_64"
14598   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14599                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14600               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14601   ""
14603   operands[1] = ix86_tls_get_addr ();
14606 ;; Local dynamic of a single variable is a lose.  Show combine how
14607 ;; to convert that back to global dynamic.
14609 (define_insn_and_split "*tls_local_dynamic_32_once"
14610   [(set (match_operand:SI 0 "register_operand" "=a")
14611         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14612                              (match_operand:SI 2 "call_insn_operand" "")]
14613                             UNSPEC_TLS_LD_BASE)
14614                  (const:SI (unspec:SI
14615                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14616                             UNSPEC_DTPOFF))))
14617    (clobber (match_scratch:SI 4 "=d"))
14618    (clobber (match_scratch:SI 5 "=c"))
14619    (clobber (reg:CC FLAGS_REG))]
14620   ""
14621   "#"
14622   ""
14623   [(parallel [(set (match_dup 0)
14624                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14625                               UNSPEC_TLS_GD))
14626               (clobber (match_dup 4))
14627               (clobber (match_dup 5))
14628               (clobber (reg:CC FLAGS_REG))])]
14629   "")
14631 ;; Load and add the thread base pointer from %gs:0.
14633 (define_insn "*load_tp_si"
14634   [(set (match_operand:SI 0 "register_operand" "=r")
14635         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14636   "!TARGET_64BIT"
14637   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14638   [(set_attr "type" "imov")
14639    (set_attr "modrm" "0")
14640    (set_attr "length" "7")
14641    (set_attr "memory" "load")
14642    (set_attr "imm_disp" "false")])
14644 (define_insn "*add_tp_si"
14645   [(set (match_operand:SI 0 "register_operand" "=r")
14646         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14647                  (match_operand:SI 1 "register_operand" "0")))
14648    (clobber (reg:CC FLAGS_REG))]
14649   "!TARGET_64BIT"
14650   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14651   [(set_attr "type" "alu")
14652    (set_attr "modrm" "0")
14653    (set_attr "length" "7")
14654    (set_attr "memory" "load")
14655    (set_attr "imm_disp" "false")])
14657 (define_insn "*load_tp_di"
14658   [(set (match_operand:DI 0 "register_operand" "=r")
14659         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14660   "TARGET_64BIT"
14661   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14662   [(set_attr "type" "imov")
14663    (set_attr "modrm" "0")
14664    (set_attr "length" "7")
14665    (set_attr "memory" "load")
14666    (set_attr "imm_disp" "false")])
14668 (define_insn "*add_tp_di"
14669   [(set (match_operand:DI 0 "register_operand" "=r")
14670         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14671                  (match_operand:DI 1 "register_operand" "0")))
14672    (clobber (reg:CC FLAGS_REG))]
14673   "TARGET_64BIT"
14674   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14675   [(set_attr "type" "alu")
14676    (set_attr "modrm" "0")
14677    (set_attr "length" "7")
14678    (set_attr "memory" "load")
14679    (set_attr "imm_disp" "false")])
14681 ;; These patterns match the binary 387 instructions for addM3, subM3,
14682 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14683 ;; SFmode.  The first is the normal insn, the second the same insn but
14684 ;; with one operand a conversion, and the third the same insn but with
14685 ;; the other operand a conversion.  The conversion may be SFmode or
14686 ;; SImode if the target mode DFmode, but only SImode if the target mode
14687 ;; is SFmode.
14689 ;; Gcc is slightly more smart about handling normal two address instructions
14690 ;; so use special patterns for add and mull.
14692 (define_insn "*fop_sf_comm_mixed"
14693   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14694         (match_operator:SF 3 "binary_fp_operator"
14695                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14696                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14697   "TARGET_MIX_SSE_I387
14698    && COMMUTATIVE_ARITH_P (operands[3])
14699    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14700   "* return output_387_binary_op (insn, operands);"
14701   [(set (attr "type") 
14702         (if_then_else (eq_attr "alternative" "1")
14703            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14704               (const_string "ssemul")
14705               (const_string "sseadd"))
14706            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14707               (const_string "fmul")
14708               (const_string "fop"))))
14709    (set_attr "mode" "SF")])
14711 (define_insn "*fop_sf_comm_sse"
14712   [(set (match_operand:SF 0 "register_operand" "=x")
14713         (match_operator:SF 3 "binary_fp_operator"
14714                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14715                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14716   "TARGET_SSE_MATH
14717    && COMMUTATIVE_ARITH_P (operands[3])
14718    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14719   "* return output_387_binary_op (insn, operands);"
14720   [(set (attr "type") 
14721         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14722            (const_string "ssemul")
14723            (const_string "sseadd")))
14724    (set_attr "mode" "SF")])
14726 (define_insn "*fop_sf_comm_i387"
14727   [(set (match_operand:SF 0 "register_operand" "=f")
14728         (match_operator:SF 3 "binary_fp_operator"
14729                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14730                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14731   "TARGET_80387
14732    && COMMUTATIVE_ARITH_P (operands[3])
14733    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14734   "* return output_387_binary_op (insn, operands);"
14735   [(set (attr "type") 
14736         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14737            (const_string "fmul")
14738            (const_string "fop")))
14739    (set_attr "mode" "SF")])
14741 (define_insn "*fop_sf_1_mixed"
14742   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14743         (match_operator:SF 3 "binary_fp_operator"
14744                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14745                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14746   "TARGET_MIX_SSE_I387
14747    && !COMMUTATIVE_ARITH_P (operands[3])
14748    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14749   "* return output_387_binary_op (insn, operands);"
14750   [(set (attr "type") 
14751         (cond [(and (eq_attr "alternative" "2")
14752                     (match_operand:SF 3 "mult_operator" ""))
14753                  (const_string "ssemul")
14754                (and (eq_attr "alternative" "2")
14755                     (match_operand:SF 3 "div_operator" ""))
14756                  (const_string "ssediv")
14757                (eq_attr "alternative" "2")
14758                  (const_string "sseadd")
14759                (match_operand:SF 3 "mult_operator" "") 
14760                  (const_string "fmul")
14761                (match_operand:SF 3 "div_operator" "") 
14762                  (const_string "fdiv")
14763               ]
14764               (const_string "fop")))
14765    (set_attr "mode" "SF")])
14767 (define_insn "*fop_sf_1_sse"
14768   [(set (match_operand:SF 0 "register_operand" "=x")
14769         (match_operator:SF 3 "binary_fp_operator"
14770                         [(match_operand:SF 1 "register_operand" "0")
14771                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14772   "TARGET_SSE_MATH
14773    && !COMMUTATIVE_ARITH_P (operands[3])"
14774   "* return output_387_binary_op (insn, operands);"
14775   [(set (attr "type") 
14776         (cond [(match_operand:SF 3 "mult_operator" "")
14777                  (const_string "ssemul")
14778                (match_operand:SF 3 "div_operator" "")
14779                  (const_string "ssediv")
14780               ]
14781               (const_string "sseadd")))
14782    (set_attr "mode" "SF")])
14784 ;; This pattern is not fully shadowed by the pattern above.
14785 (define_insn "*fop_sf_1_i387"
14786   [(set (match_operand:SF 0 "register_operand" "=f,f")
14787         (match_operator:SF 3 "binary_fp_operator"
14788                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14789                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14790   "TARGET_80387 && !TARGET_SSE_MATH
14791    && !COMMUTATIVE_ARITH_P (operands[3])
14792    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14793   "* return output_387_binary_op (insn, operands);"
14794   [(set (attr "type") 
14795         (cond [(match_operand:SF 3 "mult_operator" "") 
14796                  (const_string "fmul")
14797                (match_operand:SF 3 "div_operator" "") 
14798                  (const_string "fdiv")
14799               ]
14800               (const_string "fop")))
14801    (set_attr "mode" "SF")])
14803 ;; ??? Add SSE splitters for these!
14804 (define_insn "*fop_sf_2<mode>_i387"
14805   [(set (match_operand:SF 0 "register_operand" "=f,f")
14806         (match_operator:SF 3 "binary_fp_operator"
14807           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14808            (match_operand:SF 2 "register_operand" "0,0")]))]
14809   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14810   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14811   [(set (attr "type") 
14812         (cond [(match_operand:SF 3 "mult_operator" "") 
14813                  (const_string "fmul")
14814                (match_operand:SF 3 "div_operator" "") 
14815                  (const_string "fdiv")
14816               ]
14817               (const_string "fop")))
14818    (set_attr "fp_int_src" "true")
14819    (set_attr "mode" "<MODE>")])
14821 (define_insn "*fop_sf_3<mode>_i387"
14822   [(set (match_operand:SF 0 "register_operand" "=f,f")
14823         (match_operator:SF 3 "binary_fp_operator"
14824           [(match_operand:SF 1 "register_operand" "0,0")
14825            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14826   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14827   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14828   [(set (attr "type") 
14829         (cond [(match_operand:SF 3 "mult_operator" "") 
14830                  (const_string "fmul")
14831                (match_operand:SF 3 "div_operator" "") 
14832                  (const_string "fdiv")
14833               ]
14834               (const_string "fop")))
14835    (set_attr "fp_int_src" "true")
14836    (set_attr "mode" "<MODE>")])
14838 (define_insn "*fop_df_comm_mixed"
14839   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14840         (match_operator:DF 3 "binary_fp_operator"
14841                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14842                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14843   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14844    && COMMUTATIVE_ARITH_P (operands[3])
14845    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14846   "* return output_387_binary_op (insn, operands);"
14847   [(set (attr "type") 
14848         (if_then_else (eq_attr "alternative" "1")
14849            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14850               (const_string "ssemul")
14851               (const_string "sseadd"))
14852            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14853               (const_string "fmul")
14854               (const_string "fop"))))
14855    (set_attr "mode" "DF")])
14857 (define_insn "*fop_df_comm_sse"
14858   [(set (match_operand:DF 0 "register_operand" "=Y")
14859         (match_operator:DF 3 "binary_fp_operator"
14860                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14861                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14862   "TARGET_SSE2 && TARGET_SSE_MATH
14863    && COMMUTATIVE_ARITH_P (operands[3])
14864    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14865   "* return output_387_binary_op (insn, operands);"
14866   [(set (attr "type") 
14867         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14868            (const_string "ssemul")
14869            (const_string "sseadd")))
14870    (set_attr "mode" "DF")])
14872 (define_insn "*fop_df_comm_i387"
14873   [(set (match_operand:DF 0 "register_operand" "=f")
14874         (match_operator:DF 3 "binary_fp_operator"
14875                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14876                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14877   "TARGET_80387
14878    && COMMUTATIVE_ARITH_P (operands[3])
14879    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14880   "* return output_387_binary_op (insn, operands);"
14881   [(set (attr "type") 
14882         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14883            (const_string "fmul")
14884            (const_string "fop")))
14885    (set_attr "mode" "DF")])
14887 (define_insn "*fop_df_1_mixed"
14888   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14889         (match_operator:DF 3 "binary_fp_operator"
14890                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14891                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14892   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14893    && !COMMUTATIVE_ARITH_P (operands[3])
14894    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14895   "* return output_387_binary_op (insn, operands);"
14896   [(set (attr "type") 
14897         (cond [(and (eq_attr "alternative" "2")
14898                     (match_operand:SF 3 "mult_operator" ""))
14899                  (const_string "ssemul")
14900                (and (eq_attr "alternative" "2")
14901                     (match_operand:SF 3 "div_operator" ""))
14902                  (const_string "ssediv")
14903                (eq_attr "alternative" "2")
14904                  (const_string "sseadd")
14905                (match_operand:DF 3 "mult_operator" "") 
14906                  (const_string "fmul")
14907                (match_operand:DF 3 "div_operator" "") 
14908                  (const_string "fdiv")
14909               ]
14910               (const_string "fop")))
14911    (set_attr "mode" "DF")])
14913 (define_insn "*fop_df_1_sse"
14914   [(set (match_operand:DF 0 "register_operand" "=Y")
14915         (match_operator:DF 3 "binary_fp_operator"
14916                         [(match_operand:DF 1 "register_operand" "0")
14917                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14918   "TARGET_SSE2 && TARGET_SSE_MATH
14919    && !COMMUTATIVE_ARITH_P (operands[3])"
14920   "* return output_387_binary_op (insn, operands);"
14921   [(set_attr "mode" "DF")
14922    (set (attr "type") 
14923         (cond [(match_operand:SF 3 "mult_operator" "")
14924                  (const_string "ssemul")
14925                (match_operand:SF 3 "div_operator" "")
14926                  (const_string "ssediv")
14927               ]
14928               (const_string "sseadd")))])
14930 ;; This pattern is not fully shadowed by the pattern above.
14931 (define_insn "*fop_df_1_i387"
14932   [(set (match_operand:DF 0 "register_operand" "=f,f")
14933         (match_operator:DF 3 "binary_fp_operator"
14934                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14935                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14936   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14937    && !COMMUTATIVE_ARITH_P (operands[3])
14938    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14939   "* return output_387_binary_op (insn, operands);"
14940   [(set (attr "type") 
14941         (cond [(match_operand:DF 3 "mult_operator" "") 
14942                  (const_string "fmul")
14943                (match_operand:DF 3 "div_operator" "")
14944                  (const_string "fdiv")
14945               ]
14946               (const_string "fop")))
14947    (set_attr "mode" "DF")])
14949 ;; ??? Add SSE splitters for these!
14950 (define_insn "*fop_df_2<mode>_i387"
14951   [(set (match_operand:DF 0 "register_operand" "=f,f")
14952         (match_operator:DF 3 "binary_fp_operator"
14953            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14954             (match_operand:DF 2 "register_operand" "0,0")]))]
14955   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14956    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14957   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14958   [(set (attr "type") 
14959         (cond [(match_operand:DF 3 "mult_operator" "") 
14960                  (const_string "fmul")
14961                (match_operand:DF 3 "div_operator" "") 
14962                  (const_string "fdiv")
14963               ]
14964               (const_string "fop")))
14965    (set_attr "fp_int_src" "true")
14966    (set_attr "mode" "<MODE>")])
14968 (define_insn "*fop_df_3<mode>_i387"
14969   [(set (match_operand:DF 0 "register_operand" "=f,f")
14970         (match_operator:DF 3 "binary_fp_operator"
14971            [(match_operand:DF 1 "register_operand" "0,0")
14972             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14973   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14974    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14975   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14976   [(set (attr "type") 
14977         (cond [(match_operand:DF 3 "mult_operator" "") 
14978                  (const_string "fmul")
14979                (match_operand:DF 3 "div_operator" "") 
14980                  (const_string "fdiv")
14981               ]
14982               (const_string "fop")))
14983    (set_attr "fp_int_src" "true")
14984    (set_attr "mode" "<MODE>")])
14986 (define_insn "*fop_df_4_i387"
14987   [(set (match_operand:DF 0 "register_operand" "=f,f")
14988         (match_operator:DF 3 "binary_fp_operator"
14989            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14990             (match_operand:DF 2 "register_operand" "0,f")]))]
14991   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14992    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14993   "* return output_387_binary_op (insn, operands);"
14994   [(set (attr "type") 
14995         (cond [(match_operand:DF 3 "mult_operator" "") 
14996                  (const_string "fmul")
14997                (match_operand:DF 3 "div_operator" "") 
14998                  (const_string "fdiv")
14999               ]
15000               (const_string "fop")))
15001    (set_attr "mode" "SF")])
15003 (define_insn "*fop_df_5_i387"
15004   [(set (match_operand:DF 0 "register_operand" "=f,f")
15005         (match_operator:DF 3 "binary_fp_operator"
15006           [(match_operand:DF 1 "register_operand" "0,f")
15007            (float_extend:DF
15008             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15009   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15010   "* return output_387_binary_op (insn, operands);"
15011   [(set (attr "type") 
15012         (cond [(match_operand:DF 3 "mult_operator" "") 
15013                  (const_string "fmul")
15014                (match_operand:DF 3 "div_operator" "") 
15015                  (const_string "fdiv")
15016               ]
15017               (const_string "fop")))
15018    (set_attr "mode" "SF")])
15020 (define_insn "*fop_df_6_i387"
15021   [(set (match_operand:DF 0 "register_operand" "=f,f")
15022         (match_operator:DF 3 "binary_fp_operator"
15023           [(float_extend:DF
15024             (match_operand:SF 1 "register_operand" "0,f"))
15025            (float_extend:DF
15026             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15027   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15028   "* return output_387_binary_op (insn, operands);"
15029   [(set (attr "type") 
15030         (cond [(match_operand:DF 3 "mult_operator" "") 
15031                  (const_string "fmul")
15032                (match_operand:DF 3 "div_operator" "") 
15033                  (const_string "fdiv")
15034               ]
15035               (const_string "fop")))
15036    (set_attr "mode" "SF")])
15038 (define_insn "*fop_xf_comm_i387"
15039   [(set (match_operand:XF 0 "register_operand" "=f")
15040         (match_operator:XF 3 "binary_fp_operator"
15041                         [(match_operand:XF 1 "register_operand" "%0")
15042                          (match_operand:XF 2 "register_operand" "f")]))]
15043   "TARGET_80387
15044    && COMMUTATIVE_ARITH_P (operands[3])"
15045   "* return output_387_binary_op (insn, operands);"
15046   [(set (attr "type") 
15047         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15048            (const_string "fmul")
15049            (const_string "fop")))
15050    (set_attr "mode" "XF")])
15052 (define_insn "*fop_xf_1_i387"
15053   [(set (match_operand:XF 0 "register_operand" "=f,f")
15054         (match_operator:XF 3 "binary_fp_operator"
15055                         [(match_operand:XF 1 "register_operand" "0,f")
15056                          (match_operand:XF 2 "register_operand" "f,0")]))]
15057   "TARGET_80387
15058    && !COMMUTATIVE_ARITH_P (operands[3])"
15059   "* return output_387_binary_op (insn, operands);"
15060   [(set (attr "type") 
15061         (cond [(match_operand:XF 3 "mult_operator" "") 
15062                  (const_string "fmul")
15063                (match_operand:XF 3 "div_operator" "") 
15064                  (const_string "fdiv")
15065               ]
15066               (const_string "fop")))
15067    (set_attr "mode" "XF")])
15069 (define_insn "*fop_xf_2<mode>_i387"
15070   [(set (match_operand:XF 0 "register_operand" "=f,f")
15071         (match_operator:XF 3 "binary_fp_operator"
15072            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15073             (match_operand:XF 2 "register_operand" "0,0")]))]
15074   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15075   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15076   [(set (attr "type") 
15077         (cond [(match_operand:XF 3 "mult_operator" "") 
15078                  (const_string "fmul")
15079                (match_operand:XF 3 "div_operator" "") 
15080                  (const_string "fdiv")
15081               ]
15082               (const_string "fop")))
15083    (set_attr "fp_int_src" "true")
15084    (set_attr "mode" "<MODE>")])
15086 (define_insn "*fop_xf_3<mode>_i387"
15087   [(set (match_operand:XF 0 "register_operand" "=f,f")
15088         (match_operator:XF 3 "binary_fp_operator"
15089           [(match_operand:XF 1 "register_operand" "0,0")
15090            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15091   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15092   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15093   [(set (attr "type") 
15094         (cond [(match_operand:XF 3 "mult_operator" "") 
15095                  (const_string "fmul")
15096                (match_operand:XF 3 "div_operator" "") 
15097                  (const_string "fdiv")
15098               ]
15099               (const_string "fop")))
15100    (set_attr "fp_int_src" "true")
15101    (set_attr "mode" "<MODE>")])
15103 (define_insn "*fop_xf_4_i387"
15104   [(set (match_operand:XF 0 "register_operand" "=f,f")
15105         (match_operator:XF 3 "binary_fp_operator"
15106            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15107             (match_operand:XF 2 "register_operand" "0,f")]))]
15108   "TARGET_80387"
15109   "* return output_387_binary_op (insn, operands);"
15110   [(set (attr "type") 
15111         (cond [(match_operand:XF 3 "mult_operator" "") 
15112                  (const_string "fmul")
15113                (match_operand:XF 3 "div_operator" "") 
15114                  (const_string "fdiv")
15115               ]
15116               (const_string "fop")))
15117    (set_attr "mode" "SF")])
15119 (define_insn "*fop_xf_5_i387"
15120   [(set (match_operand:XF 0 "register_operand" "=f,f")
15121         (match_operator:XF 3 "binary_fp_operator"
15122           [(match_operand:XF 1 "register_operand" "0,f")
15123            (float_extend:XF
15124             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15125   "TARGET_80387"
15126   "* return output_387_binary_op (insn, operands);"
15127   [(set (attr "type") 
15128         (cond [(match_operand:XF 3 "mult_operator" "") 
15129                  (const_string "fmul")
15130                (match_operand:XF 3 "div_operator" "") 
15131                  (const_string "fdiv")
15132               ]
15133               (const_string "fop")))
15134    (set_attr "mode" "SF")])
15136 (define_insn "*fop_xf_6_i387"
15137   [(set (match_operand:XF 0 "register_operand" "=f,f")
15138         (match_operator:XF 3 "binary_fp_operator"
15139           [(float_extend:XF
15140             (match_operand 1 "register_operand" "0,f"))
15141            (float_extend:XF
15142             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15143   "TARGET_80387"
15144   "* return output_387_binary_op (insn, operands);"
15145   [(set (attr "type") 
15146         (cond [(match_operand:XF 3 "mult_operator" "") 
15147                  (const_string "fmul")
15148                (match_operand:XF 3 "div_operator" "") 
15149                  (const_string "fdiv")
15150               ]
15151               (const_string "fop")))
15152    (set_attr "mode" "SF")])
15154 (define_split
15155   [(set (match_operand 0 "register_operand" "")
15156         (match_operator 3 "binary_fp_operator"
15157            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15158             (match_operand 2 "register_operand" "")]))]
15159   "TARGET_80387 && reload_completed
15160    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15161   [(const_int 0)]
15163   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15164   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15165   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15166                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15167                                           GET_MODE (operands[3]),
15168                                           operands[4],
15169                                           operands[2])));
15170   ix86_free_from_memory (GET_MODE (operands[1]));
15171   DONE;
15174 (define_split
15175   [(set (match_operand 0 "register_operand" "")
15176         (match_operator 3 "binary_fp_operator"
15177            [(match_operand 1 "register_operand" "")
15178             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15179   "TARGET_80387 && reload_completed
15180    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15181   [(const_int 0)]
15183   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15184   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15185   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15186                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15187                                           GET_MODE (operands[3]),
15188                                           operands[1],
15189                                           operands[4])));
15190   ix86_free_from_memory (GET_MODE (operands[2]));
15191   DONE;
15194 ;; FPU special functions.
15196 (define_expand "sqrtsf2"
15197   [(set (match_operand:SF 0 "register_operand" "")
15198         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15199   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15201   if (!TARGET_SSE_MATH)
15202     operands[1] = force_reg (SFmode, operands[1]);
15205 (define_insn "*sqrtsf2_mixed"
15206   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15207         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15208   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15209   "@
15210    fsqrt
15211    sqrtss\t{%1, %0|%0, %1}"
15212   [(set_attr "type" "fpspc,sse")
15213    (set_attr "mode" "SF,SF")
15214    (set_attr "athlon_decode" "direct,*")])
15216 (define_insn "*sqrtsf2_sse"
15217   [(set (match_operand:SF 0 "register_operand" "=x")
15218         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15219   "TARGET_SSE_MATH"
15220   "sqrtss\t{%1, %0|%0, %1}"
15221   [(set_attr "type" "sse")
15222    (set_attr "mode" "SF")
15223    (set_attr "athlon_decode" "*")])
15225 (define_insn "*sqrtsf2_i387"
15226   [(set (match_operand:SF 0 "register_operand" "=f")
15227         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15228   "TARGET_USE_FANCY_MATH_387"
15229   "fsqrt"
15230   [(set_attr "type" "fpspc")
15231    (set_attr "mode" "SF")
15232    (set_attr "athlon_decode" "direct")])
15234 (define_expand "sqrtdf2"
15235   [(set (match_operand:DF 0 "register_operand" "")
15236         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15237   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15239   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15240     operands[1] = force_reg (DFmode, operands[1]);
15243 (define_insn "*sqrtdf2_mixed"
15244   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15245         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15246   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15247   "@
15248    fsqrt
15249    sqrtsd\t{%1, %0|%0, %1}"
15250   [(set_attr "type" "fpspc,sse")
15251    (set_attr "mode" "DF,DF")
15252    (set_attr "athlon_decode" "direct,*")])
15254 (define_insn "*sqrtdf2_sse"
15255   [(set (match_operand:DF 0 "register_operand" "=Y")
15256         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15257   "TARGET_SSE2 && TARGET_SSE_MATH"
15258   "sqrtsd\t{%1, %0|%0, %1}"
15259   [(set_attr "type" "sse")
15260    (set_attr "mode" "DF")
15261    (set_attr "athlon_decode" "*")])
15263 (define_insn "*sqrtdf2_i387"
15264   [(set (match_operand:DF 0 "register_operand" "=f")
15265         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15266   "TARGET_USE_FANCY_MATH_387"
15267   "fsqrt"
15268   [(set_attr "type" "fpspc")
15269    (set_attr "mode" "DF")
15270    (set_attr "athlon_decode" "direct")])
15272 (define_insn "*sqrtextendsfdf2_i387"
15273   [(set (match_operand:DF 0 "register_operand" "=f")
15274         (sqrt:DF (float_extend:DF
15275                   (match_operand:SF 1 "register_operand" "0"))))]
15276   "TARGET_USE_FANCY_MATH_387
15277    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15278   "fsqrt"
15279   [(set_attr "type" "fpspc")
15280    (set_attr "mode" "DF")
15281    (set_attr "athlon_decode" "direct")])
15283 (define_insn "sqrtxf2"
15284   [(set (match_operand:XF 0 "register_operand" "=f")
15285         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15286   "TARGET_USE_FANCY_MATH_387 
15287    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15288   "fsqrt"
15289   [(set_attr "type" "fpspc")
15290    (set_attr "mode" "XF")
15291    (set_attr "athlon_decode" "direct")])
15293 (define_insn "*sqrtextendsfxf2_i387"
15294   [(set (match_operand:XF 0 "register_operand" "=f")
15295         (sqrt:XF (float_extend:XF
15296                   (match_operand:SF 1 "register_operand" "0"))))]
15297   "TARGET_USE_FANCY_MATH_387"
15298   "fsqrt"
15299   [(set_attr "type" "fpspc")
15300    (set_attr "mode" "XF")
15301    (set_attr "athlon_decode" "direct")])
15303 (define_insn "*sqrtextenddfxf2_i387"
15304   [(set (match_operand:XF 0 "register_operand" "=f")
15305         (sqrt:XF (float_extend:XF
15306                   (match_operand:DF 1 "register_operand" "0"))))]
15307   "TARGET_USE_FANCY_MATH_387"
15308   "fsqrt"
15309   [(set_attr "type" "fpspc")
15310    (set_attr "mode" "XF")
15311    (set_attr "athlon_decode" "direct")])
15313 (define_insn "fpremxf4"
15314   [(set (match_operand:XF 0 "register_operand" "=f")
15315         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15316                     (match_operand:XF 3 "register_operand" "1")]
15317                    UNSPEC_FPREM_F))
15318    (set (match_operand:XF 1 "register_operand" "=u")
15319         (unspec:XF [(match_dup 2) (match_dup 3)]
15320                    UNSPEC_FPREM_U))
15321    (set (reg:CCFP FPSR_REG)
15322         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15323   "TARGET_USE_FANCY_MATH_387
15324    && flag_unsafe_math_optimizations"
15325   "fprem"
15326   [(set_attr "type" "fpspc")
15327    (set_attr "mode" "XF")])
15329 (define_expand "fmodsf3"
15330   [(use (match_operand:SF 0 "register_operand" ""))
15331    (use (match_operand:SF 1 "register_operand" ""))
15332    (use (match_operand:SF 2 "register_operand" ""))]
15333   "TARGET_USE_FANCY_MATH_387
15334    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15335    && flag_unsafe_math_optimizations"
15337   rtx label = gen_label_rtx ();
15339   rtx op1 = gen_reg_rtx (XFmode);
15340   rtx op2 = gen_reg_rtx (XFmode);
15342   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15343   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15345   emit_label (label);
15347   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15348   ix86_emit_fp_unordered_jump (label);
15350   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15351   DONE;
15354 (define_expand "fmoddf3"
15355   [(use (match_operand:DF 0 "register_operand" ""))
15356    (use (match_operand:DF 1 "register_operand" ""))
15357    (use (match_operand:DF 2 "register_operand" ""))]
15358   "TARGET_USE_FANCY_MATH_387
15359    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15360    && flag_unsafe_math_optimizations"
15362   rtx label = gen_label_rtx ();
15364   rtx op1 = gen_reg_rtx (XFmode);
15365   rtx op2 = gen_reg_rtx (XFmode);
15367   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15368   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15370   emit_label (label);
15372   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15373   ix86_emit_fp_unordered_jump (label);
15375   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15376   DONE;
15379 (define_expand "fmodxf3"
15380   [(use (match_operand:XF 0 "register_operand" ""))
15381    (use (match_operand:XF 1 "register_operand" ""))
15382    (use (match_operand:XF 2 "register_operand" ""))]
15383   "TARGET_USE_FANCY_MATH_387
15384    && flag_unsafe_math_optimizations"
15386   rtx label = gen_label_rtx ();
15388   emit_label (label);
15390   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15391                            operands[1], operands[2]));
15392   ix86_emit_fp_unordered_jump (label);
15394   emit_move_insn (operands[0], operands[1]);
15395   DONE;
15398 (define_insn "fprem1xf4"
15399   [(set (match_operand:XF 0 "register_operand" "=f")
15400         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15401                     (match_operand:XF 3 "register_operand" "1")]
15402                    UNSPEC_FPREM1_F))
15403    (set (match_operand:XF 1 "register_operand" "=u")
15404         (unspec:XF [(match_dup 2) (match_dup 3)]
15405                    UNSPEC_FPREM1_U))
15406    (set (reg:CCFP FPSR_REG)
15407         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15408   "TARGET_USE_FANCY_MATH_387
15409    && flag_unsafe_math_optimizations"
15410   "fprem1"
15411   [(set_attr "type" "fpspc")
15412    (set_attr "mode" "XF")])
15414 (define_expand "dremsf3"
15415   [(use (match_operand:SF 0 "register_operand" ""))
15416    (use (match_operand:SF 1 "register_operand" ""))
15417    (use (match_operand:SF 2 "register_operand" ""))]
15418   "TARGET_USE_FANCY_MATH_387
15419    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15420    && flag_unsafe_math_optimizations"
15422   rtx label = gen_label_rtx ();
15424   rtx op1 = gen_reg_rtx (XFmode);
15425   rtx op2 = gen_reg_rtx (XFmode);
15427   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15428   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15430   emit_label (label);
15432   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15433   ix86_emit_fp_unordered_jump (label);
15435   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15436   DONE;
15439 (define_expand "dremdf3"
15440   [(use (match_operand:DF 0 "register_operand" ""))
15441    (use (match_operand:DF 1 "register_operand" ""))
15442    (use (match_operand:DF 2 "register_operand" ""))]
15443   "TARGET_USE_FANCY_MATH_387
15444    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15445    && flag_unsafe_math_optimizations"
15447   rtx label = gen_label_rtx ();
15449   rtx op1 = gen_reg_rtx (XFmode);
15450   rtx op2 = gen_reg_rtx (XFmode);
15452   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15453   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15455   emit_label (label);
15457   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15458   ix86_emit_fp_unordered_jump (label);
15460   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15461   DONE;
15464 (define_expand "dremxf3"
15465   [(use (match_operand:XF 0 "register_operand" ""))
15466    (use (match_operand:XF 1 "register_operand" ""))
15467    (use (match_operand:XF 2 "register_operand" ""))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && flag_unsafe_math_optimizations"
15471   rtx label = gen_label_rtx ();
15473   emit_label (label);
15475   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15476                             operands[1], operands[2]));
15477   ix86_emit_fp_unordered_jump (label);
15479   emit_move_insn (operands[0], operands[1]);
15480   DONE;
15483 (define_insn "*sindf2"
15484   [(set (match_operand:DF 0 "register_operand" "=f")
15485         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15486   "TARGET_USE_FANCY_MATH_387
15487    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15488    && flag_unsafe_math_optimizations"
15489   "fsin"
15490   [(set_attr "type" "fpspc")
15491    (set_attr "mode" "DF")])
15493 (define_insn "*sinsf2"
15494   [(set (match_operand:SF 0 "register_operand" "=f")
15495         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15496   "TARGET_USE_FANCY_MATH_387
15497    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15498    && flag_unsafe_math_optimizations"
15499   "fsin"
15500   [(set_attr "type" "fpspc")
15501    (set_attr "mode" "SF")])
15503 (define_insn "*sinextendsfdf2"
15504   [(set (match_operand:DF 0 "register_operand" "=f")
15505         (unspec:DF [(float_extend:DF
15506                      (match_operand:SF 1 "register_operand" "0"))]
15507                    UNSPEC_SIN))]
15508   "TARGET_USE_FANCY_MATH_387
15509    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15510    && flag_unsafe_math_optimizations"
15511   "fsin"
15512   [(set_attr "type" "fpspc")
15513    (set_attr "mode" "DF")])
15515 (define_insn "*sinxf2"
15516   [(set (match_operand:XF 0 "register_operand" "=f")
15517         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15518   "TARGET_USE_FANCY_MATH_387
15519    && flag_unsafe_math_optimizations"
15520   "fsin"
15521   [(set_attr "type" "fpspc")
15522    (set_attr "mode" "XF")])
15524 (define_insn "*cosdf2"
15525   [(set (match_operand:DF 0 "register_operand" "=f")
15526         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15527   "TARGET_USE_FANCY_MATH_387
15528    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15529    && flag_unsafe_math_optimizations"
15530   "fcos"
15531   [(set_attr "type" "fpspc")
15532    (set_attr "mode" "DF")])
15534 (define_insn "*cossf2"
15535   [(set (match_operand:SF 0 "register_operand" "=f")
15536         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15537   "TARGET_USE_FANCY_MATH_387
15538    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15539    && flag_unsafe_math_optimizations"
15540   "fcos"
15541   [(set_attr "type" "fpspc")
15542    (set_attr "mode" "SF")])
15544 (define_insn "*cosextendsfdf2"
15545   [(set (match_operand:DF 0 "register_operand" "=f")
15546         (unspec:DF [(float_extend:DF
15547                      (match_operand:SF 1 "register_operand" "0"))]
15548                    UNSPEC_COS))]
15549   "TARGET_USE_FANCY_MATH_387
15550    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15551    && flag_unsafe_math_optimizations"
15552   "fcos"
15553   [(set_attr "type" "fpspc")
15554    (set_attr "mode" "DF")])
15556 (define_insn "*cosxf2"
15557   [(set (match_operand:XF 0 "register_operand" "=f")
15558         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15559   "TARGET_USE_FANCY_MATH_387
15560    && flag_unsafe_math_optimizations"
15561   "fcos"
15562   [(set_attr "type" "fpspc")
15563    (set_attr "mode" "XF")])
15565 ;; With sincos pattern defined, sin and cos builtin function will be
15566 ;; expanded to sincos pattern with one of its outputs left unused. 
15567 ;; Cse pass  will detected, if two sincos patterns can be combined,
15568 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15569 ;; depending on the unused output.
15571 (define_insn "sincosdf3"
15572   [(set (match_operand:DF 0 "register_operand" "=f")
15573         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15574                    UNSPEC_SINCOS_COS))
15575    (set (match_operand:DF 1 "register_operand" "=u")
15576         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15577   "TARGET_USE_FANCY_MATH_387
15578    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15579    && flag_unsafe_math_optimizations"
15580   "fsincos"
15581   [(set_attr "type" "fpspc")
15582    (set_attr "mode" "DF")])
15584 (define_split
15585   [(set (match_operand:DF 0 "register_operand" "")
15586         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15587                    UNSPEC_SINCOS_COS))
15588    (set (match_operand:DF 1 "register_operand" "")
15589         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15590   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15591    && !reload_completed && !reload_in_progress"
15592   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15593   "")
15595 (define_split
15596   [(set (match_operand:DF 0 "register_operand" "")
15597         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15598                    UNSPEC_SINCOS_COS))
15599    (set (match_operand:DF 1 "register_operand" "")
15600         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15601   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15602    && !reload_completed && !reload_in_progress"
15603   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15604   "")
15606 (define_insn "sincossf3"
15607   [(set (match_operand:SF 0 "register_operand" "=f")
15608         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15609                    UNSPEC_SINCOS_COS))
15610    (set (match_operand:SF 1 "register_operand" "=u")
15611         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15614    && flag_unsafe_math_optimizations"
15615   "fsincos"
15616   [(set_attr "type" "fpspc")
15617    (set_attr "mode" "SF")])
15619 (define_split
15620   [(set (match_operand:SF 0 "register_operand" "")
15621         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15622                    UNSPEC_SINCOS_COS))
15623    (set (match_operand:SF 1 "register_operand" "")
15624         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15625   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15626    && !reload_completed && !reload_in_progress"
15627   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15628   "")
15630 (define_split
15631   [(set (match_operand:SF 0 "register_operand" "")
15632         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15633                    UNSPEC_SINCOS_COS))
15634    (set (match_operand:SF 1 "register_operand" "")
15635         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15636   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15637    && !reload_completed && !reload_in_progress"
15638   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15639   "")
15641 (define_insn "*sincosextendsfdf3"
15642   [(set (match_operand:DF 0 "register_operand" "=f")
15643         (unspec:DF [(float_extend:DF
15644                      (match_operand:SF 2 "register_operand" "0"))]
15645                    UNSPEC_SINCOS_COS))
15646    (set (match_operand:DF 1 "register_operand" "=u")
15647         (unspec:DF [(float_extend:DF
15648                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15649   "TARGET_USE_FANCY_MATH_387
15650    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15651    && flag_unsafe_math_optimizations"
15652   "fsincos"
15653   [(set_attr "type" "fpspc")
15654    (set_attr "mode" "DF")])
15656 (define_split
15657   [(set (match_operand:DF 0 "register_operand" "")
15658         (unspec:DF [(float_extend:DF
15659                      (match_operand:SF 2 "register_operand" ""))]
15660                    UNSPEC_SINCOS_COS))
15661    (set (match_operand:DF 1 "register_operand" "")
15662         (unspec:DF [(float_extend:DF
15663                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15664   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15665    && !reload_completed && !reload_in_progress"
15666   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15667                                    (match_dup 2))] UNSPEC_SIN))]
15668   "")
15670 (define_split
15671   [(set (match_operand:DF 0 "register_operand" "")
15672         (unspec:DF [(float_extend:DF
15673                      (match_operand:SF 2 "register_operand" ""))]
15674                    UNSPEC_SINCOS_COS))
15675    (set (match_operand:DF 1 "register_operand" "")
15676         (unspec:DF [(float_extend:DF
15677                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15678   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15679    && !reload_completed && !reload_in_progress"
15680   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15681                                    (match_dup 2))] UNSPEC_COS))]
15682   "")
15684 (define_insn "sincosxf3"
15685   [(set (match_operand:XF 0 "register_operand" "=f")
15686         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15687                    UNSPEC_SINCOS_COS))
15688    (set (match_operand:XF 1 "register_operand" "=u")
15689         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15690   "TARGET_USE_FANCY_MATH_387
15691    && flag_unsafe_math_optimizations"
15692   "fsincos"
15693   [(set_attr "type" "fpspc")
15694    (set_attr "mode" "XF")])
15696 (define_split
15697   [(set (match_operand:XF 0 "register_operand" "")
15698         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15699                    UNSPEC_SINCOS_COS))
15700    (set (match_operand:XF 1 "register_operand" "")
15701         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15702   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15703    && !reload_completed && !reload_in_progress"
15704   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15705   "")
15707 (define_split
15708   [(set (match_operand:XF 0 "register_operand" "")
15709         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15710                    UNSPEC_SINCOS_COS))
15711    (set (match_operand:XF 1 "register_operand" "")
15712         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15713   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15714    && !reload_completed && !reload_in_progress"
15715   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15716   "")
15718 (define_insn "*tandf3_1"
15719   [(set (match_operand:DF 0 "register_operand" "=f")
15720         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15721                    UNSPEC_TAN_ONE))
15722    (set (match_operand:DF 1 "register_operand" "=u")
15723         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15724   "TARGET_USE_FANCY_MATH_387
15725    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15726    && flag_unsafe_math_optimizations"
15727   "fptan"
15728   [(set_attr "type" "fpspc")
15729    (set_attr "mode" "DF")])
15731 ;; optimize sequence: fptan
15732 ;;                    fstp    %st(0)
15733 ;;                    fld1
15734 ;; into fptan insn.
15736 (define_peephole2
15737   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15738                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15739                              UNSPEC_TAN_ONE))
15740              (set (match_operand:DF 1 "register_operand" "")
15741                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15742    (set (match_dup 0)
15743         (match_operand:DF 3 "immediate_operand" ""))]
15744   "standard_80387_constant_p (operands[3]) == 2"
15745   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15746              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15747   "")
15749 (define_expand "tandf2"
15750   [(parallel [(set (match_dup 2)
15751                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15752                               UNSPEC_TAN_ONE))
15753               (set (match_operand:DF 0 "register_operand" "")
15754                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15755   "TARGET_USE_FANCY_MATH_387
15756    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15757    && flag_unsafe_math_optimizations"
15759   operands[2] = gen_reg_rtx (DFmode);
15762 (define_insn "*tansf3_1"
15763   [(set (match_operand:SF 0 "register_operand" "=f")
15764         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15765                    UNSPEC_TAN_ONE))
15766    (set (match_operand:SF 1 "register_operand" "=u")
15767         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15770    && flag_unsafe_math_optimizations"
15771   "fptan"
15772   [(set_attr "type" "fpspc")
15773    (set_attr "mode" "SF")])
15775 ;; optimize sequence: fptan
15776 ;;                    fstp    %st(0)
15777 ;;                    fld1
15778 ;; into fptan insn.
15780 (define_peephole2
15781   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15782                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15783                              UNSPEC_TAN_ONE))
15784              (set (match_operand:SF 1 "register_operand" "")
15785                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15786    (set (match_dup 0)
15787         (match_operand:SF 3 "immediate_operand" ""))]
15788   "standard_80387_constant_p (operands[3]) == 2"
15789   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15790              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15791   "")
15793 (define_expand "tansf2"
15794   [(parallel [(set (match_dup 2)
15795                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15796                               UNSPEC_TAN_ONE))
15797               (set (match_operand:SF 0 "register_operand" "")
15798                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15799   "TARGET_USE_FANCY_MATH_387
15800    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15801    && flag_unsafe_math_optimizations"
15803   operands[2] = gen_reg_rtx (SFmode);
15806 (define_insn "*tanxf3_1"
15807   [(set (match_operand:XF 0 "register_operand" "=f")
15808         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15809                    UNSPEC_TAN_ONE))
15810    (set (match_operand:XF 1 "register_operand" "=u")
15811         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15812   "TARGET_USE_FANCY_MATH_387
15813    && flag_unsafe_math_optimizations"
15814   "fptan"
15815   [(set_attr "type" "fpspc")
15816    (set_attr "mode" "XF")])
15818 ;; optimize sequence: fptan
15819 ;;                    fstp    %st(0)
15820 ;;                    fld1
15821 ;; into fptan insn.
15823 (define_peephole2
15824   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15825                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15826                              UNSPEC_TAN_ONE))
15827              (set (match_operand:XF 1 "register_operand" "")
15828                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15829    (set (match_dup 0)
15830         (match_operand:XF 3 "immediate_operand" ""))]
15831   "standard_80387_constant_p (operands[3]) == 2"
15832   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15833              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15834   "")
15836 (define_expand "tanxf2"
15837   [(parallel [(set (match_dup 2)
15838                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15839                               UNSPEC_TAN_ONE))
15840               (set (match_operand:XF 0 "register_operand" "")
15841                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15845   operands[2] = gen_reg_rtx (XFmode);
15848 (define_insn "atan2df3_1"
15849   [(set (match_operand:DF 0 "register_operand" "=f")
15850         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15851                     (match_operand:DF 1 "register_operand" "u")]
15852                    UNSPEC_FPATAN))
15853    (clobber (match_scratch:DF 3 "=1"))]
15854   "TARGET_USE_FANCY_MATH_387
15855    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15856    && flag_unsafe_math_optimizations"
15857   "fpatan"
15858   [(set_attr "type" "fpspc")
15859    (set_attr "mode" "DF")])
15861 (define_expand "atan2df3"
15862   [(use (match_operand:DF 0 "register_operand" ""))
15863    (use (match_operand:DF 2 "register_operand" ""))
15864    (use (match_operand:DF 1 "register_operand" ""))]
15865   "TARGET_USE_FANCY_MATH_387
15866    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15867    && flag_unsafe_math_optimizations"
15869   rtx copy = gen_reg_rtx (DFmode);
15870   emit_move_insn (copy, operands[1]);
15871   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15872   DONE;
15875 (define_expand "atandf2"
15876   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15877                    (unspec:DF [(match_dup 2)
15878                                (match_operand:DF 1 "register_operand" "")]
15879                     UNSPEC_FPATAN))
15880               (clobber (match_scratch:DF 3 ""))])]
15881   "TARGET_USE_FANCY_MATH_387
15882    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15883    && flag_unsafe_math_optimizations"
15885   operands[2] = gen_reg_rtx (DFmode);
15886   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15889 (define_insn "atan2sf3_1"
15890   [(set (match_operand:SF 0 "register_operand" "=f")
15891         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15892                     (match_operand:SF 1 "register_operand" "u")]
15893                    UNSPEC_FPATAN))
15894    (clobber (match_scratch:SF 3 "=1"))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897    && flag_unsafe_math_optimizations"
15898   "fpatan"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "mode" "SF")])
15902 (define_expand "atan2sf3"
15903   [(use (match_operand:SF 0 "register_operand" ""))
15904    (use (match_operand:SF 2 "register_operand" ""))
15905    (use (match_operand:SF 1 "register_operand" ""))]
15906   "TARGET_USE_FANCY_MATH_387
15907    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15908    && flag_unsafe_math_optimizations"
15910   rtx copy = gen_reg_rtx (SFmode);
15911   emit_move_insn (copy, operands[1]);
15912   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15913   DONE;
15916 (define_expand "atansf2"
15917   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15918                    (unspec:SF [(match_dup 2)
15919                                (match_operand:SF 1 "register_operand" "")]
15920                     UNSPEC_FPATAN))
15921               (clobber (match_scratch:SF 3 ""))])]
15922   "TARGET_USE_FANCY_MATH_387
15923    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15924    && flag_unsafe_math_optimizations"
15926   operands[2] = gen_reg_rtx (SFmode);
15927   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15930 (define_insn "atan2xf3_1"
15931   [(set (match_operand:XF 0 "register_operand" "=f")
15932         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15933                     (match_operand:XF 1 "register_operand" "u")]
15934                    UNSPEC_FPATAN))
15935    (clobber (match_scratch:XF 3 "=1"))]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15938   "fpatan"
15939   [(set_attr "type" "fpspc")
15940    (set_attr "mode" "XF")])
15942 (define_expand "atan2xf3"
15943   [(use (match_operand:XF 0 "register_operand" ""))
15944    (use (match_operand:XF 2 "register_operand" ""))
15945    (use (match_operand:XF 1 "register_operand" ""))]
15946   "TARGET_USE_FANCY_MATH_387
15947    && flag_unsafe_math_optimizations"
15949   rtx copy = gen_reg_rtx (XFmode);
15950   emit_move_insn (copy, operands[1]);
15951   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15952   DONE;
15955 (define_expand "atanxf2"
15956   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15957                    (unspec:XF [(match_dup 2)
15958                                (match_operand:XF 1 "register_operand" "")]
15959                     UNSPEC_FPATAN))
15960               (clobber (match_scratch:XF 3 ""))])]
15961   "TARGET_USE_FANCY_MATH_387
15962    && flag_unsafe_math_optimizations"
15964   operands[2] = gen_reg_rtx (XFmode);
15965   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15968 (define_expand "asindf2"
15969   [(set (match_dup 2)
15970         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15971    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15972    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15973    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15974    (parallel [(set (match_dup 7)
15975                    (unspec:XF [(match_dup 6) (match_dup 2)]
15976                               UNSPEC_FPATAN))
15977               (clobber (match_scratch:XF 8 ""))])
15978    (set (match_operand:DF 0 "register_operand" "")
15979         (float_truncate:DF (match_dup 7)))]
15980   "TARGET_USE_FANCY_MATH_387
15981    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15982    && flag_unsafe_math_optimizations"
15984   int i;
15986   for (i=2; i<8; i++)
15987     operands[i] = gen_reg_rtx (XFmode);
15989   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15992 (define_expand "asinsf2"
15993   [(set (match_dup 2)
15994         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15995    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15996    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15997    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15998    (parallel [(set (match_dup 7)
15999                    (unspec:XF [(match_dup 6) (match_dup 2)]
16000                               UNSPEC_FPATAN))
16001               (clobber (match_scratch:XF 8 ""))])
16002    (set (match_operand:SF 0 "register_operand" "")
16003         (float_truncate:SF (match_dup 7)))]
16004   "TARGET_USE_FANCY_MATH_387
16005    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16006    && flag_unsafe_math_optimizations"
16008   int i;
16010   for (i=2; i<8; i++)
16011     operands[i] = gen_reg_rtx (XFmode);
16013   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16016 (define_expand "asinxf2"
16017   [(set (match_dup 2)
16018         (mult:XF (match_operand:XF 1 "register_operand" "")
16019                  (match_dup 1)))
16020    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16021    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16022    (parallel [(set (match_operand:XF 0 "register_operand" "")
16023                    (unspec:XF [(match_dup 5) (match_dup 1)]
16024                               UNSPEC_FPATAN))
16025               (clobber (match_scratch:XF 6 ""))])]
16026   "TARGET_USE_FANCY_MATH_387
16027    && flag_unsafe_math_optimizations"
16029   int i;
16031   for (i=2; i<6; i++)
16032     operands[i] = gen_reg_rtx (XFmode);
16034   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16037 (define_expand "acosdf2"
16038   [(set (match_dup 2)
16039         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16040    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16041    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16042    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16043    (parallel [(set (match_dup 7)
16044                    (unspec:XF [(match_dup 2) (match_dup 6)]
16045                               UNSPEC_FPATAN))
16046               (clobber (match_scratch:XF 8 ""))])
16047    (set (match_operand:DF 0 "register_operand" "")
16048         (float_truncate:DF (match_dup 7)))]
16049   "TARGET_USE_FANCY_MATH_387
16050    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16051    && flag_unsafe_math_optimizations"
16053   int i;
16055   for (i=2; i<8; i++)
16056     operands[i] = gen_reg_rtx (XFmode);
16058   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16061 (define_expand "acossf2"
16062   [(set (match_dup 2)
16063         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16064    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16065    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16066    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16067    (parallel [(set (match_dup 7)
16068                    (unspec:XF [(match_dup 2) (match_dup 6)]
16069                               UNSPEC_FPATAN))
16070               (clobber (match_scratch:XF 8 ""))])
16071    (set (match_operand:SF 0 "register_operand" "")
16072         (float_truncate:SF (match_dup 7)))]
16073   "TARGET_USE_FANCY_MATH_387
16074    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16075    && flag_unsafe_math_optimizations"
16077   int i;
16079   for (i=2; i<8; i++)
16080     operands[i] = gen_reg_rtx (XFmode);
16082   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16085 (define_expand "acosxf2"
16086   [(set (match_dup 2)
16087         (mult:XF (match_operand:XF 1 "register_operand" "")
16088                  (match_dup 1)))
16089    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16090    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16091    (parallel [(set (match_operand:XF 0 "register_operand" "")
16092                    (unspec:XF [(match_dup 1) (match_dup 5)]
16093                               UNSPEC_FPATAN))
16094               (clobber (match_scratch:XF 6 ""))])]
16095   "TARGET_USE_FANCY_MATH_387
16096    && flag_unsafe_math_optimizations"
16098   int i;
16100   for (i=2; i<6; i++)
16101     operands[i] = gen_reg_rtx (XFmode);
16103   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16106 (define_insn "fyl2x_xf3"
16107   [(set (match_operand:XF 0 "register_operand" "=f")
16108         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16109                     (match_operand:XF 1 "register_operand" "u")]
16110                    UNSPEC_FYL2X))
16111    (clobber (match_scratch:XF 3 "=1"))]
16112   "TARGET_USE_FANCY_MATH_387
16113    && flag_unsafe_math_optimizations"
16114   "fyl2x"
16115   [(set_attr "type" "fpspc")
16116    (set_attr "mode" "XF")])
16118 (define_expand "logsf2"
16119   [(set (match_dup 2)
16120         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16121    (parallel [(set (match_dup 4)
16122                    (unspec:XF [(match_dup 2)
16123                                (match_dup 3)] UNSPEC_FYL2X))
16124               (clobber (match_scratch:XF 5 ""))])
16125    (set (match_operand:SF 0 "register_operand" "")
16126         (float_truncate:SF (match_dup 4)))]
16127   "TARGET_USE_FANCY_MATH_387
16128    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16129    && flag_unsafe_math_optimizations"
16131   rtx temp;
16133   operands[2] = gen_reg_rtx (XFmode);
16134   operands[3] = gen_reg_rtx (XFmode);
16135   operands[4] = gen_reg_rtx (XFmode);
16137   temp = standard_80387_constant_rtx (4); /* fldln2 */
16138   emit_move_insn (operands[3], temp);
16141 (define_expand "logdf2"
16142   [(set (match_dup 2)
16143         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16144    (parallel [(set (match_dup 4)
16145                    (unspec:XF [(match_dup 2)
16146                                (match_dup 3)] UNSPEC_FYL2X))
16147               (clobber (match_scratch:XF 5 ""))])
16148    (set (match_operand:DF 0 "register_operand" "")
16149         (float_truncate:DF (match_dup 4)))]
16150   "TARGET_USE_FANCY_MATH_387
16151    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16152    && flag_unsafe_math_optimizations"
16154   rtx temp;
16156   operands[2] = gen_reg_rtx (XFmode);
16157   operands[3] = gen_reg_rtx (XFmode);
16158   operands[4] = gen_reg_rtx (XFmode);
16160   temp = standard_80387_constant_rtx (4); /* fldln2 */
16161   emit_move_insn (operands[3], temp);
16164 (define_expand "logxf2"
16165   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16166                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16167                                (match_dup 2)] UNSPEC_FYL2X))
16168               (clobber (match_scratch:XF 3 ""))])]
16169   "TARGET_USE_FANCY_MATH_387
16170    && flag_unsafe_math_optimizations"
16172   rtx temp;
16174   operands[2] = gen_reg_rtx (XFmode);
16175   temp = standard_80387_constant_rtx (4); /* fldln2 */
16176   emit_move_insn (operands[2], temp);
16179 (define_expand "log10sf2"
16180   [(set (match_dup 2)
16181         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16182    (parallel [(set (match_dup 4)
16183                    (unspec:XF [(match_dup 2)
16184                                (match_dup 3)] UNSPEC_FYL2X))
16185               (clobber (match_scratch:XF 5 ""))])
16186    (set (match_operand:SF 0 "register_operand" "")
16187         (float_truncate:SF (match_dup 4)))]
16188   "TARGET_USE_FANCY_MATH_387
16189    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190    && flag_unsafe_math_optimizations"
16192   rtx temp;
16194   operands[2] = gen_reg_rtx (XFmode);
16195   operands[3] = gen_reg_rtx (XFmode);
16196   operands[4] = gen_reg_rtx (XFmode);
16198   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16199   emit_move_insn (operands[3], temp);
16202 (define_expand "log10df2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16205    (parallel [(set (match_dup 4)
16206                    (unspec:XF [(match_dup 2)
16207                                (match_dup 3)] UNSPEC_FYL2X))
16208               (clobber (match_scratch:XF 5 ""))])
16209    (set (match_operand:DF 0 "register_operand" "")
16210         (float_truncate:DF (match_dup 4)))]
16211   "TARGET_USE_FANCY_MATH_387
16212    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16213    && flag_unsafe_math_optimizations"
16215   rtx temp;
16217   operands[2] = gen_reg_rtx (XFmode);
16218   operands[3] = gen_reg_rtx (XFmode);
16219   operands[4] = gen_reg_rtx (XFmode);
16221   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16222   emit_move_insn (operands[3], temp);
16225 (define_expand "log10xf2"
16226   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16227                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16228                                (match_dup 2)] UNSPEC_FYL2X))
16229               (clobber (match_scratch:XF 3 ""))])]
16230   "TARGET_USE_FANCY_MATH_387
16231    && flag_unsafe_math_optimizations"
16233   rtx temp;
16235   operands[2] = gen_reg_rtx (XFmode);
16236   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16237   emit_move_insn (operands[2], temp);
16240 (define_expand "log2sf2"
16241   [(set (match_dup 2)
16242         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16243    (parallel [(set (match_dup 4)
16244                    (unspec:XF [(match_dup 2)
16245                                (match_dup 3)] UNSPEC_FYL2X))
16246               (clobber (match_scratch:XF 5 ""))])
16247    (set (match_operand:SF 0 "register_operand" "")
16248         (float_truncate:SF (match_dup 4)))]
16249   "TARGET_USE_FANCY_MATH_387
16250    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16251    && flag_unsafe_math_optimizations"
16253   operands[2] = gen_reg_rtx (XFmode);
16254   operands[3] = gen_reg_rtx (XFmode);
16255   operands[4] = gen_reg_rtx (XFmode);
16257   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16260 (define_expand "log2df2"
16261   [(set (match_dup 2)
16262         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16263    (parallel [(set (match_dup 4)
16264                    (unspec:XF [(match_dup 2)
16265                                (match_dup 3)] UNSPEC_FYL2X))
16266               (clobber (match_scratch:XF 5 ""))])
16267    (set (match_operand:DF 0 "register_operand" "")
16268         (float_truncate:DF (match_dup 4)))]
16269   "TARGET_USE_FANCY_MATH_387
16270    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16271    && flag_unsafe_math_optimizations"
16273   operands[2] = gen_reg_rtx (XFmode);
16274   operands[3] = gen_reg_rtx (XFmode);
16275   operands[4] = gen_reg_rtx (XFmode);
16277   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16280 (define_expand "log2xf2"
16281   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16282                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16283                                (match_dup 2)] UNSPEC_FYL2X))
16284               (clobber (match_scratch:XF 3 ""))])]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16288   operands[2] = gen_reg_rtx (XFmode);
16289   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16292 (define_insn "fyl2xp1_xf3"
16293   [(set (match_operand:XF 0 "register_operand" "=f")
16294         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16295                     (match_operand:XF 1 "register_operand" "u")]
16296                    UNSPEC_FYL2XP1))
16297    (clobber (match_scratch:XF 3 "=1"))]
16298   "TARGET_USE_FANCY_MATH_387
16299    && flag_unsafe_math_optimizations"
16300   "fyl2xp1"
16301   [(set_attr "type" "fpspc")
16302    (set_attr "mode" "XF")])
16304 (define_expand "log1psf2"
16305   [(use (match_operand:SF 0 "register_operand" ""))
16306    (use (match_operand:SF 1 "register_operand" ""))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16311   rtx op0 = gen_reg_rtx (XFmode);
16312   rtx op1 = gen_reg_rtx (XFmode);
16314   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16315   ix86_emit_i387_log1p (op0, op1);
16316   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16317   DONE;
16320 (define_expand "log1pdf2"
16321   [(use (match_operand:DF 0 "register_operand" ""))
16322    (use (match_operand:DF 1 "register_operand" ""))]
16323   "TARGET_USE_FANCY_MATH_387
16324    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16325    && flag_unsafe_math_optimizations"
16327   rtx op0 = gen_reg_rtx (XFmode);
16328   rtx op1 = gen_reg_rtx (XFmode);
16330   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16331   ix86_emit_i387_log1p (op0, op1);
16332   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16333   DONE;
16336 (define_expand "log1pxf2"
16337   [(use (match_operand:XF 0 "register_operand" ""))
16338    (use (match_operand:XF 1 "register_operand" ""))]
16339   "TARGET_USE_FANCY_MATH_387
16340    && flag_unsafe_math_optimizations"
16342   ix86_emit_i387_log1p (operands[0], operands[1]);
16343   DONE;
16346 (define_insn "*fxtractxf3"
16347   [(set (match_operand:XF 0 "register_operand" "=f")
16348         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16349                    UNSPEC_XTRACT_FRACT))
16350    (set (match_operand:XF 1 "register_operand" "=u")
16351         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16352   "TARGET_USE_FANCY_MATH_387
16353    && flag_unsafe_math_optimizations"
16354   "fxtract"
16355   [(set_attr "type" "fpspc")
16356    (set_attr "mode" "XF")])
16358 (define_expand "logbsf2"
16359   [(set (match_dup 2)
16360         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16361    (parallel [(set (match_dup 3)
16362                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16363               (set (match_dup 4)
16364                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16365    (set (match_operand:SF 0 "register_operand" "")
16366         (float_truncate:SF (match_dup 4)))]
16367   "TARGET_USE_FANCY_MATH_387
16368    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16369    && flag_unsafe_math_optimizations"
16371   operands[2] = gen_reg_rtx (XFmode);
16372   operands[3] = gen_reg_rtx (XFmode);
16373   operands[4] = gen_reg_rtx (XFmode);
16376 (define_expand "logbdf2"
16377   [(set (match_dup 2)
16378         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16379    (parallel [(set (match_dup 3)
16380                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16381               (set (match_dup 4)
16382                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16383    (set (match_operand:DF 0 "register_operand" "")
16384         (float_truncate:DF (match_dup 4)))]
16385   "TARGET_USE_FANCY_MATH_387
16386    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16387    && flag_unsafe_math_optimizations"
16389   operands[2] = gen_reg_rtx (XFmode);
16390   operands[3] = gen_reg_rtx (XFmode);
16391   operands[4] = gen_reg_rtx (XFmode);
16394 (define_expand "logbxf2"
16395   [(parallel [(set (match_dup 2)
16396                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16397                               UNSPEC_XTRACT_FRACT))
16398               (set (match_operand:XF 0 "register_operand" "")
16399                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16400   "TARGET_USE_FANCY_MATH_387
16401    && flag_unsafe_math_optimizations"
16403   operands[2] = gen_reg_rtx (XFmode);
16406 (define_expand "ilogbsi2"
16407   [(parallel [(set (match_dup 2)
16408                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16409                               UNSPEC_XTRACT_FRACT))
16410               (set (match_operand:XF 3 "register_operand" "")
16411                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16412    (parallel [(set (match_operand:SI 0 "register_operand" "")
16413                    (fix:SI (match_dup 3)))
16414               (clobber (reg:CC FLAGS_REG))])]
16415   "TARGET_USE_FANCY_MATH_387
16416    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16417    && flag_unsafe_math_optimizations"
16419   operands[2] = gen_reg_rtx (XFmode);
16420   operands[3] = gen_reg_rtx (XFmode);
16423 (define_insn "*f2xm1xf2"
16424   [(set (match_operand:XF 0 "register_operand" "=f")
16425         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16426          UNSPEC_F2XM1))]
16427   "TARGET_USE_FANCY_MATH_387
16428    && flag_unsafe_math_optimizations"
16429   "f2xm1"
16430   [(set_attr "type" "fpspc")
16431    (set_attr "mode" "XF")])
16433 (define_insn "*fscalexf4"
16434   [(set (match_operand:XF 0 "register_operand" "=f")
16435         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16436                     (match_operand:XF 3 "register_operand" "1")]
16437                    UNSPEC_FSCALE_FRACT))
16438    (set (match_operand:XF 1 "register_operand" "=u")
16439         (unspec:XF [(match_dup 2) (match_dup 3)]
16440                    UNSPEC_FSCALE_EXP))]
16441   "TARGET_USE_FANCY_MATH_387
16442    && flag_unsafe_math_optimizations"
16443   "fscale"
16444   [(set_attr "type" "fpspc")
16445    (set_attr "mode" "XF")])
16447 (define_expand "expsf2"
16448   [(set (match_dup 2)
16449         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16450    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16451    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16452    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16453    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16454    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16455    (parallel [(set (match_dup 10)
16456                    (unspec:XF [(match_dup 9) (match_dup 5)]
16457                               UNSPEC_FSCALE_FRACT))
16458               (set (match_dup 11)
16459                    (unspec:XF [(match_dup 9) (match_dup 5)]
16460                               UNSPEC_FSCALE_EXP))])
16461    (set (match_operand:SF 0 "register_operand" "")
16462         (float_truncate:SF (match_dup 10)))]
16463   "TARGET_USE_FANCY_MATH_387
16464    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16465    && flag_unsafe_math_optimizations"
16467   rtx temp;
16468   int i;
16470   for (i=2; i<12; i++)
16471     operands[i] = gen_reg_rtx (XFmode);
16472   temp = standard_80387_constant_rtx (5); /* fldl2e */
16473   emit_move_insn (operands[3], temp);
16474   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16477 (define_expand "expdf2"
16478   [(set (match_dup 2)
16479         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16480    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16481    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16482    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16483    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16484    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16485    (parallel [(set (match_dup 10)
16486                    (unspec:XF [(match_dup 9) (match_dup 5)]
16487                               UNSPEC_FSCALE_FRACT))
16488               (set (match_dup 11)
16489                    (unspec:XF [(match_dup 9) (match_dup 5)]
16490                               UNSPEC_FSCALE_EXP))])
16491    (set (match_operand:DF 0 "register_operand" "")
16492         (float_truncate:DF (match_dup 10)))]
16493   "TARGET_USE_FANCY_MATH_387
16494    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16495    && flag_unsafe_math_optimizations"
16497   rtx temp;
16498   int i;
16500   for (i=2; i<12; i++)
16501     operands[i] = gen_reg_rtx (XFmode);
16502   temp = standard_80387_constant_rtx (5); /* fldl2e */
16503   emit_move_insn (operands[3], temp);
16504   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16507 (define_expand "expxf2"
16508   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16509                                (match_dup 2)))
16510    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16511    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16512    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16513    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16514    (parallel [(set (match_operand:XF 0 "register_operand" "")
16515                    (unspec:XF [(match_dup 8) (match_dup 4)]
16516                               UNSPEC_FSCALE_FRACT))
16517               (set (match_dup 9)
16518                    (unspec:XF [(match_dup 8) (match_dup 4)]
16519                               UNSPEC_FSCALE_EXP))])]
16520   "TARGET_USE_FANCY_MATH_387
16521    && flag_unsafe_math_optimizations"
16523   rtx temp;
16524   int i;
16526   for (i=2; i<10; i++)
16527     operands[i] = gen_reg_rtx (XFmode);
16528   temp = standard_80387_constant_rtx (5); /* fldl2e */
16529   emit_move_insn (operands[2], temp);
16530   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16533 (define_expand "exp10sf2"
16534   [(set (match_dup 2)
16535         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16536    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16537    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16538    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16539    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16540    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16541    (parallel [(set (match_dup 10)
16542                    (unspec:XF [(match_dup 9) (match_dup 5)]
16543                               UNSPEC_FSCALE_FRACT))
16544               (set (match_dup 11)
16545                    (unspec:XF [(match_dup 9) (match_dup 5)]
16546                               UNSPEC_FSCALE_EXP))])
16547    (set (match_operand:SF 0 "register_operand" "")
16548         (float_truncate:SF (match_dup 10)))]
16549   "TARGET_USE_FANCY_MATH_387
16550    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16551    && flag_unsafe_math_optimizations"
16553   rtx temp;
16554   int i;
16556   for (i=2; i<12; i++)
16557     operands[i] = gen_reg_rtx (XFmode);
16558   temp = standard_80387_constant_rtx (6); /* fldl2t */
16559   emit_move_insn (operands[3], temp);
16560   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16563 (define_expand "exp10df2"
16564   [(set (match_dup 2)
16565         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16566    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16567    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16568    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16569    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16570    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16571    (parallel [(set (match_dup 10)
16572                    (unspec:XF [(match_dup 9) (match_dup 5)]
16573                               UNSPEC_FSCALE_FRACT))
16574               (set (match_dup 11)
16575                    (unspec:XF [(match_dup 9) (match_dup 5)]
16576                               UNSPEC_FSCALE_EXP))])
16577    (set (match_operand:DF 0 "register_operand" "")
16578         (float_truncate:DF (match_dup 10)))]
16579   "TARGET_USE_FANCY_MATH_387
16580    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16581    && flag_unsafe_math_optimizations"
16583   rtx temp;
16584   int i;
16586   for (i=2; i<12; i++)
16587     operands[i] = gen_reg_rtx (XFmode);
16588   temp = standard_80387_constant_rtx (6); /* fldl2t */
16589   emit_move_insn (operands[3], temp);
16590   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16593 (define_expand "exp10xf2"
16594   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16595                                (match_dup 2)))
16596    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16597    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16598    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16599    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16600    (parallel [(set (match_operand:XF 0 "register_operand" "")
16601                    (unspec:XF [(match_dup 8) (match_dup 4)]
16602                               UNSPEC_FSCALE_FRACT))
16603               (set (match_dup 9)
16604                    (unspec:XF [(match_dup 8) (match_dup 4)]
16605                               UNSPEC_FSCALE_EXP))])]
16606   "TARGET_USE_FANCY_MATH_387
16607    && flag_unsafe_math_optimizations"
16609   rtx temp;
16610   int i;
16612   for (i=2; i<10; i++)
16613     operands[i] = gen_reg_rtx (XFmode);
16614   temp = standard_80387_constant_rtx (6); /* fldl2t */
16615   emit_move_insn (operands[2], temp);
16616   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16619 (define_expand "exp2sf2"
16620   [(set (match_dup 2)
16621         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16622    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16623    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16624    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16625    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16626    (parallel [(set (match_dup 8)
16627                    (unspec:XF [(match_dup 7) (match_dup 3)]
16628                               UNSPEC_FSCALE_FRACT))
16629               (set (match_dup 9)
16630                    (unspec:XF [(match_dup 7) (match_dup 3)]
16631                               UNSPEC_FSCALE_EXP))])
16632    (set (match_operand:SF 0 "register_operand" "")
16633         (float_truncate:SF (match_dup 8)))]
16634   "TARGET_USE_FANCY_MATH_387
16635    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16636    && flag_unsafe_math_optimizations"
16638   int i;
16640   for (i=2; i<10; i++)
16641     operands[i] = gen_reg_rtx (XFmode);
16642   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16645 (define_expand "exp2df2"
16646   [(set (match_dup 2)
16647         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16648    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16649    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16650    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16651    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16652    (parallel [(set (match_dup 8)
16653                    (unspec:XF [(match_dup 7) (match_dup 3)]
16654                               UNSPEC_FSCALE_FRACT))
16655               (set (match_dup 9)
16656                    (unspec:XF [(match_dup 7) (match_dup 3)]
16657                               UNSPEC_FSCALE_EXP))])
16658    (set (match_operand:DF 0 "register_operand" "")
16659         (float_truncate:DF (match_dup 8)))]
16660   "TARGET_USE_FANCY_MATH_387
16661    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16662    && flag_unsafe_math_optimizations"
16664   int i;
16666   for (i=2; i<10; i++)
16667     operands[i] = gen_reg_rtx (XFmode);
16668   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16671 (define_expand "exp2xf2"
16672   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16673    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16674    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16675    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16676    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16677    (parallel [(set (match_operand:XF 0 "register_operand" "")
16678                    (unspec:XF [(match_dup 7) (match_dup 3)]
16679                               UNSPEC_FSCALE_FRACT))
16680               (set (match_dup 8)
16681                    (unspec:XF [(match_dup 7) (match_dup 3)]
16682                               UNSPEC_FSCALE_EXP))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16686   int i;
16688   for (i=2; i<9; i++)
16689     operands[i] = gen_reg_rtx (XFmode);
16690   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16693 (define_expand "expm1df2"
16694   [(set (match_dup 2)
16695         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16696    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16697    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16698    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16699    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16700    (parallel [(set (match_dup 8)
16701                    (unspec:XF [(match_dup 7) (match_dup 5)]
16702                               UNSPEC_FSCALE_FRACT))
16703                    (set (match_dup 9)
16704                    (unspec:XF [(match_dup 7) (match_dup 5)]
16705                               UNSPEC_FSCALE_EXP))])
16706    (parallel [(set (match_dup 11)
16707                    (unspec:XF [(match_dup 10) (match_dup 9)]
16708                               UNSPEC_FSCALE_FRACT))
16709               (set (match_dup 12)
16710                    (unspec:XF [(match_dup 10) (match_dup 9)]
16711                               UNSPEC_FSCALE_EXP))])
16712    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16713    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16714    (set (match_operand:DF 0 "register_operand" "")
16715         (float_truncate:DF (match_dup 14)))]
16716   "TARGET_USE_FANCY_MATH_387
16717    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16718    && flag_unsafe_math_optimizations"
16720   rtx temp;
16721   int i;
16723   for (i=2; i<15; i++)
16724     operands[i] = gen_reg_rtx (XFmode);
16725   temp = standard_80387_constant_rtx (5); /* fldl2e */
16726   emit_move_insn (operands[3], temp);
16727   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16730 (define_expand "expm1sf2"
16731   [(set (match_dup 2)
16732         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737    (parallel [(set (match_dup 8)
16738                    (unspec:XF [(match_dup 7) (match_dup 5)]
16739                               UNSPEC_FSCALE_FRACT))
16740                    (set (match_dup 9)
16741                    (unspec:XF [(match_dup 7) (match_dup 5)]
16742                               UNSPEC_FSCALE_EXP))])
16743    (parallel [(set (match_dup 11)
16744                    (unspec:XF [(match_dup 10) (match_dup 9)]
16745                               UNSPEC_FSCALE_FRACT))
16746               (set (match_dup 12)
16747                    (unspec:XF [(match_dup 10) (match_dup 9)]
16748                               UNSPEC_FSCALE_EXP))])
16749    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16750    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16751    (set (match_operand:SF 0 "register_operand" "")
16752         (float_truncate:SF (match_dup 14)))]
16753   "TARGET_USE_FANCY_MATH_387
16754    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16755    && flag_unsafe_math_optimizations"
16757   rtx temp;
16758   int i;
16760   for (i=2; i<15; i++)
16761     operands[i] = gen_reg_rtx (XFmode);
16762   temp = standard_80387_constant_rtx (5); /* fldl2e */
16763   emit_move_insn (operands[3], temp);
16764   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16767 (define_expand "expm1xf2"
16768   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16769                                (match_dup 2)))
16770    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16771    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16772    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16773    (parallel [(set (match_dup 7)
16774                    (unspec:XF [(match_dup 6) (match_dup 4)]
16775                               UNSPEC_FSCALE_FRACT))
16776                    (set (match_dup 8)
16777                    (unspec:XF [(match_dup 6) (match_dup 4)]
16778                               UNSPEC_FSCALE_EXP))])
16779    (parallel [(set (match_dup 10)
16780                    (unspec:XF [(match_dup 9) (match_dup 8)]
16781                               UNSPEC_FSCALE_FRACT))
16782               (set (match_dup 11)
16783                    (unspec:XF [(match_dup 9) (match_dup 8)]
16784                               UNSPEC_FSCALE_EXP))])
16785    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16786    (set (match_operand:XF 0 "register_operand" "")
16787         (plus:XF (match_dup 12) (match_dup 7)))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && flag_unsafe_math_optimizations"
16791   rtx temp;
16792   int i;
16794   for (i=2; i<13; i++)
16795     operands[i] = gen_reg_rtx (XFmode);
16796   temp = standard_80387_constant_rtx (5); /* fldl2e */
16797   emit_move_insn (operands[2], temp);
16798   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16801 (define_expand "ldexpdf3"
16802   [(set (match_dup 3)
16803         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16804    (set (match_dup 4)
16805         (float:XF (match_operand:SI 2 "register_operand" "")))
16806    (parallel [(set (match_dup 5)
16807                    (unspec:XF [(match_dup 3) (match_dup 4)]
16808                               UNSPEC_FSCALE_FRACT))
16809               (set (match_dup 6)
16810                    (unspec:XF [(match_dup 3) (match_dup 4)]
16811                               UNSPEC_FSCALE_EXP))])
16812    (set (match_operand:DF 0 "register_operand" "")
16813         (float_truncate:DF (match_dup 5)))]
16814   "TARGET_USE_FANCY_MATH_387
16815    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16816    && flag_unsafe_math_optimizations"
16818   int i;
16820   for (i=3; i<7; i++)
16821     operands[i] = gen_reg_rtx (XFmode);
16824 (define_expand "ldexpsf3"
16825   [(set (match_dup 3)
16826         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16827    (set (match_dup 4)
16828         (float:XF (match_operand:SI 2 "register_operand" "")))
16829    (parallel [(set (match_dup 5)
16830                    (unspec:XF [(match_dup 3) (match_dup 4)]
16831                               UNSPEC_FSCALE_FRACT))
16832               (set (match_dup 6)
16833                    (unspec:XF [(match_dup 3) (match_dup 4)]
16834                               UNSPEC_FSCALE_EXP))])
16835    (set (match_operand:SF 0 "register_operand" "")
16836         (float_truncate:SF (match_dup 5)))]
16837   "TARGET_USE_FANCY_MATH_387
16838    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16839    && flag_unsafe_math_optimizations"
16841   int i;
16843   for (i=3; i<7; i++)
16844     operands[i] = gen_reg_rtx (XFmode);
16847 (define_expand "ldexpxf3"
16848   [(set (match_dup 3)
16849         (float:XF (match_operand:SI 2 "register_operand" "")))
16850    (parallel [(set (match_operand:XF 0 " register_operand" "")
16851                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16852                                (match_dup 3)]
16853                               UNSPEC_FSCALE_FRACT))
16854               (set (match_dup 4)
16855                    (unspec:XF [(match_dup 1) (match_dup 3)]
16856                               UNSPEC_FSCALE_EXP))])]
16857   "TARGET_USE_FANCY_MATH_387
16858    && flag_unsafe_math_optimizations"
16860   int i;
16862   for (i=3; i<5; i++)
16863     operands[i] = gen_reg_rtx (XFmode);
16867 (define_insn "frndintxf2"
16868   [(set (match_operand:XF 0 "register_operand" "=f")
16869         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16870          UNSPEC_FRNDINT))]
16871   "TARGET_USE_FANCY_MATH_387
16872    && flag_unsafe_math_optimizations"
16873   "frndint"
16874   [(set_attr "type" "fpspc")
16875    (set_attr "mode" "XF")])
16877 (define_expand "rintdf2"
16878   [(use (match_operand:DF 0 "register_operand" ""))
16879    (use (match_operand:DF 1 "register_operand" ""))]
16880   "TARGET_USE_FANCY_MATH_387
16881    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16882    && flag_unsafe_math_optimizations"
16884   rtx op0 = gen_reg_rtx (XFmode);
16885   rtx op1 = gen_reg_rtx (XFmode);
16887   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16888   emit_insn (gen_frndintxf2 (op0, op1));
16890   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16891   DONE;
16894 (define_expand "rintsf2"
16895   [(use (match_operand:SF 0 "register_operand" ""))
16896    (use (match_operand:SF 1 "register_operand" ""))]
16897   "TARGET_USE_FANCY_MATH_387
16898    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16899    && flag_unsafe_math_optimizations"
16901   rtx op0 = gen_reg_rtx (XFmode);
16902   rtx op1 = gen_reg_rtx (XFmode);
16904   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16905   emit_insn (gen_frndintxf2 (op0, op1));
16907   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16908   DONE;
16911 (define_expand "rintxf2"
16912   [(use (match_operand:XF 0 "register_operand" ""))
16913    (use (match_operand:XF 1 "register_operand" ""))]
16914   "TARGET_USE_FANCY_MATH_387
16915    && flag_unsafe_math_optimizations"
16917   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16918   DONE;
16921 (define_insn_and_split "*fistdi2_1"
16922   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16923         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16924          UNSPEC_FIST))]
16925   "TARGET_USE_FANCY_MATH_387
16926    && flag_unsafe_math_optimizations
16927    && !(reload_completed || reload_in_progress)"
16928   "#"
16929   "&& 1"
16930   [(const_int 0)]
16932   if (memory_operand (operands[0], VOIDmode))
16933     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16934   else
16935     {
16936       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16937       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16938                                          operands[2]));
16939     }
16940   DONE;
16942   [(set_attr "type" "fpspc")
16943    (set_attr "mode" "DI")])
16945 (define_insn "fistdi2"
16946   [(set (match_operand:DI 0 "memory_operand" "=m")
16947         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16948          UNSPEC_FIST))
16949    (clobber (match_scratch:XF 2 "=&1f"))]
16950   "TARGET_USE_FANCY_MATH_387
16951    && flag_unsafe_math_optimizations"
16952   "* return output_fix_trunc (insn, operands, 0);"
16953   [(set_attr "type" "fpspc")
16954    (set_attr "mode" "DI")])
16956 (define_insn "fistdi2_with_temp"
16957   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16958         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16959          UNSPEC_FIST))
16960    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16961    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && flag_unsafe_math_optimizations"
16964   "#"
16965   [(set_attr "type" "fpspc")
16966    (set_attr "mode" "DI")])
16968 (define_split 
16969   [(set (match_operand:DI 0 "register_operand" "")
16970         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16971          UNSPEC_FIST))
16972    (clobber (match_operand:DI 2 "memory_operand" ""))
16973    (clobber (match_scratch 3 ""))]
16974   "reload_completed"
16975   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16976               (clobber (match_dup 3))])
16977    (set (match_dup 0) (match_dup 2))]
16978   "")
16980 (define_split 
16981   [(set (match_operand:DI 0 "memory_operand" "")
16982         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16983          UNSPEC_FIST))
16984    (clobber (match_operand:DI 2 "memory_operand" ""))
16985    (clobber (match_scratch 3 ""))]
16986   "reload_completed"
16987   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16988               (clobber (match_dup 3))])]
16989   "")
16991 (define_insn_and_split "*fist<mode>2_1"
16992   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16993         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16994          UNSPEC_FIST))]
16995   "TARGET_USE_FANCY_MATH_387
16996    && flag_unsafe_math_optimizations
16997    && !(reload_completed || reload_in_progress)"
16998   "#"
16999   "&& 1"
17000   [(const_int 0)]
17002   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17003   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17004                                         operands[2]));
17005   DONE;
17007   [(set_attr "type" "fpspc")
17008    (set_attr "mode" "<MODE>")])
17010 (define_insn "fist<mode>2"
17011   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17012         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17013          UNSPEC_FIST))]
17014   "TARGET_USE_FANCY_MATH_387
17015    && flag_unsafe_math_optimizations"
17016   "* return output_fix_trunc (insn, operands, 0);"
17017   [(set_attr "type" "fpspc")
17018    (set_attr "mode" "<MODE>")])
17020 (define_insn "fist<mode>2_with_temp"
17021   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17022         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17023          UNSPEC_FIST))
17024    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17025   "TARGET_USE_FANCY_MATH_387
17026    && flag_unsafe_math_optimizations"
17027   "#"
17028   [(set_attr "type" "fpspc")
17029    (set_attr "mode" "<MODE>")])
17031 (define_split 
17032   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17033         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17034          UNSPEC_FIST))
17035    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17036   "reload_completed"
17037   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17038                        UNSPEC_FIST))
17039    (set (match_dup 0) (match_dup 2))]
17040   "")
17042 (define_split 
17043   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17044         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17045          UNSPEC_FIST))
17046    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17047   "reload_completed"
17048   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17049                        UNSPEC_FIST))]
17050   "")
17052 (define_expand "lrint<mode>2"
17053   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17054         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17055          UNSPEC_FIST))]
17056   "TARGET_USE_FANCY_MATH_387
17057    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17058    && flag_unsafe_math_optimizations"
17059   "")
17061 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17062 (define_insn_and_split "frndintxf2_floor"
17063   [(set (match_operand:XF 0 "register_operand" "=f")
17064         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17065          UNSPEC_FRNDINT_FLOOR))
17066    (clobber (reg:CC FLAGS_REG))]
17067   "TARGET_USE_FANCY_MATH_387
17068    && flag_unsafe_math_optimizations
17069    && !(reload_completed || reload_in_progress)"
17070   "#"
17071   "&& 1"
17072   [(const_int 0)]
17074   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17076   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17077   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17079   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17080                                         operands[2], operands[3]));
17081   DONE;
17083   [(set_attr "type" "frndint")
17084    (set_attr "i387_cw" "floor")
17085    (set_attr "mode" "XF")])
17087 (define_insn "frndintxf2_floor_i387"
17088   [(set (match_operand:XF 0 "register_operand" "=f")
17089         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17090          UNSPEC_FRNDINT_FLOOR))
17091    (use (match_operand:HI 2 "memory_operand" "m"))
17092    (use (match_operand:HI 3 "memory_operand" "m"))]
17093   "TARGET_USE_FANCY_MATH_387
17094    && flag_unsafe_math_optimizations"
17095   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17096   [(set_attr "type" "frndint")
17097    (set_attr "i387_cw" "floor")
17098    (set_attr "mode" "XF")])
17100 (define_expand "floorxf2"
17101   [(use (match_operand:XF 0 "register_operand" ""))
17102    (use (match_operand:XF 1 "register_operand" ""))]
17103   "TARGET_USE_FANCY_MATH_387
17104    && flag_unsafe_math_optimizations"
17106   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17107   DONE;
17110 (define_expand "floordf2"
17111   [(use (match_operand:DF 0 "register_operand" ""))
17112    (use (match_operand:DF 1 "register_operand" ""))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17115    && flag_unsafe_math_optimizations"
17117   rtx op0 = gen_reg_rtx (XFmode);
17118   rtx op1 = gen_reg_rtx (XFmode);
17120   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17121   emit_insn (gen_frndintxf2_floor (op0, op1));
17123   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17124   DONE;
17127 (define_expand "floorsf2"
17128   [(use (match_operand:SF 0 "register_operand" ""))
17129    (use (match_operand:SF 1 "register_operand" ""))]
17130   "TARGET_USE_FANCY_MATH_387
17131    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17132    && flag_unsafe_math_optimizations"
17134   rtx op0 = gen_reg_rtx (XFmode);
17135   rtx op1 = gen_reg_rtx (XFmode);
17137   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17138   emit_insn (gen_frndintxf2_floor (op0, op1));
17140   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17141   DONE;
17144 (define_insn_and_split "*fist<mode>2_floor_1"
17145   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17146         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17147          UNSPEC_FIST_FLOOR))
17148    (clobber (reg:CC FLAGS_REG))]
17149   "TARGET_USE_FANCY_MATH_387
17150    && flag_unsafe_math_optimizations
17151    && !(reload_completed || reload_in_progress)"
17152   "#"
17153   "&& 1"
17154   [(const_int 0)]
17156   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17158   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17159   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17160   if (memory_operand (operands[0], VOIDmode))
17161     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17162                                       operands[2], operands[3]));
17163   else
17164     {
17165       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17166       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17167                                                   operands[2], operands[3],
17168                                                   operands[4]));
17169     }
17170   DONE;
17172   [(set_attr "type" "fistp")
17173    (set_attr "i387_cw" "floor")
17174    (set_attr "mode" "<MODE>")])
17176 (define_insn "fistdi2_floor"
17177   [(set (match_operand:DI 0 "memory_operand" "=m")
17178         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17179          UNSPEC_FIST_FLOOR))
17180    (use (match_operand:HI 2 "memory_operand" "m"))
17181    (use (match_operand:HI 3 "memory_operand" "m"))
17182    (clobber (match_scratch:XF 4 "=&1f"))]
17183   "TARGET_USE_FANCY_MATH_387
17184    && flag_unsafe_math_optimizations"
17185   "* return output_fix_trunc (insn, operands, 0);"
17186   [(set_attr "type" "fistp")
17187    (set_attr "i387_cw" "floor")
17188    (set_attr "mode" "DI")])
17190 (define_insn "fistdi2_floor_with_temp"
17191   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17192         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17193          UNSPEC_FIST_FLOOR))
17194    (use (match_operand:HI 2 "memory_operand" "m,m"))
17195    (use (match_operand:HI 3 "memory_operand" "m,m"))
17196    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17197    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17198   "TARGET_USE_FANCY_MATH_387
17199    && flag_unsafe_math_optimizations"
17200   "#"
17201   [(set_attr "type" "fistp")
17202    (set_attr "i387_cw" "floor")
17203    (set_attr "mode" "DI")])
17205 (define_split 
17206   [(set (match_operand:DI 0 "register_operand" "")
17207         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17208          UNSPEC_FIST_FLOOR))
17209    (use (match_operand:HI 2 "memory_operand" ""))
17210    (use (match_operand:HI 3 "memory_operand" ""))
17211    (clobber (match_operand:DI 4 "memory_operand" ""))
17212    (clobber (match_scratch 5 ""))]
17213   "reload_completed"
17214   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17215               (use (match_dup 2))
17216               (use (match_dup 3))
17217               (clobber (match_dup 5))])
17218    (set (match_dup 0) (match_dup 4))]
17219   "")
17221 (define_split 
17222   [(set (match_operand:DI 0 "memory_operand" "")
17223         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17224          UNSPEC_FIST_FLOOR))
17225    (use (match_operand:HI 2 "memory_operand" ""))
17226    (use (match_operand:HI 3 "memory_operand" ""))
17227    (clobber (match_operand:DI 4 "memory_operand" ""))
17228    (clobber (match_scratch 5 ""))]
17229   "reload_completed"
17230   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17231               (use (match_dup 2))
17232               (use (match_dup 3))
17233               (clobber (match_dup 5))])]
17234   "")
17236 (define_insn "fist<mode>2_floor"
17237   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17238         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17239          UNSPEC_FIST_FLOOR))
17240    (use (match_operand:HI 2 "memory_operand" "m"))
17241    (use (match_operand:HI 3 "memory_operand" "m"))]
17242   "TARGET_USE_FANCY_MATH_387
17243    && flag_unsafe_math_optimizations"
17244   "* return output_fix_trunc (insn, operands, 0);"
17245   [(set_attr "type" "fistp")
17246    (set_attr "i387_cw" "floor")
17247    (set_attr "mode" "<MODE>")])
17249 (define_insn "fist<mode>2_floor_with_temp"
17250   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17251         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17252          UNSPEC_FIST_FLOOR))
17253    (use (match_operand:HI 2 "memory_operand" "m,m"))
17254    (use (match_operand:HI 3 "memory_operand" "m,m"))
17255    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17256   "TARGET_USE_FANCY_MATH_387
17257    && flag_unsafe_math_optimizations"
17258   "#"
17259   [(set_attr "type" "fistp")
17260    (set_attr "i387_cw" "floor")
17261    (set_attr "mode" "<MODE>")])
17263 (define_split 
17264   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17265         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17266          UNSPEC_FIST_FLOOR))
17267    (use (match_operand:HI 2 "memory_operand" ""))
17268    (use (match_operand:HI 3 "memory_operand" ""))
17269    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17270   "reload_completed"
17271   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17272                                   UNSPEC_FIST_FLOOR))
17273               (use (match_dup 2))
17274               (use (match_dup 3))])
17275    (set (match_dup 0) (match_dup 4))]
17276   "")
17278 (define_split 
17279   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17280         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17281          UNSPEC_FIST_FLOOR))
17282    (use (match_operand:HI 2 "memory_operand" ""))
17283    (use (match_operand:HI 3 "memory_operand" ""))
17284    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17285   "reload_completed"
17286   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17287                                   UNSPEC_FIST_FLOOR))
17288               (use (match_dup 2))
17289               (use (match_dup 3))])]
17290   "")
17292 (define_expand "lfloor<mode>2"
17293   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17294                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17295                     UNSPEC_FIST_FLOOR))
17296               (clobber (reg:CC FLAGS_REG))])]
17297   "TARGET_USE_FANCY_MATH_387
17298    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17299    && flag_unsafe_math_optimizations"
17300   "")
17302 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17303 (define_insn_and_split "frndintxf2_ceil"
17304   [(set (match_operand:XF 0 "register_operand" "=f")
17305         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17306          UNSPEC_FRNDINT_CEIL))
17307    (clobber (reg:CC FLAGS_REG))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && flag_unsafe_math_optimizations
17310    && !(reload_completed || reload_in_progress)"
17311   "#"
17312   "&& 1"
17313   [(const_int 0)]
17315   ix86_optimize_mode_switching[I387_CEIL] = 1;
17317   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17318   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17320   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17321                                        operands[2], operands[3]));
17322   DONE;
17324   [(set_attr "type" "frndint")
17325    (set_attr "i387_cw" "ceil")
17326    (set_attr "mode" "XF")])
17328 (define_insn "frndintxf2_ceil_i387"
17329   [(set (match_operand:XF 0 "register_operand" "=f")
17330         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17331          UNSPEC_FRNDINT_CEIL))
17332    (use (match_operand:HI 2 "memory_operand" "m"))
17333    (use (match_operand:HI 3 "memory_operand" "m"))]
17334   "TARGET_USE_FANCY_MATH_387
17335    && flag_unsafe_math_optimizations"
17336   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17337   [(set_attr "type" "frndint")
17338    (set_attr "i387_cw" "ceil")
17339    (set_attr "mode" "XF")])
17341 (define_expand "ceilxf2"
17342   [(use (match_operand:XF 0 "register_operand" ""))
17343    (use (match_operand:XF 1 "register_operand" ""))]
17344   "TARGET_USE_FANCY_MATH_387
17345    && flag_unsafe_math_optimizations"
17347   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17348   DONE;
17351 (define_expand "ceildf2"
17352   [(use (match_operand:DF 0 "register_operand" ""))
17353    (use (match_operand:DF 1 "register_operand" ""))]
17354   "TARGET_USE_FANCY_MATH_387
17355    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17356    && flag_unsafe_math_optimizations"
17358   rtx op0 = gen_reg_rtx (XFmode);
17359   rtx op1 = gen_reg_rtx (XFmode);
17361   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17362   emit_insn (gen_frndintxf2_ceil (op0, op1));
17364   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17365   DONE;
17368 (define_expand "ceilsf2"
17369   [(use (match_operand:SF 0 "register_operand" ""))
17370    (use (match_operand:SF 1 "register_operand" ""))]
17371   "TARGET_USE_FANCY_MATH_387
17372    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17373    && flag_unsafe_math_optimizations"
17375   rtx op0 = gen_reg_rtx (XFmode);
17376   rtx op1 = gen_reg_rtx (XFmode);
17378   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17379   emit_insn (gen_frndintxf2_ceil (op0, op1));
17381   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17382   DONE;
17385 (define_insn_and_split "*fist<mode>2_ceil_1"
17386   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17387         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17388          UNSPEC_FIST_CEIL))
17389    (clobber (reg:CC FLAGS_REG))]
17390   "TARGET_USE_FANCY_MATH_387
17391    && flag_unsafe_math_optimizations
17392    && !(reload_completed || reload_in_progress)"
17393   "#"
17394   "&& 1"
17395   [(const_int 0)]
17397   ix86_optimize_mode_switching[I387_CEIL] = 1;
17399   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17400   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17401   if (memory_operand (operands[0], VOIDmode))
17402     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17403                                      operands[2], operands[3]));
17404   else
17405     {
17406       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17407       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17408                                                  operands[2], operands[3],
17409                                                  operands[4]));
17410     }
17411   DONE;
17413   [(set_attr "type" "fistp")
17414    (set_attr "i387_cw" "ceil")
17415    (set_attr "mode" "<MODE>")])
17417 (define_insn "fistdi2_ceil"
17418   [(set (match_operand:DI 0 "memory_operand" "=m")
17419         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17420          UNSPEC_FIST_CEIL))
17421    (use (match_operand:HI 2 "memory_operand" "m"))
17422    (use (match_operand:HI 3 "memory_operand" "m"))
17423    (clobber (match_scratch:XF 4 "=&1f"))]
17424   "TARGET_USE_FANCY_MATH_387
17425    && flag_unsafe_math_optimizations"
17426   "* return output_fix_trunc (insn, operands, 0);"
17427   [(set_attr "type" "fistp")
17428    (set_attr "i387_cw" "ceil")
17429    (set_attr "mode" "DI")])
17431 (define_insn "fistdi2_ceil_with_temp"
17432   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17433         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17434          UNSPEC_FIST_CEIL))
17435    (use (match_operand:HI 2 "memory_operand" "m,m"))
17436    (use (match_operand:HI 3 "memory_operand" "m,m"))
17437    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17438    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && flag_unsafe_math_optimizations"
17441   "#"
17442   [(set_attr "type" "fistp")
17443    (set_attr "i387_cw" "ceil")
17444    (set_attr "mode" "DI")])
17446 (define_split 
17447   [(set (match_operand:DI 0 "register_operand" "")
17448         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17449          UNSPEC_FIST_CEIL))
17450    (use (match_operand:HI 2 "memory_operand" ""))
17451    (use (match_operand:HI 3 "memory_operand" ""))
17452    (clobber (match_operand:DI 4 "memory_operand" ""))
17453    (clobber (match_scratch 5 ""))]
17454   "reload_completed"
17455   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17456               (use (match_dup 2))
17457               (use (match_dup 3))
17458               (clobber (match_dup 5))])
17459    (set (match_dup 0) (match_dup 4))]
17460   "")
17462 (define_split 
17463   [(set (match_operand:DI 0 "memory_operand" "")
17464         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17465          UNSPEC_FIST_CEIL))
17466    (use (match_operand:HI 2 "memory_operand" ""))
17467    (use (match_operand:HI 3 "memory_operand" ""))
17468    (clobber (match_operand:DI 4 "memory_operand" ""))
17469    (clobber (match_scratch 5 ""))]
17470   "reload_completed"
17471   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17472               (use (match_dup 2))
17473               (use (match_dup 3))
17474               (clobber (match_dup 5))])]
17475   "")
17477 (define_insn "fist<mode>2_ceil"
17478   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17479         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17480          UNSPEC_FIST_CEIL))
17481    (use (match_operand:HI 2 "memory_operand" "m"))
17482    (use (match_operand:HI 3 "memory_operand" "m"))]
17483   "TARGET_USE_FANCY_MATH_387
17484    && flag_unsafe_math_optimizations"
17485   "* return output_fix_trunc (insn, operands, 0);"
17486   [(set_attr "type" "fistp")
17487    (set_attr "i387_cw" "ceil")
17488    (set_attr "mode" "<MODE>")])
17490 (define_insn "fist<mode>2_ceil_with_temp"
17491   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17492         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17493          UNSPEC_FIST_CEIL))
17494    (use (match_operand:HI 2 "memory_operand" "m,m"))
17495    (use (match_operand:HI 3 "memory_operand" "m,m"))
17496    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17497   "TARGET_USE_FANCY_MATH_387
17498    && flag_unsafe_math_optimizations"
17499   "#"
17500   [(set_attr "type" "fistp")
17501    (set_attr "i387_cw" "ceil")
17502    (set_attr "mode" "<MODE>")])
17504 (define_split 
17505   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17506         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17507          UNSPEC_FIST_CEIL))
17508    (use (match_operand:HI 2 "memory_operand" ""))
17509    (use (match_operand:HI 3 "memory_operand" ""))
17510    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17511   "reload_completed"
17512   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17513                                   UNSPEC_FIST_CEIL))
17514               (use (match_dup 2))
17515               (use (match_dup 3))])
17516    (set (match_dup 0) (match_dup 4))]
17517   "")
17519 (define_split 
17520   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17521         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17522          UNSPEC_FIST_CEIL))
17523    (use (match_operand:HI 2 "memory_operand" ""))
17524    (use (match_operand:HI 3 "memory_operand" ""))
17525    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17526   "reload_completed"
17527   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17528                                   UNSPEC_FIST_CEIL))
17529               (use (match_dup 2))
17530               (use (match_dup 3))])]
17531   "")
17533 (define_expand "lceil<mode>2"
17534   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17535                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17536                     UNSPEC_FIST_CEIL))
17537               (clobber (reg:CC FLAGS_REG))])]
17538   "TARGET_USE_FANCY_MATH_387
17539    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17540    && flag_unsafe_math_optimizations"
17541   "")
17543 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17544 (define_insn_and_split "frndintxf2_trunc"
17545   [(set (match_operand:XF 0 "register_operand" "=f")
17546         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17547          UNSPEC_FRNDINT_TRUNC))
17548    (clobber (reg:CC FLAGS_REG))]
17549   "TARGET_USE_FANCY_MATH_387
17550    && flag_unsafe_math_optimizations
17551    && !(reload_completed || reload_in_progress)"
17552   "#"
17553   "&& 1"
17554   [(const_int 0)]
17556   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17558   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17559   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17561   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17562                                         operands[2], operands[3]));
17563   DONE;
17565   [(set_attr "type" "frndint")
17566    (set_attr "i387_cw" "trunc")
17567    (set_attr "mode" "XF")])
17569 (define_insn "frndintxf2_trunc_i387"
17570   [(set (match_operand:XF 0 "register_operand" "=f")
17571         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17572          UNSPEC_FRNDINT_TRUNC))
17573    (use (match_operand:HI 2 "memory_operand" "m"))
17574    (use (match_operand:HI 3 "memory_operand" "m"))]
17575   "TARGET_USE_FANCY_MATH_387
17576    && flag_unsafe_math_optimizations"
17577   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17578   [(set_attr "type" "frndint")
17579    (set_attr "i387_cw" "trunc")
17580    (set_attr "mode" "XF")])
17582 (define_expand "btruncxf2"
17583   [(use (match_operand:XF 0 "register_operand" ""))
17584    (use (match_operand:XF 1 "register_operand" ""))]
17585   "TARGET_USE_FANCY_MATH_387
17586    && flag_unsafe_math_optimizations"
17588   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17589   DONE;
17592 (define_expand "btruncdf2"
17593   [(use (match_operand:DF 0 "register_operand" ""))
17594    (use (match_operand:DF 1 "register_operand" ""))]
17595   "TARGET_USE_FANCY_MATH_387
17596    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17597    && flag_unsafe_math_optimizations"
17599   rtx op0 = gen_reg_rtx (XFmode);
17600   rtx op1 = gen_reg_rtx (XFmode);
17602   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17603   emit_insn (gen_frndintxf2_trunc (op0, op1));
17605   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17606   DONE;
17609 (define_expand "btruncsf2"
17610   [(use (match_operand:SF 0 "register_operand" ""))
17611    (use (match_operand:SF 1 "register_operand" ""))]
17612   "TARGET_USE_FANCY_MATH_387
17613    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17614    && flag_unsafe_math_optimizations"
17616   rtx op0 = gen_reg_rtx (XFmode);
17617   rtx op1 = gen_reg_rtx (XFmode);
17619   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17620   emit_insn (gen_frndintxf2_trunc (op0, op1));
17622   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17623   DONE;
17626 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17627 (define_insn_and_split "frndintxf2_mask_pm"
17628   [(set (match_operand:XF 0 "register_operand" "=f")
17629         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17630          UNSPEC_FRNDINT_MASK_PM))
17631    (clobber (reg:CC FLAGS_REG))]
17632   "TARGET_USE_FANCY_MATH_387
17633    && flag_unsafe_math_optimizations
17634    && !(reload_completed || reload_in_progress)"
17635   "#"
17636   "&& 1"
17637   [(const_int 0)]
17639   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17641   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17642   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17644   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17645                                           operands[2], operands[3]));
17646   DONE;
17648   [(set_attr "type" "frndint")
17649    (set_attr "i387_cw" "mask_pm")
17650    (set_attr "mode" "XF")])
17652 (define_insn "frndintxf2_mask_pm_i387"
17653   [(set (match_operand:XF 0 "register_operand" "=f")
17654         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17655          UNSPEC_FRNDINT_MASK_PM))
17656    (use (match_operand:HI 2 "memory_operand" "m"))
17657    (use (match_operand:HI 3 "memory_operand" "m"))]
17658   "TARGET_USE_FANCY_MATH_387
17659    && flag_unsafe_math_optimizations"
17660   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17661   [(set_attr "type" "frndint")
17662    (set_attr "i387_cw" "mask_pm")
17663    (set_attr "mode" "XF")])
17665 (define_expand "nearbyintxf2"
17666   [(use (match_operand:XF 0 "register_operand" ""))
17667    (use (match_operand:XF 1 "register_operand" ""))]
17668   "TARGET_USE_FANCY_MATH_387
17669    && flag_unsafe_math_optimizations"
17671   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17673   DONE;
17676 (define_expand "nearbyintdf2"
17677   [(use (match_operand:DF 0 "register_operand" ""))
17678    (use (match_operand:DF 1 "register_operand" ""))]
17679   "TARGET_USE_FANCY_MATH_387
17680    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17681    && flag_unsafe_math_optimizations"
17683   rtx op0 = gen_reg_rtx (XFmode);
17684   rtx op1 = gen_reg_rtx (XFmode);
17686   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17687   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17689   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17690   DONE;
17693 (define_expand "nearbyintsf2"
17694   [(use (match_operand:SF 0 "register_operand" ""))
17695    (use (match_operand:SF 1 "register_operand" ""))]
17696   "TARGET_USE_FANCY_MATH_387
17697    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17698    && flag_unsafe_math_optimizations"
17700   rtx op0 = gen_reg_rtx (XFmode);
17701   rtx op1 = gen_reg_rtx (XFmode);
17703   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17704   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17706   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17707   DONE;
17711 ;; Block operation instructions
17713 (define_insn "cld"
17714  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17715  ""
17716  "cld"
17717   [(set_attr "type" "cld")])
17719 (define_expand "movmemsi"
17720   [(use (match_operand:BLK 0 "memory_operand" ""))
17721    (use (match_operand:BLK 1 "memory_operand" ""))
17722    (use (match_operand:SI 2 "nonmemory_operand" ""))
17723    (use (match_operand:SI 3 "const_int_operand" ""))]
17724   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17726  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17727    DONE;
17728  else
17729    FAIL;
17732 (define_expand "movmemdi"
17733   [(use (match_operand:BLK 0 "memory_operand" ""))
17734    (use (match_operand:BLK 1 "memory_operand" ""))
17735    (use (match_operand:DI 2 "nonmemory_operand" ""))
17736    (use (match_operand:DI 3 "const_int_operand" ""))]
17737   "TARGET_64BIT"
17739  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17740    DONE;
17741  else
17742    FAIL;
17745 ;; Most CPUs don't like single string operations
17746 ;; Handle this case here to simplify previous expander.
17748 (define_expand "strmov"
17749   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17750    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17751    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17752               (clobber (reg:CC FLAGS_REG))])
17753    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17754               (clobber (reg:CC FLAGS_REG))])]
17755   ""
17757   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17759   /* If .md ever supports :P for Pmode, these can be directly
17760      in the pattern above.  */
17761   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17762   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17764   if (TARGET_SINGLE_STRINGOP || optimize_size)
17765     {
17766       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17767                                       operands[2], operands[3],
17768                                       operands[5], operands[6]));
17769       DONE;
17770     }
17772   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17775 (define_expand "strmov_singleop"
17776   [(parallel [(set (match_operand 1 "memory_operand" "")
17777                    (match_operand 3 "memory_operand" ""))
17778               (set (match_operand 0 "register_operand" "")
17779                    (match_operand 4 "" ""))
17780               (set (match_operand 2 "register_operand" "")
17781                    (match_operand 5 "" ""))
17782               (use (reg:SI DIRFLAG_REG))])]
17783   "TARGET_SINGLE_STRINGOP || optimize_size"
17784   "")
17786 (define_insn "*strmovdi_rex_1"
17787   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17788         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17789    (set (match_operand:DI 0 "register_operand" "=D")
17790         (plus:DI (match_dup 2)
17791                  (const_int 8)))
17792    (set (match_operand:DI 1 "register_operand" "=S")
17793         (plus:DI (match_dup 3)
17794                  (const_int 8)))
17795    (use (reg:SI DIRFLAG_REG))]
17796   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17797   "movsq"
17798   [(set_attr "type" "str")
17799    (set_attr "mode" "DI")
17800    (set_attr "memory" "both")])
17802 (define_insn "*strmovsi_1"
17803   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17804         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17805    (set (match_operand:SI 0 "register_operand" "=D")
17806         (plus:SI (match_dup 2)
17807                  (const_int 4)))
17808    (set (match_operand:SI 1 "register_operand" "=S")
17809         (plus:SI (match_dup 3)
17810                  (const_int 4)))
17811    (use (reg:SI DIRFLAG_REG))]
17812   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17813   "{movsl|movsd}"
17814   [(set_attr "type" "str")
17815    (set_attr "mode" "SI")
17816    (set_attr "memory" "both")])
17818 (define_insn "*strmovsi_rex_1"
17819   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17820         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17821    (set (match_operand:DI 0 "register_operand" "=D")
17822         (plus:DI (match_dup 2)
17823                  (const_int 4)))
17824    (set (match_operand:DI 1 "register_operand" "=S")
17825         (plus:DI (match_dup 3)
17826                  (const_int 4)))
17827    (use (reg:SI DIRFLAG_REG))]
17828   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17829   "{movsl|movsd}"
17830   [(set_attr "type" "str")
17831    (set_attr "mode" "SI")
17832    (set_attr "memory" "both")])
17834 (define_insn "*strmovhi_1"
17835   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17836         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17837    (set (match_operand:SI 0 "register_operand" "=D")
17838         (plus:SI (match_dup 2)
17839                  (const_int 2)))
17840    (set (match_operand:SI 1 "register_operand" "=S")
17841         (plus:SI (match_dup 3)
17842                  (const_int 2)))
17843    (use (reg:SI DIRFLAG_REG))]
17844   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17845   "movsw"
17846   [(set_attr "type" "str")
17847    (set_attr "memory" "both")
17848    (set_attr "mode" "HI")])
17850 (define_insn "*strmovhi_rex_1"
17851   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17852         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17853    (set (match_operand:DI 0 "register_operand" "=D")
17854         (plus:DI (match_dup 2)
17855                  (const_int 2)))
17856    (set (match_operand:DI 1 "register_operand" "=S")
17857         (plus:DI (match_dup 3)
17858                  (const_int 2)))
17859    (use (reg:SI DIRFLAG_REG))]
17860   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17861   "movsw"
17862   [(set_attr "type" "str")
17863    (set_attr "memory" "both")
17864    (set_attr "mode" "HI")])
17866 (define_insn "*strmovqi_1"
17867   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17868         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17869    (set (match_operand:SI 0 "register_operand" "=D")
17870         (plus:SI (match_dup 2)
17871                  (const_int 1)))
17872    (set (match_operand:SI 1 "register_operand" "=S")
17873         (plus:SI (match_dup 3)
17874                  (const_int 1)))
17875    (use (reg:SI DIRFLAG_REG))]
17876   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17877   "movsb"
17878   [(set_attr "type" "str")
17879    (set_attr "memory" "both")
17880    (set_attr "mode" "QI")])
17882 (define_insn "*strmovqi_rex_1"
17883   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17884         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17885    (set (match_operand:DI 0 "register_operand" "=D")
17886         (plus:DI (match_dup 2)
17887                  (const_int 1)))
17888    (set (match_operand:DI 1 "register_operand" "=S")
17889         (plus:DI (match_dup 3)
17890                  (const_int 1)))
17891    (use (reg:SI DIRFLAG_REG))]
17892   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17893   "movsb"
17894   [(set_attr "type" "str")
17895    (set_attr "memory" "both")
17896    (set_attr "mode" "QI")])
17898 (define_expand "rep_mov"
17899   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17900               (set (match_operand 0 "register_operand" "")
17901                    (match_operand 5 "" ""))
17902               (set (match_operand 2 "register_operand" "")
17903                    (match_operand 6 "" ""))
17904               (set (match_operand 1 "memory_operand" "")
17905                    (match_operand 3 "memory_operand" ""))
17906               (use (match_dup 4))
17907               (use (reg:SI DIRFLAG_REG))])]
17908   ""
17909   "")
17911 (define_insn "*rep_movdi_rex64"
17912   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17913    (set (match_operand:DI 0 "register_operand" "=D") 
17914         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17915                             (const_int 3))
17916                  (match_operand:DI 3 "register_operand" "0")))
17917    (set (match_operand:DI 1 "register_operand" "=S") 
17918         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17919                  (match_operand:DI 4 "register_operand" "1")))
17920    (set (mem:BLK (match_dup 3))
17921         (mem:BLK (match_dup 4)))
17922    (use (match_dup 5))
17923    (use (reg:SI DIRFLAG_REG))]
17924   "TARGET_64BIT"
17925   "{rep\;movsq|rep movsq}"
17926   [(set_attr "type" "str")
17927    (set_attr "prefix_rep" "1")
17928    (set_attr "memory" "both")
17929    (set_attr "mode" "DI")])
17931 (define_insn "*rep_movsi"
17932   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17933    (set (match_operand:SI 0 "register_operand" "=D") 
17934         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17935                             (const_int 2))
17936                  (match_operand:SI 3 "register_operand" "0")))
17937    (set (match_operand:SI 1 "register_operand" "=S") 
17938         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17939                  (match_operand:SI 4 "register_operand" "1")))
17940    (set (mem:BLK (match_dup 3))
17941         (mem:BLK (match_dup 4)))
17942    (use (match_dup 5))
17943    (use (reg:SI DIRFLAG_REG))]
17944   "!TARGET_64BIT"
17945   "{rep\;movsl|rep movsd}"
17946   [(set_attr "type" "str")
17947    (set_attr "prefix_rep" "1")
17948    (set_attr "memory" "both")
17949    (set_attr "mode" "SI")])
17951 (define_insn "*rep_movsi_rex64"
17952   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17953    (set (match_operand:DI 0 "register_operand" "=D") 
17954         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17955                             (const_int 2))
17956                  (match_operand:DI 3 "register_operand" "0")))
17957    (set (match_operand:DI 1 "register_operand" "=S") 
17958         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17959                  (match_operand:DI 4 "register_operand" "1")))
17960    (set (mem:BLK (match_dup 3))
17961         (mem:BLK (match_dup 4)))
17962    (use (match_dup 5))
17963    (use (reg:SI DIRFLAG_REG))]
17964   "TARGET_64BIT"
17965   "{rep\;movsl|rep movsd}"
17966   [(set_attr "type" "str")
17967    (set_attr "prefix_rep" "1")
17968    (set_attr "memory" "both")
17969    (set_attr "mode" "SI")])
17971 (define_insn "*rep_movqi"
17972   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17973    (set (match_operand:SI 0 "register_operand" "=D") 
17974         (plus:SI (match_operand:SI 3 "register_operand" "0")
17975                  (match_operand:SI 5 "register_operand" "2")))
17976    (set (match_operand:SI 1 "register_operand" "=S") 
17977         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17978    (set (mem:BLK (match_dup 3))
17979         (mem:BLK (match_dup 4)))
17980    (use (match_dup 5))
17981    (use (reg:SI DIRFLAG_REG))]
17982   "!TARGET_64BIT"
17983   "{rep\;movsb|rep movsb}"
17984   [(set_attr "type" "str")
17985    (set_attr "prefix_rep" "1")
17986    (set_attr "memory" "both")
17987    (set_attr "mode" "SI")])
17989 (define_insn "*rep_movqi_rex64"
17990   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17991    (set (match_operand:DI 0 "register_operand" "=D") 
17992         (plus:DI (match_operand:DI 3 "register_operand" "0")
17993                  (match_operand:DI 5 "register_operand" "2")))
17994    (set (match_operand:DI 1 "register_operand" "=S") 
17995         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17996    (set (mem:BLK (match_dup 3))
17997         (mem:BLK (match_dup 4)))
17998    (use (match_dup 5))
17999    (use (reg:SI DIRFLAG_REG))]
18000   "TARGET_64BIT"
18001   "{rep\;movsb|rep movsb}"
18002   [(set_attr "type" "str")
18003    (set_attr "prefix_rep" "1")
18004    (set_attr "memory" "both")
18005    (set_attr "mode" "SI")])
18007 (define_expand "setmemsi"
18008    [(use (match_operand:BLK 0 "memory_operand" ""))
18009     (use (match_operand:SI 1 "nonmemory_operand" ""))
18010     (use (match_operand 2 "const_int_operand" ""))
18011     (use (match_operand 3 "const_int_operand" ""))]
18012   ""
18014  /* If value to set is not zero, use the library routine.  */
18015  if (operands[2] != const0_rtx)
18016    FAIL;
18018  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18019    DONE;
18020  else
18021    FAIL;
18024 (define_expand "setmemdi"
18025    [(use (match_operand:BLK 0 "memory_operand" ""))
18026     (use (match_operand:DI 1 "nonmemory_operand" ""))
18027     (use (match_operand 2 "const_int_operand" ""))
18028     (use (match_operand 3 "const_int_operand" ""))]
18029   "TARGET_64BIT"
18031  /* If value to set is not zero, use the library routine.  */
18032  if (operands[2] != const0_rtx)
18033    FAIL;
18035  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18036    DONE;
18037  else
18038    FAIL;
18041 ;; Most CPUs don't like single string operations
18042 ;; Handle this case here to simplify previous expander.
18044 (define_expand "strset"
18045   [(set (match_operand 1 "memory_operand" "")
18046         (match_operand 2 "register_operand" ""))
18047    (parallel [(set (match_operand 0 "register_operand" "")
18048                    (match_dup 3))
18049               (clobber (reg:CC FLAGS_REG))])]
18050   ""
18052   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18053     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18055   /* If .md ever supports :P for Pmode, this can be directly
18056      in the pattern above.  */
18057   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18058                               GEN_INT (GET_MODE_SIZE (GET_MODE
18059                                                       (operands[2]))));
18060   if (TARGET_SINGLE_STRINGOP || optimize_size)
18061     {
18062       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18063                                       operands[3]));
18064       DONE;
18065     }
18068 (define_expand "strset_singleop"
18069   [(parallel [(set (match_operand 1 "memory_operand" "")
18070                    (match_operand 2 "register_operand" ""))
18071               (set (match_operand 0 "register_operand" "")
18072                    (match_operand 3 "" ""))
18073               (use (reg:SI DIRFLAG_REG))])]
18074   "TARGET_SINGLE_STRINGOP || optimize_size"
18075   "")
18077 (define_insn "*strsetdi_rex_1"
18078   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18079         (match_operand:DI 2 "register_operand" "a"))
18080    (set (match_operand:DI 0 "register_operand" "=D")
18081         (plus:DI (match_dup 1)
18082                  (const_int 8)))
18083    (use (reg:SI DIRFLAG_REG))]
18084   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18085   "stosq"
18086   [(set_attr "type" "str")
18087    (set_attr "memory" "store")
18088    (set_attr "mode" "DI")])
18090 (define_insn "*strsetsi_1"
18091   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18092         (match_operand:SI 2 "register_operand" "a"))
18093    (set (match_operand:SI 0 "register_operand" "=D")
18094         (plus:SI (match_dup 1)
18095                  (const_int 4)))
18096    (use (reg:SI DIRFLAG_REG))]
18097   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18098   "{stosl|stosd}"
18099   [(set_attr "type" "str")
18100    (set_attr "memory" "store")
18101    (set_attr "mode" "SI")])
18103 (define_insn "*strsetsi_rex_1"
18104   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18105         (match_operand:SI 2 "register_operand" "a"))
18106    (set (match_operand:DI 0 "register_operand" "=D")
18107         (plus:DI (match_dup 1)
18108                  (const_int 4)))
18109    (use (reg:SI DIRFLAG_REG))]
18110   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18111   "{stosl|stosd}"
18112   [(set_attr "type" "str")
18113    (set_attr "memory" "store")
18114    (set_attr "mode" "SI")])
18116 (define_insn "*strsethi_1"
18117   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18118         (match_operand:HI 2 "register_operand" "a"))
18119    (set (match_operand:SI 0 "register_operand" "=D")
18120         (plus:SI (match_dup 1)
18121                  (const_int 2)))
18122    (use (reg:SI DIRFLAG_REG))]
18123   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18124   "stosw"
18125   [(set_attr "type" "str")
18126    (set_attr "memory" "store")
18127    (set_attr "mode" "HI")])
18129 (define_insn "*strsethi_rex_1"
18130   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18131         (match_operand:HI 2 "register_operand" "a"))
18132    (set (match_operand:DI 0 "register_operand" "=D")
18133         (plus:DI (match_dup 1)
18134                  (const_int 2)))
18135    (use (reg:SI DIRFLAG_REG))]
18136   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18137   "stosw"
18138   [(set_attr "type" "str")
18139    (set_attr "memory" "store")
18140    (set_attr "mode" "HI")])
18142 (define_insn "*strsetqi_1"
18143   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18144         (match_operand:QI 2 "register_operand" "a"))
18145    (set (match_operand:SI 0 "register_operand" "=D")
18146         (plus:SI (match_dup 1)
18147                  (const_int 1)))
18148    (use (reg:SI DIRFLAG_REG))]
18149   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18150   "stosb"
18151   [(set_attr "type" "str")
18152    (set_attr "memory" "store")
18153    (set_attr "mode" "QI")])
18155 (define_insn "*strsetqi_rex_1"
18156   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18157         (match_operand:QI 2 "register_operand" "a"))
18158    (set (match_operand:DI 0 "register_operand" "=D")
18159         (plus:DI (match_dup 1)
18160                  (const_int 1)))
18161    (use (reg:SI DIRFLAG_REG))]
18162   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18163   "stosb"
18164   [(set_attr "type" "str")
18165    (set_attr "memory" "store")
18166    (set_attr "mode" "QI")])
18168 (define_expand "rep_stos"
18169   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18170               (set (match_operand 0 "register_operand" "")
18171                    (match_operand 4 "" ""))
18172               (set (match_operand 2 "memory_operand" "") (const_int 0))
18173               (use (match_operand 3 "register_operand" ""))
18174               (use (match_dup 1))
18175               (use (reg:SI DIRFLAG_REG))])]
18176   ""
18177   "")
18179 (define_insn "*rep_stosdi_rex64"
18180   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18181    (set (match_operand:DI 0 "register_operand" "=D") 
18182         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18183                             (const_int 3))
18184                  (match_operand:DI 3 "register_operand" "0")))
18185    (set (mem:BLK (match_dup 3))
18186         (const_int 0))
18187    (use (match_operand:DI 2 "register_operand" "a"))
18188    (use (match_dup 4))
18189    (use (reg:SI DIRFLAG_REG))]
18190   "TARGET_64BIT"
18191   "{rep\;stosq|rep stosq}"
18192   [(set_attr "type" "str")
18193    (set_attr "prefix_rep" "1")
18194    (set_attr "memory" "store")
18195    (set_attr "mode" "DI")])
18197 (define_insn "*rep_stossi"
18198   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18199    (set (match_operand:SI 0 "register_operand" "=D") 
18200         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18201                             (const_int 2))
18202                  (match_operand:SI 3 "register_operand" "0")))
18203    (set (mem:BLK (match_dup 3))
18204         (const_int 0))
18205    (use (match_operand:SI 2 "register_operand" "a"))
18206    (use (match_dup 4))
18207    (use (reg:SI DIRFLAG_REG))]
18208   "!TARGET_64BIT"
18209   "{rep\;stosl|rep stosd}"
18210   [(set_attr "type" "str")
18211    (set_attr "prefix_rep" "1")
18212    (set_attr "memory" "store")
18213    (set_attr "mode" "SI")])
18215 (define_insn "*rep_stossi_rex64"
18216   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18217    (set (match_operand:DI 0 "register_operand" "=D") 
18218         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18219                             (const_int 2))
18220                  (match_operand:DI 3 "register_operand" "0")))
18221    (set (mem:BLK (match_dup 3))
18222         (const_int 0))
18223    (use (match_operand:SI 2 "register_operand" "a"))
18224    (use (match_dup 4))
18225    (use (reg:SI DIRFLAG_REG))]
18226   "TARGET_64BIT"
18227   "{rep\;stosl|rep stosd}"
18228   [(set_attr "type" "str")
18229    (set_attr "prefix_rep" "1")
18230    (set_attr "memory" "store")
18231    (set_attr "mode" "SI")])
18233 (define_insn "*rep_stosqi"
18234   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18235    (set (match_operand:SI 0 "register_operand" "=D") 
18236         (plus:SI (match_operand:SI 3 "register_operand" "0")
18237                  (match_operand:SI 4 "register_operand" "1")))
18238    (set (mem:BLK (match_dup 3))
18239         (const_int 0))
18240    (use (match_operand:QI 2 "register_operand" "a"))
18241    (use (match_dup 4))
18242    (use (reg:SI DIRFLAG_REG))]
18243   "!TARGET_64BIT"
18244   "{rep\;stosb|rep stosb}"
18245   [(set_attr "type" "str")
18246    (set_attr "prefix_rep" "1")
18247    (set_attr "memory" "store")
18248    (set_attr "mode" "QI")])
18250 (define_insn "*rep_stosqi_rex64"
18251   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18252    (set (match_operand:DI 0 "register_operand" "=D") 
18253         (plus:DI (match_operand:DI 3 "register_operand" "0")
18254                  (match_operand:DI 4 "register_operand" "1")))
18255    (set (mem:BLK (match_dup 3))
18256         (const_int 0))
18257    (use (match_operand:QI 2 "register_operand" "a"))
18258    (use (match_dup 4))
18259    (use (reg:SI DIRFLAG_REG))]
18260   "TARGET_64BIT"
18261   "{rep\;stosb|rep stosb}"
18262   [(set_attr "type" "str")
18263    (set_attr "prefix_rep" "1")
18264    (set_attr "memory" "store")
18265    (set_attr "mode" "QI")])
18267 (define_expand "cmpstrnsi"
18268   [(set (match_operand:SI 0 "register_operand" "")
18269         (compare:SI (match_operand:BLK 1 "general_operand" "")
18270                     (match_operand:BLK 2 "general_operand" "")))
18271    (use (match_operand 3 "general_operand" ""))
18272    (use (match_operand 4 "immediate_operand" ""))]
18273   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18275   rtx addr1, addr2, out, outlow, count, countreg, align;
18277   /* Can't use this if the user has appropriated esi or edi.  */
18278   if (global_regs[4] || global_regs[5])
18279     FAIL;
18281   out = operands[0];
18282   if (GET_CODE (out) != REG)
18283     out = gen_reg_rtx (SImode);
18285   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18286   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18287   if (addr1 != XEXP (operands[1], 0))
18288     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18289   if (addr2 != XEXP (operands[2], 0))
18290     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18292   count = operands[3];
18293   countreg = ix86_zero_extend_to_Pmode (count);
18295   /* %%% Iff we are testing strict equality, we can use known alignment
18296      to good advantage.  This may be possible with combine, particularly
18297      once cc0 is dead.  */
18298   align = operands[4];
18300   emit_insn (gen_cld ());
18301   if (GET_CODE (count) == CONST_INT)
18302     {
18303       if (INTVAL (count) == 0)
18304         {
18305           emit_move_insn (operands[0], const0_rtx);
18306           DONE;
18307         }
18308       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18309                                      operands[1], operands[2]));
18310     }
18311   else
18312     {
18313       if (TARGET_64BIT)
18314         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18315       else
18316         emit_insn (gen_cmpsi_1 (countreg, countreg));
18317       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18318                                   operands[1], operands[2]));
18319     }
18321   outlow = gen_lowpart (QImode, out);
18322   emit_insn (gen_cmpintqi (outlow));
18323   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18325   if (operands[0] != out)
18326     emit_move_insn (operands[0], out);
18328   DONE;
18331 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18333 (define_expand "cmpintqi"
18334   [(set (match_dup 1)
18335         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18336    (set (match_dup 2)
18337         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18338    (parallel [(set (match_operand:QI 0 "register_operand" "")
18339                    (minus:QI (match_dup 1)
18340                              (match_dup 2)))
18341               (clobber (reg:CC FLAGS_REG))])]
18342   ""
18343   "operands[1] = gen_reg_rtx (QImode);
18344    operands[2] = gen_reg_rtx (QImode);")
18346 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18347 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18349 (define_expand "cmpstrnqi_nz_1"
18350   [(parallel [(set (reg:CC FLAGS_REG)
18351                    (compare:CC (match_operand 4 "memory_operand" "")
18352                                (match_operand 5 "memory_operand" "")))
18353               (use (match_operand 2 "register_operand" ""))
18354               (use (match_operand:SI 3 "immediate_operand" ""))
18355               (use (reg:SI DIRFLAG_REG))
18356               (clobber (match_operand 0 "register_operand" ""))
18357               (clobber (match_operand 1 "register_operand" ""))
18358               (clobber (match_dup 2))])]
18359   ""
18360   "")
18362 (define_insn "*cmpstrnqi_nz_1"
18363   [(set (reg:CC FLAGS_REG)
18364         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18365                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18366    (use (match_operand:SI 6 "register_operand" "2"))
18367    (use (match_operand:SI 3 "immediate_operand" "i"))
18368    (use (reg:SI DIRFLAG_REG))
18369    (clobber (match_operand:SI 0 "register_operand" "=S"))
18370    (clobber (match_operand:SI 1 "register_operand" "=D"))
18371    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18372   "!TARGET_64BIT"
18373   "repz{\;| }cmpsb"
18374   [(set_attr "type" "str")
18375    (set_attr "mode" "QI")
18376    (set_attr "prefix_rep" "1")])
18378 (define_insn "*cmpstrnqi_nz_rex_1"
18379   [(set (reg:CC FLAGS_REG)
18380         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18381                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18382    (use (match_operand:DI 6 "register_operand" "2"))
18383    (use (match_operand:SI 3 "immediate_operand" "i"))
18384    (use (reg:SI DIRFLAG_REG))
18385    (clobber (match_operand:DI 0 "register_operand" "=S"))
18386    (clobber (match_operand:DI 1 "register_operand" "=D"))
18387    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18388   "TARGET_64BIT"
18389   "repz{\;| }cmpsb"
18390   [(set_attr "type" "str")
18391    (set_attr "mode" "QI")
18392    (set_attr "prefix_rep" "1")])
18394 ;; The same, but the count is not known to not be zero.
18396 (define_expand "cmpstrnqi_1"
18397   [(parallel [(set (reg:CC FLAGS_REG)
18398                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18399                                      (const_int 0))
18400                   (compare:CC (match_operand 4 "memory_operand" "")
18401                               (match_operand 5 "memory_operand" ""))
18402                   (const_int 0)))
18403               (use (match_operand:SI 3 "immediate_operand" ""))
18404               (use (reg:CC FLAGS_REG))
18405               (use (reg:SI DIRFLAG_REG))
18406               (clobber (match_operand 0 "register_operand" ""))
18407               (clobber (match_operand 1 "register_operand" ""))
18408               (clobber (match_dup 2))])]
18409   ""
18410   "")
18412 (define_insn "*cmpstrnqi_1"
18413   [(set (reg:CC FLAGS_REG)
18414         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18415                              (const_int 0))
18416           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18417                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18418           (const_int 0)))
18419    (use (match_operand:SI 3 "immediate_operand" "i"))
18420    (use (reg:CC FLAGS_REG))
18421    (use (reg:SI DIRFLAG_REG))
18422    (clobber (match_operand:SI 0 "register_operand" "=S"))
18423    (clobber (match_operand:SI 1 "register_operand" "=D"))
18424    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18425   "!TARGET_64BIT"
18426   "repz{\;| }cmpsb"
18427   [(set_attr "type" "str")
18428    (set_attr "mode" "QI")
18429    (set_attr "prefix_rep" "1")])
18431 (define_insn "*cmpstrnqi_rex_1"
18432   [(set (reg:CC FLAGS_REG)
18433         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18434                              (const_int 0))
18435           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18436                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18437           (const_int 0)))
18438    (use (match_operand:SI 3 "immediate_operand" "i"))
18439    (use (reg:CC FLAGS_REG))
18440    (use (reg:SI DIRFLAG_REG))
18441    (clobber (match_operand:DI 0 "register_operand" "=S"))
18442    (clobber (match_operand:DI 1 "register_operand" "=D"))
18443    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18444   "TARGET_64BIT"
18445   "repz{\;| }cmpsb"
18446   [(set_attr "type" "str")
18447    (set_attr "mode" "QI")
18448    (set_attr "prefix_rep" "1")])
18450 (define_expand "strlensi"
18451   [(set (match_operand:SI 0 "register_operand" "")
18452         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18453                     (match_operand:QI 2 "immediate_operand" "")
18454                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18455   ""
18457  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18458    DONE;
18459  else
18460    FAIL;
18463 (define_expand "strlendi"
18464   [(set (match_operand:DI 0 "register_operand" "")
18465         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18466                     (match_operand:QI 2 "immediate_operand" "")
18467                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18468   ""
18470  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18471    DONE;
18472  else
18473    FAIL;
18476 (define_expand "strlenqi_1"
18477   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18478               (use (reg:SI DIRFLAG_REG))
18479               (clobber (match_operand 1 "register_operand" ""))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   ""
18482   "")
18484 (define_insn "*strlenqi_1"
18485   [(set (match_operand:SI 0 "register_operand" "=&c")
18486         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18487                     (match_operand:QI 2 "register_operand" "a")
18488                     (match_operand:SI 3 "immediate_operand" "i")
18489                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18490    (use (reg:SI DIRFLAG_REG))
18491    (clobber (match_operand:SI 1 "register_operand" "=D"))
18492    (clobber (reg:CC FLAGS_REG))]
18493   "!TARGET_64BIT"
18494   "repnz{\;| }scasb"
18495   [(set_attr "type" "str")
18496    (set_attr "mode" "QI")
18497    (set_attr "prefix_rep" "1")])
18499 (define_insn "*strlenqi_rex_1"
18500   [(set (match_operand:DI 0 "register_operand" "=&c")
18501         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18502                     (match_operand:QI 2 "register_operand" "a")
18503                     (match_operand:DI 3 "immediate_operand" "i")
18504                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18505    (use (reg:SI DIRFLAG_REG))
18506    (clobber (match_operand:DI 1 "register_operand" "=D"))
18507    (clobber (reg:CC FLAGS_REG))]
18508   "TARGET_64BIT"
18509   "repnz{\;| }scasb"
18510   [(set_attr "type" "str")
18511    (set_attr "mode" "QI")
18512    (set_attr "prefix_rep" "1")])
18514 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18515 ;; handled in combine, but it is not currently up to the task.
18516 ;; When used for their truth value, the cmpstrn* expanders generate
18517 ;; code like this:
18519 ;;   repz cmpsb
18520 ;;   seta       %al
18521 ;;   setb       %dl
18522 ;;   cmpb       %al, %dl
18523 ;;   jcc        label
18525 ;; The intermediate three instructions are unnecessary.
18527 ;; This one handles cmpstrn*_nz_1...
18528 (define_peephole2
18529   [(parallel[
18530      (set (reg:CC FLAGS_REG)
18531           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18532                       (mem:BLK (match_operand 5 "register_operand" ""))))
18533      (use (match_operand 6 "register_operand" ""))
18534      (use (match_operand:SI 3 "immediate_operand" ""))
18535      (use (reg:SI DIRFLAG_REG))
18536      (clobber (match_operand 0 "register_operand" ""))
18537      (clobber (match_operand 1 "register_operand" ""))
18538      (clobber (match_operand 2 "register_operand" ""))])
18539    (set (match_operand:QI 7 "register_operand" "")
18540         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18541    (set (match_operand:QI 8 "register_operand" "")
18542         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18543    (set (reg FLAGS_REG)
18544         (compare (match_dup 7) (match_dup 8)))
18545   ]
18546   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18547   [(parallel[
18548      (set (reg:CC FLAGS_REG)
18549           (compare:CC (mem:BLK (match_dup 4))
18550                       (mem:BLK (match_dup 5))))
18551      (use (match_dup 6))
18552      (use (match_dup 3))
18553      (use (reg:SI DIRFLAG_REG))
18554      (clobber (match_dup 0))
18555      (clobber (match_dup 1))
18556      (clobber (match_dup 2))])]
18557   "")
18559 ;; ...and this one handles cmpstrn*_1.
18560 (define_peephole2
18561   [(parallel[
18562      (set (reg:CC FLAGS_REG)
18563           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18564                                (const_int 0))
18565             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18566                         (mem:BLK (match_operand 5 "register_operand" "")))
18567             (const_int 0)))
18568      (use (match_operand:SI 3 "immediate_operand" ""))
18569      (use (reg:CC FLAGS_REG))
18570      (use (reg:SI DIRFLAG_REG))
18571      (clobber (match_operand 0 "register_operand" ""))
18572      (clobber (match_operand 1 "register_operand" ""))
18573      (clobber (match_operand 2 "register_operand" ""))])
18574    (set (match_operand:QI 7 "register_operand" "")
18575         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18576    (set (match_operand:QI 8 "register_operand" "")
18577         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18578    (set (reg FLAGS_REG)
18579         (compare (match_dup 7) (match_dup 8)))
18580   ]
18581   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18582   [(parallel[
18583      (set (reg:CC FLAGS_REG)
18584           (if_then_else:CC (ne (match_dup 6)
18585                                (const_int 0))
18586             (compare:CC (mem:BLK (match_dup 4))
18587                         (mem:BLK (match_dup 5)))
18588             (const_int 0)))
18589      (use (match_dup 3))
18590      (use (reg:CC FLAGS_REG))
18591      (use (reg:SI DIRFLAG_REG))
18592      (clobber (match_dup 0))
18593      (clobber (match_dup 1))
18594      (clobber (match_dup 2))])]
18595   "")
18599 ;; Conditional move instructions.
18601 (define_expand "movdicc"
18602   [(set (match_operand:DI 0 "register_operand" "")
18603         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18604                          (match_operand:DI 2 "general_operand" "")
18605                          (match_operand:DI 3 "general_operand" "")))]
18606   "TARGET_64BIT"
18607   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18609 (define_insn "x86_movdicc_0_m1_rex64"
18610   [(set (match_operand:DI 0 "register_operand" "=r")
18611         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18612           (const_int -1)
18613           (const_int 0)))
18614    (clobber (reg:CC FLAGS_REG))]
18615   "TARGET_64BIT"
18616   "sbb{q}\t%0, %0"
18617   ; Since we don't have the proper number of operands for an alu insn,
18618   ; fill in all the blanks.
18619   [(set_attr "type" "alu")
18620    (set_attr "pent_pair" "pu")
18621    (set_attr "memory" "none")
18622    (set_attr "imm_disp" "false")
18623    (set_attr "mode" "DI")
18624    (set_attr "length_immediate" "0")])
18626 (define_insn "*movdicc_c_rex64"
18627   [(set (match_operand:DI 0 "register_operand" "=r,r")
18628         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18629                                 [(reg FLAGS_REG) (const_int 0)])
18630                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18631                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18632   "TARGET_64BIT && TARGET_CMOVE
18633    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18634   "@
18635    cmov%O2%C1\t{%2, %0|%0, %2}
18636    cmov%O2%c1\t{%3, %0|%0, %3}"
18637   [(set_attr "type" "icmov")
18638    (set_attr "mode" "DI")])
18640 (define_expand "movsicc"
18641   [(set (match_operand:SI 0 "register_operand" "")
18642         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18643                          (match_operand:SI 2 "general_operand" "")
18644                          (match_operand:SI 3 "general_operand" "")))]
18645   ""
18646   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18648 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18649 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18650 ;; So just document what we're doing explicitly.
18652 (define_insn "x86_movsicc_0_m1"
18653   [(set (match_operand:SI 0 "register_operand" "=r")
18654         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18655           (const_int -1)
18656           (const_int 0)))
18657    (clobber (reg:CC FLAGS_REG))]
18658   ""
18659   "sbb{l}\t%0, %0"
18660   ; Since we don't have the proper number of operands for an alu insn,
18661   ; fill in all the blanks.
18662   [(set_attr "type" "alu")
18663    (set_attr "pent_pair" "pu")
18664    (set_attr "memory" "none")
18665    (set_attr "imm_disp" "false")
18666    (set_attr "mode" "SI")
18667    (set_attr "length_immediate" "0")])
18669 (define_insn "*movsicc_noc"
18670   [(set (match_operand:SI 0 "register_operand" "=r,r")
18671         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18672                                 [(reg FLAGS_REG) (const_int 0)])
18673                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18674                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18675   "TARGET_CMOVE
18676    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18677   "@
18678    cmov%O2%C1\t{%2, %0|%0, %2}
18679    cmov%O2%c1\t{%3, %0|%0, %3}"
18680   [(set_attr "type" "icmov")
18681    (set_attr "mode" "SI")])
18683 (define_expand "movhicc"
18684   [(set (match_operand:HI 0 "register_operand" "")
18685         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18686                          (match_operand:HI 2 "general_operand" "")
18687                          (match_operand:HI 3 "general_operand" "")))]
18688   "TARGET_HIMODE_MATH"
18689   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18691 (define_insn "*movhicc_noc"
18692   [(set (match_operand:HI 0 "register_operand" "=r,r")
18693         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18694                                 [(reg FLAGS_REG) (const_int 0)])
18695                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18696                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18697   "TARGET_CMOVE
18698    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18699   "@
18700    cmov%O2%C1\t{%2, %0|%0, %2}
18701    cmov%O2%c1\t{%3, %0|%0, %3}"
18702   [(set_attr "type" "icmov")
18703    (set_attr "mode" "HI")])
18705 (define_expand "movqicc"
18706   [(set (match_operand:QI 0 "register_operand" "")
18707         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18708                          (match_operand:QI 2 "general_operand" "")
18709                          (match_operand:QI 3 "general_operand" "")))]
18710   "TARGET_QIMODE_MATH"
18711   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18713 (define_insn_and_split "*movqicc_noc"
18714   [(set (match_operand:QI 0 "register_operand" "=r,r")
18715         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18716                                 [(match_operand 4 "flags_reg_operand" "")
18717                                  (const_int 0)])
18718                       (match_operand:QI 2 "register_operand" "r,0")
18719                       (match_operand:QI 3 "register_operand" "0,r")))]
18720   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18721   "#"
18722   "&& reload_completed"
18723   [(set (match_dup 0)
18724         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18725                       (match_dup 2)
18726                       (match_dup 3)))]
18727   "operands[0] = gen_lowpart (SImode, operands[0]);
18728    operands[2] = gen_lowpart (SImode, operands[2]);
18729    operands[3] = gen_lowpart (SImode, operands[3]);"
18730   [(set_attr "type" "icmov")
18731    (set_attr "mode" "SI")])
18733 (define_expand "movsfcc"
18734   [(set (match_operand:SF 0 "register_operand" "")
18735         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18736                          (match_operand:SF 2 "register_operand" "")
18737                          (match_operand:SF 3 "register_operand" "")))]
18738   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18739   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18741 (define_insn "*movsfcc_1_387"
18742   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18743         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18744                                 [(reg FLAGS_REG) (const_int 0)])
18745                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18746                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18747   "TARGET_80387 && TARGET_CMOVE
18748    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18749   "@
18750    fcmov%F1\t{%2, %0|%0, %2}
18751    fcmov%f1\t{%3, %0|%0, %3}
18752    cmov%O2%C1\t{%2, %0|%0, %2}
18753    cmov%O2%c1\t{%3, %0|%0, %3}"
18754   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18755    (set_attr "mode" "SF,SF,SI,SI")])
18757 (define_expand "movdfcc"
18758   [(set (match_operand:DF 0 "register_operand" "")
18759         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18760                          (match_operand:DF 2 "register_operand" "")
18761                          (match_operand:DF 3 "register_operand" "")))]
18762   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18763   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18765 (define_insn "*movdfcc_1"
18766   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18767         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18768                                 [(reg FLAGS_REG) (const_int 0)])
18769                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18770                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18771   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18772    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18773   "@
18774    fcmov%F1\t{%2, %0|%0, %2}
18775    fcmov%f1\t{%3, %0|%0, %3}
18776    #
18777    #"
18778   [(set_attr "type" "fcmov,fcmov,multi,multi")
18779    (set_attr "mode" "DF")])
18781 (define_insn "*movdfcc_1_rex64"
18782   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18783         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18784                                 [(reg FLAGS_REG) (const_int 0)])
18785                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18786                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18787   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18788    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18789   "@
18790    fcmov%F1\t{%2, %0|%0, %2}
18791    fcmov%f1\t{%3, %0|%0, %3}
18792    cmov%O2%C1\t{%2, %0|%0, %2}
18793    cmov%O2%c1\t{%3, %0|%0, %3}"
18794   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18795    (set_attr "mode" "DF")])
18797 (define_split
18798   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18799         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18800                                 [(match_operand 4 "flags_reg_operand" "")
18801                                  (const_int 0)])
18802                       (match_operand:DF 2 "nonimmediate_operand" "")
18803                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18804   "!TARGET_64BIT && reload_completed"
18805   [(set (match_dup 2)
18806         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18807                       (match_dup 5)
18808                       (match_dup 7)))
18809    (set (match_dup 3)
18810         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18811                       (match_dup 6)
18812                       (match_dup 8)))]
18813   "split_di (operands+2, 1, operands+5, operands+6);
18814    split_di (operands+3, 1, operands+7, operands+8);
18815    split_di (operands, 1, operands+2, operands+3);")
18817 (define_expand "movxfcc"
18818   [(set (match_operand:XF 0 "register_operand" "")
18819         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18820                          (match_operand:XF 2 "register_operand" "")
18821                          (match_operand:XF 3 "register_operand" "")))]
18822   "TARGET_80387 && TARGET_CMOVE"
18823   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18825 (define_insn "*movxfcc_1"
18826   [(set (match_operand:XF 0 "register_operand" "=f,f")
18827         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18828                                 [(reg FLAGS_REG) (const_int 0)])
18829                       (match_operand:XF 2 "register_operand" "f,0")
18830                       (match_operand:XF 3 "register_operand" "0,f")))]
18831   "TARGET_80387 && TARGET_CMOVE"
18832   "@
18833    fcmov%F1\t{%2, %0|%0, %2}
18834    fcmov%f1\t{%3, %0|%0, %3}"
18835   [(set_attr "type" "fcmov")
18836    (set_attr "mode" "XF")])
18838 ;; These versions of the min/max patterns are intentionally ignorant of
18839 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18840 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18841 ;; are undefined in this condition, we're certain this is correct.
18843 (define_insn "sminsf3"
18844   [(set (match_operand:SF 0 "register_operand" "=x")
18845         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18846                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18847   "TARGET_SSE_MATH"
18848   "minss\t{%2, %0|%0, %2}"
18849   [(set_attr "type" "sseadd")
18850    (set_attr "mode" "SF")])
18852 (define_insn "smaxsf3"
18853   [(set (match_operand:SF 0 "register_operand" "=x")
18854         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18855                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18856   "TARGET_SSE_MATH"
18857   "maxss\t{%2, %0|%0, %2}"
18858   [(set_attr "type" "sseadd")
18859    (set_attr "mode" "SF")])
18861 (define_insn "smindf3"
18862   [(set (match_operand:DF 0 "register_operand" "=x")
18863         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18864                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18865   "TARGET_SSE2 && TARGET_SSE_MATH"
18866   "minsd\t{%2, %0|%0, %2}"
18867   [(set_attr "type" "sseadd")
18868    (set_attr "mode" "DF")])
18870 (define_insn "smaxdf3"
18871   [(set (match_operand:DF 0 "register_operand" "=x")
18872         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18873                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18874   "TARGET_SSE2 && TARGET_SSE_MATH"
18875   "maxsd\t{%2, %0|%0, %2}"
18876   [(set_attr "type" "sseadd")
18877    (set_attr "mode" "DF")])
18879 ;; These versions of the min/max patterns implement exactly the operations
18880 ;;   min = (op1 < op2 ? op1 : op2)
18881 ;;   max = (!(op1 < op2) ? op1 : op2)
18882 ;; Their operands are not commutative, and thus they may be used in the
18883 ;; presence of -0.0 and NaN.
18885 (define_insn "*ieee_sminsf3"
18886   [(set (match_operand:SF 0 "register_operand" "=x")
18887         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18888                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18889                    UNSPEC_IEEE_MIN))]
18890   "TARGET_SSE_MATH"
18891   "minss\t{%2, %0|%0, %2}"
18892   [(set_attr "type" "sseadd")
18893    (set_attr "mode" "SF")])
18895 (define_insn "*ieee_smaxsf3"
18896   [(set (match_operand:SF 0 "register_operand" "=x")
18897         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18898                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18899                    UNSPEC_IEEE_MAX))]
18900   "TARGET_SSE_MATH"
18901   "maxss\t{%2, %0|%0, %2}"
18902   [(set_attr "type" "sseadd")
18903    (set_attr "mode" "SF")])
18905 (define_insn "*ieee_smindf3"
18906   [(set (match_operand:DF 0 "register_operand" "=x")
18907         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18908                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18909                    UNSPEC_IEEE_MIN))]
18910   "TARGET_SSE2 && TARGET_SSE_MATH"
18911   "minsd\t{%2, %0|%0, %2}"
18912   [(set_attr "type" "sseadd")
18913    (set_attr "mode" "DF")])
18915 (define_insn "*ieee_smaxdf3"
18916   [(set (match_operand:DF 0 "register_operand" "=x")
18917         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18918                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18919                    UNSPEC_IEEE_MAX))]
18920   "TARGET_SSE2 && TARGET_SSE_MATH"
18921   "maxsd\t{%2, %0|%0, %2}"
18922   [(set_attr "type" "sseadd")
18923    (set_attr "mode" "DF")])
18925 ;; Make two stack loads independent:
18926 ;;   fld aa              fld aa
18927 ;;   fld %st(0)     ->   fld bb
18928 ;;   fmul bb             fmul %st(1), %st
18930 ;; Actually we only match the last two instructions for simplicity.
18931 (define_peephole2
18932   [(set (match_operand 0 "fp_register_operand" "")
18933         (match_operand 1 "fp_register_operand" ""))
18934    (set (match_dup 0)
18935         (match_operator 2 "binary_fp_operator"
18936            [(match_dup 0)
18937             (match_operand 3 "memory_operand" "")]))]
18938   "REGNO (operands[0]) != REGNO (operands[1])"
18939   [(set (match_dup 0) (match_dup 3))
18940    (set (match_dup 0) (match_dup 4))]
18942   ;; The % modifier is not operational anymore in peephole2's, so we have to
18943   ;; swap the operands manually in the case of addition and multiplication.
18944   "if (COMMUTATIVE_ARITH_P (operands[2]))
18945      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18946                                  operands[0], operands[1]);
18947    else
18948      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18949                                  operands[1], operands[0]);")
18951 ;; Conditional addition patterns
18952 (define_expand "addqicc"
18953   [(match_operand:QI 0 "register_operand" "")
18954    (match_operand 1 "comparison_operator" "")
18955    (match_operand:QI 2 "register_operand" "")
18956    (match_operand:QI 3 "const_int_operand" "")]
18957   ""
18958   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18960 (define_expand "addhicc"
18961   [(match_operand:HI 0 "register_operand" "")
18962    (match_operand 1 "comparison_operator" "")
18963    (match_operand:HI 2 "register_operand" "")
18964    (match_operand:HI 3 "const_int_operand" "")]
18965   ""
18966   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18968 (define_expand "addsicc"
18969   [(match_operand:SI 0 "register_operand" "")
18970    (match_operand 1 "comparison_operator" "")
18971    (match_operand:SI 2 "register_operand" "")
18972    (match_operand:SI 3 "const_int_operand" "")]
18973   ""
18974   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18976 (define_expand "adddicc"
18977   [(match_operand:DI 0 "register_operand" "")
18978    (match_operand 1 "comparison_operator" "")
18979    (match_operand:DI 2 "register_operand" "")
18980    (match_operand:DI 3 "const_int_operand" "")]
18981   "TARGET_64BIT"
18982   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18985 ;; Misc patterns (?)
18987 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18988 ;; Otherwise there will be nothing to keep
18989 ;; 
18990 ;; [(set (reg ebp) (reg esp))]
18991 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18992 ;;  (clobber (eflags)]
18993 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18995 ;; in proper program order.
18996 (define_insn "pro_epilogue_adjust_stack_1"
18997   [(set (match_operand:SI 0 "register_operand" "=r,r")
18998         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18999                  (match_operand:SI 2 "immediate_operand" "i,i")))
19000    (clobber (reg:CC FLAGS_REG))
19001    (clobber (mem:BLK (scratch)))]
19002   "!TARGET_64BIT"
19004   switch (get_attr_type (insn))
19005     {
19006     case TYPE_IMOV:
19007       return "mov{l}\t{%1, %0|%0, %1}";
19009     case TYPE_ALU:
19010       if (GET_CODE (operands[2]) == CONST_INT
19011           && (INTVAL (operands[2]) == 128
19012               || (INTVAL (operands[2]) < 0
19013                   && INTVAL (operands[2]) != -128)))
19014         {
19015           operands[2] = GEN_INT (-INTVAL (operands[2]));
19016           return "sub{l}\t{%2, %0|%0, %2}";
19017         }
19018       return "add{l}\t{%2, %0|%0, %2}";
19020     case TYPE_LEA:
19021       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19022       return "lea{l}\t{%a2, %0|%0, %a2}";
19024     default:
19025       gcc_unreachable ();
19026     }
19028   [(set (attr "type")
19029         (cond [(eq_attr "alternative" "0")
19030                  (const_string "alu")
19031                (match_operand:SI 2 "const0_operand" "")
19032                  (const_string "imov")
19033               ]
19034               (const_string "lea")))
19035    (set_attr "mode" "SI")])
19037 (define_insn "pro_epilogue_adjust_stack_rex64"
19038   [(set (match_operand:DI 0 "register_operand" "=r,r")
19039         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19040                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19041    (clobber (reg:CC FLAGS_REG))
19042    (clobber (mem:BLK (scratch)))]
19043   "TARGET_64BIT"
19045   switch (get_attr_type (insn))
19046     {
19047     case TYPE_IMOV:
19048       return "mov{q}\t{%1, %0|%0, %1}";
19050     case TYPE_ALU:
19051       if (GET_CODE (operands[2]) == CONST_INT
19052           /* Avoid overflows.  */
19053           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19054           && (INTVAL (operands[2]) == 128
19055               || (INTVAL (operands[2]) < 0
19056                   && INTVAL (operands[2]) != -128)))
19057         {
19058           operands[2] = GEN_INT (-INTVAL (operands[2]));
19059           return "sub{q}\t{%2, %0|%0, %2}";
19060         }
19061       return "add{q}\t{%2, %0|%0, %2}";
19063     case TYPE_LEA:
19064       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19065       return "lea{q}\t{%a2, %0|%0, %a2}";
19067     default:
19068       gcc_unreachable ();
19069     }
19071   [(set (attr "type")
19072         (cond [(eq_attr "alternative" "0")
19073                  (const_string "alu")
19074                (match_operand:DI 2 "const0_operand" "")
19075                  (const_string "imov")
19076               ]
19077               (const_string "lea")))
19078    (set_attr "mode" "DI")])
19080 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19081   [(set (match_operand:DI 0 "register_operand" "=r,r")
19082         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19083                  (match_operand:DI 3 "immediate_operand" "i,i")))
19084    (use (match_operand:DI 2 "register_operand" "r,r"))
19085    (clobber (reg:CC FLAGS_REG))
19086    (clobber (mem:BLK (scratch)))]
19087   "TARGET_64BIT"
19089   switch (get_attr_type (insn))
19090     {
19091     case TYPE_ALU:
19092       return "add{q}\t{%2, %0|%0, %2}";
19094     case TYPE_LEA:
19095       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19096       return "lea{q}\t{%a2, %0|%0, %a2}";
19098     default:
19099       gcc_unreachable ();
19100     }
19102   [(set_attr "type" "alu,lea")
19103    (set_attr "mode" "DI")])
19105 (define_expand "allocate_stack_worker"
19106   [(match_operand:SI 0 "register_operand" "")]
19107   "TARGET_STACK_PROBE"
19109   if (reload_completed)
19110     {
19111       if (TARGET_64BIT)
19112         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19113       else
19114         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19115     }
19116   else
19117     {
19118       if (TARGET_64BIT)
19119         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19120       else
19121         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19122     }
19123   DONE;
19126 (define_insn "allocate_stack_worker_1"
19127   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19128     UNSPECV_STACK_PROBE)
19129    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19130    (clobber (match_scratch:SI 1 "=0"))
19131    (clobber (reg:CC FLAGS_REG))]
19132   "!TARGET_64BIT && TARGET_STACK_PROBE"
19133   "call\t__alloca"
19134   [(set_attr "type" "multi")
19135    (set_attr "length" "5")])
19137 (define_expand "allocate_stack_worker_postreload"
19138   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19139                                     UNSPECV_STACK_PROBE)
19140               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19141               (clobber (match_dup 0))
19142               (clobber (reg:CC FLAGS_REG))])]
19143   ""
19144   "")
19146 (define_insn "allocate_stack_worker_rex64"
19147   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19148     UNSPECV_STACK_PROBE)
19149    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19150    (clobber (match_scratch:DI 1 "=0"))
19151    (clobber (reg:CC FLAGS_REG))]
19152   "TARGET_64BIT && TARGET_STACK_PROBE"
19153   "call\t__alloca"
19154   [(set_attr "type" "multi")
19155    (set_attr "length" "5")])
19157 (define_expand "allocate_stack_worker_rex64_postreload"
19158   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19159                                     UNSPECV_STACK_PROBE)
19160               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19161               (clobber (match_dup 0))
19162               (clobber (reg:CC FLAGS_REG))])]
19163   ""
19164   "")
19166 (define_expand "allocate_stack"
19167   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19168                    (minus:SI (reg:SI SP_REG)
19169                              (match_operand:SI 1 "general_operand" "")))
19170               (clobber (reg:CC FLAGS_REG))])
19171    (parallel [(set (reg:SI SP_REG)
19172                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19173               (clobber (reg:CC FLAGS_REG))])]
19174   "TARGET_STACK_PROBE"
19176 #ifdef CHECK_STACK_LIMIT
19177   if (GET_CODE (operands[1]) == CONST_INT
19178       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19179     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19180                            operands[1]));
19181   else 
19182 #endif
19183     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19184                                                             operands[1])));
19186   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19187   DONE;
19190 (define_expand "builtin_setjmp_receiver"
19191   [(label_ref (match_operand 0 "" ""))]
19192   "!TARGET_64BIT && flag_pic"
19194   emit_insn (gen_set_got (pic_offset_table_rtx));
19195   DONE;
19198 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19200 (define_split
19201   [(set (match_operand 0 "register_operand" "")
19202         (match_operator 3 "promotable_binary_operator"
19203            [(match_operand 1 "register_operand" "")
19204             (match_operand 2 "aligned_operand" "")]))
19205    (clobber (reg:CC FLAGS_REG))]
19206   "! TARGET_PARTIAL_REG_STALL && reload_completed
19207    && ((GET_MODE (operands[0]) == HImode 
19208         && ((!optimize_size && !TARGET_FAST_PREFIX)
19209             || GET_CODE (operands[2]) != CONST_INT
19210             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19211        || (GET_MODE (operands[0]) == QImode 
19212            && (TARGET_PROMOTE_QImode || optimize_size)))"
19213   [(parallel [(set (match_dup 0)
19214                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19215               (clobber (reg:CC FLAGS_REG))])]
19216   "operands[0] = gen_lowpart (SImode, operands[0]);
19217    operands[1] = gen_lowpart (SImode, operands[1]);
19218    if (GET_CODE (operands[3]) != ASHIFT)
19219      operands[2] = gen_lowpart (SImode, operands[2]);
19220    PUT_MODE (operands[3], SImode);")
19222 ; Promote the QImode tests, as i386 has encoding of the AND
19223 ; instruction with 32-bit sign-extended immediate and thus the
19224 ; instruction size is unchanged, except in the %eax case for
19225 ; which it is increased by one byte, hence the ! optimize_size.
19226 (define_split
19227   [(set (match_operand 0 "flags_reg_operand" "")
19228         (match_operator 2 "compare_operator"
19229           [(and (match_operand 3 "aligned_operand" "")
19230                 (match_operand 4 "const_int_operand" ""))
19231            (const_int 0)]))
19232    (set (match_operand 1 "register_operand" "")
19233         (and (match_dup 3) (match_dup 4)))]
19234   "! TARGET_PARTIAL_REG_STALL && reload_completed
19235    /* Ensure that the operand will remain sign-extended immediate.  */
19236    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19237    && ! optimize_size
19238    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19239        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19240   [(parallel [(set (match_dup 0)
19241                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19242                                     (const_int 0)]))
19243               (set (match_dup 1)
19244                    (and:SI (match_dup 3) (match_dup 4)))])]
19246   operands[4]
19247     = gen_int_mode (INTVAL (operands[4])
19248                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19249   operands[1] = gen_lowpart (SImode, operands[1]);
19250   operands[3] = gen_lowpart (SImode, operands[3]);
19253 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19254 ; the TEST instruction with 32-bit sign-extended immediate and thus
19255 ; the instruction size would at least double, which is not what we
19256 ; want even with ! optimize_size.
19257 (define_split
19258   [(set (match_operand 0 "flags_reg_operand" "")
19259         (match_operator 1 "compare_operator"
19260           [(and (match_operand:HI 2 "aligned_operand" "")
19261                 (match_operand:HI 3 "const_int_operand" ""))
19262            (const_int 0)]))]
19263   "! TARGET_PARTIAL_REG_STALL && reload_completed
19264    /* Ensure that the operand will remain sign-extended immediate.  */
19265    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19266    && ! TARGET_FAST_PREFIX
19267    && ! optimize_size"
19268   [(set (match_dup 0)
19269         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19270                          (const_int 0)]))]
19272   operands[3]
19273     = gen_int_mode (INTVAL (operands[3])
19274                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19275   operands[2] = gen_lowpart (SImode, operands[2]);
19278 (define_split
19279   [(set (match_operand 0 "register_operand" "")
19280         (neg (match_operand 1 "register_operand" "")))
19281    (clobber (reg:CC FLAGS_REG))]
19282   "! TARGET_PARTIAL_REG_STALL && reload_completed
19283    && (GET_MODE (operands[0]) == HImode
19284        || (GET_MODE (operands[0]) == QImode 
19285            && (TARGET_PROMOTE_QImode || optimize_size)))"
19286   [(parallel [(set (match_dup 0)
19287                    (neg:SI (match_dup 1)))
19288               (clobber (reg:CC FLAGS_REG))])]
19289   "operands[0] = gen_lowpart (SImode, operands[0]);
19290    operands[1] = gen_lowpart (SImode, operands[1]);")
19292 (define_split
19293   [(set (match_operand 0 "register_operand" "")
19294         (not (match_operand 1 "register_operand" "")))]
19295   "! TARGET_PARTIAL_REG_STALL && reload_completed
19296    && (GET_MODE (operands[0]) == HImode
19297        || (GET_MODE (operands[0]) == QImode 
19298            && (TARGET_PROMOTE_QImode || optimize_size)))"
19299   [(set (match_dup 0)
19300         (not:SI (match_dup 1)))]
19301   "operands[0] = gen_lowpart (SImode, operands[0]);
19302    operands[1] = gen_lowpart (SImode, operands[1]);")
19304 (define_split 
19305   [(set (match_operand 0 "register_operand" "")
19306         (if_then_else (match_operator 1 "comparison_operator" 
19307                                 [(reg FLAGS_REG) (const_int 0)])
19308                       (match_operand 2 "register_operand" "")
19309                       (match_operand 3 "register_operand" "")))]
19310   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19311    && (GET_MODE (operands[0]) == HImode
19312        || (GET_MODE (operands[0]) == QImode 
19313            && (TARGET_PROMOTE_QImode || optimize_size)))"
19314   [(set (match_dup 0)
19315         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19316   "operands[0] = gen_lowpart (SImode, operands[0]);
19317    operands[2] = gen_lowpart (SImode, operands[2]);
19318    operands[3] = gen_lowpart (SImode, operands[3]);")
19319                         
19321 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19322 ;; transform a complex memory operation into two memory to register operations.
19324 ;; Don't push memory operands
19325 (define_peephole2
19326   [(set (match_operand:SI 0 "push_operand" "")
19327         (match_operand:SI 1 "memory_operand" ""))
19328    (match_scratch:SI 2 "r")]
19329   "!optimize_size && !TARGET_PUSH_MEMORY
19330    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19331   [(set (match_dup 2) (match_dup 1))
19332    (set (match_dup 0) (match_dup 2))]
19333   "")
19335 (define_peephole2
19336   [(set (match_operand:DI 0 "push_operand" "")
19337         (match_operand:DI 1 "memory_operand" ""))
19338    (match_scratch:DI 2 "r")]
19339   "!optimize_size && !TARGET_PUSH_MEMORY
19340    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19341   [(set (match_dup 2) (match_dup 1))
19342    (set (match_dup 0) (match_dup 2))]
19343   "")
19345 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19346 ;; SImode pushes.
19347 (define_peephole2
19348   [(set (match_operand:SF 0 "push_operand" "")
19349         (match_operand:SF 1 "memory_operand" ""))
19350    (match_scratch:SF 2 "r")]
19351   "!optimize_size && !TARGET_PUSH_MEMORY
19352    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19353   [(set (match_dup 2) (match_dup 1))
19354    (set (match_dup 0) (match_dup 2))]
19355   "")
19357 (define_peephole2
19358   [(set (match_operand:HI 0 "push_operand" "")
19359         (match_operand:HI 1 "memory_operand" ""))
19360    (match_scratch:HI 2 "r")]
19361   "!optimize_size && !TARGET_PUSH_MEMORY
19362    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19363   [(set (match_dup 2) (match_dup 1))
19364    (set (match_dup 0) (match_dup 2))]
19365   "")
19367 (define_peephole2
19368   [(set (match_operand:QI 0 "push_operand" "")
19369         (match_operand:QI 1 "memory_operand" ""))
19370    (match_scratch:QI 2 "q")]
19371   "!optimize_size && !TARGET_PUSH_MEMORY
19372    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19373   [(set (match_dup 2) (match_dup 1))
19374    (set (match_dup 0) (match_dup 2))]
19375   "")
19377 ;; Don't move an immediate directly to memory when the instruction
19378 ;; gets too big.
19379 (define_peephole2
19380   [(match_scratch:SI 1 "r")
19381    (set (match_operand:SI 0 "memory_operand" "")
19382         (const_int 0))]
19383   "! optimize_size
19384    && ! TARGET_USE_MOV0
19385    && TARGET_SPLIT_LONG_MOVES
19386    && get_attr_length (insn) >= ix86_cost->large_insn
19387    && peep2_regno_dead_p (0, FLAGS_REG)"
19388   [(parallel [(set (match_dup 1) (const_int 0))
19389               (clobber (reg:CC FLAGS_REG))])
19390    (set (match_dup 0) (match_dup 1))]
19391   "")
19393 (define_peephole2
19394   [(match_scratch:HI 1 "r")
19395    (set (match_operand:HI 0 "memory_operand" "")
19396         (const_int 0))]
19397   "! optimize_size
19398    && ! TARGET_USE_MOV0
19399    && TARGET_SPLIT_LONG_MOVES
19400    && get_attr_length (insn) >= ix86_cost->large_insn
19401    && peep2_regno_dead_p (0, FLAGS_REG)"
19402   [(parallel [(set (match_dup 2) (const_int 0))
19403               (clobber (reg:CC FLAGS_REG))])
19404    (set (match_dup 0) (match_dup 1))]
19405   "operands[2] = gen_lowpart (SImode, operands[1]);")
19407 (define_peephole2
19408   [(match_scratch:QI 1 "q")
19409    (set (match_operand:QI 0 "memory_operand" "")
19410         (const_int 0))]
19411   "! optimize_size
19412    && ! TARGET_USE_MOV0
19413    && TARGET_SPLIT_LONG_MOVES
19414    && get_attr_length (insn) >= ix86_cost->large_insn
19415    && peep2_regno_dead_p (0, FLAGS_REG)"
19416   [(parallel [(set (match_dup 2) (const_int 0))
19417               (clobber (reg:CC FLAGS_REG))])
19418    (set (match_dup 0) (match_dup 1))]
19419   "operands[2] = gen_lowpart (SImode, operands[1]);")
19421 (define_peephole2
19422   [(match_scratch:SI 2 "r")
19423    (set (match_operand:SI 0 "memory_operand" "")
19424         (match_operand:SI 1 "immediate_operand" ""))]
19425   "! optimize_size
19426    && get_attr_length (insn) >= ix86_cost->large_insn
19427    && TARGET_SPLIT_LONG_MOVES"
19428   [(set (match_dup 2) (match_dup 1))
19429    (set (match_dup 0) (match_dup 2))]
19430   "")
19432 (define_peephole2
19433   [(match_scratch:HI 2 "r")
19434    (set (match_operand:HI 0 "memory_operand" "")
19435         (match_operand:HI 1 "immediate_operand" ""))]
19436   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19437   && TARGET_SPLIT_LONG_MOVES"
19438   [(set (match_dup 2) (match_dup 1))
19439    (set (match_dup 0) (match_dup 2))]
19440   "")
19442 (define_peephole2
19443   [(match_scratch:QI 2 "q")
19444    (set (match_operand:QI 0 "memory_operand" "")
19445         (match_operand:QI 1 "immediate_operand" ""))]
19446   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19447   && TARGET_SPLIT_LONG_MOVES"
19448   [(set (match_dup 2) (match_dup 1))
19449    (set (match_dup 0) (match_dup 2))]
19450   "")
19452 ;; Don't compare memory with zero, load and use a test instead.
19453 (define_peephole2
19454   [(set (match_operand 0 "flags_reg_operand" "")
19455         (match_operator 1 "compare_operator"
19456           [(match_operand:SI 2 "memory_operand" "")
19457            (const_int 0)]))
19458    (match_scratch:SI 3 "r")]
19459   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19460   [(set (match_dup 3) (match_dup 2))
19461    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19462   "")
19464 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19465 ;; Don't split NOTs with a displacement operand, because resulting XOR
19466 ;; will not be pairable anyway.
19468 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19469 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19470 ;; so this split helps here as well.
19472 ;; Note: Can't do this as a regular split because we can't get proper
19473 ;; lifetime information then.
19475 (define_peephole2
19476   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19477         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19478   "!optimize_size
19479    && peep2_regno_dead_p (0, FLAGS_REG)
19480    && ((TARGET_PENTIUM 
19481         && (GET_CODE (operands[0]) != MEM
19482             || !memory_displacement_operand (operands[0], SImode)))
19483        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19484   [(parallel [(set (match_dup 0)
19485                    (xor:SI (match_dup 1) (const_int -1)))
19486               (clobber (reg:CC FLAGS_REG))])]
19487   "")
19489 (define_peephole2
19490   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19491         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19492   "!optimize_size
19493    && peep2_regno_dead_p (0, FLAGS_REG)
19494    && ((TARGET_PENTIUM 
19495         && (GET_CODE (operands[0]) != MEM
19496             || !memory_displacement_operand (operands[0], HImode)))
19497        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19498   [(parallel [(set (match_dup 0)
19499                    (xor:HI (match_dup 1) (const_int -1)))
19500               (clobber (reg:CC FLAGS_REG))])]
19501   "")
19503 (define_peephole2
19504   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19505         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19506   "!optimize_size
19507    && peep2_regno_dead_p (0, FLAGS_REG)
19508    && ((TARGET_PENTIUM 
19509         && (GET_CODE (operands[0]) != MEM
19510             || !memory_displacement_operand (operands[0], QImode)))
19511        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19512   [(parallel [(set (match_dup 0)
19513                    (xor:QI (match_dup 1) (const_int -1)))
19514               (clobber (reg:CC FLAGS_REG))])]
19515   "")
19517 ;; Non pairable "test imm, reg" instructions can be translated to
19518 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19519 ;; byte opcode instead of two, have a short form for byte operands),
19520 ;; so do it for other CPUs as well.  Given that the value was dead,
19521 ;; this should not create any new dependencies.  Pass on the sub-word
19522 ;; versions if we're concerned about partial register stalls.
19524 (define_peephole2
19525   [(set (match_operand 0 "flags_reg_operand" "")
19526         (match_operator 1 "compare_operator"
19527           [(and:SI (match_operand:SI 2 "register_operand" "")
19528                    (match_operand:SI 3 "immediate_operand" ""))
19529            (const_int 0)]))]
19530   "ix86_match_ccmode (insn, CCNOmode)
19531    && (true_regnum (operands[2]) != 0
19532        || (GET_CODE (operands[3]) == CONST_INT
19533            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19534    && peep2_reg_dead_p (1, operands[2])"
19535   [(parallel
19536      [(set (match_dup 0)
19537            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19538                             (const_int 0)]))
19539       (set (match_dup 2)
19540            (and:SI (match_dup 2) (match_dup 3)))])]
19541   "")
19543 ;; We don't need to handle HImode case, because it will be promoted to SImode
19544 ;; on ! TARGET_PARTIAL_REG_STALL
19546 (define_peephole2
19547   [(set (match_operand 0 "flags_reg_operand" "")
19548         (match_operator 1 "compare_operator"
19549           [(and:QI (match_operand:QI 2 "register_operand" "")
19550                    (match_operand:QI 3 "immediate_operand" ""))
19551            (const_int 0)]))]
19552   "! TARGET_PARTIAL_REG_STALL
19553    && ix86_match_ccmode (insn, CCNOmode)
19554    && true_regnum (operands[2]) != 0
19555    && peep2_reg_dead_p (1, operands[2])"
19556   [(parallel
19557      [(set (match_dup 0)
19558            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19559                             (const_int 0)]))
19560       (set (match_dup 2)
19561            (and:QI (match_dup 2) (match_dup 3)))])]
19562   "")
19564 (define_peephole2
19565   [(set (match_operand 0 "flags_reg_operand" "")
19566         (match_operator 1 "compare_operator"
19567           [(and:SI
19568              (zero_extract:SI
19569                (match_operand 2 "ext_register_operand" "")
19570                (const_int 8)
19571                (const_int 8))
19572              (match_operand 3 "const_int_operand" ""))
19573            (const_int 0)]))]
19574   "! TARGET_PARTIAL_REG_STALL
19575    && ix86_match_ccmode (insn, CCNOmode)
19576    && true_regnum (operands[2]) != 0
19577    && peep2_reg_dead_p (1, operands[2])"
19578   [(parallel [(set (match_dup 0)
19579                    (match_op_dup 1
19580                      [(and:SI
19581                         (zero_extract:SI
19582                           (match_dup 2)
19583                           (const_int 8)
19584                           (const_int 8))
19585                         (match_dup 3))
19586                       (const_int 0)]))
19587               (set (zero_extract:SI (match_dup 2)
19588                                     (const_int 8)
19589                                     (const_int 8))
19590                    (and:SI 
19591                      (zero_extract:SI
19592                        (match_dup 2)
19593                        (const_int 8)
19594                        (const_int 8))
19595                      (match_dup 3)))])]
19596   "")
19598 ;; Don't do logical operations with memory inputs.
19599 (define_peephole2
19600   [(match_scratch:SI 2 "r")
19601    (parallel [(set (match_operand:SI 0 "register_operand" "")
19602                    (match_operator:SI 3 "arith_or_logical_operator"
19603                      [(match_dup 0)
19604                       (match_operand:SI 1 "memory_operand" "")]))
19605               (clobber (reg:CC FLAGS_REG))])]
19606   "! optimize_size && ! TARGET_READ_MODIFY"
19607   [(set (match_dup 2) (match_dup 1))
19608    (parallel [(set (match_dup 0)
19609                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19610               (clobber (reg:CC FLAGS_REG))])]
19611   "")
19613 (define_peephole2
19614   [(match_scratch:SI 2 "r")
19615    (parallel [(set (match_operand:SI 0 "register_operand" "")
19616                    (match_operator:SI 3 "arith_or_logical_operator"
19617                      [(match_operand:SI 1 "memory_operand" "")
19618                       (match_dup 0)]))
19619               (clobber (reg:CC FLAGS_REG))])]
19620   "! optimize_size && ! TARGET_READ_MODIFY"
19621   [(set (match_dup 2) (match_dup 1))
19622    (parallel [(set (match_dup 0)
19623                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19624               (clobber (reg:CC FLAGS_REG))])]
19625   "")
19627 ; Don't do logical operations with memory outputs
19629 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19630 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19631 ; the same decoder scheduling characteristics as the original.
19633 (define_peephole2
19634   [(match_scratch:SI 2 "r")
19635    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19636                    (match_operator:SI 3 "arith_or_logical_operator"
19637                      [(match_dup 0)
19638                       (match_operand:SI 1 "nonmemory_operand" "")]))
19639               (clobber (reg:CC FLAGS_REG))])]
19640   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19641   [(set (match_dup 2) (match_dup 0))
19642    (parallel [(set (match_dup 2)
19643                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19644               (clobber (reg:CC FLAGS_REG))])
19645    (set (match_dup 0) (match_dup 2))]
19646   "")
19648 (define_peephole2
19649   [(match_scratch:SI 2 "r")
19650    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19651                    (match_operator:SI 3 "arith_or_logical_operator"
19652                      [(match_operand:SI 1 "nonmemory_operand" "")
19653                       (match_dup 0)]))
19654               (clobber (reg:CC FLAGS_REG))])]
19655   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19656   [(set (match_dup 2) (match_dup 0))
19657    (parallel [(set (match_dup 2)
19658                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19659               (clobber (reg:CC FLAGS_REG))])
19660    (set (match_dup 0) (match_dup 2))]
19661   "")
19663 ;; Attempt to always use XOR for zeroing registers.
19664 (define_peephole2
19665   [(set (match_operand 0 "register_operand" "")
19666         (match_operand 1 "const0_operand" ""))]
19667   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19668    && (! TARGET_USE_MOV0 || optimize_size)
19669    && GENERAL_REG_P (operands[0])
19670    && peep2_regno_dead_p (0, FLAGS_REG)"
19671   [(parallel [(set (match_dup 0) (const_int 0))
19672               (clobber (reg:CC FLAGS_REG))])]
19674   operands[0] = gen_lowpart (word_mode, operands[0]);
19677 (define_peephole2
19678   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19679         (const_int 0))]
19680   "(GET_MODE (operands[0]) == QImode
19681     || GET_MODE (operands[0]) == HImode)
19682    && (! TARGET_USE_MOV0 || optimize_size)
19683    && peep2_regno_dead_p (0, FLAGS_REG)"
19684   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19685               (clobber (reg:CC FLAGS_REG))])])
19687 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19688 (define_peephole2
19689   [(set (match_operand 0 "register_operand" "")
19690         (const_int -1))]
19691   "(GET_MODE (operands[0]) == HImode
19692     || GET_MODE (operands[0]) == SImode 
19693     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19694    && (optimize_size || TARGET_PENTIUM)
19695    && peep2_regno_dead_p (0, FLAGS_REG)"
19696   [(parallel [(set (match_dup 0) (const_int -1))
19697               (clobber (reg:CC FLAGS_REG))])]
19698   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19699                               operands[0]);")
19701 ;; Attempt to convert simple leas to adds. These can be created by
19702 ;; move expanders.
19703 (define_peephole2
19704   [(set (match_operand:SI 0 "register_operand" "")
19705         (plus:SI (match_dup 0)
19706                  (match_operand:SI 1 "nonmemory_operand" "")))]
19707   "peep2_regno_dead_p (0, FLAGS_REG)"
19708   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19709               (clobber (reg:CC FLAGS_REG))])]
19710   "")
19712 (define_peephole2
19713   [(set (match_operand:SI 0 "register_operand" "")
19714         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19715                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19716   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19717   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19718               (clobber (reg:CC FLAGS_REG))])]
19719   "operands[2] = gen_lowpart (SImode, operands[2]);")
19721 (define_peephole2
19722   [(set (match_operand:DI 0 "register_operand" "")
19723         (plus:DI (match_dup 0)
19724                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19725   "peep2_regno_dead_p (0, FLAGS_REG)"
19726   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19727               (clobber (reg:CC FLAGS_REG))])]
19728   "")
19730 (define_peephole2
19731   [(set (match_operand:SI 0 "register_operand" "")
19732         (mult:SI (match_dup 0)
19733                  (match_operand:SI 1 "const_int_operand" "")))]
19734   "exact_log2 (INTVAL (operands[1])) >= 0
19735    && peep2_regno_dead_p (0, FLAGS_REG)"
19736   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19737               (clobber (reg:CC FLAGS_REG))])]
19738   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19740 (define_peephole2
19741   [(set (match_operand:DI 0 "register_operand" "")
19742         (mult:DI (match_dup 0)
19743                  (match_operand:DI 1 "const_int_operand" "")))]
19744   "exact_log2 (INTVAL (operands[1])) >= 0
19745    && peep2_regno_dead_p (0, FLAGS_REG)"
19746   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19747               (clobber (reg:CC FLAGS_REG))])]
19748   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19750 (define_peephole2
19751   [(set (match_operand:SI 0 "register_operand" "")
19752         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19753                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19754   "exact_log2 (INTVAL (operands[2])) >= 0
19755    && REGNO (operands[0]) == REGNO (operands[1])
19756    && peep2_regno_dead_p (0, FLAGS_REG)"
19757   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19758               (clobber (reg:CC FLAGS_REG))])]
19759   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19761 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19762 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19763 ;; many CPUs it is also faster, since special hardware to avoid esp
19764 ;; dependencies is present.
19766 ;; While some of these conversions may be done using splitters, we use peepholes
19767 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19769 ;; Convert prologue esp subtractions to push.
19770 ;; We need register to push.  In order to keep verify_flow_info happy we have
19771 ;; two choices
19772 ;; - use scratch and clobber it in order to avoid dependencies
19773 ;; - use already live register
19774 ;; We can't use the second way right now, since there is no reliable way how to
19775 ;; verify that given register is live.  First choice will also most likely in
19776 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19777 ;; call clobbered registers are dead.  We may want to use base pointer as an
19778 ;; alternative when no register is available later.
19780 (define_peephole2
19781   [(match_scratch:SI 0 "r")
19782    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19783               (clobber (reg:CC FLAGS_REG))
19784               (clobber (mem:BLK (scratch)))])]
19785   "optimize_size || !TARGET_SUB_ESP_4"
19786   [(clobber (match_dup 0))
19787    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19788               (clobber (mem:BLK (scratch)))])])
19790 (define_peephole2
19791   [(match_scratch:SI 0 "r")
19792    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19793               (clobber (reg:CC FLAGS_REG))
19794               (clobber (mem:BLK (scratch)))])]
19795   "optimize_size || !TARGET_SUB_ESP_8"
19796   [(clobber (match_dup 0))
19797    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19798    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19799               (clobber (mem:BLK (scratch)))])])
19801 ;; Convert esp subtractions to push.
19802 (define_peephole2
19803   [(match_scratch:SI 0 "r")
19804    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19805               (clobber (reg:CC FLAGS_REG))])]
19806   "optimize_size || !TARGET_SUB_ESP_4"
19807   [(clobber (match_dup 0))
19808    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19810 (define_peephole2
19811   [(match_scratch:SI 0 "r")
19812    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19813               (clobber (reg:CC FLAGS_REG))])]
19814   "optimize_size || !TARGET_SUB_ESP_8"
19815   [(clobber (match_dup 0))
19816    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19817    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19819 ;; Convert epilogue deallocator to pop.
19820 (define_peephole2
19821   [(match_scratch:SI 0 "r")
19822    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19823               (clobber (reg:CC FLAGS_REG))
19824               (clobber (mem:BLK (scratch)))])]
19825   "optimize_size || !TARGET_ADD_ESP_4"
19826   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19827               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19828               (clobber (mem:BLK (scratch)))])]
19829   "")
19831 ;; Two pops case is tricky, since pop causes dependency on destination register.
19832 ;; We use two registers if available.
19833 (define_peephole2
19834   [(match_scratch:SI 0 "r")
19835    (match_scratch:SI 1 "r")
19836    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19837               (clobber (reg:CC FLAGS_REG))
19838               (clobber (mem:BLK (scratch)))])]
19839   "optimize_size || !TARGET_ADD_ESP_8"
19840   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19841               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19842               (clobber (mem:BLK (scratch)))])
19843    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19844               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19845   "")
19847 (define_peephole2
19848   [(match_scratch:SI 0 "r")
19849    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19850               (clobber (reg:CC FLAGS_REG))
19851               (clobber (mem:BLK (scratch)))])]
19852   "optimize_size"
19853   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19854               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19855               (clobber (mem:BLK (scratch)))])
19856    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19857               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19858   "")
19860 ;; Convert esp additions to pop.
19861 (define_peephole2
19862   [(match_scratch:SI 0 "r")
19863    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19864               (clobber (reg:CC FLAGS_REG))])]
19865   ""
19866   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19867               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19868   "")
19870 ;; Two pops case is tricky, since pop causes dependency on destination register.
19871 ;; We use two registers if available.
19872 (define_peephole2
19873   [(match_scratch:SI 0 "r")
19874    (match_scratch:SI 1 "r")
19875    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19876               (clobber (reg:CC FLAGS_REG))])]
19877   ""
19878   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19879               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19880    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19881               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19882   "")
19884 (define_peephole2
19885   [(match_scratch:SI 0 "r")
19886    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19887               (clobber (reg:CC FLAGS_REG))])]
19888   "optimize_size"
19889   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19890               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19891    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19892               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19893   "")
19895 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19896 ;; required and register dies.  Similarly for 128 to plus -128.
19897 (define_peephole2
19898   [(set (match_operand 0 "flags_reg_operand" "")
19899         (match_operator 1 "compare_operator"
19900           [(match_operand 2 "register_operand" "")
19901            (match_operand 3 "const_int_operand" "")]))]
19902   "(INTVAL (operands[3]) == -1
19903     || INTVAL (operands[3]) == 1
19904     || INTVAL (operands[3]) == 128)
19905    && ix86_match_ccmode (insn, CCGCmode)
19906    && peep2_reg_dead_p (1, operands[2])"
19907   [(parallel [(set (match_dup 0)
19908                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19909               (clobber (match_dup 2))])]
19910   "")
19912 (define_peephole2
19913   [(match_scratch:DI 0 "r")
19914    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19915               (clobber (reg:CC FLAGS_REG))
19916               (clobber (mem:BLK (scratch)))])]
19917   "optimize_size || !TARGET_SUB_ESP_4"
19918   [(clobber (match_dup 0))
19919    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19920               (clobber (mem:BLK (scratch)))])])
19922 (define_peephole2
19923   [(match_scratch:DI 0 "r")
19924    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19925               (clobber (reg:CC FLAGS_REG))
19926               (clobber (mem:BLK (scratch)))])]
19927   "optimize_size || !TARGET_SUB_ESP_8"
19928   [(clobber (match_dup 0))
19929    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19930    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19931               (clobber (mem:BLK (scratch)))])])
19933 ;; Convert esp subtractions to push.
19934 (define_peephole2
19935   [(match_scratch:DI 0 "r")
19936    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19937               (clobber (reg:CC FLAGS_REG))])]
19938   "optimize_size || !TARGET_SUB_ESP_4"
19939   [(clobber (match_dup 0))
19940    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19942 (define_peephole2
19943   [(match_scratch:DI 0 "r")
19944    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19945               (clobber (reg:CC FLAGS_REG))])]
19946   "optimize_size || !TARGET_SUB_ESP_8"
19947   [(clobber (match_dup 0))
19948    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19949    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19951 ;; Convert epilogue deallocator to pop.
19952 (define_peephole2
19953   [(match_scratch:DI 0 "r")
19954    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19955               (clobber (reg:CC FLAGS_REG))
19956               (clobber (mem:BLK (scratch)))])]
19957   "optimize_size || !TARGET_ADD_ESP_4"
19958   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19959               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19960               (clobber (mem:BLK (scratch)))])]
19961   "")
19963 ;; Two pops case is tricky, since pop causes dependency on destination register.
19964 ;; We use two registers if available.
19965 (define_peephole2
19966   [(match_scratch:DI 0 "r")
19967    (match_scratch:DI 1 "r")
19968    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19969               (clobber (reg:CC FLAGS_REG))
19970               (clobber (mem:BLK (scratch)))])]
19971   "optimize_size || !TARGET_ADD_ESP_8"
19972   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19973               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19974               (clobber (mem:BLK (scratch)))])
19975    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19976               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19977   "")
19979 (define_peephole2
19980   [(match_scratch:DI 0 "r")
19981    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19982               (clobber (reg:CC FLAGS_REG))
19983               (clobber (mem:BLK (scratch)))])]
19984   "optimize_size"
19985   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19986               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19987               (clobber (mem:BLK (scratch)))])
19988    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19989               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19990   "")
19992 ;; Convert esp additions to pop.
19993 (define_peephole2
19994   [(match_scratch:DI 0 "r")
19995    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19996               (clobber (reg:CC FLAGS_REG))])]
19997   ""
19998   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19999               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20000   "")
20002 ;; Two pops case is tricky, since pop causes dependency on destination register.
20003 ;; We use two registers if available.
20004 (define_peephole2
20005   [(match_scratch:DI 0 "r")
20006    (match_scratch:DI 1 "r")
20007    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20008               (clobber (reg:CC FLAGS_REG))])]
20009   ""
20010   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20011               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20012    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20013               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20014   "")
20016 (define_peephole2
20017   [(match_scratch:DI 0 "r")
20018    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20019               (clobber (reg:CC FLAGS_REG))])]
20020   "optimize_size"
20021   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20022               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20023    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20024               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20025   "")
20027 ;; Convert imul by three, five and nine into lea
20028 (define_peephole2
20029   [(parallel
20030     [(set (match_operand:SI 0 "register_operand" "")
20031           (mult:SI (match_operand:SI 1 "register_operand" "")
20032                    (match_operand:SI 2 "const_int_operand" "")))
20033      (clobber (reg:CC FLAGS_REG))])]
20034   "INTVAL (operands[2]) == 3
20035    || INTVAL (operands[2]) == 5
20036    || INTVAL (operands[2]) == 9"
20037   [(set (match_dup 0)
20038         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20039                  (match_dup 1)))]
20040   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20042 (define_peephole2
20043   [(parallel
20044     [(set (match_operand:SI 0 "register_operand" "")
20045           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20046                    (match_operand:SI 2 "const_int_operand" "")))
20047      (clobber (reg:CC FLAGS_REG))])]
20048   "!optimize_size 
20049    && (INTVAL (operands[2]) == 3
20050        || INTVAL (operands[2]) == 5
20051        || INTVAL (operands[2]) == 9)"
20052   [(set (match_dup 0) (match_dup 1))
20053    (set (match_dup 0)
20054         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20055                  (match_dup 0)))]
20056   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20058 (define_peephole2
20059   [(parallel
20060     [(set (match_operand:DI 0 "register_operand" "")
20061           (mult:DI (match_operand:DI 1 "register_operand" "")
20062                    (match_operand:DI 2 "const_int_operand" "")))
20063      (clobber (reg:CC FLAGS_REG))])]
20064   "TARGET_64BIT
20065    && (INTVAL (operands[2]) == 3
20066        || INTVAL (operands[2]) == 5
20067        || INTVAL (operands[2]) == 9)"
20068   [(set (match_dup 0)
20069         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20070                  (match_dup 1)))]
20071   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20073 (define_peephole2
20074   [(parallel
20075     [(set (match_operand:DI 0 "register_operand" "")
20076           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20077                    (match_operand:DI 2 "const_int_operand" "")))
20078      (clobber (reg:CC FLAGS_REG))])]
20079   "TARGET_64BIT
20080    && !optimize_size 
20081    && (INTVAL (operands[2]) == 3
20082        || INTVAL (operands[2]) == 5
20083        || INTVAL (operands[2]) == 9)"
20084   [(set (match_dup 0) (match_dup 1))
20085    (set (match_dup 0)
20086         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20087                  (match_dup 0)))]
20088   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20090 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20091 ;; imul $32bit_imm, reg, reg is direct decoded.
20092 (define_peephole2
20093   [(match_scratch:DI 3 "r")
20094    (parallel [(set (match_operand:DI 0 "register_operand" "")
20095                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20096                             (match_operand:DI 2 "immediate_operand" "")))
20097               (clobber (reg:CC FLAGS_REG))])]
20098   "TARGET_K8 && !optimize_size
20099    && (GET_CODE (operands[2]) != CONST_INT
20100        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
20101   [(set (match_dup 3) (match_dup 1))
20102    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20103               (clobber (reg:CC FLAGS_REG))])]
20106 (define_peephole2
20107   [(match_scratch:SI 3 "r")
20108    (parallel [(set (match_operand:SI 0 "register_operand" "")
20109                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20110                             (match_operand:SI 2 "immediate_operand" "")))
20111               (clobber (reg:CC FLAGS_REG))])]
20112   "TARGET_K8 && !optimize_size
20113    && (GET_CODE (operands[2]) != CONST_INT
20114        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
20115   [(set (match_dup 3) (match_dup 1))
20116    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20117               (clobber (reg:CC FLAGS_REG))])]
20120 (define_peephole2
20121   [(match_scratch:SI 3 "r")
20122    (parallel [(set (match_operand:DI 0 "register_operand" "")
20123                    (zero_extend:DI
20124                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20125                               (match_operand:SI 2 "immediate_operand" ""))))
20126               (clobber (reg:CC FLAGS_REG))])]
20127   "TARGET_K8 && !optimize_size
20128    && (GET_CODE (operands[2]) != CONST_INT
20129        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
20130   [(set (match_dup 3) (match_dup 1))
20131    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20132               (clobber (reg:CC FLAGS_REG))])]
20135 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20136 ;; Convert it into imul reg, reg
20137 ;; It would be better to force assembler to encode instruction using long
20138 ;; immediate, but there is apparently no way to do so.
20139 (define_peephole2
20140   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20141                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20142                             (match_operand:DI 2 "const_int_operand" "")))
20143               (clobber (reg:CC FLAGS_REG))])
20144    (match_scratch:DI 3 "r")]
20145   "TARGET_K8 && !optimize_size
20146    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
20147   [(set (match_dup 3) (match_dup 2))
20148    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20149               (clobber (reg:CC FLAGS_REG))])]
20151   if (!rtx_equal_p (operands[0], operands[1]))
20152     emit_move_insn (operands[0], operands[1]);
20155 (define_peephole2
20156   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20157                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20158                             (match_operand:SI 2 "const_int_operand" "")))
20159               (clobber (reg:CC FLAGS_REG))])
20160    (match_scratch:SI 3 "r")]
20161   "TARGET_K8 && !optimize_size
20162    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
20163   [(set (match_dup 3) (match_dup 2))
20164    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20165               (clobber (reg:CC FLAGS_REG))])]
20167   if (!rtx_equal_p (operands[0], operands[1]))
20168     emit_move_insn (operands[0], operands[1]);
20171 (define_peephole2
20172   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20173                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20174                             (match_operand:HI 2 "immediate_operand" "")))
20175               (clobber (reg:CC FLAGS_REG))])
20176    (match_scratch:HI 3 "r")]
20177   "TARGET_K8 && !optimize_size"
20178   [(set (match_dup 3) (match_dup 2))
20179    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20180               (clobber (reg:CC FLAGS_REG))])]
20182   if (!rtx_equal_p (operands[0], operands[1]))
20183     emit_move_insn (operands[0], operands[1]);
20186 ;; After splitting up read-modify operations, array accesses with memory
20187 ;; operands might end up in form:
20188 ;;  sall    $2, %eax
20189 ;;  movl    4(%esp), %edx
20190 ;;  addl    %edx, %eax
20191 ;; instead of pre-splitting:
20192 ;;  sall    $2, %eax
20193 ;;  addl    4(%esp), %eax
20194 ;; Turn it into:
20195 ;;  movl    4(%esp), %edx
20196 ;;  leal    (%edx,%eax,4), %eax
20198 (define_peephole2
20199   [(parallel [(set (match_operand 0 "register_operand" "")
20200                    (ashift (match_operand 1 "register_operand" "")
20201                            (match_operand 2 "const_int_operand" "")))
20202                (clobber (reg:CC FLAGS_REG))])
20203    (set (match_operand 3 "register_operand")
20204         (match_operand 4 "x86_64_general_operand" ""))
20205    (parallel [(set (match_operand 5 "register_operand" "")
20206                    (plus (match_operand 6 "register_operand" "")
20207                          (match_operand 7 "register_operand" "")))
20208                    (clobber (reg:CC FLAGS_REG))])]
20209   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20210    /* Validate MODE for lea.  */
20211    && ((!TARGET_PARTIAL_REG_STALL
20212         && (GET_MODE (operands[0]) == QImode
20213             || GET_MODE (operands[0]) == HImode))
20214        || GET_MODE (operands[0]) == SImode 
20215        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20216    /* We reorder load and the shift.  */
20217    && !rtx_equal_p (operands[1], operands[3])
20218    && !reg_overlap_mentioned_p (operands[0], operands[4])
20219    /* Last PLUS must consist of operand 0 and 3.  */
20220    && !rtx_equal_p (operands[0], operands[3])
20221    && (rtx_equal_p (operands[3], operands[6])
20222        || rtx_equal_p (operands[3], operands[7]))
20223    && (rtx_equal_p (operands[0], operands[6])
20224        || rtx_equal_p (operands[0], operands[7]))
20225    /* The intermediate operand 0 must die or be same as output.  */
20226    && (rtx_equal_p (operands[0], operands[5])
20227        || peep2_reg_dead_p (3, operands[0]))"
20228   [(set (match_dup 3) (match_dup 4))
20229    (set (match_dup 0) (match_dup 1))]
20231   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20232   int scale = 1 << INTVAL (operands[2]);
20233   rtx index = gen_lowpart (Pmode, operands[1]);
20234   rtx base = gen_lowpart (Pmode, operands[3]);
20235   rtx dest = gen_lowpart (mode, operands[5]);
20237   operands[1] = gen_rtx_PLUS (Pmode, base,
20238                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20239   if (mode != Pmode)
20240     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20241   operands[0] = dest;
20244 ;; Call-value patterns last so that the wildcard operand does not
20245 ;; disrupt insn-recog's switch tables.
20247 (define_insn "*call_value_pop_0"
20248   [(set (match_operand 0 "" "")
20249         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20250               (match_operand:SI 2 "" "")))
20251    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20252                             (match_operand:SI 3 "immediate_operand" "")))]
20253   "!TARGET_64BIT"
20255   if (SIBLING_CALL_P (insn))
20256     return "jmp\t%P1";
20257   else
20258     return "call\t%P1";
20260   [(set_attr "type" "callv")])
20262 (define_insn "*call_value_pop_1"
20263   [(set (match_operand 0 "" "")
20264         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20265               (match_operand:SI 2 "" "")))
20266    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20267                             (match_operand:SI 3 "immediate_operand" "i")))]
20268   "!TARGET_64BIT"
20270   if (constant_call_address_operand (operands[1], Pmode))
20271     {
20272       if (SIBLING_CALL_P (insn))
20273         return "jmp\t%P1";
20274       else
20275         return "call\t%P1";
20276     }
20277   if (SIBLING_CALL_P (insn))
20278     return "jmp\t%A1";
20279   else
20280     return "call\t%A1";
20282   [(set_attr "type" "callv")])
20284 (define_insn "*call_value_0"
20285   [(set (match_operand 0 "" "")
20286         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20287               (match_operand:SI 2 "" "")))]
20288   "!TARGET_64BIT"
20290   if (SIBLING_CALL_P (insn))
20291     return "jmp\t%P1";
20292   else
20293     return "call\t%P1";
20295   [(set_attr "type" "callv")])
20297 (define_insn "*call_value_0_rex64"
20298   [(set (match_operand 0 "" "")
20299         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20300               (match_operand:DI 2 "const_int_operand" "")))]
20301   "TARGET_64BIT"
20303   if (SIBLING_CALL_P (insn))
20304     return "jmp\t%P1";
20305   else
20306     return "call\t%P1";
20308   [(set_attr "type" "callv")])
20310 (define_insn "*call_value_1"
20311   [(set (match_operand 0 "" "")
20312         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20313               (match_operand:SI 2 "" "")))]
20314   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20316   if (constant_call_address_operand (operands[1], Pmode))
20317     return "call\t%P1";
20318   return "call\t%A1";
20320   [(set_attr "type" "callv")])
20322 (define_insn "*sibcall_value_1"
20323   [(set (match_operand 0 "" "")
20324         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20325               (match_operand:SI 2 "" "")))]
20326   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20328   if (constant_call_address_operand (operands[1], Pmode))
20329     return "jmp\t%P1";
20330   return "jmp\t%A1";
20332   [(set_attr "type" "callv")])
20334 (define_insn "*call_value_1_rex64"
20335   [(set (match_operand 0 "" "")
20336         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20337               (match_operand:DI 2 "" "")))]
20338   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20340   if (constant_call_address_operand (operands[1], Pmode))
20341     return "call\t%P1";
20342   return "call\t%A1";
20344   [(set_attr "type" "callv")])
20346 (define_insn "*sibcall_value_1_rex64"
20347   [(set (match_operand 0 "" "")
20348         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20349               (match_operand:DI 2 "" "")))]
20350   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20351   "jmp\t%P1"
20352   [(set_attr "type" "callv")])
20354 (define_insn "*sibcall_value_1_rex64_v"
20355   [(set (match_operand 0 "" "")
20356         (call (mem:QI (reg:DI 40))
20357               (match_operand:DI 1 "" "")))]
20358   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20359   "jmp\t*%%r11"
20360   [(set_attr "type" "callv")])
20362 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20363 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20364 ;; caught for use by garbage collectors and the like.  Using an insn that
20365 ;; maps to SIGILL makes it more likely the program will rightfully die.
20366 ;; Keeping with tradition, "6" is in honor of #UD.
20367 (define_insn "trap"
20368   [(trap_if (const_int 1) (const_int 6))]
20369   ""
20370   { return ASM_SHORT "0x0b0f"; }
20371   [(set_attr "length" "2")])
20373 (define_expand "sse_prologue_save"
20374   [(parallel [(set (match_operand:BLK 0 "" "")
20375                    (unspec:BLK [(reg:DI 21)
20376                                 (reg:DI 22)
20377                                 (reg:DI 23)
20378                                 (reg:DI 24)
20379                                 (reg:DI 25)
20380                                 (reg:DI 26)
20381                                 (reg:DI 27)
20382                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20383               (use (match_operand:DI 1 "register_operand" ""))
20384               (use (match_operand:DI 2 "immediate_operand" ""))
20385               (use (label_ref:DI (match_operand 3 "" "")))])]
20386   "TARGET_64BIT"
20387   "")
20389 (define_insn "*sse_prologue_save_insn"
20390   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20391                           (match_operand:DI 4 "const_int_operand" "n")))
20392         (unspec:BLK [(reg:DI 21)
20393                      (reg:DI 22)
20394                      (reg:DI 23)
20395                      (reg:DI 24)
20396                      (reg:DI 25)
20397                      (reg:DI 26)
20398                      (reg:DI 27)
20399                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20400    (use (match_operand:DI 1 "register_operand" "r"))
20401    (use (match_operand:DI 2 "const_int_operand" "i"))
20402    (use (label_ref:DI (match_operand 3 "" "X")))]
20403   "TARGET_64BIT
20404    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20405    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20406   "*
20408   int i;
20409   operands[0] = gen_rtx_MEM (Pmode,
20410                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20411   output_asm_insn (\"jmp\\t%A1\", operands);
20412   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20413     {
20414       operands[4] = adjust_address (operands[0], DImode, i*16);
20415       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20416       PUT_MODE (operands[4], TImode);
20417       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20418         output_asm_insn (\"rex\", operands);
20419       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20420     }
20421   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20422                              CODE_LABEL_NUMBER (operands[3]));
20423   RET;
20425   "
20426   [(set_attr "type" "other")
20427    (set_attr "length_immediate" "0")
20428    (set_attr "length_address" "0")
20429    (set_attr "length" "135")
20430    (set_attr "memory" "store")
20431    (set_attr "modrm" "0")
20432    (set_attr "mode" "DI")])
20434 (define_expand "prefetch"
20435   [(prefetch (match_operand 0 "address_operand" "")
20436              (match_operand:SI 1 "const_int_operand" "")
20437              (match_operand:SI 2 "const_int_operand" ""))]
20438   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20440   int rw = INTVAL (operands[1]);
20441   int locality = INTVAL (operands[2]);
20443   gcc_assert (rw == 0 || rw == 1);
20444   gcc_assert (locality >= 0 && locality <= 3);
20445   gcc_assert (GET_MODE (operands[0]) == Pmode
20446               || GET_MODE (operands[0]) == VOIDmode);
20448   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20449      supported by SSE counterpart or the SSE prefetch is not available
20450      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20451      of locality.  */
20452   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20453     operands[2] = GEN_INT (3);
20454   else
20455     operands[1] = const0_rtx;
20458 (define_insn "*prefetch_sse"
20459   [(prefetch (match_operand:SI 0 "address_operand" "p")
20460              (const_int 0)
20461              (match_operand:SI 1 "const_int_operand" ""))]
20462   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20464   static const char * const patterns[4] = {
20465    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20466   };
20468   int locality = INTVAL (operands[1]);
20469   gcc_assert (locality >= 0 && locality <= 3);
20471   return patterns[locality];  
20473   [(set_attr "type" "sse")
20474    (set_attr "memory" "none")])
20476 (define_insn "*prefetch_sse_rex"
20477   [(prefetch (match_operand:DI 0 "address_operand" "p")
20478              (const_int 0)
20479              (match_operand:SI 1 "const_int_operand" ""))]
20480   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20482   static const char * const patterns[4] = {
20483    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20484   };
20486   int locality = INTVAL (operands[1]);
20487   gcc_assert (locality >= 0 && locality <= 3);
20489   return patterns[locality];  
20491   [(set_attr "type" "sse")
20492    (set_attr "memory" "none")])
20494 (define_insn "*prefetch_3dnow"
20495   [(prefetch (match_operand:SI 0 "address_operand" "p")
20496              (match_operand:SI 1 "const_int_operand" "n")
20497              (const_int 3))]
20498   "TARGET_3DNOW && !TARGET_64BIT"
20500   if (INTVAL (operands[1]) == 0)
20501     return "prefetch\t%a0";
20502   else
20503     return "prefetchw\t%a0";
20505   [(set_attr "type" "mmx")
20506    (set_attr "memory" "none")])
20508 (define_insn "*prefetch_3dnow_rex"
20509   [(prefetch (match_operand:DI 0 "address_operand" "p")
20510              (match_operand:SI 1 "const_int_operand" "n")
20511              (const_int 3))]
20512   "TARGET_3DNOW && TARGET_64BIT"
20514   if (INTVAL (operands[1]) == 0)
20515     return "prefetch\t%a0";
20516   else
20517     return "prefetchw\t%a0";
20519   [(set_attr "type" "mmx")
20520    (set_attr "memory" "none")])
20522 (define_expand "stack_protect_set"
20523   [(match_operand 0 "memory_operand" "")
20524    (match_operand 1 "memory_operand" "")]
20525   ""
20527 #ifdef TARGET_THREAD_SSP_OFFSET
20528   if (TARGET_64BIT)
20529     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20530                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20531   else
20532     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20533                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20534 #else
20535   if (TARGET_64BIT)
20536     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20537   else
20538     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20539 #endif
20540   DONE;
20543 (define_insn "stack_protect_set_si"
20544   [(set (match_operand:SI 0 "memory_operand" "=m")
20545         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20546    (set (match_scratch:SI 2 "=&r") (const_int 0))
20547    (clobber (reg:CC FLAGS_REG))]
20548   ""
20549   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20550   [(set_attr "type" "multi")])
20552 (define_insn "stack_protect_set_di"
20553   [(set (match_operand:DI 0 "memory_operand" "=m")
20554         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20555    (set (match_scratch:DI 2 "=&r") (const_int 0))
20556    (clobber (reg:CC FLAGS_REG))]
20557   "TARGET_64BIT"
20558   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20559   [(set_attr "type" "multi")])
20561 (define_insn "stack_tls_protect_set_si"
20562   [(set (match_operand:SI 0 "memory_operand" "=m")
20563         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20564    (set (match_scratch:SI 2 "=&r") (const_int 0))
20565    (clobber (reg:CC FLAGS_REG))]
20566   ""
20567   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20568   [(set_attr "type" "multi")])
20570 (define_insn "stack_tls_protect_set_di"
20571   [(set (match_operand:DI 0 "memory_operand" "=m")
20572         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20573    (set (match_scratch:DI 2 "=&r") (const_int 0))
20574    (clobber (reg:CC FLAGS_REG))]
20575   "TARGET_64BIT"
20576   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20577   [(set_attr "type" "multi")])
20579 (define_expand "stack_protect_test"
20580   [(match_operand 0 "memory_operand" "")
20581    (match_operand 1 "memory_operand" "")
20582    (match_operand 2 "" "")]
20583   ""
20585   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20586   ix86_compare_op0 = operands[0];
20587   ix86_compare_op1 = operands[1];
20588   ix86_compare_emitted = flags;
20590 #ifdef TARGET_THREAD_SSP_OFFSET
20591   if (TARGET_64BIT)
20592     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20593                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20594   else
20595     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20596                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20597 #else
20598   if (TARGET_64BIT)
20599     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20600   else
20601     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20602 #endif
20603   emit_jump_insn (gen_beq (operands[2]));
20604   DONE;
20607 (define_insn "stack_protect_test_si"
20608   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20609         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20610                      (match_operand:SI 2 "memory_operand" "m")]
20611                     UNSPEC_SP_TEST))
20612    (clobber (match_scratch:SI 3 "=&r"))]
20613   ""
20614   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20615   [(set_attr "type" "multi")])
20617 (define_insn "stack_protect_test_di"
20618   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20619         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20620                      (match_operand:DI 2 "memory_operand" "m")]
20621                     UNSPEC_SP_TEST))
20622    (clobber (match_scratch:DI 3 "=&r"))]
20623   "TARGET_64BIT"
20624   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20625   [(set_attr "type" "multi")])
20627 (define_insn "stack_tls_protect_test_si"
20628   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20629         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20630                      (match_operand:SI 2 "const_int_operand" "i")]
20631                     UNSPEC_SP_TLS_TEST))
20632    (clobber (match_scratch:SI 3 "=r"))]
20633   ""
20634   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20635   [(set_attr "type" "multi")])
20637 (define_insn "stack_tls_protect_test_di"
20638   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20639         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20640                      (match_operand:DI 2 "const_int_operand" "i")]
20641                     UNSPEC_SP_TLS_TEST))
20642    (clobber (match_scratch:DI 3 "=r"))]
20643   "TARGET_64BIT"
20644   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20645   [(set_attr "type" "multi")])
20647 (include "sse.md")
20648 (include "mmx.md")
20649 (include "sync.md")